Compare commits

..

30 Commits

Author SHA1 Message Date
79da411f10 Merge branch 'dev' into web/config-provider-2a-branded
* dev:
  web: Replace  calls to `rootInterface()?.tenant?` with a contextual `this.tenant` object (#7778)
2024-01-08 13:20:03 -08:00
ce761c4337 Merge branch 'web/config-provider-2-tenant' into web/config-provider-2a-branded
* web/config-provider-2-tenant: (146 commits)
  web: abstract `rootInterface()?.config?.capabilities.includes()` into `.can()` (#7737)
  web: update some locale details (#8090)
  web: bump the eslint group in /web with 2 updates (#8082)
  web: bump rollup from 4.9.2 to 4.9.4 in /web (#8083)
  core: bump github.com/redis/go-redis/v9 from 9.3.1 to 9.4.0 (#8085)
  web: bump the eslint group in /tests/wdio with 2 updates (#8086)
  website: bump @types/react from 18.2.46 to 18.2.47 in /website (#8088)
  stages/user_login: only set last_ip in session if a binding is given (#8074)
  providers/oauth2: fix missing nonce in token endpoint not being saved (#8073)
  core: bump goauthentik.io/api/v3 from 3.2023105.3 to 3.2023105.5 (#8066)
  providers/oauth2: fix missing nonce in id_token (#8072)
  rbac: fix error when looking up permissions for now uninstalled apps (#8068)
  web/flows: fix device picker incorrect foreground color (#8067)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#8061)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#8062)
  website: bump postcss from 8.4.32 to 8.4.33 in /website (#8063)
  web: bump the sentry group in /web with 2 updates (#8064)
  core: bump golang.org/x/sync from 0.5.0 to 0.6.0 (#8065)
  website/docs: add link to our example flows (#8052)
  providers/oauth2: offline access (#8026)
  ...
2024-01-08 13:08:51 -08:00
0d3025794c Merge branch 'main' into web/config-provider-2-tenant
* main: (146 commits)
  web: abstract `rootInterface()?.config?.capabilities.includes()` into `.can()` (#7737)
  web: update some locale details (#8090)
  web: bump the eslint group in /web with 2 updates (#8082)
  web: bump rollup from 4.9.2 to 4.9.4 in /web (#8083)
  core: bump github.com/redis/go-redis/v9 from 9.3.1 to 9.4.0 (#8085)
  web: bump the eslint group in /tests/wdio with 2 updates (#8086)
  website: bump @types/react from 18.2.46 to 18.2.47 in /website (#8088)
  stages/user_login: only set last_ip in session if a binding is given (#8074)
  providers/oauth2: fix missing nonce in token endpoint not being saved (#8073)
  core: bump goauthentik.io/api/v3 from 3.2023105.3 to 3.2023105.5 (#8066)
  providers/oauth2: fix missing nonce in id_token (#8072)
  rbac: fix error when looking up permissions for now uninstalled apps (#8068)
  web/flows: fix device picker incorrect foreground color (#8067)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#8061)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#8062)
  website: bump postcss from 8.4.32 to 8.4.33 in /website (#8063)
  web: bump the sentry group in /web with 2 updates (#8064)
  core: bump golang.org/x/sync from 0.5.0 to 0.6.0 (#8065)
  website/docs: add link to our example flows (#8052)
  providers/oauth2: offline access (#8026)
  ...
2024-01-08 10:33:03 -08:00
79601f6d66 Merge branch 'web/config-provider-2-tenant' into web/config-provider-2a-branded
* web/config-provider-2-tenant:
  scripts: postgres, redis: only listen on localhost (#7849)
  website: bump @types/react from 18.2.42 to 18.2.43 in /website (#7840)
  web: bump ts-node from 10.9.1 to 10.9.2 in /tests/wdio (#7846)
  core: bump github.com/go-openapi/runtime from 0.26.0 to 0.26.2 (#7841)
  website: bump prettier from 3.1.0 to 3.1.1 in /website (#7839)
  web: bump the esbuild group in /web with 2 updates (#7842)
  web: bump rollup from 4.6.1 to 4.7.0 in /web (#7843)
  web: bump prettier from 3.1.0 to 3.1.1 in /web (#7844)
  web: bump the wdio group in /tests/wdio with 2 updates (#7845)
  web: bump prettier from 3.1.0 to 3.1.1 in /tests/wdio (#7847)
  translate: Updates for file web/xliff/en.xlf in fr (#7851)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in fr (#7850)
  core: bump python from 3.12.0-slim-bookworm to 3.12.1-slim-bookworm
  web/flows: update flow background (#7833)
  web/flows: fix logo height (#7834)
  Fix cache related image build issues
2023-12-11 08:29:35 -08:00
1ec0623ab6 Merge branch 'web/config-provider' into web/config-provider-2-tenant
* web/config-provider:
  scripts: postgres, redis: only listen on localhost (#7849)
  website: bump @types/react from 18.2.42 to 18.2.43 in /website (#7840)
  web: bump ts-node from 10.9.1 to 10.9.2 in /tests/wdio (#7846)
  core: bump github.com/go-openapi/runtime from 0.26.0 to 0.26.2 (#7841)
  website: bump prettier from 3.1.0 to 3.1.1 in /website (#7839)
  web: bump the esbuild group in /web with 2 updates (#7842)
  web: bump rollup from 4.6.1 to 4.7.0 in /web (#7843)
  web: bump prettier from 3.1.0 to 3.1.1 in /web (#7844)
  web: bump the wdio group in /tests/wdio with 2 updates (#7845)
  web: bump prettier from 3.1.0 to 3.1.1 in /tests/wdio (#7847)
  translate: Updates for file web/xliff/en.xlf in fr (#7851)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in fr (#7850)
  core: bump python from 3.12.0-slim-bookworm to 3.12.1-slim-bookworm
  web/flows: update flow background (#7833)
  web/flows: fix logo height (#7834)
  Fix cache related image build issues
2023-12-11 08:29:13 -08:00
4bf151cfc2 Merge branch 'main' into web/config-provider
* main:
  scripts: postgres, redis: only listen on localhost (#7849)
  website: bump @types/react from 18.2.42 to 18.2.43 in /website (#7840)
  web: bump ts-node from 10.9.1 to 10.9.2 in /tests/wdio (#7846)
  core: bump github.com/go-openapi/runtime from 0.26.0 to 0.26.2 (#7841)
  website: bump prettier from 3.1.0 to 3.1.1 in /website (#7839)
  web: bump the esbuild group in /web with 2 updates (#7842)
  web: bump rollup from 4.6.1 to 4.7.0 in /web (#7843)
  web: bump prettier from 3.1.0 to 3.1.1 in /web (#7844)
  web: bump the wdio group in /tests/wdio with 2 updates (#7845)
  web: bump prettier from 3.1.0 to 3.1.1 in /tests/wdio (#7847)
  translate: Updates for file web/xliff/en.xlf in fr (#7851)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in fr (#7850)
  core: bump python from 3.12.0-slim-bookworm to 3.12.1-slim-bookworm
  web/flows: update flow background (#7833)
  web/flows: fix logo height (#7834)
  Fix cache related image build issues
2023-12-11 08:29:01 -08:00
6752d19375 Merge branch 'web/config-provider-2-tenant' into web/config-provider-2a-branded
* web/config-provider-2-tenant:
  web/flows: show logo in card (#7824)
2023-12-08 13:22:21 -08:00
284c2327c6 Merge branch 'web/config-provider' into web/config-provider-2-tenant
* web/config-provider:
  web/flows: show logo in card (#7824)
2023-12-08 13:02:50 -08:00
600c3caa62 Merge branch 'dev' into web/config-provider
* dev:
  web/flows: show logo in card (#7824)
2023-12-08 13:01:06 -08:00
366d48eddb Merge branch 'web/config-provider-2-tenant' into web/config-provider-2a-branded
* web/config-provider-2-tenant:
  web: prettier still having opinions.
  blueprints: improve file change handler (#7813)
  web/user: fix search not updating app (#7825)
  web: bump the storybook group in /web with 5 updates (#7819)
  core: compile backend translations (#7827)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in de (#7812)
  core: bump github.com/go-openapi/strfmt from 0.21.8 to 0.21.9 (#7814)
  ci: bump actions/stale from 8 to 9 (#7815)
  web: bump the wdio group in /tests/wdio with 1 update (#7816)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#7820)
  web: bump the sentry group in /web with 2 updates (#7817)
  web: bump vite-tsconfig-paths from 4.2.1 to 4.2.2 in /web (#7818)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#7821)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in zh-Hans (#7822)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in zh_CN (#7823)
  web: bump typescript from 5.3.2 to 5.3.3 in /web (#7806)
  website: bump typescript from 5.3.2 to 5.3.3 in /website (#7807)
  web: bump typescript from 5.3.2 to 5.3.3 in /tests/wdio (#7808)
  core: bump goauthentik.io/api/v3 from 3.2023104.1 to 3.2023104.2 (#7809)
  ci: bump actions/setup-go from 4 to 5
2023-12-08 09:58:01 -08:00
e67a290b73 web: prettier still having opinions. 2023-12-08 09:56:56 -08:00
4456f085d3 Merge branch 'web/config-provider' into web/config-provider-2-tenant
* web/config-provider:
  blueprints: improve file change handler (#7813)
  web/user: fix search not updating app (#7825)
  web: bump the storybook group in /web with 5 updates (#7819)
  core: compile backend translations (#7827)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in de (#7812)
  core: bump github.com/go-openapi/strfmt from 0.21.8 to 0.21.9 (#7814)
  ci: bump actions/stale from 8 to 9 (#7815)
  web: bump the wdio group in /tests/wdio with 1 update (#7816)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#7820)
  web: bump the sentry group in /web with 2 updates (#7817)
  web: bump vite-tsconfig-paths from 4.2.1 to 4.2.2 in /web (#7818)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#7821)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in zh-Hans (#7822)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in zh_CN (#7823)
  web: bump typescript from 5.3.2 to 5.3.3 in /web (#7806)
  website: bump typescript from 5.3.2 to 5.3.3 in /website (#7807)
  web: bump typescript from 5.3.2 to 5.3.3 in /tests/wdio (#7808)
  core: bump goauthentik.io/api/v3 from 3.2023104.1 to 3.2023104.2 (#7809)
  ci: bump actions/setup-go from 4 to 5
2023-12-08 09:55:15 -08:00
53e982594e Merge branch 'dev' into web/config-provider
* dev:
  blueprints: improve file change handler (#7813)
  web/user: fix search not updating app (#7825)
  web: bump the storybook group in /web with 5 updates (#7819)
  core: compile backend translations (#7827)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in de (#7812)
  core: bump github.com/go-openapi/strfmt from 0.21.8 to 0.21.9 (#7814)
  ci: bump actions/stale from 8 to 9 (#7815)
  web: bump the wdio group in /tests/wdio with 1 update (#7816)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#7820)
  web: bump the sentry group in /web with 2 updates (#7817)
  web: bump vite-tsconfig-paths from 4.2.1 to 4.2.2 in /web (#7818)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#7821)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in zh-Hans (#7822)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in zh_CN (#7823)
  web: bump typescript from 5.3.2 to 5.3.3 in /web (#7806)
  website: bump typescript from 5.3.2 to 5.3.3 in /website (#7807)
  web: bump typescript from 5.3.2 to 5.3.3 in /tests/wdio (#7808)
  core: bump goauthentik.io/api/v3 from 3.2023104.1 to 3.2023104.2 (#7809)
  ci: bump actions/setup-go from 4 to 5
2023-12-08 09:48:26 -08:00
def988c3b1 Merge branch 'web/config-provider-2-tenant' into web/config-provider-2a-branded
* web/config-provider-2-tenant:
  web: bump API Client version (#7803)
  events: add graph for event volume (#7639)
  website/docs: change links to point to our YouTube (#7794)
  web: bump core-js from 3.33.3 to 3.34.0 in /web (#7796)
  core: bump golang from 1.21.4-bookworm to 1.21.5-bookworm (#7798)
  web: bump the wdio group in /tests/wdio with 4 updates (#7799)
  web/admin: revise wizard form handling (#7331)
  web: bump the eslint group in /tests/wdio with 2 updates (#7783)
  web: bump the sentry group in /web with 2 updates (#7784)
  web: bump the eslint group in /web with 2 updates (#7785)
  web: bump chart.js from 4.4.0 to 4.4.1 in /web (#7786)
  website: bump @types/react from 18.2.41 to 18.2.42 in /website (#7787)
  website: bump react-tooltip from 5.24.0 to 5.25.0 in /website (#7788)
  outposts/ldap: avoid nil ptr deref in MemorySearcher (#7767)
2023-12-06 10:14:04 -08:00
e164661321 Merge branch 'web/config-provider' into web/config-provider-2-tenant
* web/config-provider:
  web: bump API Client version (#7803)
  events: add graph for event volume (#7639)
  website/docs: change links to point to our YouTube (#7794)
  web: bump core-js from 3.33.3 to 3.34.0 in /web (#7796)
  core: bump golang from 1.21.4-bookworm to 1.21.5-bookworm (#7798)
  web: bump the wdio group in /tests/wdio with 4 updates (#7799)
  web/admin: revise wizard form handling (#7331)
  web: bump the eslint group in /tests/wdio with 2 updates (#7783)
  web: bump the sentry group in /web with 2 updates (#7784)
  web: bump the eslint group in /web with 2 updates (#7785)
  web: bump chart.js from 4.4.0 to 4.4.1 in /web (#7786)
  website: bump @types/react from 18.2.41 to 18.2.42 in /website (#7787)
  website: bump react-tooltip from 5.24.0 to 5.25.0 in /website (#7788)
  outposts/ldap: avoid nil ptr deref in MemorySearcher (#7767)
2023-12-06 10:06:55 -08:00
849fea6e91 Merge branch 'dev' into web/config-provider
* dev:
  web: bump API Client version (#7803)
  events: add graph for event volume (#7639)
  website/docs: change links to point to our YouTube (#7794)
  web: bump core-js from 3.33.3 to 3.34.0 in /web (#7796)
  core: bump golang from 1.21.4-bookworm to 1.21.5-bookworm (#7798)
  web: bump the wdio group in /tests/wdio with 4 updates (#7799)
  web/admin: revise wizard form handling (#7331)
  web: bump the eslint group in /tests/wdio with 2 updates (#7783)
  web: bump the sentry group in /web with 2 updates (#7784)
  web: bump the eslint group in /web with 2 updates (#7785)
  web: bump chart.js from 4.4.0 to 4.4.1 in /web (#7786)
  website: bump @types/react from 18.2.41 to 18.2.42 in /website (#7787)
  website: bump react-tooltip from 5.24.0 to 5.25.0 in /website (#7788)
  outposts/ldap: avoid nil ptr deref in MemorySearcher (#7767)
2023-12-06 09:53:26 -08:00
24278d0781 web: change "tenant" to "brand" in all context uses, and update SidebarBrand and DefaultBrand to match. 2023-12-04 11:01:53 -08:00
8c6f83b88e Merge branch 'web/config-provider-2-tenant' into web/config-provider-2a-branded
* web/config-provider-2-tenant:
  web: prettier having opinions after merging with dependent branch
  web: Jens requested that the default subscription state for contexts be , and it's the right call.
  web: Jens requested that subscription be  by default, and it's the right call.
  web: prettier had opinions about the README
2023-12-04 10:52:36 -08:00
fc80596432 web: prettier having opinions after merging with dependent branch 2023-12-04 10:32:16 -08:00
03fde51313 web: Jens requested that the default subscription state for contexts be , and it's the right call. 2023-12-04 10:26:28 -08:00
f669222529 Merge branch 'web/config-provider' into web/config-provider-2-tenant
* web/config-provider:
  web: Jens requested that subscription be  by default, and it's the right call.
  web: prettier had opinions about the README
2023-12-04 10:21:44 -08:00
297c29b231 web: Jens requested that subscription be by default, and it's the right call. 2023-12-04 10:21:26 -08:00
21b50838db web: began rename, but had to stop and go back for a revision. 2023-12-04 10:19:02 -08:00
d2a9b2a343 web: prettier had opinions about the README 2023-12-04 09:56:55 -08:00
c52fa631b4 web: prettier did a thing 2023-12-04 09:49:41 -08:00
6cf2de8a7c Merge branch 'web/config-provider' into web/config-provider-2-tenant
* web/config-provider: (23 commits)
  web: Added a README with a description of the applications' "mental model," essentially an architectural description.
  stages/email: improve error handling for incorrect template syntax (#7758)
  core: bump github.com/go-openapi/strfmt from 0.21.7 to 0.21.8 (#7768)
  website: bump postcss from 8.4.31 to 8.4.32 in /website (#7770)
  web: bump the eslint group in /tests/wdio with 1 update (#7773)
  website: bump @types/react from 18.2.39 to 18.2.41 in /website (#7769)
  web: bump the eslint group in /web with 1 update (#7772)
  website: fix typos in example URLs (#7774)
  root: include ca-certificates in container (#7763)
  root: don't show warning when app has no URLs to import (#7765)
  web: revert storybook (#7764)
  web: bump the eslint group in /web with 2 updates (#7730)
  website: bump @types/react from 18.2.38 to 18.2.39 in /website (#7720)
  web: bump the storybook group in /web with 5 updates (#7750)
  website/blog: fix email syntax (#7753)
  web: bump the wdio group in /tests/wdio with 3 updates (#7751)
  web: bump the babel group in /web with 3 updates (#7741)
  web: bump the sentry group in /web with 2 updates (#7747)
  web: bump pyright from 1.1.337 to 1.1.338 in /web (#7743)
  website: bump the docusaurus group in /website with 9 updates (#7746)
  ...
2023-12-04 09:46:55 -08:00
d4b80c17e8 web: Added a README with a description of the applications' "mental model," essentially an architectural description. 2023-12-04 09:43:22 -08:00
828b8a83ea Merge branch 'main' into web/config-provider
* main: (22 commits)
  stages/email: improve error handling for incorrect template syntax (#7758)
  core: bump github.com/go-openapi/strfmt from 0.21.7 to 0.21.8 (#7768)
  website: bump postcss from 8.4.31 to 8.4.32 in /website (#7770)
  web: bump the eslint group in /tests/wdio with 1 update (#7773)
  website: bump @types/react from 18.2.39 to 18.2.41 in /website (#7769)
  web: bump the eslint group in /web with 1 update (#7772)
  website: fix typos in example URLs (#7774)
  root: include ca-certificates in container (#7763)
  root: don't show warning when app has no URLs to import (#7765)
  web: revert storybook (#7764)
  web: bump the eslint group in /web with 2 updates (#7730)
  website: bump @types/react from 18.2.38 to 18.2.39 in /website (#7720)
  web: bump the storybook group in /web with 5 updates (#7750)
  website/blog: fix email syntax (#7753)
  web: bump the wdio group in /tests/wdio with 3 updates (#7751)
  web: bump the babel group in /web with 3 updates (#7741)
  web: bump the sentry group in /web with 2 updates (#7747)
  web: bump pyright from 1.1.337 to 1.1.338 in /web (#7743)
  website: bump the docusaurus group in /website with 9 updates (#7746)
  web: bump rollup from 4.6.0 to 4.6.1 in /web (#7748)
  ...
2023-12-04 09:43:03 -08:00
115e2f3dcb This commit abstracts access to the object rootInterface()?.tenant? into a single accessor,
`tenant`, that can be mixed into any AKElement object that requires access to it.

Like `WithCapabilitiesConfig` and `WithAuthentikConfig`, this one is named `WithTenantConfig`.

TODO:

``` javascript
rootInterface()?.uiConfig;
me();
```
2023-11-29 15:30:42 -08:00
6228931305 This commit abstracts access to the object rootInterface()?.config? into a single accessor,
`authentikConfig`, that can be mixed into any AKElement object that requires access to it.

Since access to `rootInterface()?.config?` is _universally_ used for a single (and repetitive)
boolean check, a separate accessor has been provided that converts all calls of the form:

``` javascript
rootInterface()?.config?.capabilities.includes(CapabilitiesEnum.CanImpersonate)
```

into:

``` javascript
this.can(CapabilitiesEnum.CanImpersonate)
```

It does this via a Mixin, `WithCapabilitiesConfig`, which understands that these calls only make
sense in the context of a running, fully configured authentik instance, and that their purpose is to
inform authentik components of a user’s capabilities. The latter is why I don’t feel uncomfortable
turning a function call into a method; we should make it explicit that this is a relationship
between components.

The mixin has a single single field, `[WCC.capabilitiesConfig]`, where its association with the
upper-level configuration is made. If that syntax looks peculiar to you, good! I’ve used an explict
unique symbol as the field name; it is inaccessable an innumerable in the object list. The debugger
shows it only as:

    Symbol(): {
        cacheTimeout: 300
        cacheTimeoutFlows: 300
        cacheTimeoutPolicies: 300
        cacheTimeoutReputation: 300
        capabilities: (5) ['can_save_media', 'can_geo_ip', 'can_impersonate', 'can_debug', 'is_enterprise']
    }

Since you can’t reference it by identity, you can’t write to it. Until every browser supports actual
private fields, this is the best we can do; it does guarantee that field name collisions are
impossible, which is a win.

The mixin takes a second optional boolean; setting this to true will cause any web component using
the mixin to automatically schedule a re-render if the capabilities list changes.

The mixin is also generic; despite the "...into a Lit-Context" in the title, the internals of the
Mixin can be replaced with anything so long as the signature of `.can()` is preserved.

Because this work builds off the work I did to give the Sidebar access to the configuration without
ad-hoc retrieval or prop-drilling, it wasn’t necessary to create a new context for it. That will be
necessary for the following:

TODO:

``` javascript
rootInterface()?.uiConfig;
rootInterface()?.tenant;
me();
```
2023-11-29 14:32:54 -08:00
112 changed files with 2128 additions and 7903 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 2023.10.6
current_version = 2023.10.5
tag = True
commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)

View File

@ -4,7 +4,7 @@ description: "Setup authentik testing environment"
inputs:
postgresql_version:
description: "Optional postgresql image tag"
default: "16"
default: "12"
runs:
using: "composite"
@ -18,7 +18,7 @@ runs:
- name: Setup python and restore poetry
uses: actions/setup-python@v4
with:
python-version-file: "pyproject.toml"
python-version-file: 'pyproject.toml'
cache: "poetry"
- name: Setup node
uses: actions/setup-node@v3

View File

@ -2,7 +2,7 @@ version: "3.7"
services:
postgresql:
image: docker.io/library/postgres:${PSQL_TAG:-16}
image: docker.io/library/postgres:${PSQL_TAG:-12}
volumes:
- db-data:/var/lib/postgresql/data
environment:

View File

@ -35,7 +35,6 @@ updates:
sentry:
patterns:
- "@sentry/*"
- "@spotlightjs/*"
babel:
patterns:
- "@babel/*"
@ -67,7 +66,6 @@ updates:
sentry:
patterns:
- "@sentry/*"
- "@spotlightjs/*"
babel:
patterns:
- "@babel/*"

View File

@ -172,7 +172,7 @@ jobs:
run: |
docker-compose -f tests/e2e/docker-compose.yml up -d
- id: cache-web
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: web/dist
key: ${{ runner.os }}-web-${{ hashFiles('web/package-lock.json', 'web/src/**') }}

View File

@ -1,6 +1,24 @@
# syntax=docker/dockerfile:1
# Stage 1: Build webui
# Stage 1: Build website
FROM --platform=${BUILDPLATFORM} docker.io/node:21 as website-builder
ENV NODE_ENV=production
WORKDIR /work/website
RUN --mount=type=bind,target=/work/website/package.json,src=./website/package.json \
--mount=type=bind,target=/work/website/package-lock.json,src=./website/package-lock.json \
--mount=type=cache,id=npm-website,sharing=shared,target=/root/.npm \
npm ci --include=dev
COPY ./website /work/website/
COPY ./blueprints /work/blueprints/
COPY ./SECURITY.md /work/
RUN npm run build-docs-only
# Stage 2: Build webui
FROM --platform=${BUILDPLATFORM} docker.io/node:21 as web-builder
ENV NODE_ENV=production
@ -18,8 +36,8 @@ COPY ./gen-ts-api /work/web/node_modules/@goauthentik/api
RUN npm run build
# Stage 2: Build go proxy
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.6-bookworm AS go-builder
# Stage 3: Build go proxy
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.5-bookworm AS go-builder
ARG TARGETOS
ARG TARGETARCH
@ -50,8 +68,8 @@ RUN --mount=type=cache,sharing=locked,target=/go/pkg/mod \
--mount=type=cache,id=go-build-$TARGETARCH$TARGETVARIANT,sharing=locked,target=/root/.cache/go-build \
GOARM="${TARGETVARIANT#v}" go build -o /go/authentik ./cmd/server
# Stage 3: MaxMind GeoIP
FROM --platform=${BUILDPLATFORM} ghcr.io/maxmind/geoipupdate:v6.1 as geoip
# Stage 4: MaxMind GeoIP
FROM --platform=${BUILDPLATFORM} ghcr.io/maxmind/geoipupdate:v6.0 as geoip
ENV GEOIPUPDATE_EDITION_IDS="GeoLite2-City GeoLite2-ASN"
ENV GEOIPUPDATE_VERBOSE="true"
@ -64,7 +82,7 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
mkdir -p /usr/share/GeoIP && \
/bin/sh -c "/usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
# Stage 4: Python dependencies
# Stage 5: Python dependencies
FROM docker.io/python:3.12.1-slim-bookworm AS python-deps
WORKDIR /ak-root/poetry
@ -89,7 +107,7 @@ RUN --mount=type=bind,target=./pyproject.toml,src=./pyproject.toml \
pip3 install poetry && \
poetry install --only=main --no-ansi --no-interaction
# Stage 5: Run
# Stage 6: Run
FROM docker.io/python:3.12.1-slim-bookworm AS final-image
ARG GIT_BUILD_HASH
@ -131,6 +149,7 @@ COPY --from=go-builder /go/authentik /bin/authentik
COPY --from=python-deps /ak-root/venv /ak-root/venv
COPY --from=web-builder /work/web/dist/ /web/dist/
COPY --from=web-builder /work/web/authentik/ /web/authentik/
COPY --from=website-builder /work/website/help/ /website/help/
COPY --from=geoip /usr/share/GeoIP /geoip
USER 1000

View File

@ -2,7 +2,7 @@
from os import environ
from typing import Optional
__version__ = "2023.10.6"
__version__ = "2023.10.5"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -35,7 +35,7 @@ from authentik.core.models import (
Source,
UserSourceConnection,
)
from authentik.enterprise.models import LicenseKey, LicenseUsage
from authentik.enterprise.models import LicenseUsage
from authentik.events.utils import cleanse_dict
from authentik.flows.models import FlowToken, Stage
from authentik.lib.models import SerializerModel
@ -108,16 +108,12 @@ class Importer:
self.__pk_map: dict[Any, Model] = {}
self._import = blueprint
self.logger = get_logger()
ctx = self.default_context()
ctx = {}
always_merger.merge(ctx, self._import.context)
if context:
always_merger.merge(ctx, context)
self._import.context = ctx
def default_context(self):
"""Default context"""
return {"goauthentik.io/enterprise/licensed": LicenseKey.get_total().is_valid()}
@staticmethod
def from_string(yaml_input: str, context: dict | None = None) -> "Importer":
"""Parse YAML string and create blueprint importer from it"""

View File

@ -1,18 +1,15 @@
"""RAC Provider API Views"""
from django_filters.filters import AllValuesMultipleFilter
from django_filters.filterset import FilterSet
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import extend_schema_field
from rest_framework.fields import CharField
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.propertymappings import PropertyMappingSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import JSONDictField
from authentik.enterprise.api import EnterpriseRequiredMixin
from authentik.enterprise.providers.rac.models import RACPropertyMapping
class RACPropertyMappingSerializer(PropertyMappingSerializer):
class RACPropertyMappingSerializer(EnterpriseRequiredMixin, PropertyMappingSerializer):
"""RACPropertyMapping Serializer"""
static_settings = JSONDictField()
@ -29,16 +26,6 @@ class RACPropertyMappingSerializer(PropertyMappingSerializer):
fields = PropertyMappingSerializer.Meta.fields + ["static_settings"]
class RACPropertyMappingFilter(FilterSet):
"""Filter for RACPropertyMapping"""
managed = extend_schema_field(OpenApiTypes.STR)(AllValuesMultipleFilter(field_name="managed"))
class Meta:
model = RACPropertyMapping
fields = ["name", "managed"]
class RACPropertyMappingViewSet(UsedByMixin, ModelViewSet):
"""RACPropertyMapping Viewset"""
@ -46,4 +33,4 @@ class RACPropertyMappingViewSet(UsedByMixin, ModelViewSet):
serializer_class = RACPropertyMappingSerializer
search_fields = ["name"]
ordering = ["name"]
filterset_class = RACPropertyMappingFilter
filterset_fields = ["name", "managed"]

View File

@ -15,7 +15,7 @@ from authentik.events.models import Event, EventAction
from authentik.flows.challenge import RedirectChallenge
from authentik.flows.exceptions import FlowNonApplicableException
from authentik.flows.models import in_memory_stage
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, FlowPlanner
from authentik.flows.planner import FlowPlanner
from authentik.flows.stage import RedirectStage
from authentik.flows.views.executor import SESSION_KEY_PLAN
from authentik.lib.utils.time import timedelta_from_string
@ -39,12 +39,7 @@ class RACStartView(EnterprisePolicyAccessView):
planner = FlowPlanner(self.provider.authorization_flow)
planner.allow_empty_flows = True
try:
plan = planner.plan(
self.request,
{
PLAN_CONTEXT_APPLICATION: self.application,
},
)
plan = planner.plan(self.request)
except FlowNonApplicableException:
raise Http404
plan.insert_stage(

View File

@ -61,6 +61,9 @@ IGNORED_MODELS = (
def should_log_model(model: Model) -> bool:
"""Return true if operation on `model` should be logged"""
# Check for silk by string so this comparison doesn't fail when silk isn't installed
if model.__module__.startswith("silk"):
return False
return model.__class__ not in IGNORED_MODELS

View File

@ -94,6 +94,7 @@ def get_logger_config():
"kubernetes": "INFO",
"asyncio": "WARNING",
"redis": "WARNING",
"silk": "INFO",
"fsevents": "WARNING",
"uvicorn": "WARNING",
"gunicorn": "INFO",

View File

@ -60,8 +60,6 @@ def sentry_init(**sentry_init_kwargs):
},
}
kwargs.update(**sentry_init_kwargs)
if settings.DEBUG:
kwargs["spotlight"] = True
# pylint: disable=abstract-class-instantiated
sentry_sdk_init(
dsn=CONFIG.get("error_reporting.sentry_dsn"),

View File

@ -87,25 +87,6 @@ class TestAuthorize(OAuthTestCase):
)
OAuthAuthorizationParams.from_request(request)
def test_blocked_redirect_uri(self):
"""test missing/invalid redirect URI"""
OAuth2Provider.objects.create(
name=generate_id(),
client_id="test",
authorization_flow=create_test_flow(),
redirect_uris="data:local.invalid",
)
with self.assertRaises(RedirectUriError):
request = self.factory.get(
"/",
data={
"response_type": "code",
"client_id": "test",
"redirect_uri": "data:localhost",
},
)
OAuthAuthorizationParams.from_request(request)
def test_invalid_redirect_uri_empty(self):
"""test missing/invalid redirect URI"""
provider = OAuth2Provider.objects.create(

View File

@ -76,7 +76,6 @@ PLAN_CONTEXT_PARAMS = "goauthentik.io/providers/oauth2/params"
SESSION_KEY_LAST_LOGIN_UID = "authentik/providers/oauth2/last_login_uid"
ALLOWED_PROMPT_PARAMS = {PROMPT_NONE, PROMPT_CONSENT, PROMPT_LOGIN}
FORBIDDEN_URI_SCHEMES = {"javascript", "data", "vbscript"}
@dataclass(slots=True)
@ -180,10 +179,6 @@ class OAuthAuthorizationParams:
self.check_scope(github_compat)
self.check_nonce()
self.check_code_challenge()
if self.request:
raise AuthorizeError(
self.redirect_uri, "request_not_supported", self.grant_type, self.state
)
def check_redirect_uri(self):
"""Redirect URI validation."""
@ -221,9 +216,10 @@ class OAuthAuthorizationParams:
redirect_uri_expected=allowed_redirect_urls,
)
raise RedirectUriError(self.redirect_uri, allowed_redirect_urls)
# Check against forbidden schemes
if urlparse(self.redirect_uri).scheme in FORBIDDEN_URI_SCHEMES:
raise RedirectUriError(self.redirect_uri, allowed_redirect_urls)
if self.request:
raise AuthorizeError(
self.redirect_uri, "request_not_supported", self.grant_type, self.state
)
def check_scope(self, github_compat=False):
"""Ensure openid scope is set in Hybrid flows, or when requesting an id_token"""

View File

@ -6,7 +6,6 @@ from hashlib import sha256
from re import error as RegexError
from re import fullmatch
from typing import Any, Optional
from urllib.parse import urlparse
from django.http import HttpRequest, HttpResponse
from django.utils import timezone
@ -56,7 +55,6 @@ from authentik.providers.oauth2.models import (
RefreshToken,
)
from authentik.providers.oauth2.utils import TokenResponse, cors_allow, extract_client_auth
from authentik.providers.oauth2.views.authorize import FORBIDDEN_URI_SCHEMES
from authentik.sources.oauth.models import OAuthSource
from authentik.stages.password.stage import PLAN_CONTEXT_METHOD, PLAN_CONTEXT_METHOD_ARGS
@ -208,10 +206,6 @@ class TokenParams:
).from_http(request)
raise TokenError("invalid_client")
# Check against forbidden schemes
if urlparse(self.redirect_uri).scheme in FORBIDDEN_URI_SCHEMES:
raise TokenError("invalid_request")
self.authorization_code = AuthorizationCode.objects.filter(code=raw_code).first()
if not self.authorization_code:
LOGGER.warning("Code does not exist", code=raw_code)

View File

@ -415,6 +415,8 @@ _update_settings("data.user_settings")
if DEBUG:
CELERY["task_always_eager"] = True
os.environ[ENV_GIT_HASH_KEY] = "dev"
INSTALLED_APPS.append("silk")
MIDDLEWARE = ["silk.middleware.SilkyMiddleware"] + MIDDLEWARE
REST_FRAMEWORK["DEFAULT_RENDERER_CLASSES"].append(
"rest_framework.renderers.BrowsableAPIRenderer"
)

View File

@ -1,4 +1,5 @@
"""authentik URL Configuration"""
from django.conf import settings
from django.urls import include, path
from structlog.stdlib import get_logger
@ -47,3 +48,8 @@ urlpatterns += [
path("-/health/live/", LiveView.as_view(), name="health-live"),
path("-/health/ready/", ReadyView.as_view(), name="health-ready"),
]
if settings.DEBUG:
urlpatterns += [
path("debug/silk/", include("silk.urls", namespace="silk")),
]

View File

@ -24,7 +24,7 @@ class SourceTypeSerializer(PassiveSerializer):
"""Serializer for SourceType"""
name = CharField(required=True)
verbose_name = CharField(required=True)
slug = CharField(required=True)
urls_customizable = BooleanField()
request_token_url = CharField(read_only=True, allow_null=True)
authorization_url = CharField(read_only=True, allow_null=True)
@ -56,7 +56,6 @@ class OAuthSourceSerializer(SourceSerializer):
"""Get source's type configuration"""
return SourceTypeSerializer(instance.source_type).data
# pylint: disable=too-many-locals
def validate(self, attrs: dict) -> dict:
session = get_http_session()
source_type = registry.find_type(attrs["provider_type"])
@ -74,17 +73,9 @@ class OAuthSourceSerializer(SourceSerializer):
config = well_known_config.json()
if "issuer" not in config:
raise ValidationError({"oidc_well_known_url": "Invalid well-known configuration"})
field_map = {
# authentik field to oidc field
"authorization_url": "authorization_endpoint",
"access_token_url": "token_endpoint",
"profile_url": "userinfo_endpoint",
}
for ak_key, oidc_key in field_map.items():
# Don't overwrite user-set values
if ak_key in attrs and attrs[ak_key]:
continue
attrs[ak_key] = config.get(oidc_key, "")
attrs["authorization_url"] = config.get("authorization_endpoint", "")
attrs["access_token_url"] = config.get("token_endpoint", "")
attrs["profile_url"] = config.get("userinfo_endpoint", "")
inferred_oidc_jwks_url = config.get("jwks_uri", "")
# Prefer user-entered URL to inferred URL to default URL

View File

@ -44,7 +44,3 @@ class TestTypeAzureAD(TestCase):
self.assertEqual(ak_context["username"], AAD_USER["userPrincipalName"])
self.assertEqual(ak_context["email"], AAD_USER["mail"])
self.assertEqual(ak_context["name"], AAD_USER["displayName"])
def test_user_id(self):
"""Test azure AD user ID"""
self.assertEqual(AzureADOAuthCallback().get_user_id(AAD_USER), AAD_USER["id"])

View File

@ -1,14 +1,13 @@
"""OAuth Source tests"""
from django.test import TestCase
from django.urls import reverse
from requests_mock import Mocker
from rest_framework.test import APITestCase
from authentik.core.tests.utils import create_test_admin_user
from authentik.sources.oauth.api.source import OAuthSourceSerializer
from authentik.sources.oauth.models import OAuthSource
class TestOAuthSource(APITestCase):
class TestOAuthSource(TestCase):
"""OAuth Source tests"""
def setUp(self):
@ -21,19 +20,6 @@ class TestOAuthSource(APITestCase):
consumer_key="",
)
def test_api_read(self):
"""Test reading a source"""
self.client.force_login(create_test_admin_user())
response = self.client.get(
reverse(
"authentik_api:oauthsource-detail",
kwargs={
"slug": self.source.slug,
},
)
)
self.assertEqual(response.status_code, 200)
def test_api_validate(self):
"""Test API validation"""
self.assertTrue(
@ -83,6 +69,9 @@ class TestOAuthSource(APITestCase):
"provider_type": "openidconnect",
"consumer_key": "foo",
"consumer_secret": "foo",
"authorization_url": "http://foo",
"access_token_url": "http://foo",
"profile_url": "http://foo",
"oidc_well_known_url": url,
"oidc_jwks_url": "",
},

View File

@ -25,11 +25,6 @@ class AzureADOAuthCallback(OpenIDConnectOAuth2Callback):
client_class = UserprofileHeaderAuthClient
def get_user_id(self, info: dict[str, str]) -> str:
# Default try to get `id` for the Graph API endpoint
# fallback to OpenID logic in case the profile URL was changed
return info.get("id", super().get_user_id(info))
def get_user_enroll_context(
self,
info: dict[str, Any],
@ -55,7 +50,7 @@ class AzureADType(SourceType):
authorization_url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
access_token_url = "https://login.microsoftonline.com/common/oauth2/v2.0/token" # nosec
profile_url = "https://graph.microsoft.com/v1.0/me"
profile_url = "https://login.microsoftonline.com/common/openid/userinfo"
oidc_well_known_url = (
"https://login.microsoftonline.com/common/.well-known/openid-configuration"
)

View File

@ -1,5 +1,4 @@
"""Validation stage challenge checking"""
from json import loads
from typing import Optional
from urllib.parse import urlencode
@ -11,12 +10,11 @@ from django.utils.translation import gettext_lazy as _
from rest_framework.fields import CharField
from rest_framework.serializers import ValidationError
from structlog.stdlib import get_logger
from webauthn import options_to_json
from webauthn.authentication.generate_authentication_options import generate_authentication_options
from webauthn.authentication.verify_authentication_response import verify_authentication_response
from webauthn.helpers.base64url_to_bytes import base64url_to_bytes
from webauthn.helpers.exceptions import InvalidAuthenticationResponse
from webauthn.helpers.structs import UserVerificationRequirement
from webauthn.helpers.structs import AuthenticationCredential
from authentik.core.api.utils import JSONDictField, PassiveSerializer
from authentik.core.models import Application, User
@ -68,7 +66,12 @@ def get_webauthn_challenge_without_user(
)
request.session[SESSION_KEY_WEBAUTHN_CHALLENGE] = authentication_options.challenge
return loads(options_to_json(authentication_options))
return authentication_options.model_dump(
mode="json",
by_alias=True,
exclude_unset=False,
exclude_none=True,
)
def get_webauthn_challenge(
@ -88,12 +91,17 @@ def get_webauthn_challenge(
authentication_options = generate_authentication_options(
rp_id=get_rp_id(request),
allow_credentials=allowed_credentials,
user_verification=UserVerificationRequirement(stage.webauthn_user_verification),
user_verification=stage.webauthn_user_verification,
)
request.session[SESSION_KEY_WEBAUTHN_CHALLENGE] = authentication_options.challenge
return loads(options_to_json(authentication_options))
return authentication_options.model_dump(
mode="json",
by_alias=True,
exclude_unset=False,
exclude_none=True,
)
def select_challenge(request: HttpRequest, device: Device):
@ -144,7 +152,7 @@ def validate_challenge_webauthn(data: dict, stage_view: StageView, user: User) -
try:
authentication_verification = verify_authentication_response(
credential=data,
credential=AuthenticationCredential.model_validate(data),
expected_challenge=challenge,
expected_rp_id=get_rp_id(request),
expected_origin=get_origin(request),

View File

@ -1,18 +1,14 @@
"""WebAuthn stage"""
from json import loads
from django.http import HttpRequest, HttpResponse
from django.http.request import QueryDict
from rest_framework.fields import CharField
from rest_framework.serializers import ValidationError
from webauthn import options_to_json
from webauthn.helpers.bytes_to_base64url import bytes_to_base64url
from webauthn.helpers.exceptions import InvalidRegistrationResponse
from webauthn.helpers.structs import (
AuthenticatorSelectionCriteria,
PublicKeyCredentialCreationOptions,
ResidentKeyRequirement,
UserVerificationRequirement,
RegistrationCredential,
)
from webauthn.registration.generate_registration_options import generate_registration_options
from webauthn.registration.verify_registration_response import (
@ -57,7 +53,7 @@ class AuthenticatorWebAuthnChallengeResponse(ChallengeResponse):
try:
registration: VerifiedRegistration = verify_registration_response(
credential=response,
credential=RegistrationCredential.model_validate(response),
expected_challenge=challenge,
expected_rp_id=get_rp_id(self.request),
expected_origin=get_origin(self.request),
@ -95,12 +91,12 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
registration_options: PublicKeyCredentialCreationOptions = generate_registration_options(
rp_id=get_rp_id(self.request),
rp_name=self.request.tenant.branding_title,
user_id=user.uid.encode("utf-8"),
user_id=user.uid,
user_name=user.username,
user_display_name=user.name,
authenticator_selection=AuthenticatorSelectionCriteria(
resident_key=ResidentKeyRequirement(str(stage.resident_key_requirement)),
user_verification=UserVerificationRequirement(str(stage.user_verification)),
resident_key=str(stage.resident_key_requirement),
user_verification=str(stage.user_verification),
authenticator_attachment=authenticator_attachment,
),
)
@ -110,7 +106,12 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
return AuthenticatorWebAuthnChallenge(
data={
"type": ChallengeTypes.NATIVE.value,
"registration": loads(options_to_json(registration_options)),
"registration": registration_options.model_dump(
mode="json",
by_alias=True,
exclude_unset=False,
exclude_none=True,
),
}
)

View File

@ -32,7 +32,7 @@ services:
volumes:
- redis:/data
server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.6}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.5}
restart: unless-stopped
command: server
environment:
@ -53,7 +53,7 @@ services:
- postgresql
- redis
worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.6}
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.5}
restart: unless-stopped
command: worker
environment:

14
go.mod
View File

@ -4,8 +4,9 @@ go 1.21
require (
beryju.io/ldap v0.1.0
github.com/Netflix/go-env v0.0.0-20210215222557-e437a7e7f9fb
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/getsentry/sentry-go v0.26.0
github.com/getsentry/sentry-go v0.25.0
github.com/go-http-utils/etag v0.0.0-20161124023236-513ea8f21eb1
github.com/go-ldap/ldap/v3 v3.4.6
github.com/go-openapi/runtime v0.26.2
@ -23,14 +24,13 @@ require (
github.com/pires/go-proxyproto v0.7.0
github.com/prometheus/client_golang v1.18.0
github.com/redis/go-redis/v9 v9.4.0
github.com/sethvargo/go-envconfig v1.0.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0
github.com/stretchr/testify v1.8.4
github.com/wwt/guac v1.3.2
goauthentik.io/api/v3 v3.2023106.3
goauthentik.io/api/v3 v3.2023105.5
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
golang.org/x/oauth2 v0.16.0
golang.org/x/oauth2 v0.15.0
golang.org/x/sync v0.6.0
gopkg.in/yaml.v2 v2.4.0
layeh.com/radius v0.0.0-20210819152912-ad72663a72ab
@ -74,9 +74,9 @@ require (
go.opentelemetry.io/otel v1.17.0 // indirect
go.opentelemetry.io/otel/metric v1.17.0 // indirect
go.opentelemetry.io/otel/trace v1.17.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.31.0 // indirect

32
go.sum
View File

@ -37,6 +37,8 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Netflix/go-env v0.0.0-20210215222557-e437a7e7f9fb h1:w9IDEB7P1VzNcBpOG7kMpFkZp2DkyJIUt0gDx5MBhRU=
github.com/Netflix/go-env v0.0.0-20210215222557-e437a7e7f9fb/go.mod h1:9XMFaCeRyW7fC9XJOWQ+NdAv8VLG7ys7l3x4ozEGLUQ=
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA=
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
@ -71,8 +73,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/getsentry/sentry-go v0.26.0 h1:IX3++sF6/4B5JcevhdZfdKIHfyvMmAq/UnqcyT2H6mA=
github.com/getsentry/sentry-go v0.26.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI=
github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA=
github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
@ -165,8 +167,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
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=
@ -262,8 +264,6 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sethvargo/go-envconfig v1.0.0 h1:1C66wzy4QrROf5ew4KdVw942CQDa55qmlYmw9FZxZdU=
github.com/sethvargo/go-envconfig v1.0.0/go.mod h1:Lzc75ghUn5ucmcRGIdGQ33DKJrcjk4kihFYgSTBmjIc=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
@ -316,8 +316,8 @@ go.opentelemetry.io/otel/trace v1.17.0 h1:/SWhSRHmDPOImIAetP1QAeMnZYiQXrTy4fMMYO
go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
goauthentik.io/api/v3 v3.2023106.3 h1:/ROBnDg6HBNOEyINKdI8pnwiu+ETQfB3MMdjgAoxJ/I=
goauthentik.io/api/v3 v3.2023106.3/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
goauthentik.io/api/v3 v3.2023105.5 h1:wIL3Q0jry1g4kRWpH/Dv1sQqhzuL4BLC+uP/Tar1P/g=
goauthentik.io/api/v3 v3.2023105.5/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=
@ -327,8 +327,8 @@ golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -394,16 +394,16 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
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.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ=
golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM=
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=
@ -452,8 +452,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=

View File

@ -1,7 +1,6 @@
package config
import (
"context"
_ "embed"
"errors"
"fmt"
@ -11,11 +10,10 @@ import (
"reflect"
"strings"
env "github.com/sethvargo/go-envconfig"
env "github.com/Netflix/go-env"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
"goauthentik.io/authentik/lib"
"gopkg.in/yaml.v2"
)
var cfg *Config
@ -115,8 +113,7 @@ func (c *Config) LoadConfigFromFile(path string) error {
}
func (c *Config) fromEnv() error {
ctx := context.Background()
err := env.Process(ctx, c)
_, err := env.UnmarshalFromEnviron(c)
if err != nil {
return fmt.Errorf("failed to load environment variables: %w", err)
}

View File

@ -3,17 +3,17 @@ package config
type Config struct {
// Core specific config
Paths PathsConfig `yaml:"paths"`
LogLevel string `yaml:"log_level" env:"AUTHENTIK_LOG_LEVEL, overwrite"`
ErrorReporting ErrorReportingConfig `yaml:"error_reporting" env:", prefix=AUTHENTIK_ERROR_REPORTING__"`
Redis RedisConfig `yaml:"redis" env:", prefix=AUTHENTIK_REDIS__"`
Outposts OutpostConfig `yaml:"outposts" env:", prefix=AUTHENTIK_OUTPOSTS__"`
LogLevel string `yaml:"log_level" env:"AUTHENTIK_LOG_LEVEL"`
ErrorReporting ErrorReportingConfig `yaml:"error_reporting"`
Redis RedisConfig `yaml:"redis"`
Outposts OutpostConfig `yaml:"outposts"`
// Config for core and embedded outpost
SecretKey string `yaml:"secret_key" env:"AUTHENTIK_SECRET_KEY, overwrite"`
SecretKey string `yaml:"secret_key" env:"AUTHENTIK_SECRET_KEY"`
// Config for both core and outposts
Debug bool `yaml:"debug" env:"AUTHENTIK_DEBUG, overwrite"`
Listen ListenConfig `yaml:"listen" env:", prefix=AUTHENTIK_LISTEN__"`
Debug bool `yaml:"debug" env:"AUTHENTIK_DEBUG"`
Listen ListenConfig `yaml:"listen"`
// Outpost specific config
// These are only relevant for proxy/ldap outposts, and cannot be set via YAML
@ -25,24 +25,24 @@ type Config struct {
}
type RedisConfig struct {
Host string `yaml:"host" env:"HOST, overwrite"`
Port int `yaml:"port" env:"PORT, overwrite"`
DB int `yaml:"db" env:"DB, overwrite"`
Username string `yaml:"username" env:"USERNAME, overwrite"`
Password string `yaml:"password" env:"PASSWORD, overwrite"`
TLS bool `yaml:"tls" env:"TLS, overwrite"`
TLSReqs string `yaml:"tls_reqs" env:"TLS_REQS, overwrite"`
Host string `yaml:"host" env:"AUTHENTIK_REDIS__HOST"`
Port int `yaml:"port" env:"AUTHENTIK_REDIS__PORT"`
DB int `yaml:"db" env:"AUTHENTIK_REDIS__DB"`
Username string `yaml:"username" env:"AUTHENTIK_REDIS__USERNAME"`
Password string `yaml:"password" env:"AUTHENTIK_REDIS__PASSWORD"`
TLS bool `yaml:"tls" env:"AUTHENTIK_REDIS__TLS"`
TLSReqs string `yaml:"tls_reqs" env:"AUTHENTIK_REDIS__TLS_REQS"`
}
type ListenConfig struct {
HTTP string `yaml:"listen_http" env:"HTTP, overwrite"`
HTTPS string `yaml:"listen_https" env:"HTTPS, overwrite"`
LDAP string `yaml:"listen_ldap" env:"LDAP, overwrite"`
LDAPS string `yaml:"listen_ldaps" env:"LDAPS, overwrite"`
Radius string `yaml:"listen_radius" env:"RADIUS, overwrite"`
Metrics string `yaml:"listen_metrics" env:"METRICS, overwrite"`
Debug string `yaml:"listen_debug" env:"DEBUG, overwrite"`
TrustedProxyCIDRs []string `yaml:"trusted_proxy_cidrs" env:"TRUSTED_PROXY_CIDRS, overwrite"`
HTTP string `yaml:"listen_http" env:"AUTHENTIK_LISTEN__HTTP"`
HTTPS string `yaml:"listen_https" env:"AUTHENTIK_LISTEN__HTTPS"`
LDAP string `yaml:"listen_ldap" env:"AUTHENTIK_LISTEN__LDAP"`
LDAPS string `yaml:"listen_ldaps" env:"AUTHENTIK_LISTEN__LDAPS"`
Radius string `yaml:"listen_radius" env:"AUTHENTIK_LISTEN__RADIUS"`
Metrics string `yaml:"listen_metrics" env:"AUTHENTIK_LISTEN__METRICS"`
Debug string `yaml:"listen_debug" env:"AUTHENTIK_LISTEN__DEBUG"`
TrustedProxyCIDRs []string `yaml:"trusted_proxy_cidrs" env:"AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS"`
}
type PathsConfig struct {
@ -50,15 +50,15 @@ type PathsConfig struct {
}
type ErrorReportingConfig struct {
Enabled bool `yaml:"enabled" env:"ENABLED, overwrite"`
SentryDSN string `yaml:"sentry_dsn" env:"SENTRY_DSN, overwrite"`
Environment string `yaml:"environment" env:"ENVIRONMENT, overwrite"`
SendPII bool `yaml:"send_pii" env:"SEND_PII, overwrite"`
SampleRate float64 `yaml:"sample_rate" env:"SAMPLE_RATE, overwrite"`
Enabled bool `yaml:"enabled" env:"AUTHENTIK_ERROR_REPORTING__ENABLED"`
SentryDSN string `yaml:"sentry_dsn" env:"AUTHENTIK_ERROR_REPORTING__SENTRY_DSN"`
Environment string `yaml:"environment" env:"AUTHENTIK_ERROR_REPORTING__ENVIRONMENT"`
SendPII bool `yaml:"send_pii" env:"AUTHENTIK_ERROR_REPORTING__SEND_PII"`
SampleRate float64 `yaml:"sample_rate" env:"AUTHENTIK_ERROR_REPORTING__SAMPLE_RATE"`
}
type OutpostConfig struct {
ContainerImageBase string `yaml:"container_image_base" env:"CONTAINER_IMAGE_BASE, overwrite"`
Discover bool `yaml:"discover" env:"DISCOVER, overwrite"`
DisableEmbeddedOutpost bool `yaml:"disable_embedded_outpost" env:"DISABLE_EMBEDDED_OUTPOST, overwrite"`
ContainerImageBase string `yaml:"container_image_base" env:"AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE"`
Discover bool `yaml:"discover" env:"AUTHENTIK_OUTPOSTS__DISCOVER"`
DisableEmbeddedOutpost bool `yaml:"disable_embedded_outpost" env:"AUTHENTIK_OUTPOSTS__DISABLE_EMBEDDED_OUTPOST"`
}

View File

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

View File

@ -22,6 +22,7 @@ func (ws *WebServer) configureStatic() {
distFs := http.FileServer(http.Dir("./web/dist"))
distHandler := http.StripPrefix("/static/dist/", distFs)
authentikHandler := http.StripPrefix("/static/authentik/", http.FileServer(http.Dir("./web/authentik")))
helpHandler := http.FileServer(http.Dir("./website/help/"))
indexLessRouter.PathPrefix("/static/dist/").Handler(distHandler)
indexLessRouter.PathPrefix("/static/authentik/").Handler(authentikHandler)
@ -41,6 +42,9 @@ func (ws *WebServer) configureStatic() {
indexLessRouter.PathPrefix("/media/").Handler(http.StripPrefix("/media", fs))
statRouter.PathPrefix("/if/help/").Handler(http.StripPrefix("/if/help/", helpHandler))
statRouter.PathPrefix("/help").Handler(http.RedirectHandler("/if/help/", http.StatusMovedPermanently))
ws.lh.Path("/robots.txt").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
rw.Header()["Content-Type"] = []string{"text/plain"}
rw.WriteHeader(200)

View File

@ -1,7 +1,7 @@
# syntax=docker/dockerfile:1
# Stage 1: Build
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.6-bookworm AS builder
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.5-bookworm AS builder
ARG TARGETOS
ARG TARGETARCH

262
poetry.lock generated
View File

@ -326,6 +326,20 @@ six = "*"
[package.extras]
visualize = ["Twisted (>=16.1.1)", "graphviz (>0.5.1)"]
[[package]]
name = "autopep8"
version = "2.0.4"
description = "A tool that automatically formats Python code to conform to the PEP 8 style guide"
optional = false
python-versions = ">=3.6"
files = [
{file = "autopep8-2.0.4-py2.py3-none-any.whl", hash = "sha256:067959ca4a07b24dbd5345efa8325f5f58da4298dab0dde0443d5ed765de80cb"},
{file = "autopep8-2.0.4.tar.gz", hash = "sha256:2913064abd97b3419d1cc83ea71f042cb821f87e45b9c88cad5ad3c4ea87fe0c"},
]
[package.dependencies]
pycodestyle = ">=2.10.0"
[[package]]
name = "bandit"
version = "1.7.6"
@ -669,20 +683,20 @@ tests = ["async-timeout", "coverage (>=4.5,<5.0)", "pytest", "pytest-asyncio", "
[[package]]
name = "channels-redis"
version = "4.2.0"
version = "4.1.0"
description = "Redis-backed ASGI channel layer implementation"
optional = false
python-versions = ">=3.8"
python-versions = ">=3.7"
files = [
{file = "channels_redis-4.2.0-py3-none-any.whl", hash = "sha256:2c5b944a39bd984b72aa8005a3ae11637bf29b5092adeb91c9aad4ab819a8ac4"},
{file = "channels_redis-4.2.0.tar.gz", hash = "sha256:01c26c4d5d3a203f104bba9e5585c0305a70df390d21792386586068162027fd"},
{file = "channels_redis-4.1.0-py3-none-any.whl", hash = "sha256:3696f5b9fe367ea495d402ba83d7c3c99e8ca0e1354ff8d913535976ed0abf73"},
{file = "channels_redis-4.1.0.tar.gz", hash = "sha256:6bd4f75f4ab4a7db17cee495593ace886d7e914c66f8214a1f247ff6659c073a"},
]
[package.dependencies]
asgiref = ">=3.2.10,<4"
channels = "*"
msgpack = ">=1.0,<2.0"
redis = ">=4.6"
redis = ">=4.5.3"
[package.extras]
cryptography = ["cryptography (>=1.3.0)"]
@ -1095,17 +1109,17 @@ graph = ["objgraph (>=1.7.2)"]
[[package]]
name = "django"
version = "5.0.1"
version = "5.0"
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
optional = false
python-versions = ">=3.10"
files = [
{file = "Django-5.0.1-py3-none-any.whl", hash = "sha256:f47a37a90b9bbe2c8ec360235192c7fddfdc832206fcf618bb849b39256affc1"},
{file = "Django-5.0.1.tar.gz", hash = "sha256:8c8659665bc6e3a44fefe1ab0a291e5a3fb3979f9a8230be29de975e57e8f854"},
{file = "Django-5.0-py3-none-any.whl", hash = "sha256:3a9fd52b8dbeae335ddf4a9dfa6c6a0853a1122f1fb071a8d5eca979f73a05c8"},
{file = "Django-5.0.tar.gz", hash = "sha256:7d29e14dfbc19cb6a95a4bd669edbde11f5d4c6a71fdaa42c2d40b6846e807f7"},
]
[package.dependencies]
asgiref = ">=3.7.0,<4"
asgiref = ">=3.7.0"
sqlparse = ">=0.3.1"
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
@ -1187,6 +1201,23 @@ redis = ">=3,<4.0.0 || >4.0.0,<4.0.1 || >4.0.1"
[package.extras]
hiredis = ["redis[hiredis] (>=3,!=4.0.0,!=4.0.1)"]
[[package]]
name = "django-silk"
version = "5.0.4"
description = "Silky smooth profiling for the Django Framework"
optional = false
python-versions = ">=3.8"
files = [
{file = "django-silk-5.0.4.tar.gz", hash = "sha256:8cbfbc647d182527726d8d52d3fcfa193f4d250f21406c3fb1062efa6fb95c63"},
{file = "django_silk-5.0.4-py3-none-any.whl", hash = "sha256:b345d3973d1d382e09735eb525eaf3eebd3edee9a69d1003eb9b01badb2438db"},
]
[package.dependencies]
autopep8 = "*"
Django = ">=3.2"
gprof2dot = ">=2017.09.19"
sqlparse = "*"
[[package]]
name = "djangorestframework"
version = "3.14.0"
@ -1516,20 +1547,20 @@ smmap = ">=3.0.1,<6"
[[package]]
name = "gitpython"
version = "3.1.41"
version = "3.1.40"
description = "GitPython is a Python library used to interact with Git repositories"
optional = false
python-versions = ">=3.7"
files = [
{file = "GitPython-3.1.41-py3-none-any.whl", hash = "sha256:c36b6634d069b3f719610175020a9aed919421c87552185b085e04fbbdb10b7c"},
{file = "GitPython-3.1.41.tar.gz", hash = "sha256:ed66e624884f76df22c8e16066d567aaa5a37d5b5fa19db2c6df6f7156db9048"},
{file = "GitPython-3.1.40-py3-none-any.whl", hash = "sha256:cf14627d5a8049ffbf49915732e5eddbe8134c3bdb9d476e6182b676fc573f8a"},
{file = "GitPython-3.1.40.tar.gz", hash = "sha256:22b126e9ffb671fdd0c129796343a02bf67bf2994b35449ffc9321aa755e18a4"},
]
[package.dependencies]
gitdb = ">=4.0.1,<5"
[package.extras]
test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "sumtypes"]
test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-instafail", "pytest-subtests", "pytest-sugar"]
[[package]]
name = "google-auth"
@ -1554,6 +1585,17 @@ pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"]
reauth = ["pyu2f (>=0.1.5)"]
requests = ["requests (>=2.20.0,<3.0.0.dev0)"]
[[package]]
name = "gprof2dot"
version = "2022.7.29"
description = "Generate a dot graph from the output of several profilers."
optional = false
python-versions = ">=2.7"
files = [
{file = "gprof2dot-2022.7.29-py2.py3-none-any.whl", hash = "sha256:f165b3851d3c52ee4915eb1bd6cca571e5759823c2cd0f71a79bda93c2dc85d6"},
{file = "gprof2dot-2022.7.29.tar.gz", hash = "sha256:45b4d298bd36608fccf9511c3fd88a773f7a1abc04d6cd39445b11ba43133ec5"},
]
[[package]]
name = "gunicorn"
version = "21.2.0"
@ -1744,13 +1786,13 @@ colors = ["colorama (>=0.4.6)"]
[[package]]
name = "jinja2"
version = "3.1.3"
version = "3.1.2"
description = "A very fast and expressive template engine."
optional = false
python-versions = ">=3.7"
files = [
{file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"},
{file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"},
{file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
{file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
]
[package.dependencies]
@ -1853,13 +1895,13 @@ zookeeper = ["kazoo (>=2.8.0)"]
[[package]]
name = "kubernetes"
version = "29.0.0"
version = "27.2.0"
description = "Kubernetes python client"
optional = false
python-versions = ">=3.6"
files = [
{file = "kubernetes-29.0.0-py2.py3-none-any.whl", hash = "sha256:ab8cb0e0576ccdfb71886366efb102c6a20f268d817be065ce7f9909c631e43e"},
{file = "kubernetes-29.0.0.tar.gz", hash = "sha256:c4812e227ae74d07d53c88293e564e54b850452715a59a927e7e1bc6b9a60459"},
{file = "kubernetes-27.2.0-py2.py3-none-any.whl", hash = "sha256:0f9376329c85cf07615ed6886bf9bf21eb1cbfc05e14ec7b0f74ed8153cd2815"},
{file = "kubernetes-27.2.0.tar.gz", hash = "sha256:d479931c6f37561dbfdf28fc5f46384b1cb8b28f9db344ed4a232ce91990825a"},
]
[package.dependencies]
@ -2543,13 +2585,13 @@ files = [
[[package]]
name = "pdoc"
version = "14.4.0"
version = "14.3.0"
description = "API Documentation for Python Projects"
optional = false
python-versions = ">=3.8"
files = [
{file = "pdoc-14.4.0-py3-none-any.whl", hash = "sha256:6ea4fe07620b1f7601e2708a307a257636ec206e20b5611640b30f2e3cab47d6"},
{file = "pdoc-14.4.0.tar.gz", hash = "sha256:c92edc425429ccbe287ace2a027953c24f13de53eab484c1a6d31ca72dd2fda9"},
{file = "pdoc-14.3.0-py3-none-any.whl", hash = "sha256:9a8f9a48bda5a99c249367c2b99779dbdd9f4a56f905068c9c2d6868dbae6882"},
{file = "pdoc-14.3.0.tar.gz", hash = "sha256:40bf8f092fcd91560d5e6cebb7c21b65df699f90a468c8ea316235c3368d5449"},
]
[package.dependencies]
@ -2620,23 +2662,23 @@ wcwidth = "*"
[[package]]
name = "psycopg"
version = "3.1.17"
version = "3.1.16"
description = "PostgreSQL database adapter for Python"
optional = false
python-versions = ">=3.7"
files = [
{file = "psycopg-3.1.17-py3-none-any.whl", hash = "sha256:96b7b13af6d5a514118b759a66b2799a8a4aa78675fa6bb0d3f7d52d67eff002"},
{file = "psycopg-3.1.17.tar.gz", hash = "sha256:437e7d7925459f21de570383e2e10542aceb3b9cb972ce957fdd3826ca47edc6"},
{file = "psycopg-3.1.16-py3-none-any.whl", hash = "sha256:0bfe9741f4fb1c8115cadd8fe832fa91ac277e81e0652ff7fa1400f0ef0f59ba"},
{file = "psycopg-3.1.16.tar.gz", hash = "sha256:a34d922fd7df3134595e71c3428ba6f1bd5f4968db74857fe95de12db2d6b763"},
]
[package.dependencies]
psycopg-c = {version = "3.1.17", optional = true, markers = "implementation_name != \"pypy\" and extra == \"c\""}
psycopg-c = {version = "3.1.16", optional = true, markers = "implementation_name != \"pypy\" and extra == \"c\""}
typing-extensions = ">=4.1"
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
[package.extras]
binary = ["psycopg-binary (==3.1.17)"]
c = ["psycopg-c (==3.1.17)"]
binary = ["psycopg-binary (==3.1.16)"]
c = ["psycopg-c (==3.1.16)"]
dev = ["black (>=23.1.0)", "codespell (>=2.2)", "dnspython (>=2.1)", "flake8 (>=4.0)", "mypy (>=1.4.1)", "types-setuptools (>=57.4)", "wheel (>=0.37)"]
docs = ["Sphinx (>=5.0)", "furo (==2022.6.21)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.12)"]
pool = ["psycopg-pool"]
@ -2644,12 +2686,12 @@ test = ["anyio (>=3.6.2,<4.0)", "mypy (>=1.4.1)", "pproxy (>=2.7)", "pytest (>=6
[[package]]
name = "psycopg-c"
version = "3.1.17"
version = "3.1.16"
description = "PostgreSQL database adapter for Python -- C optimisation distribution"
optional = false
python-versions = ">=3.7"
files = [
{file = "psycopg-c-3.1.17.tar.gz", hash = "sha256:5cc4d544d552b8ab92a9e3a9dbe3b4f46ce0a86338654d26387fc076e0c97977"},
{file = "psycopg-c-3.1.16.tar.gz", hash = "sha256:24f9805e0c20742c72c7be1412e3a600de0980104ff1a264a49333996e6adba3"},
]
[[package]]
@ -2677,6 +2719,17 @@ files = [
[package.dependencies]
pyasn1 = ">=0.4.6,<0.6.0"
[[package]]
name = "pycodestyle"
version = "2.11.1"
description = "Python style guide checker"
optional = false
python-versions = ">=3.8"
files = [
{file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"},
{file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"},
]
[[package]]
name = "pycparser"
version = "2.21"
@ -2690,43 +2743,43 @@ files = [
[[package]]
name = "pycryptodome"
version = "3.20.0"
version = "3.19.1"
description = "Cryptographic library for Python"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
files = [
{file = "pycryptodome-3.20.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:f0e6d631bae3f231d3634f91ae4da7a960f7ff87f2865b2d2b831af1dfb04e9a"},
{file = "pycryptodome-3.20.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:baee115a9ba6c5d2709a1e88ffe62b73ecc044852a925dcb67713a288c4ec70f"},
{file = "pycryptodome-3.20.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:417a276aaa9cb3be91f9014e9d18d10e840a7a9b9a9be64a42f553c5b50b4d1d"},
{file = "pycryptodome-3.20.0-cp27-cp27m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a1250b7ea809f752b68e3e6f3fd946b5939a52eaeea18c73bdab53e9ba3c2dd"},
{file = "pycryptodome-3.20.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:d5954acfe9e00bc83ed9f5cb082ed22c592fbbef86dc48b907238be64ead5c33"},
{file = "pycryptodome-3.20.0-cp27-cp27m-win32.whl", hash = "sha256:06d6de87c19f967f03b4cf9b34e538ef46e99a337e9a61a77dbe44b2cbcf0690"},
{file = "pycryptodome-3.20.0-cp27-cp27m-win_amd64.whl", hash = "sha256:ec0bb1188c1d13426039af8ffcb4dbe3aad1d7680c35a62d8eaf2a529b5d3d4f"},
{file = "pycryptodome-3.20.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5601c934c498cd267640b57569e73793cb9a83506f7c73a8ec57a516f5b0b091"},
{file = "pycryptodome-3.20.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d29daa681517f4bc318cd8a23af87e1f2a7bad2fe361e8aa29c77d652a065de4"},
{file = "pycryptodome-3.20.0-cp27-cp27mu-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3427d9e5310af6680678f4cce149f54e0bb4af60101c7f2c16fdf878b39ccccc"},
{file = "pycryptodome-3.20.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:3cd3ef3aee1079ae44afaeee13393cf68b1058f70576b11439483e34f93cf818"},
{file = "pycryptodome-3.20.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac1c7c0624a862f2e53438a15c9259d1655325fc2ec4392e66dc46cdae24d044"},
{file = "pycryptodome-3.20.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:76658f0d942051d12a9bd08ca1b6b34fd762a8ee4240984f7c06ddfb55eaf15a"},
{file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f35d6cee81fa145333137009d9c8ba90951d7d77b67c79cbe5f03c7eb74d8fe2"},
{file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76cb39afede7055127e35a444c1c041d2e8d2f1f9c121ecef573757ba4cd2c3c"},
{file = "pycryptodome-3.20.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a4c4dc60b78ec41d2afa392491d788c2e06edf48580fbfb0dd0f828af49d25"},
{file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fb3b87461fa35afa19c971b0a2b7456a7b1db7b4eba9a8424666104925b78128"},
{file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:acc2614e2e5346a4a4eab6e199203034924313626f9620b7b4b38e9ad74b7e0c"},
{file = "pycryptodome-3.20.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:210ba1b647837bfc42dd5a813cdecb5b86193ae11a3f5d972b9a0ae2c7e9e4b4"},
{file = "pycryptodome-3.20.0-cp35-abi3-win32.whl", hash = "sha256:8d6b98d0d83d21fb757a182d52940d028564efe8147baa9ce0f38d057104ae72"},
{file = "pycryptodome-3.20.0-cp35-abi3-win_amd64.whl", hash = "sha256:9b3ae153c89a480a0ec402e23db8d8d84a3833b65fa4b15b81b83be9d637aab9"},
{file = "pycryptodome-3.20.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:4401564ebf37dfde45d096974c7a159b52eeabd9969135f0426907db367a652a"},
{file = "pycryptodome-3.20.0-pp27-pypy_73-win32.whl", hash = "sha256:ec1f93feb3bb93380ab0ebf8b859e8e5678c0f010d2d78367cf6bc30bfeb148e"},
{file = "pycryptodome-3.20.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:acae12b9ede49f38eb0ef76fdec2df2e94aad85ae46ec85be3648a57f0a7db04"},
{file = "pycryptodome-3.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f47888542a0633baff535a04726948e876bf1ed880fddb7c10a736fa99146ab3"},
{file = "pycryptodome-3.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e0e4a987d38cfc2e71b4a1b591bae4891eeabe5fa0f56154f576e26287bfdea"},
{file = "pycryptodome-3.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c18b381553638414b38705f07d1ef0a7cf301bc78a5f9bc17a957eb19446834b"},
{file = "pycryptodome-3.20.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a60fedd2b37b4cb11ccb5d0399efe26db9e0dd149016c1cc6c8161974ceac2d6"},
{file = "pycryptodome-3.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:405002eafad114a2f9a930f5db65feef7b53c4784495dd8758069b89baf68eab"},
{file = "pycryptodome-3.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ab6ab0cb755154ad14e507d1df72de9897e99fd2d4922851a276ccc14f4f1a5"},
{file = "pycryptodome-3.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:acf6e43fa75aca2d33e93409f2dafe386fe051818ee79ee8a3e21de9caa2ac9e"},
{file = "pycryptodome-3.20.0.tar.gz", hash = "sha256:09609209ed7de61c2b560cc5c8c4fbf892f8b15b1faf7e4cbffac97db1fffda7"},
{file = "pycryptodome-3.19.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:694020d2ff985cd714381b9da949a21028c24b86f562526186f6af7c7547e986"},
{file = "pycryptodome-3.19.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:4464b0e8fd5508bff9baf18e6fd4c6548b1ac2ce9862d6965ff6a84ec9cb302a"},
{file = "pycryptodome-3.19.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:420972f9c62978e852c74055d81c354079ce3c3a2213a92c9d7e37bbc63a26e2"},
{file = "pycryptodome-3.19.1-cp27-cp27m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1bc0c49d986a1491d66d2a56570f12e960b12508b7e71f2423f532e28857f36"},
{file = "pycryptodome-3.19.1-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:e038ab77fec0956d7aa989a3c647652937fc142ef41c9382c2ebd13c127d5b4a"},
{file = "pycryptodome-3.19.1-cp27-cp27m-win32.whl", hash = "sha256:a991f8ffe8dfe708f86690948ae46442eebdd0fff07dc1b605987939a34ec979"},
{file = "pycryptodome-3.19.1-cp27-cp27m-win_amd64.whl", hash = "sha256:2c16426ef49d9cba018be2340ea986837e1dfa25c2ea181787971654dd49aadd"},
{file = "pycryptodome-3.19.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6d0d2b97758ebf2f36c39060520447c26455acb3bcff309c28b1c816173a6ff5"},
{file = "pycryptodome-3.19.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:b8b80ff92049fd042177282917d994d344365ab7e8ec2bc03e853d93d2401786"},
{file = "pycryptodome-3.19.1-cp27-cp27mu-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd4e7e8bf0fc1ada854688b9b309ee607e2aa85a8b44180f91021a4dd330a928"},
{file = "pycryptodome-3.19.1-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:8cf5d3d6cf921fa81acd1f632f6cedcc03f5f68fc50c364cd39490ba01d17c49"},
{file = "pycryptodome-3.19.1-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:67939a3adbe637281c611596e44500ff309d547e932c449337649921b17b6297"},
{file = "pycryptodome-3.19.1-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:11ddf6c9b52116b62223b6a9f4741bc4f62bb265392a4463282f7f34bb287180"},
{file = "pycryptodome-3.19.1-cp35-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3e6f89480616781d2a7f981472d0cdb09b9da9e8196f43c1234eff45c915766"},
{file = "pycryptodome-3.19.1-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27e1efcb68993b7ce5d1d047a46a601d41281bba9f1971e6be4aa27c69ab8065"},
{file = "pycryptodome-3.19.1-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c6273ca5a03b672e504995529b8bae56da0ebb691d8ef141c4aa68f60765700"},
{file = "pycryptodome-3.19.1-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:b0bfe61506795877ff974f994397f0c862d037f6f1c0bfc3572195fc00833b96"},
{file = "pycryptodome-3.19.1-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:f34976c5c8eb79e14c7d970fb097482835be8d410a4220f86260695ede4c3e17"},
{file = "pycryptodome-3.19.1-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7c9e222d0976f68d0cf6409cfea896676ddc1d98485d601e9508f90f60e2b0a2"},
{file = "pycryptodome-3.19.1-cp35-abi3-win32.whl", hash = "sha256:4805e053571140cb37cf153b5c72cd324bb1e3e837cbe590a19f69b6cf85fd03"},
{file = "pycryptodome-3.19.1-cp35-abi3-win_amd64.whl", hash = "sha256:a470237ee71a1efd63f9becebc0ad84b88ec28e6784a2047684b693f458f41b7"},
{file = "pycryptodome-3.19.1-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:ed932eb6c2b1c4391e166e1a562c9d2f020bfff44a0e1b108f67af38b390ea89"},
{file = "pycryptodome-3.19.1-pp27-pypy_73-win32.whl", hash = "sha256:81e9d23c0316fc1b45d984a44881b220062336bbdc340aa9218e8d0656587934"},
{file = "pycryptodome-3.19.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:37e531bf896b70fe302f003d3be5a0a8697737a8d177967da7e23eff60d6483c"},
{file = "pycryptodome-3.19.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd4e95b0eb4b28251c825fe7aa941fe077f993e5ca9b855665935b86fbb1cc08"},
{file = "pycryptodome-3.19.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c22c80246c3c880c6950d2a8addf156cee74ec0dc5757d01e8e7067a3c7da015"},
{file = "pycryptodome-3.19.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e70f5c839c7798743a948efa2a65d1fe96bb397fe6d7f2bde93d869fe4f0ad69"},
{file = "pycryptodome-3.19.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6c3df3613592ea6afaec900fd7189d23c8c28b75b550254f4bd33fe94acb84b9"},
{file = "pycryptodome-3.19.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08b445799d571041765e7d5c9ca09c5d3866c2f22eeb0dd4394a4169285184f4"},
{file = "pycryptodome-3.19.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:954d156cd50130afd53f8d77f830fe6d5801bd23e97a69d358fed068f433fbfe"},
{file = "pycryptodome-3.19.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b7efd46b0b4ac869046e814d83244aeab14ef787f4850644119b1c8b0ec2d637"},
{file = "pycryptodome-3.19.1.tar.gz", hash = "sha256:8ae0dd1bcfada451c35f9e29a3e5db385caabc190f98e4a80ad02a61098fb776"},
]
[[package]]
@ -3473,28 +3526,28 @@ pyasn1 = ">=0.1.3"
[[package]]
name = "ruff"
version = "0.1.13"
version = "0.1.9"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
{file = "ruff-0.1.13-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e3fd36e0d48aeac672aa850045e784673449ce619afc12823ea7868fcc41d8ba"},
{file = "ruff-0.1.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9fb6b3b86450d4ec6a6732f9f60c4406061b6851c4b29f944f8c9d91c3611c7a"},
{file = "ruff-0.1.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b13ba5d7156daaf3fd08b6b993360a96060500aca7e307d95ecbc5bb47a69296"},
{file = "ruff-0.1.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9ebb40442f7b531e136d334ef0851412410061e65d61ca8ce90d894a094feb22"},
{file = "ruff-0.1.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:226b517f42d59a543d6383cfe03cccf0091e3e0ed1b856c6824be03d2a75d3b6"},
{file = "ruff-0.1.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5f0312ba1061e9b8c724e9a702d3c8621e3c6e6c2c9bd862550ab2951ac75c16"},
{file = "ruff-0.1.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2f59bcf5217c661254bd6bc42d65a6fd1a8b80c48763cb5c2293295babd945dd"},
{file = "ruff-0.1.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e6894b00495e00c27b6ba61af1fc666f17de6140345e5ef27dd6e08fb987259d"},
{file = "ruff-0.1.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1600942485c6e66119da294c6294856b5c86fd6df591ce293e4a4cc8e72989"},
{file = "ruff-0.1.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ee3febce7863e231a467f90e681d3d89210b900d49ce88723ce052c8761be8c7"},
{file = "ruff-0.1.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dcaab50e278ff497ee4d1fe69b29ca0a9a47cd954bb17963628fa417933c6eb1"},
{file = "ruff-0.1.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f57de973de4edef3ad3044d6a50c02ad9fc2dff0d88587f25f1a48e3f72edf5e"},
{file = "ruff-0.1.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7a36fa90eb12208272a858475ec43ac811ac37e91ef868759770b71bdabe27b6"},
{file = "ruff-0.1.13-py3-none-win32.whl", hash = "sha256:a623349a505ff768dad6bd57087e2461be8db58305ebd5577bd0e98631f9ae69"},
{file = "ruff-0.1.13-py3-none-win_amd64.whl", hash = "sha256:f988746e3c3982bea7f824c8fa318ce7f538c4dfefec99cd09c8770bd33e6539"},
{file = "ruff-0.1.13-py3-none-win_arm64.whl", hash = "sha256:6bbbc3042075871ec17f28864808540a26f0f79a4478c357d3e3d2284e832998"},
{file = "ruff-0.1.13.tar.gz", hash = "sha256:e261f1baed6291f434ffb1d5c6bd8051d1c2a26958072d38dfbec39b3dda7352"},
{file = "ruff-0.1.9-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e6a212f436122ac73df851f0cf006e0c6612fe6f9c864ed17ebefce0eff6a5fd"},
{file = "ruff-0.1.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:28d920e319783d5303333630dae46ecc80b7ba294aeffedf946a02ac0b7cc3db"},
{file = "ruff-0.1.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:104aa9b5e12cb755d9dce698ab1b97726b83012487af415a4512fedd38b1459e"},
{file = "ruff-0.1.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1e63bf5a4a91971082a4768a0aba9383c12392d0d6f1e2be2248c1f9054a20da"},
{file = "ruff-0.1.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4d0738917c203246f3e275b37006faa3aa96c828b284ebfe3e99a8cb413c8c4b"},
{file = "ruff-0.1.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:69dac82d63a50df2ab0906d97a01549f814b16bc806deeac4f064ff95c47ddf5"},
{file = "ruff-0.1.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2aec598fb65084e41a9c5d4b95726173768a62055aafb07b4eff976bac72a592"},
{file = "ruff-0.1.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:744dfe4b35470fa3820d5fe45758aace6269c578f7ddc43d447868cfe5078bcb"},
{file = "ruff-0.1.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:479ca4250cab30f9218b2e563adc362bd6ae6343df7c7b5a7865300a5156d5a6"},
{file = "ruff-0.1.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:aa8344310f1ae79af9ccd6e4b32749e93cddc078f9b5ccd0e45bd76a6d2e8bb6"},
{file = "ruff-0.1.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:837c739729394df98f342319f5136f33c65286b28b6b70a87c28f59354ec939b"},
{file = "ruff-0.1.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:e6837202c2859b9f22e43cb01992373c2dbfeae5c0c91ad691a4a2e725392464"},
{file = "ruff-0.1.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:331aae2cd4a0554667ac683243b151c74bd60e78fb08c3c2a4ac05ee1e606a39"},
{file = "ruff-0.1.9-py3-none-win32.whl", hash = "sha256:8151425a60878e66f23ad47da39265fc2fad42aed06fb0a01130e967a7a064f4"},
{file = "ruff-0.1.9-py3-none-win_amd64.whl", hash = "sha256:c497d769164df522fdaf54c6eba93f397342fe4ca2123a2e014a5b8fc7df81c7"},
{file = "ruff-0.1.9-py3-none-win_arm64.whl", hash = "sha256:0e17f53bcbb4fff8292dfd84cf72d767b5e146f009cccd40c2fad27641f8a7a9"},
{file = "ruff-0.1.9.tar.gz", hash = "sha256:b041dee2734719ddbb4518f762c982f2e912e7f28b8ee4fe1dee0b15d1b6e800"},
]
[[package]]
@ -3516,13 +3569,13 @@ urllib3 = {version = ">=1.26,<3", extras = ["socks"]}
[[package]]
name = "sentry-sdk"
version = "1.39.2"
version = "1.39.1"
description = "Python client for Sentry (https://sentry.io)"
optional = false
python-versions = "*"
files = [
{file = "sentry-sdk-1.39.2.tar.gz", hash = "sha256:24c83b0b41c887d33328a9166f5950dc37ad58f01c9f2fbff6b87a6f1094170c"},
{file = "sentry_sdk-1.39.2-py2.py3-none-any.whl", hash = "sha256:acaf597b30258fc7663063b291aa99e58f3096e91fe1e6634f4b79f9c1943e8e"},
{file = "sentry-sdk-1.39.1.tar.gz", hash = "sha256:320a55cdf9da9097a0bead239c35b7e61f53660ef9878861824fd6d9b2eaf3b5"},
{file = "sentry_sdk-1.39.1-py2.py3-none-any.whl", hash = "sha256:81b5b9ffdd1a374e9eb0c053b5d2012155db9cbe76393a8585677b753bd5fdc1"},
]
[package.dependencies]
@ -3548,7 +3601,7 @@ huey = ["huey (>=2)"]
loguru = ["loguru (>=0.5)"]
opentelemetry = ["opentelemetry-distro (>=0.35b0)"]
opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"]
pure-eval = ["asttokens", "executing", "pure_eval"]
pure-eval = ["asttokens", "executing", "pure-eval"]
pymongo = ["pymongo (>=3.1)"]
pyspark = ["pyspark (>=2.4.4)"]
quart = ["blinker (>=1.1)", "quart (>=0.16.1)"]
@ -3561,13 +3614,13 @@ tornado = ["tornado (>=5)"]
[[package]]
name = "service-identity"
version = "24.1.0"
version = "23.1.0"
description = "Service identity verification for pyOpenSSL & cryptography."
optional = false
python-versions = ">=3.8"
files = [
{file = "service_identity-24.1.0-py3-none-any.whl", hash = "sha256:a28caf8130c8a5c1c7a6f5293faaf239bbfb7751e4862436920ee6f2616f568a"},
{file = "service_identity-24.1.0.tar.gz", hash = "sha256:6829c9d62fb832c2e1c435629b0a8c476e1929881f28bee4d20bc24161009221"},
{file = "service_identity-23.1.0-py3-none-any.whl", hash = "sha256:87415a691d52fcad954a500cb81f424d0273f8e7e3ee7d766128f4575080f383"},
{file = "service_identity-23.1.0.tar.gz", hash = "sha256:ecb33cd96307755041e978ab14f8b14e13b40f1fbd525a4dc78f46d2b986431d"},
]
[package.dependencies]
@ -3577,7 +3630,7 @@ pyasn1 = "*"
pyasn1-modules = "*"
[package.extras]
dev = ["pyopenssl", "service-identity[idna,mypy,tests]"]
dev = ["pyopenssl", "service-identity[docs,idna,mypy,tests]"]
docs = ["furo", "myst-parser", "pyopenssl", "sphinx", "sphinx-notfound-page"]
idna = ["idna"]
mypy = ["idna", "mypy", "types-pyopenssl"]
@ -3675,13 +3728,13 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0"
[[package]]
name = "structlog"
version = "24.1.0"
version = "23.3.0"
description = "Structured Logging for Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "structlog-24.1.0-py3-none-any.whl", hash = "sha256:3f6efe7d25fab6e86f277713c218044669906537bb717c1807a09d46bca0714d"},
{file = "structlog-24.1.0.tar.gz", hash = "sha256:41a09886e4d55df25bdcb9b5c9674bccfab723ff43e0a86a1b7b236be8e57b16"},
{file = "structlog-23.3.0-py3-none-any.whl", hash = "sha256:d6922a88ceabef5b13b9eda9c4043624924f60edbb00397f4d193bd754cde60a"},
{file = "structlog-23.3.0.tar.gz", hash = "sha256:24b42b914ac6bc4a4e6f716e82ac70d7fb1e8c3b1035a765591953bfc37101a5"},
]
[package.extras]
@ -3773,13 +3826,13 @@ wsproto = ">=0.14"
[[package]]
name = "twilio"
version = "8.11.1"
version = "8.11.0"
description = "Twilio API client and TwiML generator"
optional = false
python-versions = ">=3.7.0"
files = [
{file = "twilio-8.11.1-py2.py3-none-any.whl", hash = "sha256:0c079601b972cca25dbe0e259d5c4a01c94795842f6b9f1d02c82269019d7cbb"},
{file = "twilio-8.11.1.tar.gz", hash = "sha256:6dfafb60e7a89ad19d2fc4055ce2b86215d30fc68d88452fa588897de8608c71"},
{file = "twilio-8.11.0-py2.py3-none-any.whl", hash = "sha256:90fd47f220e597163020d3755a81aed76fd217e116ab36fd241d9bf48d1a0a18"},
{file = "twilio-8.11.0.tar.gz", hash = "sha256:792509da936c4f47d9fa7071d5f1f3bdc9314aaf96225bac4f0ef28f8688a95b"},
]
[package.dependencies]
@ -3936,13 +3989,13 @@ zstd = ["zstandard (>=0.18.0)"]
[[package]]
name = "uvicorn"
version = "0.26.0"
version = "0.25.0"
description = "The lightning-fast ASGI server."
optional = false
python-versions = ">=3.8"
files = [
{file = "uvicorn-0.26.0-py3-none-any.whl", hash = "sha256:cdb58ef6b8188c6c174994b2b1ba2150a9a8ae7ea5fb2f1b856b94a815d6071d"},
{file = "uvicorn-0.26.0.tar.gz", hash = "sha256:48bfd350fce3c5c57af5fb4995fded8fb50da3b4feb543eb18ad7e0d54589602"},
{file = "uvicorn-0.25.0-py3-none-any.whl", hash = "sha256:ce107f5d9bd02b4636001a77a4e74aab5e1e2b146868ebbad565237145af444c"},
{file = "uvicorn-0.25.0.tar.gz", hash = "sha256:6dddbad1d7ee0f5140aba5ec138ddc9612c5109399903828b4874c9937f009c2"},
]
[package.dependencies]
@ -4153,20 +4206,21 @@ files = [
[[package]]
name = "webauthn"
version = "2.0.0"
version = "1.11.1"
description = "Pythonic WebAuthn"
optional = false
python-versions = "*"
files = [
{file = "webauthn-2.0.0-py3-none-any.whl", hash = "sha256:644dc68af5caaade06be6a2a2278775e85116e92dd755ad7a49d992d51c82033"},
{file = "webauthn-2.0.0.tar.gz", hash = "sha256:12cc1759da98668b8242badc37c4129df300f89d89f5c183fac80e7b33c41dfd"},
{file = "webauthn-1.11.1-py3-none-any.whl", hash = "sha256:13592ee71489b571cb6e4a5d8b3c34f7b040cd3539a9d94b6b7d23fa88df5dfb"},
{file = "webauthn-1.11.1.tar.gz", hash = "sha256:24eda57903897369797f52a377f8c470e7057e79da5525779d0720a9fcc11926"},
]
[package.dependencies]
asn1crypto = ">=1.4.0"
cbor2 = ">=5.4.6"
cryptography = ">=41.0.7"
pyOpenSSL = ">=23.3.0"
cryptography = ">=41.0.4"
pydantic = ">=1.10.11"
pyOpenSSL = ">=23.2.0"
[[package]]
name = "websocket-client"
@ -4488,4 +4542,4 @@ files = [
[metadata]
lock-version = "2.0"
python-versions = "~3.12"
content-hash = "6dcbc2c6d02643a72285e075528ec0841b9c8fda244632386ec19efb7350d4cd"
content-hash = "9d28b9e79139895839ffcba88e2eaad0f842a15888f3f6f8c0ac8879616ac850"

View File

@ -17,7 +17,7 @@ COPY web .
RUN npm run build-proxy
# Stage 2: Build
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.6-bookworm AS builder
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.5-bookworm AS builder
ARG TARGETOS
ARG TARGETARCH

View File

@ -113,7 +113,7 @@ filterwarnings = [
[tool.poetry]
name = "authentik"
version = "2023.10.6"
version = "2023.10.5"
description = ""
authors = ["authentik Team <hello@goauthentik.io>"]
@ -185,6 +185,7 @@ bump2version = "*"
colorama = "*"
coverage = { extras = ["toml"], version = "*" }
debugpy = "*"
django-silk = "*"
drf-jsonschema-serializer = "*"
freezegun = "*"
importlib-metadata = "*"

View File

@ -1,7 +1,7 @@
# syntax=docker/dockerfile:1
# Stage 1: Build
FROM docker.io/golang:1.21.6-bookworm AS builder
FROM docker.io/golang:1.21.5-bookworm AS builder
WORKDIR /go/src/goauthentik.io

View File

@ -1,7 +1,7 @@
# syntax=docker/dockerfile:1
# Stage 1: Build
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.6-bookworm AS builder
FROM --platform=${BUILDPLATFORM} docker.io/golang:1.21.5-bookworm AS builder
ARG TARGETOS
ARG TARGETARCH

View File

@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: authentik
version: 2023.10.6
version: 2023.10.5
description: Making authentication simple.
contact:
email: hello@goauthentik.io
@ -13961,11 +13961,7 @@ paths:
- in: query
name: managed
schema:
type: array
items:
type: string
explode: true
style: form
type: string
- in: query
name: name
schema:
@ -42372,7 +42368,7 @@ components:
properties:
name:
type: string
verbose_name:
slug:
type: string
urls_customizable:
type: boolean
@ -42408,8 +42404,8 @@ components:
- oidc_well_known_url
- profile_url
- request_token_url
- slug
- urls_customizable
- verbose_name
SpBindingEnum:
enum:
- redirect

View File

@ -3,7 +3,7 @@ version: "3.7"
services:
postgresql:
container_name: postgres
image: docker.io/library/postgres:16
image: docker.io/library/postgres:12
volumes:
- db-data:/var/lib/postgresql/data
environment:
@ -18,11 +18,6 @@ services:
ports:
- 127.0.0.1:6379:6379
restart: always
spotlight:
image: ghcr.io/getsentry/spotlight
ports:
- 127.0.0.1:8969:8969
restart: always
volumes:
db-data:

View File

@ -2,6 +2,3 @@
node_modules
# don't lint nyc coverage output
coverage
# Prettier breaks the tsconfig file
tsconfig.json
.eslintrc.json

View File

@ -7,17 +7,17 @@
"name": "@goauthentik/web-tests",
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@typescript-eslint/eslint-plugin": "^6.19.0",
"@typescript-eslint/parser": "^6.19.0",
"@wdio/cli": "^8.28.6",
"@wdio/local-runner": "^8.28.7",
"@wdio/mocha-framework": "^8.28.6",
"@wdio/spec-reporter": "^8.28.6",
"@typescript-eslint/eslint-plugin": "^6.18.0",
"@typescript-eslint/parser": "^6.18.0",
"@wdio/cli": "^8.27.1",
"@wdio/local-runner": "^8.27.0",
"@wdio/mocha-framework": "^8.27.0",
"@wdio/spec-reporter": "^8.27.0",
"eslint": "^8.56.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-sonarjs": "^0.23.0",
"npm-run-all": "^4.1.5",
"prettier": "^3.2.4",
"prettier": "^3.1.1",
"ts-node": "^10.9.2",
"typescript": "^5.3.3",
"wdio-wait-for": "^3.0.10"
@ -946,16 +946,16 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.19.0.tgz",
"integrity": "sha512-DUCUkQNklCQYnrBSSikjVChdc84/vMPDQSgJTHBZ64G9bA9w0Crc0rd2diujKbTdp6w2J47qkeHQLoi0rpLCdg==",
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.18.0.tgz",
"integrity": "sha512-3lqEvQUdCozi6d1mddWqd+kf8KxmGq2Plzx36BlkjuQe3rSTm/O98cLf0A4uDO+a5N1KD2SeEEl6fW97YHY+6w==",
"dev": true,
"dependencies": {
"@eslint-community/regexpp": "^4.5.1",
"@typescript-eslint/scope-manager": "6.19.0",
"@typescript-eslint/type-utils": "6.19.0",
"@typescript-eslint/utils": "6.19.0",
"@typescript-eslint/visitor-keys": "6.19.0",
"@typescript-eslint/scope-manager": "6.18.0",
"@typescript-eslint/type-utils": "6.18.0",
"@typescript-eslint/utils": "6.18.0",
"@typescript-eslint/visitor-keys": "6.18.0",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
"ignore": "^5.2.4",
@ -981,15 +981,15 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.19.0.tgz",
"integrity": "sha512-1DyBLG5SH7PYCd00QlroiW60YJ4rWMuUGa/JBV0iZuqi4l4IK3twKPq5ZkEebmGqRjXWVgsUzfd3+nZveewgow==",
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.18.0.tgz",
"integrity": "sha512-v6uR68SFvqhNQT41frCMCQpsP+5vySy6IdgjlzUWoo7ALCnpaWYcz/Ij2k4L8cEsL0wkvOviCMpjmtRtHNOKzA==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "6.19.0",
"@typescript-eslint/types": "6.19.0",
"@typescript-eslint/typescript-estree": "6.19.0",
"@typescript-eslint/visitor-keys": "6.19.0",
"@typescript-eslint/scope-manager": "6.18.0",
"@typescript-eslint/types": "6.18.0",
"@typescript-eslint/typescript-estree": "6.18.0",
"@typescript-eslint/visitor-keys": "6.18.0",
"debug": "^4.3.4"
},
"engines": {
@ -1009,13 +1009,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.19.0.tgz",
"integrity": "sha512-dO1XMhV2ehBI6QN8Ufi7I10wmUovmLU0Oru3n5LVlM2JuzB4M+dVphCPLkVpKvGij2j/pHBWuJ9piuXx+BhzxQ==",
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.18.0.tgz",
"integrity": "sha512-o/UoDT2NgOJ2VfHpfr+KBY2ErWvCySNUIX/X7O9g8Zzt/tXdpfEU43qbNk8LVuWUT2E0ptzTWXh79i74PP0twA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.19.0",
"@typescript-eslint/visitor-keys": "6.19.0"
"@typescript-eslint/types": "6.18.0",
"@typescript-eslint/visitor-keys": "6.18.0"
},
"engines": {
"node": "^16.0.0 || >=18.0.0"
@ -1026,13 +1026,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.19.0.tgz",
"integrity": "sha512-mcvS6WSWbjiSxKCwBcXtOM5pRkPQ6kcDds/juxcy/727IQr3xMEcwr/YLHW2A2+Fp5ql6khjbKBzOyjuPqGi/w==",
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.18.0.tgz",
"integrity": "sha512-ZeMtrXnGmTcHciJN1+u2CigWEEXgy1ufoxtWcHORt5kGvpjjIlK9MUhzHm4RM8iVy6dqSaZA/6PVkX6+r+ChjQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/typescript-estree": "6.19.0",
"@typescript-eslint/utils": "6.19.0",
"@typescript-eslint/typescript-estree": "6.18.0",
"@typescript-eslint/utils": "6.18.0",
"debug": "^4.3.4",
"ts-api-utils": "^1.0.1"
},
@ -1053,9 +1053,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.19.0.tgz",
"integrity": "sha512-lFviGV/vYhOy3m8BJ/nAKoAyNhInTdXpftonhWle66XHAtT1ouBlkjL496b5H5hb8dWXHwtypTqgtb/DEa+j5A==",
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.18.0.tgz",
"integrity": "sha512-/RFVIccwkwSdW/1zeMx3hADShWbgBxBnV/qSrex6607isYjj05t36P6LyONgqdUrNLl5TYU8NIKdHUYpFvExkA==",
"dev": true,
"engines": {
"node": "^16.0.0 || >=18.0.0"
@ -1066,13 +1066,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.0.tgz",
"integrity": "sha512-o/zefXIbbLBZ8YJ51NlkSAt2BamrK6XOmuxSR3hynMIzzyMY33KuJ9vuMdFSXW+H0tVvdF9qBPTHA91HDb4BIQ==",
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.18.0.tgz",
"integrity": "sha512-klNvl+Ql4NsBNGB4W9TZ2Od03lm7aGvTbs0wYaFYsplVPhr+oeXjlPZCDI4U9jgJIDK38W1FKhacCFzCC+nbIg==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.19.0",
"@typescript-eslint/visitor-keys": "6.19.0",
"@typescript-eslint/types": "6.18.0",
"@typescript-eslint/visitor-keys": "6.18.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@ -1118,17 +1118,17 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.19.0.tgz",
"integrity": "sha512-QR41YXySiuN++/dC9UArYOg4X86OAYP83OWTewpVx5ct1IZhjjgTLocj7QNxGhWoTqknsgpl7L+hGygCO+sdYw==",
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.18.0.tgz",
"integrity": "sha512-wiKKCbUeDPGaYEYQh1S580dGxJ/V9HI7K5sbGAVklyf+o5g3O+adnS4UNJajplF4e7z2q0uVBaTdT/yLb4XAVA==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"@types/json-schema": "^7.0.12",
"@types/semver": "^7.5.0",
"@typescript-eslint/scope-manager": "6.19.0",
"@typescript-eslint/types": "6.19.0",
"@typescript-eslint/typescript-estree": "6.19.0",
"@typescript-eslint/scope-manager": "6.18.0",
"@typescript-eslint/types": "6.18.0",
"@typescript-eslint/typescript-estree": "6.18.0",
"semver": "^7.5.4"
},
"engines": {
@ -1143,12 +1143,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "6.19.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.0.tgz",
"integrity": "sha512-hZaUCORLgubBvtGpp1JEFEazcuEdfxta9j4iUwdSAr7mEsYYAp3EAUyCZk3VEEqGj6W+AV4uWyrDGtrlawAsgQ==",
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.18.0.tgz",
"integrity": "sha512-1wetAlSZpewRDb2h9p/Q8kRjdGuqdTAQbkJIOUMLug2LBLG+QOjiWoSj6/3B/hA9/tVTFFdtiKvAYoYnSRW/RA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "6.19.0",
"@typescript-eslint/types": "6.18.0",
"eslint-visitor-keys": "^3.4.1"
},
"engines": {
@ -1166,18 +1166,18 @@
"dev": true
},
"node_modules/@wdio/cli": {
"version": "8.28.6",
"resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.28.6.tgz",
"integrity": "sha512-cBgm/RA12tlKGqIywsqAJaACST2tbcBtbkNl16io88iiBKAWOMlK5tX75+5dNEeyKs7JlQqBJ+3toXcypf68tA==",
"version": "8.27.1",
"resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.27.1.tgz",
"integrity": "sha512-RY9o4h0iN6UGpU31X5c9mu/TK2FlHtKtDaRJYunm5ycZvGahQcN+naYpea1ftDr4IpI2gGGlHxvEeHkJF7urDQ==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.1",
"@wdio/config": "8.28.6",
"@wdio/globals": "8.28.6",
"@wdio/logger": "8.28.0",
"@wdio/config": "8.27.0",
"@wdio/globals": "8.27.0",
"@wdio/logger": "8.24.12",
"@wdio/protocols": "8.24.12",
"@wdio/types": "8.28.6",
"@wdio/utils": "8.28.6",
"@wdio/types": "8.27.0",
"@wdio/utils": "8.27.0",
"async-exit-hook": "^2.0.1",
"chalk": "^5.2.0",
"chokidar": "^3.5.3",
@ -1192,7 +1192,7 @@
"lodash.union": "^4.6.0",
"read-pkg-up": "^10.0.0",
"recursive-readdir": "^2.2.3",
"webdriverio": "8.28.6",
"webdriverio": "8.27.0",
"yargs": "^17.7.2"
},
"bin": {
@ -1215,14 +1215,14 @@
}
},
"node_modules/@wdio/config": {
"version": "8.28.6",
"resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.28.6.tgz",
"integrity": "sha512-rJ7GFnzg55MvG/CmN3rX79fFFBMcpoFZpILPTNaWJg43lBxidHue5pm7kXJT06D41sSJJPbtgoh6w4VPThIJrg==",
"version": "8.27.0",
"resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.27.0.tgz",
"integrity": "sha512-zYM5daeiBVVAbQj0ASymAt0RUsocLVIwKiUHNa8gg/1GsZnztGjetXExSp1gXlxtMVM5xWUSKjh6ceFK79gWDQ==",
"dev": true,
"dependencies": {
"@wdio/logger": "8.28.0",
"@wdio/types": "8.28.6",
"@wdio/utils": "8.28.6",
"@wdio/logger": "8.24.12",
"@wdio/types": "8.27.0",
"@wdio/utils": "8.27.0",
"decamelize": "^6.0.0",
"deepmerge-ts": "^5.0.0",
"glob": "^10.2.2",
@ -1233,29 +1233,29 @@
}
},
"node_modules/@wdio/globals": {
"version": "8.28.6",
"resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.28.6.tgz",
"integrity": "sha512-6Wjk7iWnpK1ft/caTAhDXxlmwU+pARouzCssqUtdO/vlvP1VhUo3xArCA2dzzJgE+uD16KLR63DRpgkTdwWPkQ==",
"version": "8.27.0",
"resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.27.0.tgz",
"integrity": "sha512-HUPOIsrmxfF0LhU68lVsNGQGZkW/bWOvcCd8WxeaggTAH9JyxasxxfwzeCceAuhAvwtlwoMXITOpjAXO2mj38Q==",
"dev": true,
"engines": {
"node": "^16.13 || >=18"
},
"optionalDependencies": {
"expect-webdriverio": "^4.8.0",
"webdriverio": "8.28.6"
"expect-webdriverio": "^4.6.1",
"webdriverio": "8.27.0"
}
},
"node_modules/@wdio/local-runner": {
"version": "8.28.7",
"resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.28.7.tgz",
"integrity": "sha512-QOeJluWEV3My+41f4kHe7Bo08UcSd3TvH4TbPMflOkl0VvGqxJuKfXlllkQhJ8w5e53fBRsf368vzHscbX86/A==",
"version": "8.27.0",
"resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.27.0.tgz",
"integrity": "sha512-nxS17mhoLkXP20eoPMkz7tbMFMOQejSw0hZfkEvuDCNhJokr8ugp6IjYXL9f7yV9IB9UDGHox8WGY4ArSrOeBA==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@wdio/logger": "8.28.0",
"@wdio/logger": "8.24.12",
"@wdio/repl": "8.24.12",
"@wdio/runner": "8.28.7",
"@wdio/types": "8.28.6",
"@wdio/runner": "8.27.0",
"@wdio/types": "8.27.0",
"async-exit-hook": "^2.0.1",
"split2": "^4.1.0",
"stream-buffers": "^3.0.2"
@ -1265,9 +1265,9 @@
}
},
"node_modules/@wdio/logger": {
"version": "8.28.0",
"resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.28.0.tgz",
"integrity": "sha512-/s6zNCqwy1hoc+K4SJypis0Ud0dlJ+urOelJFO1x0G0rwDRWyFiUP6ijTaCcFxAm29jYEcEPWijl2xkVIHwOyA==",
"version": "8.24.12",
"resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.24.12.tgz",
"integrity": "sha512-QisOiVIWKTUCf1H7S+DOtC+gruhlpimQrUXfWMTeeh672PvAJYnTpOJDWA+BtXfsikkUYFAzAaq8SeMJk8rqKg==",
"dev": true,
"dependencies": {
"chalk": "^5.1.2",
@ -1292,16 +1292,16 @@
}
},
"node_modules/@wdio/mocha-framework": {
"version": "8.28.6",
"resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.28.6.tgz",
"integrity": "sha512-3jTI1GilFGZROJi+UCywEt/ac0b8ETQkG9YlkTAVcxMqG+wUKY2Ks7ow/UDGAaYMHkrEPdopvUFGZmJmpNMKUg==",
"version": "8.27.0",
"resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.27.0.tgz",
"integrity": "sha512-NaFUPv90ks1XlZy0qdUaJ5/ilBtiCCgTIxaPexshJiaVDT5cV+Igjag/O80HIcvqknOZpdKAR0I1ArQzhJrmcA==",
"dev": true,
"dependencies": {
"@types/mocha": "^10.0.0",
"@types/node": "^20.1.0",
"@wdio/logger": "8.28.0",
"@wdio/types": "8.28.6",
"@wdio/utils": "8.28.6",
"@wdio/logger": "8.24.12",
"@wdio/types": "8.27.0",
"@wdio/utils": "8.27.0",
"mocha": "^10.0.0"
},
"engines": {
@ -1327,14 +1327,14 @@
}
},
"node_modules/@wdio/reporter": {
"version": "8.28.6",
"resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.28.6.tgz",
"integrity": "sha512-2KUSytk75fjT4XGEL43u1XLzZSvu1SUg3a7h8fRm2fU2q1dCC16TJk5eod4eSxHzjm2fL1vwFQIAZkwO3WyQZQ==",
"version": "8.27.0",
"resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.27.0.tgz",
"integrity": "sha512-kBwsrHbsblmXfHSWlaOKXjPRPeT29WSKTUoCmzuTcCkhvbjY4TrEB0p04cpaM7uNqdIZTxHng54gZVaG/nZPiw==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@wdio/logger": "8.28.0",
"@wdio/types": "8.28.6",
"@wdio/logger": "8.24.12",
"@wdio/types": "8.27.0",
"diff": "^5.0.0",
"object-inspect": "^1.12.0"
},
@ -1343,35 +1343,35 @@
}
},
"node_modules/@wdio/runner": {
"version": "8.28.7",
"resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.28.7.tgz",
"integrity": "sha512-qk/3cMccCLXrIMN4a/vqmL0UeKaGXDclL/8buWC61IeZZ3SpDUgOoCJH47ULrkIeuoXXrnttZvo12fGjb8zmOg==",
"version": "8.27.0",
"resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.27.0.tgz",
"integrity": "sha512-da332r2d1QXdRhMhsDxMObcqLZS0l/u14pHICNTvEHp+72gOttbjUDvdMHPQY6Ae5ul7AVVQ05qpmz9CX7TzOg==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@wdio/config": "8.28.6",
"@wdio/globals": "8.28.6",
"@wdio/logger": "8.28.0",
"@wdio/types": "8.28.6",
"@wdio/utils": "8.28.6",
"@wdio/config": "8.27.0",
"@wdio/globals": "8.27.0",
"@wdio/logger": "8.24.12",
"@wdio/types": "8.27.0",
"@wdio/utils": "8.27.0",
"deepmerge-ts": "^5.0.0",
"expect-webdriverio": "^4.8.0",
"expect-webdriverio": "^4.6.1",
"gaze": "^1.1.2",
"webdriver": "8.28.6",
"webdriverio": "8.28.6"
"webdriver": "8.27.0",
"webdriverio": "8.27.0"
},
"engines": {
"node": "^16.13 || >=18"
}
},
"node_modules/@wdio/spec-reporter": {
"version": "8.28.6",
"resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.28.6.tgz",
"integrity": "sha512-ZMwbM7hxcV0DumGaK0Y9jzPgTjwYHN539FFcEgbYZV1eNKUyIi9cdEP2xIWZiYQHmq2eKBMlUEPA87mwVZ1V6w==",
"version": "8.27.0",
"resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.27.0.tgz",
"integrity": "sha512-EOXLBIr4oLzSDp/BQ86IqCulSF0jwEAj2EiMeY6dh9WXzBBtoR8WnoX/27xFoZ8GU2zetWC3EVnLJ0Ex8Up1mA==",
"dev": true,
"dependencies": {
"@wdio/reporter": "8.28.6",
"@wdio/types": "8.28.6",
"@wdio/reporter": "8.27.0",
"@wdio/types": "8.27.0",
"chalk": "^5.1.2",
"easy-table": "^1.2.0",
"pretty-ms": "^7.0.0"
@ -1393,9 +1393,9 @@
}
},
"node_modules/@wdio/types": {
"version": "8.28.6",
"resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.28.6.tgz",
"integrity": "sha512-FU3mMRqULpc2XYh6DrSo/KgNoaS6EO9GFJQX5q7+EiOAqVeo1TCLggvAWIPayKyjfD1/ctd9q+uW9vmNicaOjw==",
"version": "8.27.0",
"resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.27.0.tgz",
"integrity": "sha512-LbP9FKh8r0uW9/dKhTIUCC1Su8PsP9TmzGKXkWt6/IMacgJiB/zW3u1CgyaLw9lG0UiQORHGoeJX9zB2HZAh4w==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0"
@ -1405,14 +1405,14 @@
}
},
"node_modules/@wdio/utils": {
"version": "8.28.6",
"resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.28.6.tgz",
"integrity": "sha512-EYQmGvejMiTMB18lW3CDc6cR+jXXjxDebP6ci53oK20QPx9VBuMQZdCbuoftKrKVLA+e9Fk0XfXq8xWYbjAvBQ==",
"version": "8.27.0",
"resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.27.0.tgz",
"integrity": "sha512-4BY+JBQssVn003P5lA289uDMie3LtGinHze5btkcW9timB6VaU+EeZS4eKTPC0pziizLhteVvXYxv3YTpeeRfA==",
"dev": true,
"dependencies": {
"@puppeteer/browsers": "^1.6.0",
"@wdio/logger": "8.28.0",
"@wdio/types": "8.28.6",
"@wdio/logger": "8.24.12",
"@wdio/types": "8.27.0",
"decamelize": "^6.0.0",
"deepmerge-ts": "^5.1.0",
"edgedriver": "^5.3.5",
@ -2481,9 +2481,9 @@
}
},
"node_modules/devtools-protocol": {
"version": "0.0.1245094",
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1245094.tgz",
"integrity": "sha512-c7Tk8wCk2bw+wuQbl8vDh/7rDboWY8TEtcuHj5Q8S9E4F0AJMGJBnp+OqBCTI+xuVeGitQHt04/Rp3tzUStJxg==",
"version": "0.0.1237913",
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1237913.tgz",
"integrity": "sha512-Pxtmz2ZIqBkpU82HaIdsvCQBG94yTC4xajrEsWx9p38QKEfBCJktSazsHkrjf9j3dVVNPhg5LR21F6KWeXpjiQ==",
"dev": true
},
"node_modules/diff": {
@ -3182,9 +3182,9 @@
}
},
"node_modules/expect-webdriverio": {
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/expect-webdriverio/-/expect-webdriverio-4.8.1.tgz",
"integrity": "sha512-JD5aboj/tCiMXdEPCpt3BA0xL3DBhNu1MoiOdBGT9LT+9COIXoDG6Ks6h5S4c4PNwLs6xSeU8s7XxFAmBPu45Q==",
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/expect-webdriverio/-/expect-webdriverio-4.6.1.tgz",
"integrity": "sha512-w6ee91kN3BoxNGVKQheAqFpRGMehdDg7kDiErEk/oM7tbd/WUT4R4v9KYOUtjiaUFHWWCRW2FtcOOjcd0+1pvQ==",
"dev": true,
"dependencies": {
"expect": "^29.7.0",
@ -3195,9 +3195,9 @@
"node": ">=16 || >=18 || >=20"
},
"optionalDependencies": {
"@wdio/globals": "^8.27.0",
"@wdio/logger": "^8.24.12",
"webdriverio": "^8.27.0"
"@wdio/globals": "^8.23.1",
"@wdio/logger": "^8.16.17",
"webdriverio": "^8.23.1"
}
},
"node_modules/external-editor": {
@ -6508,9 +6508,9 @@
}
},
"node_modules/prettier": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.4.tgz",
"integrity": "sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz",
"integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
@ -8520,18 +8520,18 @@
}
},
"node_modules/webdriver": {
"version": "8.28.6",
"resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.28.6.tgz",
"integrity": "sha512-qKZuG2uqGhq2xjk14vSAvE3C6TTTYQyOqDHQOSWNzPNhdBI99g2h4EUbmO3bc/5YaWRsVWWp+RB7jfQZUcE/MA==",
"version": "8.27.0",
"resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.27.0.tgz",
"integrity": "sha512-n1IA+rR3u84XxU9swiKUM06BkEC0GDimfZkBML57cny+utQOUbdM/mBpqCUnkWX/RBz/p2EfHdKNyOs3/REaog==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@types/ws": "^8.5.3",
"@wdio/config": "8.28.6",
"@wdio/logger": "8.28.0",
"@wdio/config": "8.27.0",
"@wdio/logger": "8.24.12",
"@wdio/protocols": "8.24.12",
"@wdio/types": "8.28.6",
"@wdio/utils": "8.28.6",
"@wdio/types": "8.27.0",
"@wdio/utils": "8.27.0",
"deepmerge-ts": "^5.1.0",
"got": "^12.6.1",
"ky": "^0.33.0",
@ -8542,23 +8542,23 @@
}
},
"node_modules/webdriverio": {
"version": "8.28.6",
"resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.28.6.tgz",
"integrity": "sha512-vWo3Qx0bWubzUBBLaLYgeQkSN63KTfW5P3IbayhJ8Qx+NVVnclG0mu4mQj00gvj8+3a8opef6T54gdzitVSHSw==",
"version": "8.27.0",
"resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.27.0.tgz",
"integrity": "sha512-Qh5VCiBjEmxnmXcL1QEFoDzFqTtaWKrXriuU5G0yHKCModGAt2G7IHTkAok3CpmkVJfZpEvY630aP1MvgDtFhw==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@wdio/config": "8.28.6",
"@wdio/logger": "8.28.0",
"@wdio/config": "8.27.0",
"@wdio/logger": "8.24.12",
"@wdio/protocols": "8.24.12",
"@wdio/repl": "8.24.12",
"@wdio/types": "8.28.6",
"@wdio/utils": "8.28.6",
"@wdio/types": "8.27.0",
"@wdio/utils": "8.27.0",
"archiver": "^6.0.0",
"aria-query": "^5.0.0",
"css-shorthand-properties": "^1.1.1",
"css-value": "^0.0.1",
"devtools-protocol": "^0.0.1245094",
"devtools-protocol": "^0.0.1237913",
"grapheme-splitter": "^1.0.2",
"import-meta-resolve": "^4.0.0",
"is-plain-obj": "^4.1.0",
@ -8570,7 +8570,7 @@
"resq": "^1.9.1",
"rgb2hex": "0.2.5",
"serialize-error": "^11.0.1",
"webdriver": "8.28.6"
"webdriver": "8.27.0"
},
"engines": {
"node": "^16.13 || >=18"

View File

@ -4,17 +4,17 @@
"type": "module",
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@typescript-eslint/eslint-plugin": "^6.19.0",
"@typescript-eslint/parser": "^6.19.0",
"@wdio/cli": "^8.28.6",
"@wdio/local-runner": "^8.28.7",
"@wdio/mocha-framework": "^8.28.6",
"@wdio/spec-reporter": "^8.28.6",
"@typescript-eslint/eslint-plugin": "^6.18.0",
"@typescript-eslint/parser": "^6.18.0",
"@wdio/cli": "^8.27.1",
"@wdio/local-runner": "^8.27.0",
"@wdio/mocha-framework": "^8.27.0",
"@wdio/spec-reporter": "^8.27.0",
"eslint": "^8.56.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-sonarjs": "^0.23.0",
"npm-run-all": "^4.1.5",
"prettier": "^3.2.4",
"prettier": "^3.1.1",
"ts-node": "^10.9.2",
"typescript": "^5.3.3",
"wdio-wait-for": "^3.0.10"

View File

@ -9,5 +9,3 @@ poly.ts
src/locale-codes.ts
src/locales/
storybook-static/
# Prettier breaks the tsconfig file
tsconfig.json

1118
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -40,17 +40,17 @@
"@codemirror/lang-xml": "^6.0.2",
"@codemirror/legacy-modes": "^6.3.3",
"@codemirror/theme-one-dark": "^6.1.2",
"@formatjs/intl-listformat": "^7.5.5",
"@formatjs/intl-listformat": "^7.5.3",
"@fortawesome/fontawesome-free": "^6.5.1",
"@goauthentik/api": "^2023.10.6-1705263684",
"@goauthentik/api": "^2023.10.5-1704382057",
"@lit-labs/context": "^0.4.0",
"@lit-labs/task": "^3.1.0",
"@lit/localize": "^0.11.4",
"@open-wc/lit-helpers": "^0.6.0",
"@patternfly/elements": "^2.4.0",
"@patternfly/patternfly": "^4.224.2",
"@sentry/browser": "^7.93.0",
"@sentry/tracing": "^7.93.0",
"@sentry/browser": "^7.92.0",
"@sentry/tracing": "^7.92.0",
"@webcomponents/webcomponentsjs": "^2.8.0",
"base64-js": "^1.5.1",
"chart.js": "^4.4.1",
@ -62,7 +62,7 @@
"fuse.js": "^7.0.0",
"guacamole-common-js": "^1.5.0",
"lit": "^2.8.0",
"mermaid": "^10.7.0",
"mermaid": "^10.6.1",
"rapidoc": "^9.3.4",
"style-mod": "^4.1.0",
"webcomponent-qr-code": "^1.2.0",
@ -75,7 +75,7 @@
"@babel/plugin-transform-private-methods": "^7.23.3",
"@babel/plugin-transform-private-property-in-object": "^7.23.4",
"@babel/plugin-transform-runtime": "^7.23.7",
"@babel/preset-env": "^7.23.8",
"@babel/preset-env": "^7.23.7",
"@babel/preset-typescript": "^7.23.3",
"@hcaptcha/types": "^1.0.3",
"@jackfranklin/rollup-plugin-markdown": "^0.4.0",
@ -86,22 +86,21 @@
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.5",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^11.1.6",
"@spotlightjs/spotlight": "^1.2.7",
"@storybook/addon-essentials": "^7.6.9",
"@storybook/addon-links": "^7.6.9",
"@storybook/api": "^7.6.9",
"@rollup/plugin-typescript": "^11.1.5",
"@storybook/addon-essentials": "^7.6.7",
"@storybook/addon-links": "^7.6.7",
"@storybook/api": "^7.6.7",
"@storybook/blocks": "^7.6.4",
"@storybook/manager-api": "^7.6.9",
"@storybook/web-components": "^7.6.9",
"@storybook/web-components-vite": "^7.6.9",
"@storybook/manager-api": "^7.6.7",
"@storybook/web-components": "^7.6.7",
"@storybook/web-components-vite": "^7.6.7",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/chart.js": "^2.9.41",
"@types/codemirror": "5.60.15",
"@types/grecaptcha": "^3.0.7",
"@types/guacamole-common-js": "1.5.2",
"@typescript-eslint/eslint-plugin": "^6.19.0",
"@typescript-eslint/parser": "^6.19.0",
"@typescript-eslint/eslint-plugin": "^6.18.0",
"@typescript-eslint/parser": "^6.18.0",
"babel-plugin-macros": "^3.1.0",
"babel-plugin-tsconfig-paths": "^1.0.3",
"cross-env": "^7.0.3",
@ -111,25 +110,25 @@
"eslint-plugin-lit": "^1.11.0",
"eslint-plugin-sonarjs": "^0.23.0",
"eslint-plugin-storybook": "^0.6.15",
"lit-analyzer": "^2.0.3",
"lit-analyzer": "^2.0.2",
"npm-run-all": "^4.1.5",
"prettier": "^3.2.4",
"prettier": "^3.1.1",
"pseudolocale": "^2.0.0",
"pyright": "=1.1.338",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rollup": "^4.9.5",
"rollup": "^4.9.4",
"rollup-plugin-copy": "^3.5.0",
"rollup-plugin-cssimport": "^1.0.3",
"rollup-plugin-modify": "^3.0.0",
"rollup-plugin-postcss-lit": "^2.1.0",
"storybook": "^7.6.9",
"storybook": "^7.6.7",
"storybook-addon-mock": "^4.3.0",
"ts-lit-plugin": "^2.0.2",
"ts-lit-plugin": "^2.0.1",
"tslib": "^2.6.2",
"turnstile-types": "^1.2.0",
"typescript": "^5.3.3",
"vite-tsconfig-paths": "^4.3.1"
"vite-tsconfig-paths": "^4.2.3"
},
"optionalDependencies": {
"@esbuild/darwin-arm64": "^0.19.11",

View File

@ -7,7 +7,7 @@ import "@goauthentik/components/ak-number-input";
import "@goauthentik/components/ak-radio-input";
import "@goauthentik/components/ak-switch-input";
import "@goauthentik/components/ak-text-input";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
@ -32,7 +32,7 @@ import {
} from "./LDAPOptionsAndHelp";
@customElement("ak-application-wizard-authentication-by-ldap")
export class ApplicationWizardApplicationDetails extends WithTenantConfig(BaseProviderPanel) {
export class ApplicationWizardApplicationDetails extends WithBrandConfig(BaseProviderPanel) {
render() {
const provider = this.wizard.provider as LDAPProvider | undefined;
const errors = this.wizard.errors.provider;
@ -57,7 +57,7 @@ export class ApplicationWizardApplicationDetails extends WithTenantConfig(BasePr
<ak-tenanted-flow-search
flowType=${FlowsInstancesListDesignationEnum.Authentication}
.currentFlow=${provider?.authorizationFlow}
.tenantFlow=${this.tenant.flowAuthentication}
.tenantFlow=${this.brand.flowAuthentication}
required
></ak-tenanted-flow-search>
<p class="pf-c-form__helper-text">

View File

@ -3,7 +3,7 @@ import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
import { ascii_letters, digits, first, randomString } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-text-input";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
@ -17,7 +17,7 @@ import { FlowsInstancesListDesignationEnum, RadiusProvider } from "@goauthentik/
import BaseProviderPanel from "../BaseProviderPanel";
@customElement("ak-application-wizard-authentication-by-radius")
export class ApplicationWizardAuthenticationByRadius extends WithTenantConfig(BaseProviderPanel) {
export class ApplicationWizardAuthenticationByRadius extends WithBrandConfig(BaseProviderPanel) {
render() {
const provider = this.wizard.provider as RadiusProvider | undefined;
const errors = this.wizard.errors.provider;
@ -42,7 +42,7 @@ export class ApplicationWizardAuthenticationByRadius extends WithTenantConfig(Ba
<ak-tenanted-flow-search
flowType=${FlowsInstancesListDesignationEnum.Authentication}
.currentFlow=${provider?.authorizationFlow}
.tenantFlow=${this.tenant.flowAuthentication}
.tenantFlow=${this.brand.flowAuthentication}
required
></ak-tenanted-flow-search>
<p class="pf-c-form__helper-text">

View File

@ -9,11 +9,11 @@ import { MessageLevel } from "@goauthentik/common/messages";
import { uiConfig } from "@goauthentik/common/ui/config";
import { first } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-status-label";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import {
CapabilitiesEnum,
WithCapabilitiesConfig,
} from "@goauthentik/elements/Interface/capabilitiesProvider";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import "@goauthentik/elements/buttons/ActionButton";
import "@goauthentik/elements/buttons/Dropdown";
import "@goauthentik/elements/forms/DeleteBulkForm";
@ -110,7 +110,7 @@ export class RelatedUserAdd extends Form<{ users: number[] }> {
}
@customElement("ak-user-related-list")
export class RelatedUserList extends WithTenantConfig(WithCapabilitiesConfig(Table<User>)) {
export class RelatedUserList extends WithBrandConfig(WithCapabilitiesConfig(Table<User>)) {
expandable = true;
checkbox = true;
@ -295,7 +295,7 @@ export class RelatedUserList extends WithTenantConfig(WithCapabilitiesConfig(Tab
${msg("Set password")}
</button>
</ak-forms-modal>
${this.tenant?.flowRecovery
${this.brand?.flowRecovery
? html`
<ak-action-button
class="pf-m-secondary"

View File

@ -5,7 +5,6 @@ import "@goauthentik/admin/property-mappings/PropertyMappingSAMLForm";
import "@goauthentik/admin/property-mappings/PropertyMappingScopeForm";
import "@goauthentik/admin/property-mappings/PropertyMappingTestForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import "@goauthentik/elements/Alert";
import { AKElement } from "@goauthentik/elements/Base";
import "@goauthentik/elements/forms/ProxyForm";
import "@goauthentik/elements/wizard/FormWizardPage";
@ -64,7 +63,7 @@ export class InitialPropertyMappingWizardPage extends WizardPage {
];
this.host.isValid = true;
}}
?disabled=${type.requiresEnterprise ? this.enterprise?.hasLicense : false}
?disabled=${type.requiresEnterprise ? !this.enterprise?.hasLicense : false}
/>
<label class="pf-c-radio__label" for=${`${type.component}-${type.modelName}`}
>${type.name}</label
@ -115,7 +114,6 @@ export class PropertyMappingWizard extends AKElement {
<ak-property-mapping-wizard-initial
slot="initial"
.mappingTypes=${this.mappingTypes}
.enterprise=${this.enterprise}
>
</ak-property-mapping-wizard-initial>
${this.mappingTypes.map((type) => {

View File

@ -3,7 +3,7 @@ import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
import { BaseProviderForm } from "@goauthentik/admin/providers/BaseProviderForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
import "@goauthentik/elements/forms/Radio";
@ -25,7 +25,7 @@ import {
} from "@goauthentik/api";
@customElement("ak-provider-ldap-form")
export class LDAPProviderFormPage extends WithTenantConfig(BaseProviderForm<LDAPProvider>) {
export class LDAPProviderFormPage extends WithBrandConfig(BaseProviderForm<LDAPProvider>) {
async loadInstance(pk: number): Promise<LDAPProvider> {
return new ProvidersApi(DEFAULT_CONFIG).providersLdapRetrieve({
id: pk,
@ -68,7 +68,7 @@ export class LDAPProviderFormPage extends WithTenantConfig(BaseProviderForm<LDAP
<ak-tenanted-flow-search
flowType=${FlowsInstancesListDesignationEnum.Authentication}
.currentFlow=${this.instance?.authorizationFlow}
.tenantFlow=${this.tenant?.flowAuthentication}
.tenantFlow=${this.brand?.flowAuthentication}
required
></ak-tenanted-flow-search>
<p class="pf-c-form__helper-text">${msg("Flow used for users to authenticate.")}</p>

View File

@ -203,9 +203,8 @@ export class LDAPProviderViewPage extends AKElement {
class="pf-c-form-control"
readonly
type="text"
value=${`cn=${
this.me?.user.username
},ou=users,${this.provider?.baseDn?.toLowerCase()}`}
value=${`cn=${this.me?.user
.username},ou=users,${this.provider?.baseDn?.toLowerCase()}`}
/>
</div>
<div class="pf-c-form__group">

View File

@ -1,7 +1,7 @@
import { BaseProviderForm } from "@goauthentik/admin/providers/BaseProviderForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { ascii_letters, digits, first, randomString } from "@goauthentik/common/utils";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
import "@goauthentik/elements/forms/SearchSelect";
@ -14,7 +14,7 @@ import { customElement } from "lit/decorators.js";
import { FlowsInstancesListDesignationEnum, ProvidersApi, RadiusProvider } from "@goauthentik/api";
@customElement("ak-provider-radius-form")
export class RadiusProviderFormPage extends WithTenantConfig(BaseProviderForm<RadiusProvider>) {
export class RadiusProviderFormPage extends WithBrandConfig(BaseProviderForm<RadiusProvider>) {
loadInstance(pk: number): Promise<RadiusProvider> {
return new ProvidersApi(DEFAULT_CONFIG).providersRadiusRetrieve({
id: pk,
@ -57,7 +57,7 @@ export class RadiusProviderFormPage extends WithTenantConfig(BaseProviderForm<Ra
<ak-tenanted-flow-search
flowType=${FlowsInstancesListDesignationEnum.Authentication}
.currentFlow=${this.instance?.authorizationFlow}
.tenantFlow=${this.tenant?.flowAuthentication}
.tenantFlow=${this.brand?.flowAuthentication}
required
></ak-tenanted-flow-search>
<p class="pf-c-form__helper-text">${msg("Flow used for users to authenticate.")}</p>

View File

@ -64,7 +64,7 @@ export class OAuthSourceForm extends WithCapabilitiesConfig(BaseSourceForm<OAuth
clearIcon = false;
async send(data: OAuthSource): Promise<OAuthSource> {
data.providerType = (this.providerType?.name || "") as ProviderTypeEnum;
data.providerType = (this.providerType?.slug || "") as ProviderTypeEnum;
let source: OAuthSource;
if (this.instance) {
source = await new SourcesApi(DEFAULT_CONFIG).sourcesOauthPartialUpdate({
@ -178,7 +178,7 @@ export class OAuthSourceForm extends WithCapabilitiesConfig(BaseSourceForm<OAuth
</p>
</ak-form-element-horizontal> `
: html``}
${this.providerType.name === ProviderTypeEnum.Openidconnect ||
${this.providerType.slug === ProviderTypeEnum.Openidconnect ||
this.providerType.oidcWellKnownUrl !== ""
? html`<ak-form-element-horizontal
label=${msg("OIDC Well-known URL")}
@ -200,7 +200,7 @@ export class OAuthSourceForm extends WithCapabilitiesConfig(BaseSourceForm<OAuth
</p>
</ak-form-element-horizontal>`
: html``}
${this.providerType.name === ProviderTypeEnum.Openidconnect ||
${this.providerType.slug === ProviderTypeEnum.Openidconnect ||
this.providerType.oidcJwksUrl !== ""
? html`<ak-form-element-horizontal
label=${msg("OIDC JWKS URL")}

View File

@ -8,7 +8,7 @@ import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
import "@goauthentik/elements/forms/SearchSelect";
import { DefaultTenant } from "@goauthentik/elements/sidebar/SidebarBrand";
import { DefaultBrand } from "@goauthentik/elements/sidebar/SidebarBrand";
import YAML from "yaml";
import { msg } from "@lit/localize";
@ -93,7 +93,7 @@ export class TenantForm extends ModelForm<Tenant, string> {
type="text"
value="${first(
this.instance?.brandingTitle,
DefaultTenant.brandingTitle,
DefaultBrand.brandingTitle,
)}"
class="pf-c-form-control"
required
@ -109,10 +109,7 @@ export class TenantForm extends ModelForm<Tenant, string> {
>
<input
type="text"
value="${first(
this.instance?.brandingLogo,
DefaultTenant.brandingLogo,
)}"
value="${first(this.instance?.brandingLogo, DefaultBrand.brandingLogo)}"
class="pf-c-form-control"
required
/>
@ -129,7 +126,7 @@ export class TenantForm extends ModelForm<Tenant, string> {
type="text"
value="${first(
this.instance?.brandingFavicon,
DefaultTenant.brandingFavicon,
DefaultBrand.brandingFavicon,
)}"
class="pf-c-form-control"
required

View File

@ -12,11 +12,11 @@ import { DefaultUIConfig, uiConfig } from "@goauthentik/common/ui/config";
import { first } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-status-label";
import { rootInterface } from "@goauthentik/elements/Base";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import {
CapabilitiesEnum,
WithCapabilitiesConfig,
} from "@goauthentik/elements/Interface/capabilitiesProvider";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { PFSize } from "@goauthentik/elements/Spinner";
import "@goauthentik/elements/TreeView";
import "@goauthentik/elements/buttons/ActionButton";
@ -91,7 +91,7 @@ const recoveryButtonStyles = css`
`;
@customElement("ak-user-list")
export class UserListPage extends WithTenantConfig(WithCapabilitiesConfig(TablePage<User>)) {
export class UserListPage extends WithBrandConfig(WithCapabilitiesConfig(TablePage<User>)) {
expandable = true;
checkbox = true;
@ -352,7 +352,7 @@ export class UserListPage extends WithTenantConfig(WithCapabilitiesConfig(TableP
${msg("Set password")}
</button>
</ak-forms-modal>
${this.tenant.flowRecovery
${this.brand.flowRecovery
? html`
<ak-action-button
class="pf-m-secondary"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 699 KiB

After

Width:  |  Height:  |  Size: 717 KiB

View File

@ -6,7 +6,13 @@ import {
import { EVENT_LOCALE_REQUEST, EVENT_REFRESH, VERSION } from "@goauthentik/common/constants";
import { globalAK } from "@goauthentik/common/global";
import { Config, Configuration, CoreApi, CurrentTenant, RootApi } from "@goauthentik/api";
import {
Config,
Configuration,
CoreApi,
CurrentTenant as CurrentBrand,
RootApi,
} from "@goauthentik/api";
let globalConfigPromise: Promise<Config> | undefined = Promise.resolve(globalAK().config);
export function config(): Promise<Config> {
@ -16,7 +22,7 @@ export function config(): Promise<Config> {
return globalConfigPromise;
}
export function tenantSetFavicon(tenant: CurrentTenant) {
export function brandSetFavicon(brand: CurrentBrand) {
/**
* <link rel="icon" href="/static/dist/assets/icons/icon.png">
* <link rel="shortcut icon" href="/static/dist/assets/icons/icon.png">
@ -29,36 +35,36 @@ export function tenantSetFavicon(tenant: CurrentTenant) {
relIcon.rel = rel;
document.getElementsByTagName("head")[0].appendChild(relIcon);
}
relIcon.href = tenant.brandingFavicon;
relIcon.href = brand.brandingFavicon;
});
}
export function tenantSetLocale(tenant: CurrentTenant) {
if (tenant.defaultLocale === "") {
export function brandSetLocale(brand: CurrentBrand) {
if (brand.defaultLocale === "") {
return;
}
console.debug("authentik/locale: setting locale from tenant default");
console.debug("authentik/locale: setting locale from brand default");
window.dispatchEvent(
new CustomEvent(EVENT_LOCALE_REQUEST, {
composed: true,
bubbles: true,
detail: { locale: tenant.defaultLocale },
detail: { locale: brand.defaultLocale },
}),
);
}
let globalTenantPromise: Promise<CurrentTenant> | undefined = Promise.resolve(globalAK().tenant);
export function tenant(): Promise<CurrentTenant> {
if (!globalTenantPromise) {
globalTenantPromise = new CoreApi(DEFAULT_CONFIG)
let globalBrandPromise: Promise<CurrentBrand> | undefined = Promise.resolve(globalAK().tenant);
export function brand(): Promise<CurrentBrand> {
if (!globalBrandPromise) {
globalBrandPromise = new CoreApi(DEFAULT_CONFIG)
.coreTenantsCurrentRetrieve()
.then((tenant) => {
tenantSetFavicon(tenant);
tenantSetLocale(tenant);
return tenant;
.then((brand) => {
brandSetFavicon(brand);
brandSetLocale(brand);
return brand;
});
}
return globalTenantPromise;
return globalBrandPromise;
}
export function getMetaContent(key: string): string {
@ -90,9 +96,9 @@ window.addEventListener(EVENT_REFRESH, () => {
// Upon global refresh, disregard whatever was pre-hydrated and
// actually load info from API
globalConfigPromise = undefined;
globalTenantPromise = undefined;
globalBrandPromise = undefined;
config();
tenant();
brand();
});
console.debug(`authentik(early): version ${VERSION}, apiBase ${DEFAULT_CONFIG.basePath}`);

View File

@ -2,7 +2,7 @@ import { EVENT_REQUEST_POST } from "@goauthentik/common/constants";
import { getCookie } from "@goauthentik/common/utils";
import {
CurrentTenant,
CurrentTenant as CurrentBrand,
FetchParams,
Middleware,
RequestContext,
@ -18,13 +18,13 @@ export interface RequestInfo {
}
export class LoggingMiddleware implements Middleware {
tenant: CurrentTenant;
constructor(tenant: CurrentTenant) {
this.tenant = tenant;
brand: CurrentBrand;
constructor(brand: CurrentBrand) {
this.brand = brand;
}
post(context: ResponseContext): Promise<Response | void> {
let msg = `authentik/api[${this.tenant.matchedDomain}]: `;
let msg = `authentik/api[${this.brand.matchedDomain}]: `;
// https://developer.mozilla.org/en-US/docs/Web/API/console#styling_console_output
msg += `%c${context.response.status}%c ${context.init.method} ${context.url}`;
let style = "";

View File

@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
export const ERROR_CLASS = "pf-m-danger";
export const PROGRESS_CLASS = "pf-m-in-progress";
export const CURRENT_CLASS = "pf-m-current";
export const VERSION = "2023.10.6";
export const VERSION = "2023.10.5";
export const TITLE_DEFAULT = "authentik";
export const ROUTE_SEPARATOR = ";";

View File

@ -5,7 +5,7 @@ import { me } from "@goauthentik/common/users";
import * as Sentry from "@sentry/browser";
import { Integrations } from "@sentry/tracing";
import { CapabilitiesEnum, Config, ResponseError } from "@goauthentik/api";
import { Config, ResponseError } from "@goauthentik/api";
export const TAG_SENTRY_COMPONENT = "authentik.component";
export const TAG_SENTRY_CAPABILITIES = "authentik.capabilities";
@ -60,11 +60,6 @@ export async function configureSentry(canDoPpi = false): Promise<Config> {
scope.setTransactionName(`authentik.web.if.${currentInterface()}`),
);
}
if (cfg.capabilities.includes(CapabilitiesEnum.CanDebug)) {
const Spotlight = await import("@spotlightjs/spotlight");
Spotlight.init({ injectImmediately: true });
}
if (cfg.errorReporting.sendPii && canDoPpi) {
me().then((user) => {
Sentry.setUser({ email: user.user.email });

View File

@ -134,11 +134,9 @@ html > form > input {
);
max-height: 9rem;
}
.ak-brand {
display: flex;
justify-content: center;
width: 100%;
}
.ak-brand img {
padding: 0 2rem;

View File

@ -257,8 +257,7 @@ select[multiple] option:checked {
.pf-c-login__main-header-desc {
color: var(--ak-dark-foreground);
}
.pf-c-login__main-footer-links-item img,
.pf-c-login__main-footer-links-item .fas {
.pf-c-login__main-footer-links-item img {
filter: invert(1);
}
.pf-c-login__main-footer-band {

View File

@ -1,11 +1,9 @@
import { createContext } from "@lit-labs/context";
import type { Config, CurrentTenant } from "@goauthentik/api";
import type { Config, CurrentTenant as CurrentBrand } from "@goauthentik/api";
export const authentikConfigContext = createContext<Config>(Symbol("authentik-config-context"));
export const authentikTenantContext = createContext<CurrentTenant>(
Symbol("authentik-tenant-context"),
);
export const authentikBrandContext = createContext<CurrentBrand>(Symbol("authentik-brand-context"));
export default authentikConfigContext;

View File

@ -9,13 +9,13 @@ import { LitElement } from "lit";
import AKGlobal from "@goauthentik/common/styles/authentik.css";
import ThemeDark from "@goauthentik/common/styles/theme-dark.css";
import { Config, CurrentTenant, UiThemeEnum } from "@goauthentik/api";
import { Config, CurrentTenant as CurrentBrand, UiThemeEnum } from "@goauthentik/api";
import { AdoptedStyleSheetsElement } from "./types";
type AkInterface = HTMLElement & {
getTheme: () => Promise<UiThemeEnum>;
tenant?: CurrentTenant;
brand?: CurrentBrand;
uiConfig?: UIConfig;
config?: Config;
};

View File

@ -1,8 +1,8 @@
import { config, tenant } from "@goauthentik/common/api/config";
import { brand, config } from "@goauthentik/common/api/config";
import { UIConfig, uiConfig } from "@goauthentik/common/ui/config";
import {
authentikBrandContext,
authentikConfigContext,
authentikTenantContext,
} from "@goauthentik/elements/AuthentikContexts";
import type { AdoptedStyleSheetsElement } from "@goauthentik/elements/types";
import { ensureCSSStyleSheet } from "@goauthentik/elements/utils/ensureCSSStyleSheet";
@ -12,13 +12,13 @@ import { state } from "lit/decorators.js";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { Config, CurrentTenant, UiThemeEnum } from "@goauthentik/api";
import { Config, CurrentTenant as CurrentBrand, UiThemeEnum } from "@goauthentik/api";
import { AKElement } from "../Base";
type AkInterface = HTMLElement & {
getTheme: () => Promise<UiThemeEnum>;
tenant?: CurrentTenant;
brand?: CurrentBrand;
uiConfig?: UIConfig;
config?: Config;
};
@ -45,28 +45,28 @@ export class Interface extends AKElement implements AkInterface {
return this._config;
}
_tenantContext = new ContextProvider(this, {
context: authentikTenantContext,
_brandContext = new ContextProvider(this, {
context: authentikBrandContext,
initialValue: undefined,
});
_tenant?: CurrentTenant;
_brand?: CurrentBrand;
@state()
set tenant(c: CurrentTenant) {
this._tenant = c;
this._tenantContext.setValue(c);
set brand(c: CurrentBrand) {
this._brand = c;
this._brandContext.setValue(c);
this.requestUpdate();
}
get tenant(): CurrentTenant | undefined {
return this._tenant;
get brand(): CurrentBrand | undefined {
return this._brand;
}
constructor() {
super();
document.adoptedStyleSheets = [...document.adoptedStyleSheets, ensureCSSStyleSheet(PFBase)];
tenant().then((tenant) => (this.tenant = tenant));
brand().then((brand) => (this.brand = brand));
config().then((config) => (this.config = config));
this.dataset.akInterfaceRoot = "true";
}

View File

@ -0,0 +1,20 @@
import { authentikBrandContext } from "@goauthentik/elements/AuthentikContexts";
import { consume } from "@lit-labs/context";
import type { LitElement } from "lit";
import type { CurrentTenant as CurrentBrand } from "@goauthentik/api";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Constructor<T = object> = abstract new (...args: any[]) => T;
export function WithBrandConfig<T extends Constructor<LitElement>>(
superclass: T,
subscribe = true,
) {
abstract class WithBrandProvider extends superclass {
@consume({ context: authentikBrandContext, subscribe })
public brand!: CurrentBrand;
}
return WithBrandProvider;
}

View File

@ -1,20 +0,0 @@
import { authentikTenantContext } from "@goauthentik/elements/AuthentikContexts";
import { consume } from "@lit-labs/context";
import type { LitElement } from "lit";
import type { CurrentTenant } from "@goauthentik/api";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Constructor<T = object> = abstract new (...args: any[]) => T;
export function WithTenantConfig<T extends Constructor<LitElement>>(
superclass: T,
subscribe = true,
) {
abstract class WithTenantProvider extends superclass {
@consume({ context: authentikTenantContext, subscribe })
public tenant!: CurrentTenant;
}
return WithTenantProvider;
}

View File

@ -9,7 +9,7 @@ import {
import { currentInterface } from "@goauthentik/common/sentry";
import { me } from "@goauthentik/common/users";
import { AKElement } from "@goauthentik/elements/Base";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
import { msg } from "@lit/localize";
@ -24,7 +24,7 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { EventsApi } from "@goauthentik/api";
@customElement("ak-page-header")
export class PageHeader extends WithTenantConfig(AKElement) {
export class PageHeader extends WithBrandConfig(AKElement) {
@property()
icon?: string;
@ -37,7 +37,7 @@ export class PageHeader extends WithTenantConfig(AKElement) {
@property()
set header(value: string) {
const currentIf = currentInterface();
let title = this.tenant?.brandingTitle || TITLE_DEFAULT;
let title = this.brand?.brandingTitle || TITLE_DEFAULT;
if (currentIf === "admin") {
title = `${msg("Admin")} - ${title}`;
}

View File

@ -0,0 +1,324 @@
import { PreventFormSubmit } from "@goauthentik/app/elements/forms/helpers";
import { EVENT_REFRESH } from "@goauthentik/common/constants";
import { ascii_letters, digits, groupBy, randomString } from "@goauthentik/common/utils";
import { adaptCSS } from "@goauthentik/common/utils";
import { AKElement } from "@goauthentik/elements/Base";
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, html, render } from "lit";
import { customElement, property } from "lit/decorators.js";
import PFDropdown from "@patternfly/patternfly/components/Dropdown/dropdown.css";
import PFForm from "@patternfly/patternfly/components/Form/form.css";
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
import PFSelect from "@patternfly/patternfly/components/Select/select.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
@customElement("ak-search-select")
export class SearchSelect<T> extends CustomEmitterElement(AKElement) {
@property()
query?: string;
@property({ attribute: false })
objects?: T[];
@property({ attribute: false })
selectedObject?: T;
@property()
name?: string;
@property({ type: Boolean })
open = false;
@property({ type: Boolean })
blankable = false;
@property()
placeholder: string = msg("Select an object.");
static get styles(): CSSResult[] {
return [PFBase, PFForm, PFFormControl, PFSelect];
}
@property({ attribute: false })
fetchObjects!: (query?: string) => Promise<T[]>;
@property({ attribute: false })
renderElement!: (element: T) => string;
@property({ attribute: false })
renderDescription?: (element: T) => TemplateResult;
@property({ attribute: false })
value!: (element: T | undefined) => unknown;
@property({ attribute: false })
selected?: (element: T, elements: T[]) => boolean;
@property()
emptyOption = "---------";
@property({ attribute: false })
groupBy: (items: T[]) => [string, T[]][] = (items: T[]): [string, T[]][] => {
return groupBy(items, () => {
return "";
});
};
scrollHandler?: () => void;
observer: IntersectionObserver;
dropdownUID: string;
dropdownContainer: HTMLDivElement;
isFetchingData = false;
constructor() {
super();
if (!document.adoptedStyleSheets.includes(PFDropdown)) {
document.adoptedStyleSheets = adaptCSS([...document.adoptedStyleSheets, PFDropdown]);
}
this.dropdownContainer = document.createElement("div");
this.observer = new IntersectionObserver(() => {
this.open = false;
this.shadowRoot
?.querySelectorAll<HTMLInputElement>(
".pf-c-form-control.pf-c-select__toggle-typeahead",
)
.forEach((input) => {
input.blur();
});
});
this.observer.observe(this);
this.dropdownUID = `dropdown-${randomString(10, ascii_letters + digits)}`;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
shouldUpdate(changedProperties: Map<string, any>) {
if (changedProperties.has("selectedObject")) {
this.dispatchCustomEvent("ak-change", {
value: this.selectedObject,
});
}
return true;
}
toForm(): unknown {
if (!this.objects) {
throw new PreventFormSubmit(msg("Loading options..."));
}
return this.value(this.selectedObject) || "";
}
firstUpdated(): void {
this.updateData();
}
updateData(): void {
if (this.isFetchingData) {
return;
}
this.isFetchingData = true;
this.fetchObjects(this.query).then((objects) => {
objects.forEach((obj) => {
if (this.selected && this.selected(obj, objects || [])) {
this.selectedObject = obj;
}
});
this.objects = objects;
this.isFetchingData = false;
});
}
connectedCallback(): void {
super.connectedCallback();
this.dropdownContainer = document.createElement("div");
this.dropdownContainer.dataset["managedBy"] = "ak-search-select";
if (this.name) {
this.dropdownContainer.dataset["managedFor"] = this.name;
}
document.body.append(this.dropdownContainer);
this.updateData();
this.addEventListener(EVENT_REFRESH, this.updateData);
this.scrollHandler = () => {
this.requestUpdate();
};
window.addEventListener("scroll", this.scrollHandler);
}
disconnectedCallback(): void {
super.disconnectedCallback();
this.removeEventListener(EVENT_REFRESH, this.updateData);
if (this.scrollHandler) {
window.removeEventListener("scroll", this.scrollHandler);
}
this.dropdownContainer.remove();
this.observer.disconnect();
}
/*
* This is a little bit hacky. Because we mainly want to use this field in modal-based forms,
* rendering this menu inline makes the menu not overlay over top of the modal, and cause
* the modal to scroll.
* Hence, we render the menu into the document root, hide it when this menu isn't open
* and remove it on disconnect
* Also to move it to the correct position we're getting this elements's position and use that
* to position the menu
* The other downside this has is that, since we're rendering outside of a shadow root,
* the pf-c-dropdown CSS needs to be loaded on the body.
*/
renderMenu(): void {
if (!this.objects) {
return;
}
const pos = this.getBoundingClientRect();
let groupedItems = this.groupBy(this.objects);
let shouldRenderGroups = true;
if (groupedItems.length === 1) {
if (groupedItems[0].length < 1 || groupedItems[0][0] === "") {
shouldRenderGroups = false;
}
}
if (groupedItems.length === 0) {
shouldRenderGroups = false;
groupedItems = [["", []]];
}
const renderGroup = (items: T[], tabIndexStart: number): TemplateResult => {
return html`${items.map((obj, index) => {
let desc = undefined;
if (this.renderDescription) {
desc = this.renderDescription(obj);
}
return html`
<li>
<button
class="pf-c-dropdown__menu-item ${desc === undefined
? ""
: "pf-m-description"}"
role="option"
@click=${() => {
this.selectedObject = obj;
this.open = false;
}}
tabindex=${index + tabIndexStart}
>
${desc === undefined
? this.renderElement(obj)
: html`
<div class="pf-c-dropdown__menu-item-main">
${this.renderElement(obj)}
</div>
<div class="pf-c-dropdown__menu-item-description">
${desc}
</div>
`}
</button>
</li>
`;
})}`;
};
render(
html`<div
class="pf-c-dropdown pf-m-expanded"
style="position: fixed; inset: 0px auto auto 0px; z-index: 9999; transform: translate(${pos.x}px, ${pos.y +
this.offsetHeight}px); width: ${pos.width}px; ${this.open
? ""
: "visibility: hidden;"}"
>
<ul
class="pf-c-dropdown__menu pf-m-static"
role="listbox"
style="max-height:50vh;overflow-y:auto;"
id=${this.dropdownUID}
tabindex="0"
>
${this.blankable
? html`
<li>
<button
class="pf-c-dropdown__menu-item"
role="option"
@click=${() => {
this.selectedObject = undefined;
this.open = false;
}}
tabindex="0"
>
${this.emptyOption}
</button>
</li>
`
: html``}
${shouldRenderGroups
? html`${groupedItems.map(([group, items], idx) => {
return html`
<section class="pf-c-dropdown__group">
<h1 class="pf-c-dropdown__group-title">${group}</h1>
<ul>
${renderGroup(items, idx)}
</ul>
</section>
`;
})}`
: html`${renderGroup(groupedItems[0][1], 0)}`}
</ul>
</div>`,
this.dropdownContainer,
{ host: this },
);
}
render(): TemplateResult {
this.renderMenu();
let value = "";
if (!this.objects) {
value = msg("Loading...");
} else if (this.selectedObject) {
value = this.renderElement(this.selectedObject);
} else if (this.blankable) {
value = this.emptyOption;
}
return html`<div class="pf-c-select">
<div class="pf-c-select__toggle pf-m-typeahead">
<div class="pf-c-select__toggle-wrapper">
<input
class="pf-c-form-control pf-c-select__toggle-typeahead"
type="text"
placeholder=${this.placeholder}
spellcheck="false"
@input=${(ev: InputEvent) => {
this.query = (ev.target as HTMLInputElement).value;
this.updateData();
}}
@focus=${() => {
this.open = true;
this.renderMenu();
}}
@blur=${(ev: FocusEvent) => {
// For Safari, we get the <ul> element itself here when clicking on one of
// it's buttons, as the container has tabindex set
if (
ev.relatedTarget &&
(ev.relatedTarget as HTMLElement).id === this.dropdownUID
) {
return;
}
// Check if we're losing focus to one of our dropdown items, and if such don't blur
if (ev.relatedTarget instanceof HTMLButtonElement) {
const parentMenu = ev.relatedTarget.closest(
"ul.pf-c-dropdown__menu.pf-m-static",
);
if (parentMenu && parentMenu.id === this.dropdownUID) {
return;
}
}
this.open = false;
this.renderMenu();
}}
.value=${value}
/>
</div>
</div>
</div>`;
}
}

View File

@ -1,370 +0,0 @@
import { PreventFormSubmit } from "@goauthentik/app/elements/forms/helpers";
import { EVENT_REFRESH } from "@goauthentik/common/constants";
import { ascii_letters, digits, groupBy, randomString } from "@goauthentik/common/utils";
import { AKElement } from "@goauthentik/elements/Base";
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
import { msg } from "@lit/localize";
import { TemplateResult, html, render } from "lit";
import { customElement, property } from "lit/decorators.js";
import { styleMap } from "lit/directives/style-map.js";
import PFDropdown from "@patternfly/patternfly/components/Dropdown/dropdown.css";
import PFForm from "@patternfly/patternfly/components/Form/form.css";
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
import PFSelect from "@patternfly/patternfly/components/Select/select.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
type Group<T> = [string, T[]];
@customElement("ak-search-select")
export class SearchSelect<T> extends CustomEmitterElement(AKElement) {
// A function which takes the query state object (accepting that it may be empty) and returns a
// new collection of objects.
@property({ attribute: false })
fetchObjects!: (query?: string) => Promise<T[]>;
// A function passed to this object that extracts a string representation of items of the
// collection under search.
@property({ attribute: false })
renderElement!: (element: T) => string;
// A function passed to this object that extracts an HTML representation of additional
// information for items of the collection under search.
@property({ attribute: false })
renderDescription?: (element: T) => TemplateResult;
// A function which returns the currently selected object's primary key, used for serialization
// into forms.
@property({ attribute: false })
value!: (element: T | undefined) => unknown;
// A function passed to this object that determines an object in the collection under search
// should be automatically selected. Only used when the search itself is responsible for
// fetching the data; sets an initial default value.
@property({ attribute: false })
selected?: (element: T, elements: T[]) => boolean;
// A function passed to this object (or using the default below) that groups objects in the
// collection under search into categories.
@property({ attribute: false })
groupBy: (items: T[]) => [string, T[]][] = (items: T[]): [string, T[]][] => {
return groupBy(items, () => {
return "";
});
};
// Whether or not the dropdown component can be left blank
@property({ type: Boolean })
blankable = false;
// An initial string to filter the search contents, and the value of the input which further
// serves to restrict the search
@property()
query?: string;
// The objects currently available under search
@property({ attribute: false })
objects?: T[];
// The currently selected object
@property({ attribute: false })
selectedObject?: T;
// Not used in this object. No known purpose.
@property()
name?: string;
// Whether or not the dropdown component is visible.
@property({ type: Boolean })
open = false;
// The textual placeholder for the search's <input> object, if currently empty. Used as the
// native <input> object's `placeholder` field.
@property()
placeholder: string = msg("Select an object.");
// A textual string representing "The user has affirmed they want to leave the selection blank."
// Only used if `blankable` above is true.
@property()
emptyOption = "---------";
// Handle the behavior of the drop-down when the :host scrolls off the page.
scrollHandler?: () => void;
observer: IntersectionObserver;
// Handle communication between the :host and the portal
dropdownUID: string;
dropdownContainer: HTMLDivElement;
isFetchingData = false;
static styles = [PFBase, PFForm, PFFormControl, PFSelect];
constructor() {
super();
if (!document.adoptedStyleSheets.includes(PFDropdown)) {
document.adoptedStyleSheets = [...document.adoptedStyleSheets, PFDropdown];
}
this.dropdownContainer = document.createElement("div");
this.observer = new IntersectionObserver(() => {
this.open = false;
this.shadowRoot
?.querySelectorAll<HTMLInputElement>(
".pf-c-form-control.pf-c-select__toggle-typeahead",
)
.forEach((input) => {
input.blur();
});
});
this.observer.observe(this);
this.dropdownUID = `dropdown-${randomString(10, ascii_letters + digits)}`;
this.onMenuItemClick = this.onMenuItemClick.bind(this);
this.renderWithMenuGroupTitle = this.renderWithMenuGroupTitle.bind(this);
}
toForm(): unknown {
if (!this.objects) {
throw new PreventFormSubmit(msg("Loading options..."));
}
return this.value(this.selectedObject) || "";
}
firstUpdated(): void {
this.updateData();
}
updateData(): void {
if (this.isFetchingData) {
return;
}
this.isFetchingData = true;
this.fetchObjects(this.query).then((objects) => {
objects.forEach((obj) => {
if (this.selected && this.selected(obj, objects || [])) {
this.selectedObject = obj;
}
});
this.objects = objects;
this.isFetchingData = false;
});
}
connectedCallback(): void {
super.connectedCallback();
this.dropdownContainer = document.createElement("div");
this.dropdownContainer.dataset["managedBy"] = "ak-search-select";
document.body.append(this.dropdownContainer);
this.updateData();
this.addEventListener(EVENT_REFRESH, this.updateData);
this.scrollHandler = () => {
this.requestUpdate();
};
window.addEventListener("scroll", this.scrollHandler);
}
disconnectedCallback(): void {
super.disconnectedCallback();
this.removeEventListener(EVENT_REFRESH, this.updateData);
if (this.scrollHandler) {
window.removeEventListener("scroll", this.scrollHandler);
}
this.dropdownContainer.remove();
this.observer.disconnect();
}
renderMenuItemWithDescription(obj: T, desc: TemplateResult, index: number) {
return html`
<li>
<button
class="pf-c-dropdown__menu-item pf-m-description"
role="option"
@click=${this.onMenuItemClick(obj)}
tabindex=${index}
>
<div class="pf-c-dropdown__menu-item-main">${this.renderElement(obj)}</div>
<div class="pf-c-dropdown__menu-item-description">${desc}</div>
</button>
</li>
`;
}
renderMenuItemWithoutDescription(obj: T, index: number) {
return html`
<li>
<button
class="pf-c-dropdown__menu-item"
role="option"
@click=${this.onMenuItemClick(obj)}
tabindex=${index}
>
${this.renderElement(obj)}
</button>
</li>
`;
}
renderEmptyMenuItem() {
return html`<li>
<button
class="pf-c-dropdown__menu-item"
role="option"
@click=${this.onMenuItemClick(undefined)}
tabindex="0"
>
${this.emptyOption}
</button>
</li>`;
}
onMenuItemClick(obj: T | undefined) {
return () => {
this.selectedObject = obj;
this.open = false;
};
}
renderMenuGroup(items: T[], tabIndexStart: number) {
const renderedItems = items.map((obj, index) => {
const desc = this.renderDescription ? this.renderDescription(obj) : null;
const tabIndex = index + tabIndexStart;
return desc
? this.renderMenuItemWithDescription(obj, desc, tabIndex)
: this.renderMenuItemWithoutDescription(obj, tabIndex);
});
return html`${renderedItems}`;
}
renderWithMenuGroupTitle([group, items]: Group<T>, idx: number) {
return html`
<section class="pf-c-dropdown__group">
<h1 class="pf-c-dropdown__group-title">${group}</h1>
<ul>
${this.renderMenuGroup(items, idx)}
</ul>
</section>
`;
}
get groupedItems(): [boolean, Group<T>[]] {
const items = this.groupBy(this.objects || []);
if (items.length === 0) {
return [false, [["", []]]];
}
if (items.length === 1 && (items[0].length < 1 || items[0][0] === "")) {
return [false, items];
}
return [true, items];
}
/*
* This is a little bit hacky. Because we mainly want to use this field in modal-based forms,
* rendering this menu inline makes the menu not overlay over top of the modal, and cause
* the modal to scroll.
* Hence, we render the menu into the document root, hide it when this menu isn't open
* and remove it on disconnect
* Also to move it to the correct position we're getting this elements's position and use that
* to position the menu
* The other downside this has is that, since we're rendering outside of a shadow root,
* the pf-c-dropdown CSS needs to be loaded on the body.
*/
renderMenu(): void {
if (!this.objects) {
return;
}
const [shouldRenderGroups, groupedItems] = this.groupedItems;
const pos = this.getBoundingClientRect();
const position = {
"position": "fixed",
"inset": "0px auto auto 0px",
"z-index": "9999",
"transform": `translate(${pos.x}px, ${pos.y + this.offsetHeight}px)`,
"width": `${pos.width}px`,
...(this.open ? {} : { visibility: "hidden" }),
};
render(
html`<div style=${styleMap(position)} class="pf-c-dropdown pf-m-expanded">
<ul
class="pf-c-dropdown__menu pf-m-static"
role="listbox"
style="max-height:50vh;overflow-y:auto;"
id=${this.dropdownUID}
tabindex="0"
>
${this.blankable ? this.renderEmptyMenuItem() : html``}
${shouldRenderGroups
? html`${groupedItems.map(this.renderWithMenuGroupTitle)}`
: html`${this.renderMenuGroup(groupedItems[0][1], 0)}`}
</ul>
</div>`,
this.dropdownContainer,
{ host: this },
);
}
get renderedValue() {
// prettier-ignore
return (!this.objects) ? msg("Loading...")
: (this.selectedObject) ? this.renderElement(this.selectedObject)
: (this.blankable) ? this.emptyOption
: "";
}
render(): TemplateResult {
this.renderMenu();
const onFocus = (ev: FocusEvent) => {
this.open = true;
this.renderMenu();
if (this.blankable && this.renderedValue === this.emptyOption) {
if (ev.target && ev.target instanceof HTMLInputElement) {
ev.target.value = "";
}
}
};
const onInput = (ev: InputEvent) => {
this.query = (ev.target as HTMLInputElement).value;
this.updateData();
};
const onBlur = (ev: FocusEvent) => {
// For Safari, we get the <ul> element itself here when clicking on one of
// it's buttons, as the container has tabindex set
if (ev.relatedTarget && (ev.relatedTarget as HTMLElement).id === this.dropdownUID) {
return;
}
// Check if we're losing focus to one of our dropdown items, and if such don't blur
if (ev.relatedTarget instanceof HTMLButtonElement) {
const parentMenu = ev.relatedTarget.closest("ul.pf-c-dropdown__menu.pf-m-static");
if (parentMenu && parentMenu.id === this.dropdownUID) {
return;
}
}
this.open = false;
this.renderMenu();
};
return html`<div class="pf-c-select">
<div class="pf-c-select__toggle pf-m-typeahead">
<div class="pf-c-select__toggle-wrapper">
<input
class="pf-c-form-control pf-c-select__toggle-typeahead"
type="text"
placeholder=${this.placeholder}
spellcheck="false"
@input=${onInput}
@focus=${onFocus}
@blur=${onBlur}
.value=${this.renderedValue}
/>
</div>
</div>
</div>`;
}
}
export default SearchSelect;

View File

@ -1,4 +0,0 @@
import { SearchSelect } from "./ak-search-select";
export { SearchSelect };
export default SearchSelect;

View File

@ -1,6 +1,6 @@
import { EVENT_SIDEBAR_TOGGLE } from "@goauthentik/common/constants";
import { AKElement } from "@goauthentik/elements/Base";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement } from "lit/decorators.js";
@ -10,13 +10,13 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGlobal from "@patternfly/patternfly/patternfly-base.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { CurrentTenant, UiThemeEnum } from "@goauthentik/api";
import { CurrentTenant as CurrentBrand, UiThemeEnum } from "@goauthentik/api";
// If the viewport is wider than MIN_WIDTH, the sidebar
// is shown besides the content, and not overlaid.
export const MIN_WIDTH = 1200;
export const DefaultTenant: CurrentTenant = {
export const DefaultBrand: CurrentBrand = {
brandingLogo: "/static/dist/assets/icons/icon_left_brand.svg",
brandingFavicon: "/static/dist/assets/icons/icon.png",
brandingTitle: "authentik",
@ -27,7 +27,7 @@ export const DefaultTenant: CurrentTenant = {
};
@customElement("ak-sidebar-brand")
export class SidebarBrand extends WithTenantConfig(AKElement) {
export class SidebarBrand extends WithBrandConfig(AKElement) {
static get styles(): CSSResult[] {
return [
PFBase,
@ -43,6 +43,7 @@ export class SidebarBrand extends WithTenantConfig(AKElement) {
min-height: 114px;
}
.pf-c-brand img {
width: 100%;
padding: 0 0.5rem;
height: 42px;
}
@ -64,6 +65,7 @@ export class SidebarBrand extends WithTenantConfig(AKElement) {
}
render(): TemplateResult {
console.log(this.brand);
return html` ${window.innerWidth <= MIN_WIDTH
? html`
<button
@ -84,7 +86,7 @@ export class SidebarBrand extends WithTenantConfig(AKElement) {
<a href="#/" class="pf-c-page__header-brand-link">
<div class="pf-c-brand ak-brand">
<img
src=${this.tenant?.brandingLogo ?? DefaultTenant.brandingLogo}
src=${this.brand?.brandingLogo ?? DefaultBrand.brandingLogo}
alt="authentik Logo"
loading="lazy"
/>

View File

@ -83,12 +83,8 @@ export class RacInterface extends Interface {
// Keep track of current connection attempt
connectionAttempt = 0;
static domSize(): { width: number; height: number } {
const size = document.body.getBoundingClientRect();
return {
width: size.width * window.devicePixelRatio,
height: size.height * window.devicePixelRatio,
};
static domSize(): DOMRect {
return document.body.getBoundingClientRect();
}
constructor() {
@ -209,7 +205,7 @@ export class RacInterface extends Interface {
}
updateTitle(): void {
let title = this.tenant?.brandingTitle || TITLE_DEFAULT;
let title = this.brand?.brandingTitle || TITLE_DEFAULT;
if (this.endpointName) {
title = `${this.endpointName} - ${title}`;
}

View File

@ -9,6 +9,7 @@ import { configureSentry } from "@goauthentik/common/sentry";
import { first } from "@goauthentik/common/utils";
import { WebsocketClient } from "@goauthentik/common/ws";
import { Interface } from "@goauthentik/elements/Interface";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import "@goauthentik/elements/LoadingOverlay";
import "@goauthentik/elements/ak-locale-context";
import "@goauthentik/flow/sources/apple/AppleLoginInit";
@ -45,7 +46,7 @@ import {
} from "@goauthentik/api";
@customElement("ak-flow-executor")
export class FlowExecutor extends Interface implements StageHost {
export class FlowExecutor extends WithBrandConfig(Interface) implements StageHost {
@property()
flowSlug: string = window.location.pathname.split("/")[3];
@ -55,9 +56,9 @@ export class FlowExecutor extends Interface implements StageHost {
set challenge(value: ChallengeTypes | undefined) {
this._challenge = value;
if (value?.flowInfo?.title) {
document.title = `${value.flowInfo?.title} - ${this.tenant?.brandingTitle}`;
document.title = `${value.flowInfo?.title} - ${this.brand?.brandingTitle}`;
} else {
document.title = this.tenant?.brandingTitle || TITLE_DEFAULT;
document.title = this.brand?.brandingTitle || TITLE_DEFAULT;
}
this.requestUpdate();
}
@ -213,10 +214,8 @@ export class FlowExecutor extends Interface implements StageHost {
if (this.challenge.flowInfo) {
this.flowInfo = this.challenge.flowInfo;
}
if (this.challenge.responseErrors) {
return false;
}
return true;
return this.challenge.responseErrors ? false : true;
} catch (exc: unknown) {
this.errorMessage(exc as Error | ResponseError);
return false;
@ -430,7 +429,7 @@ export class FlowExecutor extends Interface implements StageHost {
renderChallengeWrapper(): TemplateResult {
const logo = html`<div class="pf-c-login__main-header pf-c-brand ak-brand">
<img src="${first(this.tenant?.brandingLogo, "")}" alt="authentik Logo" />
<img src="${first(this.brand?.brandingLogo, "")}" alt="authentik Logo" />
</div>`;
if (!this.challenge) {
return html`${logo}<ak-empty-state ?loading=${true} header=${msg("Loading")}>
@ -483,12 +482,20 @@ export class FlowExecutor extends Interface implements StageHost {
<div class="pf-c-drawer__body">
<div class="pf-c-login ${this.getLayout()}">
<div class="${this.getLayoutClass()}">
<header class="pf-c-login__header">
<div class="pf-c-brand ak-brand">
<img
src="${first(this.brand?.brandingLogo, "")}"
alt="authentik Logo"
/>
</div>
</header>
<div class="pf-c-login__main">
${this.renderChallengeWrapper()}
</div>
<footer class="pf-c-login__footer">
<ul class="pf-c-list pf-m-inline">
${this.tenant?.uiFooterLinks?.map((link) => {
${this.brand?.uiFooterLinks?.map((link) => {
return html`<li>
<a href="${link.href || ""}"
>${link.name}</a
@ -505,7 +512,7 @@ export class FlowExecutor extends Interface implements StageHost {
? html`
<li>
<a
href="https://unsplash.com/@theforestbirds"
href="https://unsplash.com/@federize"
>${msg("Background image")}</a
>
</li>

View File

@ -4,7 +4,7 @@ import { globalAK } from "@goauthentik/common/global";
import { first, getCookie } from "@goauthentik/common/utils";
import { Interface } from "@goauthentik/elements/Interface";
import "@goauthentik/elements/ak-locale-context";
import { DefaultTenant } from "@goauthentik/elements/sidebar/SidebarBrand";
import { DefaultBrand } from "@goauthentik/elements/sidebar/SidebarBrand";
import "rapidoc";
import { CSSResult, TemplateResult, css, html } from "lit";
@ -103,7 +103,7 @@ export class APIBrowser extends Interface {
<img
alt="authentik Logo"
class="logo"
src="${first(this.tenant?.brandingLogo, DefaultTenant.brandingLogo)}"
src="${first(this.brand?.brandingLogo, DefaultBrand.brandingLogo)}"
/>
</div>
</rapi-doc>

View File

@ -19,7 +19,7 @@ import "@goauthentik/elements/notifications/NotificationDrawer";
import { getURLParam, updateURLParams } from "@goauthentik/elements/router/RouteMatch";
import "@goauthentik/elements/router/RouterOutlet";
import "@goauthentik/elements/sidebar/Sidebar";
import { DefaultTenant } from "@goauthentik/elements/sidebar/SidebarBrand";
import { DefaultBrand } from "@goauthentik/elements/sidebar/SidebarBrand";
import "@goauthentik/elements/sidebar/SidebarItem";
import { ROUTES } from "@goauthentik/user/Routes";
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
@ -192,11 +192,8 @@ export class UserInterface extends Interface {
<a href="#/" class="pf-c-page__header-brand-link">
<img
class="pf-c-brand"
src="${first(
this.tenant?.brandingLogo,
DefaultTenant.brandingLogo,
)}"
alt="${(this.tenant?.brandingTitle, DefaultTenant.brandingTitle)}"
src="${first(this.brand?.brandingLogo, DefaultBrand.brandingLogo)}"
alt="${(this.brand?.brandingTitle, DefaultBrand.brandingTitle)}"
/>
</a>
</div>

View File

@ -3,7 +3,7 @@ import { EVENT_REFRESH } from "@goauthentik/common/constants";
import { MessageLevel } from "@goauthentik/common/messages";
import { refreshMe } from "@goauthentik/common/users";
import { AKElement } from "@goauthentik/elements/Base";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
import { StageHost } from "@goauthentik/flow/stages/base";
import "@goauthentik/user/user-settings/details/stages/prompt/PromptStage";
@ -31,10 +31,7 @@ import {
} from "@goauthentik/api";
@customElement("ak-user-settings-flow-executor")
export class UserSettingsFlowExecutor
extends WithTenantConfig(AKElement, true)
implements StageHost
{
export class UserSettingsFlowExecutor extends WithBrandConfig(AKElement) implements StageHost {
@property()
flowSlug?: string;
@ -87,7 +84,7 @@ export class UserSettingsFlowExecutor
}
firstUpdated(): void {
this.flowSlug = this.tenant?.flowUserSettings;
this.flowSlug = this.brand?.flowUserSettings;
if (!this.flowSlug) {
return;
}

View File

@ -6249,12 +6249,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s62418cbcd2a25498">
<source>Maximum concurrent allowed connections to this endpoint. Can be set to -1 to disable the limit.</source>
</trans-unit>
<trans-unit id="s94d61907ee22a8c1">
<source>Korean</source>
</trans-unit>
<trans-unit id="s95d56e58f816d211">
<source>Dutch</source>
</trans-unit>
</body>
</file>

View File

@ -6525,12 +6525,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s62418cbcd2a25498">
<source>Maximum concurrent allowed connections to this endpoint. Can be set to -1 to disable the limit.</source>
</trans-unit>
<trans-unit id="s94d61907ee22a8c1">
<source>Korean</source>
</trans-unit>
<trans-unit id="s95d56e58f816d211">
<source>Dutch</source>
</trans-unit>
</body>
</file>

View File

@ -6165,12 +6165,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s62418cbcd2a25498">
<source>Maximum concurrent allowed connections to this endpoint. Can be set to -1 to disable the limit.</source>
</trans-unit>
<trans-unit id="s94d61907ee22a8c1">
<source>Korean</source>
</trans-unit>
<trans-unit id="s95d56e58f816d211">
<source>Dutch</source>
</trans-unit>
</body>
</file>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<?xml version="1.0"?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file target-language="fr" source-language="en" original="lit-localize-inputs" datatype="plaintext">
<body>
<trans-unit id="s4caed5b7a7e5d89b">
@ -613,9 +613,9 @@ Il y a <x id="0" equiv-text="${ago}"/> jour(s)</target>
</trans-unit>
<trans-unit id="saa0e2675da69651b">
<source>The URL &quot;<x id="0" equiv-text="${this.url}"/>&quot; was not found.</source>
<target>L'URL &quot;
<x id="0" equiv-text="${this.url}"/>&quot; n'a pas été trouvée.</target>
<source>The URL "<x id="0" equiv-text="${this.url}"/>" was not found.</source>
<target>L'URL "
<x id="0" equiv-text="${this.url}"/>" n'a pas été trouvée.</target>
</trans-unit>
<trans-unit id="s58cd9c2fe836d9c6">
@ -1057,8 +1057,8 @@ Il y a <x id="0" equiv-text="${ago}"/> jour(s)</target>
</trans-unit>
<trans-unit id="sa8384c9c26731f83">
<source>To allow any redirect URI, set this value to &quot;.*&quot;. Be aware of the possible security implications this can have.</source>
<target>Pour permettre n'importe quelle URI de redirection, définissez cette valeur sur &quot;.*&quot;. Soyez conscient des possibles implications de sécurité que cela peut avoir.</target>
<source>To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have.</source>
<target>Pour permettre n'importe quelle URI de redirection, définissez cette valeur sur ".*". Soyez conscient des possibles implications de sécurité que cela peut avoir.</target>
</trans-unit>
<trans-unit id="s55787f4dfcdce52b">
@ -1630,7 +1630,7 @@ Il y a <x id="0" equiv-text="${ago}"/> jour(s)</target>
</trans-unit>
<trans-unit id="s33ed903c210a6209">
<source>Token to authenticate with. Currently only bearer authentication is supported.</source>
<target>Jeton d'authentification à utiliser. Actuellement, seule l'authentification &quot;bearer authentication&quot; est prise en charge.</target>
<target>Jeton d'authentification à utiliser. Actuellement, seule l'authentification "bearer authentication" est prise en charge.</target>
</trans-unit>
<trans-unit id="sfc8bb104e2c05af8">
@ -1798,8 +1798,8 @@ Il y a <x id="0" equiv-text="${ago}"/> jour(s)</target>
</trans-unit>
<trans-unit id="sa90b7809586c35ce">
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon &quot;fa-test&quot;.</source>
<target>Entrez une URL complète, un chemin relatif ou utilisez 'fa://fa-test' pour utiliser l'icône Font Awesome &quot;fa-test&quot;.</target>
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test".</source>
<target>Entrez une URL complète, un chemin relatif ou utilisez 'fa://fa-test' pour utiliser l'icône Font Awesome "fa-test".</target>
</trans-unit>
<trans-unit id="s0410779cb47de312">
@ -2892,7 +2892,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s33683c3b1dbaf264">
<source>To use SSL instead, use 'ldaps://' and disable this option.</source>
<target>Pour utiliser SSL à la base, utilisez &quot;ldaps://&quot; et désactviez cette option.</target>
<target>Pour utiliser SSL à la base, utilisez "ldaps://" et désactviez cette option.</target>
</trans-unit>
<trans-unit id="s2221fef80f4753a2">
@ -2981,8 +2981,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s76768bebabb7d543">
<source>Field which contains members of a group. Note that if using the &quot;memberUid&quot; field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>Champ qui contient les membres d'un groupe. Si vous utilisez le champ &quot;memberUid&quot;, la valeur est censée contenir un nom distinctif relatif, par exemple 'memberUid=un-utilisateur' au lieu de 'memberUid=cn=un-utilisateur,ou=groups,...'</target>
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>Champ qui contient les membres d'un groupe. Si vous utilisez le champ "memberUid", la valeur est censée contenir un nom distinctif relatif, par exemple 'memberUid=un-utilisateur' au lieu de 'memberUid=cn=un-utilisateur,ou=groups,...'</target>
</trans-unit>
<trans-unit id="s026555347e589f0e">
@ -3277,7 +3277,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s3198c384c2f68b08">
<source>Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually.</source>
<target>Moment où les utilisateurs temporaires doivent être supprimés. Cela ne s'applique que si votre IDP utilise le format NameID &quot;transient&quot; et que l'utilisateur ne se déconnecte pas manuellement.</target>
<target>Moment où les utilisateurs temporaires doivent être supprimés. Cela ne s'applique que si votre IDP utilise le format NameID "transient" et que l'utilisateur ne se déconnecte pas manuellement.</target>
</trans-unit>
<trans-unit id="sb32e9c1faa0b8673">
@ -3445,7 +3445,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s9f8aac89fe318acc">
<source>Optionally set the 'FriendlyName' value of the Assertion attribute.</source>
<target>Indiquer la valeur &quot;FriendlyName&quot; de l'attribut d'assertion (optionnel)</target>
<target>Indiquer la valeur "FriendlyName" de l'attribut d'assertion (optionnel)</target>
</trans-unit>
<trans-unit id="s851c108679653d2a">
@ -3774,8 +3774,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s7b1fba26d245cb1c">
<source>When using an external logging solution for archiving, this can be set to &quot;minutes=5&quot;.</source>
<target>En cas d'utilisation d'une solution de journalisation externe pour l'archivage, cette valeur peut être fixée à &quot;minutes=5&quot;.</target>
<source>When using an external logging solution for archiving, this can be set to "minutes=5".</source>
<target>En cas d'utilisation d'une solution de journalisation externe pour l'archivage, cette valeur peut être fixée à "minutes=5".</target>
</trans-unit>
<trans-unit id="s44536d20bb5c8257">
@ -3784,8 +3784,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: &quot;weeks=3;days=2;hours=3,seconds=2&quot;.</source>
<target>Format : &quot;weeks=3;days=2;hours=3,seconds=2&quot;.</target>
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>Format : "weeks=3;days=2;hours=3,seconds=2".</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
@ -3981,10 +3981,10 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sa95a538bfbb86111">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> &quot;<x id="1" equiv-text="${this.obj?.name}"/>&quot;?</source>
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> "<x id="1" equiv-text="${this.obj?.name}"/>"?</source>
<target>Êtes-vous sûr de vouloir mettre à jour
<x id="0" equiv-text="${this.objectLabel}"/>&quot;
<x id="1" equiv-text="${this.obj?.name}"/>&quot; ?</target>
<x id="0" equiv-text="${this.objectLabel}"/>"
<x id="1" equiv-text="${this.obj?.name}"/>" ?</target>
</trans-unit>
<trans-unit id="sc92d7cfb6ee1fec6">
@ -5070,8 +5070,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sdf1d8edef27236f0">
<source>A &quot;roaming&quot; authenticator, like a YubiKey</source>
<target>Un authentificateur &quot;itinérant&quot;, comme une YubiKey</target>
<source>A "roaming" authenticator, like a YubiKey</source>
<target>Un authentificateur "itinérant", comme une YubiKey</target>
</trans-unit>
<trans-unit id="sfffba7b23d8fb40c">
@ -5396,7 +5396,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s5170f9ef331949c0">
<source>Show arbitrary input fields to the user, for example during enrollment. Data is saved in the flow context under the 'prompt_data' variable.</source>
<target>Afficher des champs de saisie arbitraires à l'utilisateur, par exemple pendant l'inscription. Les données sont enregistrées dans le contexte du flux sous la variable &quot;prompt_data&quot;.</target>
<target>Afficher des champs de saisie arbitraires à l'utilisateur, par exemple pendant l'inscription. Les données sont enregistrées dans le contexte du flux sous la variable "prompt_data".</target>
</trans-unit>
<trans-unit id="s36cb242ac90353bc">
@ -5405,10 +5405,10 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s2d5f69929bb7221d">
<source><x id="0" equiv-text="${prompt.name}"/> (&quot;<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;, of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<source><x id="0" equiv-text="${prompt.name}"/> ("<x id="1" equiv-text="${prompt.fieldKey}"/>", of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<target>
<x id="0" equiv-text="${prompt.name}"/>(&quot;
<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;, de type
<x id="0" equiv-text="${prompt.name}"/>("
<x id="1" equiv-text="${prompt.fieldKey}"/>", de type
<x id="2" equiv-text="${prompt.type}"/>)</target>
</trans-unit>
@ -5457,8 +5457,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s1608b2f94fa0dbd4">
<source>If set to a duration above 0, the user will have the option to choose to &quot;stay signed in&quot;, which will extend their session by the time specified here.</source>
<target>Si défini à une durée supérieure à 0, l'utilisateur aura la possibilité de choisir de &quot;rester connecté&quot;, ce qui prolongera sa session jusqu'à la durée spécifiée ici.</target>
<source>If set to a duration above 0, the user will have the option to choose to "stay signed in", which will extend their session by the time specified here.</source>
<target>Si défini à une durée supérieure à 0, l'utilisateur aura la possibilité de choisir de "rester connecté", ce qui prolongera sa session jusqu'à la durée spécifiée ici.</target>
</trans-unit>
<trans-unit id="s542a71bb8f41e057">
@ -6093,7 +6093,7 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
</trans-unit>
<trans-unit id="s8afc8c5aafb392d3">
<source>Radius</source>
<target>Radius</target>
<target>Rayon</target>
</trans-unit>
<trans-unit id="s03970aa76a09982d">
@ -6242,7 +6242,7 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
</trans-unit>
<trans-unit id="sa7fcf026bd25f231">
<source>Can be in the format of 'unix://' when connecting to a local docker daemon, using 'ssh://' to connect via SSH, or 'https://:2376' when connecting to a remote system.</source>
<target>Peut être au format &quot;unix://&quot; pour une connexion à un service docker local, &quot;ssh://&quot; pour une connexion via SSH, ou &quot;https://:2376&quot; pour une connexion à un système distant.</target>
<target>Peut être au format "unix://" pour une connexion à un service docker local, "ssh://" pour une connexion via SSH, ou "https://:2376" pour une connexion à un système distant.</target>
</trans-unit>
<trans-unit id="saf1d289e3137c2ea">
@ -7549,7 +7549,7 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
</trans-unit>
<trans-unit id="sff0ac1ace2d90709">
<source>Use this provider with nginx's auth_request or traefik's forwardAuth. Each application/domain needs its own provider. Additionally, on each domain, /outpost.goauthentik.io must be routed to the outpost (when using a managed outpost, this is done for you).</source>
<target>Utilisez ce fournisseur avec l'option &quot;auth_request&quot; de Nginx ou &quot;forwardAuth&quot; de Traefik. Chaque application/domaine a besoin de son propre fournisseur. De plus, sur chaque domaine, &quot;/outpost.goauthentik.io&quot; doit être routé vers le poste avancé (lorsque vous utilisez un poste avancé géré, cela est fait pour vous).</target>
<target>Utilisez ce fournisseur avec l'option "auth_request" de Nginx ou "forwardAuth" de Traefik. Chaque application/domaine a besoin de son propre fournisseur. De plus, sur chaque domaine, "/outpost.goauthentik.io" doit être routé vers le poste avancé (lorsque vous utilisez un poste avancé géré, cela est fait pour vous).</target>
</trans-unit>
<trans-unit id="scb58b8a60cad8762">
<source>Default relay state</source>
@ -7963,7 +7963,7 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
<target>Utilisateur créé et ajouté au groupe <x id="0" equiv-text="${this.group.name}"/> avec succès</target>
</trans-unit>
<trans-unit id="s824e0943a7104668">
<source>This user will be added to the group &quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&quot;.</source>
<source>This user will be added to the group "<x id="0" equiv-text="${this.targetGroup.name}"/>".</source>
<target>Cet utilisateur sera ajouté au groupe &amp;quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&amp;quot;.</target>
</trans-unit>
<trans-unit id="s62e7f6ed7d9cb3ca">
@ -8204,28 +8204,16 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
</trans-unit>
<trans-unit id="scc7f34824150bfb8">
<source>Provider require enterprise.</source>
<target>Ce fournisseur requiert la version entreprise.</target>
</trans-unit>
<trans-unit id="s31f1afc1bfe1cb3a">
<source>Learn more</source>
<target>En apprendre plus</target>
</trans-unit>
<trans-unit id="sc39f6abf0daedb0f">
<source>Maximum concurrent connections</source>
<target>Connections concurrentes maximum</target>
</trans-unit>
<trans-unit id="s62418cbcd2a25498">
<source>Maximum concurrent allowed connections to this endpoint. Can be set to -1 to disable the limit.</source>
<target>Nombre maximum de connections concurrentes à ce point de terminaison. Peut être défini à -1 pour désactiver la limite.</target>
</trans-unit>
<trans-unit id="s94d61907ee22a8c1">
<source>Korean</source>
<target>Coréen</target>
</trans-unit>
<trans-unit id="s95d56e58f816d211">
<source>Dutch</source>
<target>Néerlandais</target>
</trans-unit>
</body>
</file>
</xliff>
</xliff>

View File

@ -1,4 +1,4 @@
<?xml version="1.0"?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file target-language="ko" source-language="en" original="lit-localize-inputs" datatype="plaintext">
<body>
<trans-unit id="s4caed5b7a7e5d89b">
@ -612,8 +612,8 @@
</trans-unit>
<trans-unit id="saa0e2675da69651b">
<source>The URL "<x id="0" equiv-text="${this.url}"/>" was not found.</source>
<target>URL "<x id="0" equiv-text="${this.url}"/>" 을 찾을 수 없습니다.</target>
<source>The URL &quot;<x id="0" equiv-text="${this.url}"/>&quot; was not found.</source>
<target>URL &quot;<x id="0" equiv-text="${this.url}"/>&quot; 을 찾을 수 없습니다.</target>
</trans-unit>
<trans-unit id="s58cd9c2fe836d9c6">
@ -1054,8 +1054,8 @@
</trans-unit>
<trans-unit id="sa8384c9c26731f83">
<source>To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have.</source>
<target>리디렉션 URI를 허용하려면 이 값을 ".*"로 설정합니다. 이로 인해 발생할 수 있는 보안상의 영향에 유의하세요.</target>
<source>To allow any redirect URI, set this value to &quot;.*&quot;. Be aware of the possible security implications this can have.</source>
<target>리디렉션 URI를 허용하려면 이 값을 &quot;.*&quot;로 설정합니다. 이로 인해 발생할 수 있는 보안상의 영향에 유의하세요.</target>
</trans-unit>
<trans-unit id="s55787f4dfcdce52b">
@ -1792,8 +1792,8 @@
</trans-unit>
<trans-unit id="sa90b7809586c35ce">
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test".</source>
<target>전체 URL, 상대 경로를 입력하거나, 또는 'fa://fa-test'를 사용하여 Font Awesome 아이콘 "fa-test"를 사용합니다.</target>
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon &quot;fa-test&quot;.</source>
<target>전체 URL, 상대 경로를 입력하거나, 또는 'fa://fa-test'를 사용하여 Font Awesome 아이콘 &quot;fa-test&quot;를 사용합니다.</target>
</trans-unit>
<trans-unit id="s0410779cb47de312">
@ -2972,7 +2972,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s76768bebabb7d543">
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<source>Field which contains members of a group. Note that if using the &quot;memberUid&quot; field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>그룹 구성원이 포함된 필드입니다. 'memberUid' 필드를 사용하는 경우 값에 상대적인 고유 이름이 포함된 것으로 가정합니다 (예:'memberUid=some-user' 대신 'memberUid=cn=some-user,ou=groups,...').</target>
</trans-unit>
@ -3764,8 +3764,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s7b1fba26d245cb1c">
<source>When using an external logging solution for archiving, this can be set to "minutes=5".</source>
<target>아카이브에 외부 로깅 솔루션을 사용하는 경우, 이 값을 "minutes=5"로 설정할 수 있습니다.</target>
<source>When using an external logging solution for archiving, this can be set to &quot;minutes=5&quot;.</source>
<target>아카이브에 외부 로깅 솔루션을 사용하는 경우, 이 값을 &quot;minutes=5&quot;로 설정할 수 있습니다.</target>
</trans-unit>
<trans-unit id="s44536d20bb5c8257">
@ -3774,8 +3774,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>서식: "weeks=3;days=2;hours=3,seconds=2".</target>
<source>Format: &quot;weeks=3;days=2;hours=3,seconds=2&quot;.</source>
<target>서식: &quot;weeks=3;days=2;hours=3,seconds=2&quot;.</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
@ -3967,8 +3967,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sa95a538bfbb86111">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> "<x id="1" equiv-text="${this.obj?.name}"/>"?</source>
<target>정말 <x id="0" equiv-text="${this.objectLabel}"/> "<x id="1" equiv-text="${this.obj?.name}"/>" 을(를) 업데이트 하시겠습니까?</target>
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> &quot;<x id="1" equiv-text="${this.obj?.name}"/>&quot;?</source>
<target>정말 <x id="0" equiv-text="${this.objectLabel}"/> &quot;<x id="1" equiv-text="${this.obj?.name}"/>&quot; 을(를) 업데이트 하시겠습니까?</target>
</trans-unit>
<trans-unit id="sc92d7cfb6ee1fec6">
@ -5052,8 +5052,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sdf1d8edef27236f0">
<source>A "roaming" authenticator, like a YubiKey</source>
<target>YubiKey 같은 "로밍" 인증기</target>
<source>A &quot;roaming&quot; authenticator, like a YubiKey</source>
<target>YubiKey 같은 &quot;로밍&quot; 인증기</target>
</trans-unit>
<trans-unit id="sfffba7b23d8fb40c">
@ -5387,8 +5387,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s2d5f69929bb7221d">
<source><x id="0" equiv-text="${prompt.name}"/> ("<x id="1" equiv-text="${prompt.fieldKey}"/>", of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<target><x id="0" equiv-text="${prompt.name}"/> ("<x id="1" equiv-text="${prompt.fieldKey}"/>", of type <x id="2" equiv-text="${prompt.type}"/>)</target>
<source><x id="0" equiv-text="${prompt.name}"/> (&quot;<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;, of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<target><x id="0" equiv-text="${prompt.name}"/> (&quot;<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;, of type <x id="2" equiv-text="${prompt.type}"/>)</target>
</trans-unit>
<trans-unit id="s3b7b519444181264">
@ -5436,7 +5436,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s1608b2f94fa0dbd4">
<source>If set to a duration above 0, the user will have the option to choose to "stay signed in", which will extend their session by the time specified here.</source>
<source>If set to a duration above 0, the user will have the option to choose to &quot;stay signed in&quot;, which will extend their session by the time specified here.</source>
<target>기간을 0 이상으로 설정하면, 사용자에게 '로그인 상태 유지'를 선택할 수 있는 옵션이 제공되며, 이 경우 세션이 여기에 지정된 시간만큼 연장됩니다.</target>
</trans-unit>
@ -7926,8 +7926,8 @@ Bindings to groups/users are checked against the user of the event.</source>
<target>사용자 생성과 <x id="0" equiv-text="${this.group.name}"/> 그룹 추가에 성공했습니다.</target>
</trans-unit>
<trans-unit id="s824e0943a7104668">
<source>This user will be added to the group "<x id="0" equiv-text="${this.targetGroup.name}"/>".</source>
<target>이 사용자는 "<x id="0" equiv-text="${this.targetGroup.name}"/>" 그룹에 추가됩니다.</target>
<source>This user will be added to the group &quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&quot;.</source>
<target>이 사용자는 &quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&quot; 그룹에 추가됩니다.</target>
</trans-unit>
<trans-unit id="s62e7f6ed7d9cb3ca">
<source>Pretend user exists</source>
@ -8004,145 +8004,7 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s047a5f0211fedc72">
<source>Require Outpost (flow can only be executed from an outpost).</source>
<target>Outpost필요 (플로우는 Outpost에서만 실행할 수 있음).</target>
</trans-unit>
<trans-unit id="scc7f34824150bfb8">
<source>Provider require enterprise.</source>
</trans-unit>
<trans-unit id="s31f1afc1bfe1cb3a">
<source>Learn more</source>
</trans-unit>
<trans-unit id="sa2ea0fcd3ffa80e0">
<source>Connection expiry</source>
</trans-unit>
<trans-unit id="s6dd297c217729828">
<source>Determines how long a session lasts before being disconnected and requiring re-authorization.</source>
</trans-unit>
<trans-unit id="s3271da6c18c25b18">
<source>Connection settings.</source>
</trans-unit>
<trans-unit id="s2f4ca2148183d692">
<source>Successfully updated endpoint.</source>
</trans-unit>
<trans-unit id="s5adee855dbe191d9">
<source>Successfully created endpoint.</source>
</trans-unit>
<trans-unit id="s61e136c0658e27d5">
<source>Protocol</source>
</trans-unit>
<trans-unit id="sa062b019ff0c8809">
<source>RDP</source>
</trans-unit>
<trans-unit id="s97f9bf19fa5b57d1">
<source>SSH</source>
</trans-unit>
<trans-unit id="s7c100119e9ffcc32">
<source>VNC</source>
</trans-unit>
<trans-unit id="s6b05f9d8801fc14f">
<source>Host</source>
</trans-unit>
<trans-unit id="sb474f652a2c2fc76">
<source>Hostname/IP to connect to.</source>
</trans-unit>
<trans-unit id="sc39f6abf0daedb0f">
<source>Maximum concurrent connections</source>
</trans-unit>
<trans-unit id="s62418cbcd2a25498">
<source>Maximum concurrent allowed connections to this endpoint. Can be set to -1 to disable the limit.</source>
</trans-unit>
<trans-unit id="s8276649077e8715c">
<source>Endpoint(s)</source>
</trans-unit>
<trans-unit id="sf1dabfe0fe8a75ad">
<source>Update Endpoint</source>
</trans-unit>
<trans-unit id="s008496c7716b9812">
<source>These bindings control which users will have access to this endpoint. Users must also have access to the application.</source>
</trans-unit>
<trans-unit id="s38e7cd1a24e70faa">
<source>Create Endpoint</source>
</trans-unit>
<trans-unit id="s4770c10e5b1c028c">
<source>RAC is in preview.</source>
</trans-unit>
<trans-unit id="s168565f5ac74a89f">
<source>Update RAC Provider</source>
</trans-unit>
<trans-unit id="s8465a2caa2d9ea5d">
<source>Endpoints</source>
</trans-unit>
<trans-unit id="s9857d883d8eb98fc">
<source>General settings</source>
</trans-unit>
<trans-unit id="sd2066881798a1b96">
<source>RDP settings</source>
</trans-unit>
<trans-unit id="sb864dc36a463a155">
<source>Ignore server certificate</source>
</trans-unit>
<trans-unit id="s20366a8d1eaaca54">
<source>Enable wallpaper</source>
</trans-unit>
<trans-unit id="s1e44c5350ef7598c">
<source>Enable font-smoothing</source>
</trans-unit>
<trans-unit id="s04ff5d6ae711e6d6">
<source>Enable full window dragging</source>
</trans-unit>
<trans-unit id="s94d61907ee22a8c1">
<source>Korean</source>
</trans-unit>
<trans-unit id="s95d56e58f816d211">
<source>Dutch</source>
</trans-unit>
<trans-unit id="s663ccbfdf27e8dd0">
<source>Network binding</source>
</trans-unit>
<trans-unit id="sb108a06693c67753">
<source>No binding</source>
</trans-unit>
<trans-unit id="s5aab90c74f1233b8">
<source>Bind ASN</source>
</trans-unit>
<trans-unit id="s488303b048afe83b">
<source>Bind ASN and Network</source>
</trans-unit>
<trans-unit id="s3268dcfe0c8234dc">
<source>Bind ASN, Network and IP</source>
</trans-unit>
<trans-unit id="s226381aca231644f">
<source>Configure if sessions created by this stage should be bound to the Networks they were created in.</source>
</trans-unit>
<trans-unit id="s2555a1f20f3fd93e">
<source>GeoIP binding</source>
</trans-unit>
<trans-unit id="s3d63c78f93c9a92e">
<source>Bind Continent</source>
</trans-unit>
<trans-unit id="s395d5863b3a259b5">
<source>Bind Continent and Country</source>
</trans-unit>
<trans-unit id="s625ea0c32b4b136c">
<source>Bind Continent, Country and City</source>
</trans-unit>
<trans-unit id="s4bc7a1a88961be90">
<source>Configure if sessions created by this stage should be bound to their GeoIP-based location</source>
</trans-unit>
<trans-unit id="sa06cd519ff151b6d">
<source>RAC</source>
</trans-unit>
<trans-unit id="s28b99b59541f54ca">
<source>Connection failed after <x id="0" equiv-text="${this.connectionAttempt}"/> attempts.</source>
</trans-unit>
<trans-unit id="s7c7d956418e1c8c8">
<source>Re-connecting in <x id="0" equiv-text="${Math.max(1, delay / 1000)}"/> second(s).</source>
</trans-unit>
<trans-unit id="sfc003381f593d943">
<source>Connecting...</source>
</trans-unit>
<trans-unit id="s31aa94a0b3c7edb2">
<source>Select endpoint to connect to</source>
</trans-unit>
</body>
</file>
</xliff>
</xliff>

File diff suppressed because it is too large Load Diff

View File

@ -6373,12 +6373,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s62418cbcd2a25498">
<source>Maximum concurrent allowed connections to this endpoint. Can be set to -1 to disable the limit.</source>
</trans-unit>
<trans-unit id="s94d61907ee22a8c1">
<source>Korean</source>
</trans-unit>
<trans-unit id="s95d56e58f816d211">
<source>Dutch</source>
</trans-unit>
</body>
</file>

View File

@ -8111,10 +8111,4 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s62418cbcd2a25498">
<source>Maximum concurrent allowed connections to this endpoint. Can be set to -1 to disable the limit.</source>
</trans-unit>
<trans-unit id="s94d61907ee22a8c1">
<source>Korean</source>
</trans-unit>
<trans-unit id="s95d56e58f816d211">
<source>Dutch</source>
</trans-unit>
</body></file></xliff>

View File

@ -6158,12 +6158,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s62418cbcd2a25498">
<source>Maximum concurrent allowed connections to this endpoint. Can be set to -1 to disable the limit.</source>
</trans-unit>
<trans-unit id="s94d61907ee22a8c1">
<source>Korean</source>
</trans-unit>
<trans-unit id="s95d56e58f816d211">
<source>Dutch</source>
</trans-unit>
</body>
</file>

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<?xml version="1.0"?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file target-language="zh-Hans" source-language="en" original="lit-localize-inputs" datatype="plaintext">
<body>
<trans-unit id="s4caed5b7a7e5d89b">
@ -613,9 +613,9 @@
</trans-unit>
<trans-unit id="saa0e2675da69651b">
<source>The URL &quot;<x id="0" equiv-text="${this.url}"/>&quot; was not found.</source>
<target>未找到 URL &quot;
<x id="0" equiv-text="${this.url}"/>&quot;。</target>
<source>The URL "<x id="0" equiv-text="${this.url}"/>" was not found.</source>
<target>未找到 URL "
<x id="0" equiv-text="${this.url}"/>"。</target>
</trans-unit>
<trans-unit id="s58cd9c2fe836d9c6">
@ -1057,8 +1057,8 @@
</trans-unit>
<trans-unit id="sa8384c9c26731f83">
<source>To allow any redirect URI, set this value to &quot;.*&quot;. Be aware of the possible security implications this can have.</source>
<target>要允许任何重定向 URI请将此值设置为 &quot;.*&quot;。请注意这可能带来的安全影响。</target>
<source>To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have.</source>
<target>要允许任何重定向 URI请将此值设置为 ".*"。请注意这可能带来的安全影响。</target>
</trans-unit>
<trans-unit id="s55787f4dfcdce52b">
@ -1799,8 +1799,8 @@
</trans-unit>
<trans-unit id="sa90b7809586c35ce">
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon &quot;fa-test&quot;.</source>
<target>输入完整 URL、相对路径或者使用 'fa://fa-test' 来使用 Font Awesome 图标 &quot;fa-test&quot;。</target>
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test".</source>
<target>输入完整 URL、相对路径或者使用 'fa://fa-test' 来使用 Font Awesome 图标 "fa-test"。</target>
</trans-unit>
<trans-unit id="s0410779cb47de312">
@ -2983,8 +2983,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s76768bebabb7d543">
<source>Field which contains members of a group. Note that if using the &quot;memberUid&quot; field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>包含组成员的字段。请注意,如果使用 &quot;memberUid&quot; 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...'</target>
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>包含组成员的字段。请注意,如果使用 "memberUid" 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...'</target>
</trans-unit>
<trans-unit id="s026555347e589f0e">
@ -3776,8 +3776,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s7b1fba26d245cb1c">
<source>When using an external logging solution for archiving, this can be set to &quot;minutes=5&quot;.</source>
<target>使用外部日志记录解决方案进行存档时,可以将其设置为 &quot;minutes=5&quot;。</target>
<source>When using an external logging solution for archiving, this can be set to "minutes=5".</source>
<target>使用外部日志记录解决方案进行存档时,可以将其设置为 "minutes=5"。</target>
</trans-unit>
<trans-unit id="s44536d20bb5c8257">
@ -3786,8 +3786,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: &quot;weeks=3;days=2;hours=3,seconds=2&quot;.</source>
<target>格式:&quot;weeks=3;days=2;hours=3,seconds=2&quot;。</target>
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>格式:"weeks=3;days=2;hours=3,seconds=2"。</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
@ -3983,10 +3983,10 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sa95a538bfbb86111">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> &quot;<x id="1" equiv-text="${this.obj?.name}"/>&quot;?</source>
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> "<x id="1" equiv-text="${this.obj?.name}"/>"?</source>
<target>您确定要更新
<x id="0" equiv-text="${this.objectLabel}"/>&quot;
<x id="1" equiv-text="${this.obj?.name}"/>&quot; 吗?</target>
<x id="0" equiv-text="${this.objectLabel}"/>"
<x id="1" equiv-text="${this.obj?.name}"/>" 吗?</target>
</trans-unit>
<trans-unit id="sc92d7cfb6ee1fec6">
@ -5072,7 +5072,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sdf1d8edef27236f0">
<source>A &quot;roaming&quot; authenticator, like a YubiKey</source>
<source>A "roaming" authenticator, like a YubiKey</source>
<target>像 YubiKey 这样的“漫游”身份验证器</target>
</trans-unit>
@ -5407,10 +5407,10 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s2d5f69929bb7221d">
<source><x id="0" equiv-text="${prompt.name}"/> (&quot;<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;, of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<source><x id="0" equiv-text="${prompt.name}"/> ("<x id="1" equiv-text="${prompt.fieldKey}"/>", of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<target>
<x id="0" equiv-text="${prompt.name}"/>&quot;
<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;,类型为
<x id="0" equiv-text="${prompt.name}"/>"
<x id="1" equiv-text="${prompt.fieldKey}"/>",类型为
<x id="2" equiv-text="${prompt.type}"/></target>
</trans-unit>
@ -5459,7 +5459,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s1608b2f94fa0dbd4">
<source>If set to a duration above 0, the user will have the option to choose to &quot;stay signed in&quot;, which will extend their session by the time specified here.</source>
<source>If set to a duration above 0, the user will have the option to choose to "stay signed in", which will extend their session by the time specified here.</source>
<target>如果设置时长大于 0用户可以选择“保持登录”选项这将使用户的会话延长此处设置的时间。</target>
</trans-unit>
@ -7965,7 +7965,7 @@ Bindings to groups/users are checked against the user of the event.</source>
<target>成功创建用户并添加到组 <x id="0" equiv-text="${this.group.name}"/></target>
</trans-unit>
<trans-unit id="s824e0943a7104668">
<source>This user will be added to the group &quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&quot;.</source>
<source>This user will be added to the group "<x id="0" equiv-text="${this.targetGroup.name}"/>".</source>
<target>此用户将会被添加到组 &amp;quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&amp;quot;。</target>
</trans-unit>
<trans-unit id="s62e7f6ed7d9cb3ca">
@ -8214,20 +8214,10 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="sc39f6abf0daedb0f">
<source>Maximum concurrent connections</source>
<target>最大并发连接数</target>
</trans-unit>
<trans-unit id="s62418cbcd2a25498">
<source>Maximum concurrent allowed connections to this endpoint. Can be set to -1 to disable the limit.</source>
<target>允许到此端点的最大并发连接数。可以设置为 -1 以禁用限制。</target>
</trans-unit>
<trans-unit id="s94d61907ee22a8c1">
<source>Korean</source>
<target>韩语</target>
</trans-unit>
<trans-unit id="s95d56e58f816d211">
<source>Dutch</source>
<target>荷兰语</target>
</trans-unit>
</body>
</file>
</xliff>
</xliff>

View File

@ -6206,12 +6206,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s62418cbcd2a25498">
<source>Maximum concurrent allowed connections to this endpoint. Can be set to -1 to disable the limit.</source>
</trans-unit>
<trans-unit id="s94d61907ee22a8c1">
<source>Korean</source>
</trans-unit>
<trans-unit id="s95d56e58f816d211">
<source>Dutch</source>
</trans-unit>
</body>
</file>

View File

@ -8211,22 +8211,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s31f1afc1bfe1cb3a">
<source>Learn more</source>
<target>了解更多</target>
</trans-unit>
<trans-unit id="sc39f6abf0daedb0f">
<source>Maximum concurrent connections</source>
<target>最大并发连接数</target>
</trans-unit>
<trans-unit id="s62418cbcd2a25498">
<source>Maximum concurrent allowed connections to this endpoint. Can be set to -1 to disable the limit.</source>
<target>允许到此端点的最大并发连接数。可以设置为 -1 以禁用限制。</target>
</trans-unit>
<trans-unit id="s94d61907ee22a8c1">
<source>Korean</source>
<target>韩语</target>
</trans-unit>
<trans-unit id="s95d56e58f816d211">
<source>Dutch</source>
<target>荷兰语</target>
</trans-unit>
</body>
</file>

View File

@ -8095,12 +8095,6 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s62418cbcd2a25498">
<source>Maximum concurrent allowed connections to this endpoint. Can be set to -1 to disable the limit.</source>
</trans-unit>
<trans-unit id="s94d61907ee22a8c1">
<source>Korean</source>
</trans-unit>
<trans-unit id="s95d56e58f816d211">
<source>Dutch</source>
</trans-unit>
</body>
</file>

View File

@ -1,99 +0,0 @@
---
title: "Happy New Year from Authentik Security"
slug: 2024-1-12-happy-new-year-from-authentik-security
authors:
- name: Jens Langhammer
title: CTO at Authentik Security Inc
url: https://github.com/BeryJu
image_url: https://github.com/BeryJu.png
tags:
- authentik
- happy new year
- new features
- year in review
- SSO
- SaaS
- SCIM
- RADIUS
- remote access
- RBAC
- identity provider
- authentication
- Authentik Security
hide_table_of_contents: false
---
> **_authentik is an open source Identity Provider that unifies your identity needs into a single platform, replacing Okta, Active Directory, and auth0. Authentik Security is a [public benefit company](https://github.com/OpenCoreVentures/ocv-public-benefit-company/blob/main/ocv-public-benefit-company-charter.md) building on top of the open source project._**
---
A hearty Happy New Year to you all, from all of of us at Authentik Security, with sincere wishes that your 2024 may be filled with a maximum of joys (new features and elegant code) and a minimum of pains (bugs and the dreadful reality of not-enough-time).
> The start of a new year makes me want to first say **thank you** for the past year.
## Thank you!
**Thank you to our community**, from the newly joined members to our long-time friends and moderators and holders-of-knowledge. Without you all, well… we literally wouldnt be here. No matter how deep your knowledge of authentik is, its really your willingness to explore and test and give feedback on new and old features, all while supporting each other and staying in touch with good humor and vibes, that make us such a vibrant community.
**Thank you to our users**, from those who run authentik in their homelabs to those who run authentik in production, and everyone in between. We appreciate your trust and guidance, and your input into how we can provide the most-needed features and grow our product in the ways that solve your business needs and challenges.
**And of course thanks to our small team** here at Authentik Security, who joined me on this adventure and brought your skills and talents, your experience and passions, and your dedication to our product and users. We built a lot together last year, and this year has a rock-star list of features and functionality coming up!
## Accomplishments in 2023
Looking back to the work we did in 2023, the new features are just a part of the overall achievements and celebrations (and challenges) of building a new [company](https://goauthentik.io/blog/2022-11-02-the-next-step-for-authentik), growing the team, celebrating our [1st year](https://goauthentik.io/blog/2023-11-1-happy-birthday-to-us), and [defining our tools and processes](https://goauthentik.io/blog/2023-12-21-five-lessons-from-choosing-infrastructure-tooling). But we released quite a few new features that Im proud to share.
### RBAC
[RBAC](https://goauthentik.io/docs/user-group-role/access-control/) (role-based access control) is the gold standard of access control. RBAC provides the ability to finely configure permissions within authentik. These permissions can be used to delegate different tasks, such as user management, application creation and more to users without granting them full superuser permissions. authentik has had internal RBAC for a long time (and of course the policy engine for restricting access to applications), however access to different objects within authentik (like Users, Groups, etc) was not possible previously.
### Enterprise Support
Providing dedicated support with a proper ticketing system was a big accomplishment for 2023. Support was the flagship feature of our [Enterprise release](https://goauthentik.io/blog/2023-08-31-announcing-the-authentik-enterprise-release) in the fall of 2023.
### SCIM support
Our [2023.3 release](https://goauthentik.io/docs/releases/2023.3) added support for SCIM (System for Cross-domain Identity Management) protocol, allowing for the provision of users into other IT systems, where the provider synchronizes Users, Groups and the user membership.
### RADIUS Support
The [RADIUS protocol](https://goauthentik.io/docs/providers/radius/) for authentication allows for the integration of a wider variety of systems such as VPN software, network switches/routers, and others. The RADIUS provider also uses a flow to authenticate users, and supports the same stages as the [LDAP Provider](https://goauthentik.io/docs/providers/ldap/).
## Whats coming up in 2024?
Looking forward to new functionality for the new year, let me share some of the ones I am most excited about. As with any small development team, we tackle what we can, with an eye on which features will be most beneficial for you all, which have dependencies upon later features, maintainability as we further develop the feature, and how to best get them all out the door fully tested and documented.
### Wizardry
The task of adding the applications that you want authentik to authenticate is about to get a lot easier; we have a new wizard that combines the process of defining a new provider and a new application into one single task. This new wizard saves many steps and streamlines the process. Look for it in preview mode in our current 2023.10 release (navigate to the Applications page in the Admin UI), and let us know your thoughts. We will continue tweaking it, specifically the multi-select functionality, but feedback is always welcome!
![](./new-app-wizard.png)
### Remote Access Control (RAC)
With [RAC](https://goauthentik.io/docs/providers/rac/), in preview now with a full release in early 2024, authentik Admins are able to access remote Windows/macOS/Linux machines via [RDP](https://en.wikipedia.org/wiki/Remote_Desktop_Protocol)/[SSH](https://en.wikipedia.org/wiki/Secure_Shell)/[VNC](https://en.wikipedia.org/wiki/Virtual_Network_Computing). The preview version already has capabilities for using a bi-directoinal clipboard between the authentik client and the remote machine, audio redirection (meaning you can hear audio from the remote machine on your local instance), and resizing of the window you view of the remote machine.
### Mobile authenticator app for authentik
Soon you will be able to download our new authentik authentication app from Apple Store, and a bit further into 2024, from Google Play Store. This app can be used for 2FA/MFA verification when authentik users log in to authentik or access any application managed by an authentik instance. The first release of this app will use number-matching as the default verification process; users will view their authentik authenticator app on their phone, be prompted with a set of three numbers, and then need to select the same number that is displayed on their authentik instance login panel.
### Building out our SaaS offering
One of our most exciting, and definitely our biggest, projects for 2024 will be developing our SaaS offering, the hosted, fully-managed Enterprise Cloud. The Enterprise Cloud plan will provide the convenience of our enterprise-level product as a SaaS offering, hosted and managed by Authentik Security. For many organizations, the benefits of decreased operational costs and universal data access (no VPN, servers, and network configuration required) make SaaS the best choice. With the cloud offering, the same enterprise-level support plan is included, and migrating to self-hosted is always an option.
### DX and UX and quality-of-life improvements
As we mentioned in our blog about our one-year anniversary, we also plan to spend some time focused on user experience.
- Increase our focus on UX and ease-of-use, templatizing as much as possible of the frontend components, and developing a UI Style Guide
- A redesigned website, with more information about our solutions, use cases, and offerings
- New structure for our technical documentation; leveraging information architecture and user research to make it easier to find what you are looking for in our docs
- Defining even more robust tests and checks for our CI/CD pipeline and build process
- Stronger integration and migration testing, both automated and manual
- Spending more time on outreach and user research to learn what you all want
### Yes, a big year ahead
As most of us in the software and technology space know, the hard work of building new features and growing a company is, well, actually kind of fun. Challenging, yes, but always rewarding.
Wed love to hear from you all about our upcoming plans; reach out to us with an email to [hello@goauthentik.io](mailto:hello@goauthentik.io) or on [Discord](https://discord.com/channels/809154715984199690/809154716507963434).

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

View File

@ -116,7 +116,7 @@ To check if your config has been applied correctly, you can run the following co
`AUTHENTIK_REDIS__CACHE_TIMEOUT_REPUTATION` only applies to the cache expiry, see [`AUTHENTIK_REPUTATION__EXPIRY`](#authentik_reputation__expiry) to control how long reputation is persisted for.
:::
## Listen Settings
## Listen Setting
- `AUTHENTIK_LISTEN__HTTP`: Listening address:port (e.g. `0.0.0.0:9000`) for HTTP (Applies to Server and Proxy outpost)
- `AUTHENTIK_LISTEN__HTTPS`: Listening address:port (e.g. `0.0.0.0:9443`) for HTTPS (Applies to Server and Proxy outpost)
@ -124,7 +124,7 @@ To check if your config has been applied correctly, you can run the following co
- `AUTHENTIK_LISTEN__LDAPS`: Listening address:port (e.g. `0.0.0.0:6636`) for LDAPS (Applies to LDAP outpost)
- `AUTHENTIK_LISTEN__METRICS`: Listening address:port (e.g. `0.0.0.0:9300`) for Prometheus metrics (Applies to All)
- `AUTHENTIK_LISTEN__DEBUG`: Listening address:port (e.g. `0.0.0.0:9900`) for Go Debugging metrics (Applies to All)
- `AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS`: List of comma-separated CIDRs that proxy headers should be accepted from (Applies to Server)
- `AUTHENTIK_LISTEN__TRUSTED_PROXY_CIDRS`: List of CIDRs that proxy headers should be accepted from (Applies to Server)
Defaults to `127.0.0.0/8`, `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `fe80::/10`, `::1/128`.

View File

@ -4,16 +4,16 @@ title: Docker Compose installation
This installation method is for test-setups and small-scale production setups.
:::info
You can also [view a video walk-through](https://www.youtube.com/watch?v=O1qUbrk4Yc8) of the installation process on Docker (with bonus details about email configuration and other important options).
:::
## Requirements
- A host with at least 2 CPU cores and 2 GB of RAM
- Docker
- Docker Compose
## Video
<iframe width="560" height="315" src="https://www.youtube.com/embed/O1qUbrk4Yc8?si=HiSBjmJYhE_oJhB1&amp;start=22" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
## Preparation
To download the latest `docker-compose.yml` open your terminal and navigate to the directory of your choice.

View File

@ -4,6 +4,6 @@ title: Installation
Everything you need to get authentik up and running! For information about upgrading to a new version, refer to the <b>Upgrade</b> section in the relevant [Release Notes](../releases).
import DocCardList from "@theme/DocCardList";
import DocCardList from '@theme/DocCardList';
<DocCardList />

View File

@ -13,10 +13,6 @@ You can also [view a video walk-through](https://www.youtube.com/watch?v=O1qUbrk
- Kubernetes
- Helm
## Video
<iframe width="560" height="315" src="https://www.youtube.com/embed/O1qUbrk4Yc8?si=hs-ZhbVk4Y-TW_Vw&amp;start=562" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
### Generate Passwords
Start by generating passwords for the database and cache. You can use either of the following commands:

View File

@ -181,18 +181,6 @@ helm upgrade authentik authentik/authentik -f values.yaml --version ^2023.10
- web/admin: always show oidc well-known URL fields when they're set (#7560)
- web/user: fix search not updating app (cherry-pick #7825) (#7933)
## Fixed in 2023.10.6
- core: fix PropertyMapping context not being available in request context
- outposts: disable deployment and secret reconciler for embedded outpost in code instead of in config (cherry-pick #8021) (#8024)
- outposts: fix Outpost reconcile not re-assigning managed attribute (cherry-pick #8014) (#8020)
- providers/oauth2: fix [CVE-2024-21637](../../security/CVE-2024-21637.md), Reported by [@lauritzh](https://github.com/lauritzh) (#8104)
- providers/oauth2: remember session_id from initial token (cherry-pick #7976) (#7977)
- providers/proxy: use access token (cherry-pick #8022) (#8023)
- rbac: fix error when looking up permissions for now uninstalled apps (cherry-pick #8068) (#8070)
- sources/oauth: fix missing get_user_id for OIDC-like sources (Azure AD) (#7970)
- web/flows: fix device picker incorrect foreground color (cherry-pick #8067) (#8069)
## API Changes
#### What's New

View File

@ -163,10 +163,6 @@ image:
- security: fix [CVE-2023-48228](../../security/CVE-2023-48228.md), Reported by [@Sapd](https://github.com/Sapd) (#7666)
## Fixed in 2023.8.6
- providers/oauth2: fix [CVE-2024-21637](../../security/CVE-2024-21637.md), Reported by [@lauritzh](https://github.com/lauritzh) (#8104)
## API Changes
#### What's New

View File

@ -1,39 +0,0 @@
# CVE-2024-21637
_Reported by [@lauritzh](https://github.com/lauritzh)_
## XSS in Authentik via JavaScript-URI as Redirect URI and form_post Response Mode
### Summary
Given an OAuth2 provider configured with allowed redirect URIs set to `*` or `.*`, an attacker can send an OAuth Authorization request using `response_mode=form_post` and setting `redirect_uri` to a malicious URI, to capture authentik's session token.
### Patches
authentik 2023.8.6 and 2023.10.6 fix this issue.
### Impact
The impact depends on the attack scenario. In the following I will describe the two scenario that were identified for Authentik.
#### Redirect URI Misconfiguration
While advising that this may cause security issues, Authentik generally allows wildcards as Redirect URI. Therefore, using a wildcard-only effectively allowing arbitrary URLS is possible misconfiguration that may be present in real-world instances.
In such cases, unauthenticated and unprivileged attackers can perform the above described actions.
### User with (only) App Administration Permissions
A more likely scenario is an administrative user (e.g. a normal developer) having only permissions to manage applications.
This relatively user could use the described attacks to perform a privilege escalation.
### Workaround
It is recommended to upgrade to the patched version of authentik. If not possible, ensure that OAuth2 providers do not use a wildcard (`*` or `.*`) value as allowed redirect URI setting. (This is _not_ exploitable if part of the redirect URI has a wildcard, for example `https://foo-.*\.bar\.com`)
### For more information
If you have any questions or comments about this advisory:
- Email us at [security@goauthentik.io](mailto:security@goauthentik.io)

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