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
21 changed files with 122 additions and 119 deletions

View File

@ -7,7 +7,7 @@ import "@goauthentik/components/ak-number-input";
import "@goauthentik/components/ak-radio-input"; import "@goauthentik/components/ak-radio-input";
import "@goauthentik/components/ak-switch-input"; import "@goauthentik/components/ak-switch-input";
import "@goauthentik/components/ak-text-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/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement"; import "@goauthentik/elements/forms/HorizontalFormElement";
@ -32,7 +32,7 @@ import {
} from "./LDAPOptionsAndHelp"; } from "./LDAPOptionsAndHelp";
@customElement("ak-application-wizard-authentication-by-ldap") @customElement("ak-application-wizard-authentication-by-ldap")
export class ApplicationWizardApplicationDetails extends WithTenantConfig(BaseProviderPanel) { export class ApplicationWizardApplicationDetails extends WithBrandConfig(BaseProviderPanel) {
render() { render() {
const provider = this.wizard.provider as LDAPProvider | undefined; const provider = this.wizard.provider as LDAPProvider | undefined;
const errors = this.wizard.errors.provider; const errors = this.wizard.errors.provider;
@ -57,7 +57,7 @@ export class ApplicationWizardApplicationDetails extends WithTenantConfig(BasePr
<ak-tenanted-flow-search <ak-tenanted-flow-search
flowType=${FlowsInstancesListDesignationEnum.Authentication} flowType=${FlowsInstancesListDesignationEnum.Authentication}
.currentFlow=${provider?.authorizationFlow} .currentFlow=${provider?.authorizationFlow}
.tenantFlow=${this.tenant.flowAuthentication} .tenantFlow=${this.brand.flowAuthentication}
required required
></ak-tenanted-flow-search> ></ak-tenanted-flow-search>
<p class="pf-c-form__helper-text"> <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 "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
import { ascii_letters, digits, first, randomString } from "@goauthentik/common/utils"; import { ascii_letters, digits, first, randomString } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-text-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/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement"; import "@goauthentik/elements/forms/HorizontalFormElement";
@ -17,7 +17,7 @@ import { FlowsInstancesListDesignationEnum, RadiusProvider } from "@goauthentik/
import BaseProviderPanel from "../BaseProviderPanel"; import BaseProviderPanel from "../BaseProviderPanel";
@customElement("ak-application-wizard-authentication-by-radius") @customElement("ak-application-wizard-authentication-by-radius")
export class ApplicationWizardAuthenticationByRadius extends WithTenantConfig(BaseProviderPanel) { export class ApplicationWizardAuthenticationByRadius extends WithBrandConfig(BaseProviderPanel) {
render() { render() {
const provider = this.wizard.provider as RadiusProvider | undefined; const provider = this.wizard.provider as RadiusProvider | undefined;
const errors = this.wizard.errors.provider; const errors = this.wizard.errors.provider;
@ -42,7 +42,7 @@ export class ApplicationWizardAuthenticationByRadius extends WithTenantConfig(Ba
<ak-tenanted-flow-search <ak-tenanted-flow-search
flowType=${FlowsInstancesListDesignationEnum.Authentication} flowType=${FlowsInstancesListDesignationEnum.Authentication}
.currentFlow=${provider?.authorizationFlow} .currentFlow=${provider?.authorizationFlow}
.tenantFlow=${this.tenant.flowAuthentication} .tenantFlow=${this.brand.flowAuthentication}
required required
></ak-tenanted-flow-search> ></ak-tenanted-flow-search>
<p class="pf-c-form__helper-text"> <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 { uiConfig } from "@goauthentik/common/ui/config";
import { first } from "@goauthentik/common/utils"; import { first } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-status-label"; import "@goauthentik/components/ak-status-label";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import { import {
CapabilitiesEnum, CapabilitiesEnum,
WithCapabilitiesConfig, WithCapabilitiesConfig,
} from "@goauthentik/elements/Interface/capabilitiesProvider"; } from "@goauthentik/elements/Interface/capabilitiesProvider";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import "@goauthentik/elements/buttons/ActionButton"; import "@goauthentik/elements/buttons/ActionButton";
import "@goauthentik/elements/buttons/Dropdown"; import "@goauthentik/elements/buttons/Dropdown";
import "@goauthentik/elements/forms/DeleteBulkForm"; import "@goauthentik/elements/forms/DeleteBulkForm";
@ -110,7 +110,7 @@ export class RelatedUserAdd extends Form<{ users: number[] }> {
} }
@customElement("ak-user-related-list") @customElement("ak-user-related-list")
export class RelatedUserList extends WithTenantConfig(WithCapabilitiesConfig(Table<User>)) { export class RelatedUserList extends WithBrandConfig(WithCapabilitiesConfig(Table<User>)) {
expandable = true; expandable = true;
checkbox = true; checkbox = true;
@ -295,7 +295,7 @@ export class RelatedUserList extends WithTenantConfig(WithCapabilitiesConfig(Tab
${msg("Set password")} ${msg("Set password")}
</button> </button>
</ak-forms-modal> </ak-forms-modal>
${this.tenant?.flowRecovery ${this.brand?.flowRecovery
? html` ? html`
<ak-action-button <ak-action-button
class="pf-m-secondary" class="pf-m-secondary"

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,13 @@ import {
import { EVENT_LOCALE_REQUEST, EVENT_REFRESH, VERSION } from "@goauthentik/common/constants"; import { EVENT_LOCALE_REQUEST, EVENT_REFRESH, VERSION } from "@goauthentik/common/constants";
import { globalAK } from "@goauthentik/common/global"; 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); let globalConfigPromise: Promise<Config> | undefined = Promise.resolve(globalAK().config);
export function config(): Promise<Config> { export function config(): Promise<Config> {
@ -16,7 +22,7 @@ export function config(): Promise<Config> {
return globalConfigPromise; return globalConfigPromise;
} }
export function tenantSetFavicon(tenant: CurrentTenant) { export function brandSetFavicon(brand: CurrentBrand) {
/** /**
* <link rel="icon" href="/static/dist/assets/icons/icon.png"> * <link rel="icon" href="/static/dist/assets/icons/icon.png">
* <link rel="shortcut 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; relIcon.rel = rel;
document.getElementsByTagName("head")[0].appendChild(relIcon); document.getElementsByTagName("head")[0].appendChild(relIcon);
} }
relIcon.href = tenant.brandingFavicon; relIcon.href = brand.brandingFavicon;
}); });
} }
export function tenantSetLocale(tenant: CurrentTenant) { export function brandSetLocale(brand: CurrentBrand) {
if (tenant.defaultLocale === "") { if (brand.defaultLocale === "") {
return; return;
} }
console.debug("authentik/locale: setting locale from tenant default"); console.debug("authentik/locale: setting locale from brand default");
window.dispatchEvent( window.dispatchEvent(
new CustomEvent(EVENT_LOCALE_REQUEST, { new CustomEvent(EVENT_LOCALE_REQUEST, {
composed: true, composed: true,
bubbles: true, bubbles: true,
detail: { locale: tenant.defaultLocale }, detail: { locale: brand.defaultLocale },
}), }),
); );
} }
let globalTenantPromise: Promise<CurrentTenant> | undefined = Promise.resolve(globalAK().tenant); let globalBrandPromise: Promise<CurrentBrand> | undefined = Promise.resolve(globalAK().tenant);
export function tenant(): Promise<CurrentTenant> { export function brand(): Promise<CurrentBrand> {
if (!globalTenantPromise) { if (!globalBrandPromise) {
globalTenantPromise = new CoreApi(DEFAULT_CONFIG) globalBrandPromise = new CoreApi(DEFAULT_CONFIG)
.coreTenantsCurrentRetrieve() .coreTenantsCurrentRetrieve()
.then((tenant) => { .then((brand) => {
tenantSetFavicon(tenant); brandSetFavicon(brand);
tenantSetLocale(tenant); brandSetLocale(brand);
return tenant; return brand;
}); });
} }
return globalTenantPromise; return globalBrandPromise;
} }
export function getMetaContent(key: string): string { export function getMetaContent(key: string): string {
@ -90,9 +96,9 @@ window.addEventListener(EVENT_REFRESH, () => {
// Upon global refresh, disregard whatever was pre-hydrated and // Upon global refresh, disregard whatever was pre-hydrated and
// actually load info from API // actually load info from API
globalConfigPromise = undefined; globalConfigPromise = undefined;
globalTenantPromise = undefined; globalBrandPromise = undefined;
config(); config();
tenant(); brand();
}); });
console.debug(`authentik(early): version ${VERSION}, apiBase ${DEFAULT_CONFIG.basePath}`); 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 { getCookie } from "@goauthentik/common/utils";
import { import {
CurrentTenant, CurrentTenant as CurrentBrand,
FetchParams, FetchParams,
Middleware, Middleware,
RequestContext, RequestContext,
@ -18,13 +18,13 @@ export interface RequestInfo {
} }
export class LoggingMiddleware implements Middleware { export class LoggingMiddleware implements Middleware {
tenant: CurrentTenant; brand: CurrentBrand;
constructor(tenant: CurrentTenant) { constructor(brand: CurrentBrand) {
this.tenant = tenant; this.brand = brand;
} }
post(context: ResponseContext): Promise<Response | void> { 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 // https://developer.mozilla.org/en-US/docs/Web/API/console#styling_console_output
msg += `%c${context.response.status}%c ${context.init.method} ${context.url}`; msg += `%c${context.response.status}%c ${context.init.method} ${context.url}`;
let style = ""; let style = "";

View File

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

View File

@ -9,13 +9,13 @@ import { LitElement } from "lit";
import AKGlobal from "@goauthentik/common/styles/authentik.css"; import AKGlobal from "@goauthentik/common/styles/authentik.css";
import ThemeDark from "@goauthentik/common/styles/theme-dark.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"; import { AdoptedStyleSheetsElement } from "./types";
type AkInterface = HTMLElement & { type AkInterface = HTMLElement & {
getTheme: () => Promise<UiThemeEnum>; getTheme: () => Promise<UiThemeEnum>;
tenant?: CurrentTenant; brand?: CurrentBrand;
uiConfig?: UIConfig; uiConfig?: UIConfig;
config?: Config; 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 { UIConfig, uiConfig } from "@goauthentik/common/ui/config";
import { import {
authentikBrandContext,
authentikConfigContext, authentikConfigContext,
authentikTenantContext,
} from "@goauthentik/elements/AuthentikContexts"; } from "@goauthentik/elements/AuthentikContexts";
import type { AdoptedStyleSheetsElement } from "@goauthentik/elements/types"; import type { AdoptedStyleSheetsElement } from "@goauthentik/elements/types";
import { ensureCSSStyleSheet } from "@goauthentik/elements/utils/ensureCSSStyleSheet"; 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 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"; import { AKElement } from "../Base";
type AkInterface = HTMLElement & { type AkInterface = HTMLElement & {
getTheme: () => Promise<UiThemeEnum>; getTheme: () => Promise<UiThemeEnum>;
tenant?: CurrentTenant; brand?: CurrentBrand;
uiConfig?: UIConfig; uiConfig?: UIConfig;
config?: Config; config?: Config;
}; };
@ -45,28 +45,28 @@ export class Interface extends AKElement implements AkInterface {
return this._config; return this._config;
} }
_tenantContext = new ContextProvider(this, { _brandContext = new ContextProvider(this, {
context: authentikTenantContext, context: authentikBrandContext,
initialValue: undefined, initialValue: undefined,
}); });
_tenant?: CurrentTenant; _brand?: CurrentBrand;
@state() @state()
set tenant(c: CurrentTenant) { set brand(c: CurrentBrand) {
this._tenant = c; this._brand = c;
this._tenantContext.setValue(c); this._brandContext.setValue(c);
this.requestUpdate(); this.requestUpdate();
} }
get tenant(): CurrentTenant | undefined { get brand(): CurrentBrand | undefined {
return this._tenant; return this._brand;
} }
constructor() { constructor() {
super(); super();
document.adoptedStyleSheets = [...document.adoptedStyleSheets, ensureCSSStyleSheet(PFBase)]; document.adoptedStyleSheets = [...document.adoptedStyleSheets, ensureCSSStyleSheet(PFBase)];
tenant().then((tenant) => (this.tenant = tenant)); brand().then((brand) => (this.brand = brand));
config().then((config) => (this.config = config)); config().then((config) => (this.config = config));
this.dataset.akInterfaceRoot = "true"; 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 { currentInterface } from "@goauthentik/common/sentry";
import { me } from "@goauthentik/common/users"; import { me } from "@goauthentik/common/users";
import { AKElement } from "@goauthentik/elements/Base"; 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 "@patternfly/elements/pf-tooltip/pf-tooltip.js";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
@ -24,7 +24,7 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { EventsApi } from "@goauthentik/api"; import { EventsApi } from "@goauthentik/api";
@customElement("ak-page-header") @customElement("ak-page-header")
export class PageHeader extends WithTenantConfig(AKElement) { export class PageHeader extends WithBrandConfig(AKElement) {
@property() @property()
icon?: string; icon?: string;
@ -37,7 +37,7 @@ export class PageHeader extends WithTenantConfig(AKElement) {
@property() @property()
set header(value: string) { set header(value: string) {
const currentIf = currentInterface(); const currentIf = currentInterface();
let title = this.tenant?.brandingTitle || TITLE_DEFAULT; let title = this.brand?.brandingTitle || TITLE_DEFAULT;
if (currentIf === "admin") { if (currentIf === "admin") {
title = `${msg("Admin")} - ${title}`; title = `${msg("Admin")} - ${title}`;
} }

View File

@ -1,6 +1,6 @@
import { EVENT_SIDEBAR_TOGGLE } from "@goauthentik/common/constants"; import { EVENT_SIDEBAR_TOGGLE } from "@goauthentik/common/constants";
import { AKElement } from "@goauthentik/elements/Base"; 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 { CSSResult, TemplateResult, css, html } from "lit";
import { customElement } from "lit/decorators.js"; 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 PFGlobal from "@patternfly/patternfly/patternfly-base.css";
import PFBase 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 // If the viewport is wider than MIN_WIDTH, the sidebar
// is shown besides the content, and not overlaid. // is shown besides the content, and not overlaid.
export const MIN_WIDTH = 1200; export const MIN_WIDTH = 1200;
export const DefaultTenant: CurrentTenant = { export const DefaultBrand: CurrentBrand = {
brandingLogo: "/static/dist/assets/icons/icon_left_brand.svg", brandingLogo: "/static/dist/assets/icons/icon_left_brand.svg",
brandingFavicon: "/static/dist/assets/icons/icon.png", brandingFavicon: "/static/dist/assets/icons/icon.png",
brandingTitle: "authentik", brandingTitle: "authentik",
@ -27,7 +27,7 @@ export const DefaultTenant: CurrentTenant = {
}; };
@customElement("ak-sidebar-brand") @customElement("ak-sidebar-brand")
export class SidebarBrand extends WithTenantConfig(AKElement) { export class SidebarBrand extends WithBrandConfig(AKElement) {
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return [ return [
PFBase, PFBase,
@ -65,6 +65,7 @@ export class SidebarBrand extends WithTenantConfig(AKElement) {
} }
render(): TemplateResult { render(): TemplateResult {
console.log(this.brand);
return html` ${window.innerWidth <= MIN_WIDTH return html` ${window.innerWidth <= MIN_WIDTH
? html` ? html`
<button <button
@ -85,7 +86,7 @@ export class SidebarBrand extends WithTenantConfig(AKElement) {
<a href="#/" class="pf-c-page__header-brand-link"> <a href="#/" class="pf-c-page__header-brand-link">
<div class="pf-c-brand ak-brand"> <div class="pf-c-brand ak-brand">
<img <img
src=${this.tenant?.brandingLogo ?? DefaultTenant.brandingLogo} src=${this.brand?.brandingLogo ?? DefaultBrand.brandingLogo}
alt="authentik Logo" alt="authentik Logo"
loading="lazy" loading="lazy"
/> />

View File

@ -205,7 +205,7 @@ export class RacInterface extends Interface {
} }
updateTitle(): void { updateTitle(): void {
let title = this.tenant?.brandingTitle || TITLE_DEFAULT; let title = this.brand?.brandingTitle || TITLE_DEFAULT;
if (this.endpointName) { if (this.endpointName) {
title = `${this.endpointName} - ${title}`; title = `${this.endpointName} - ${title}`;
} }

View File

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

View File

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

View File

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

View File

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