Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

web: Application wizard v2 with tests #7004

Merged
merged 135 commits into from
Oct 18, 2023

Conversation

kensternberg-authentik
Copy link
Contributor

@kensternberg-authentik kensternberg-authentik commented Sep 27, 2023

web: application wizard

Details

This commit incorporates the actual application wizard into the Web UI.

It consists of three parts:

The Wizard!

The Wizard component, which provides a framework for the Header, Nav/Breadcrumb bar, and Button Bar. That, in turn consists of four interacting components:

  • The frame, ak-wizard-frame, which is a purely passive Lit component that renders the Header, Navbar, Button Bar, and central content according to properties passed into it.
  • The Wizard (AKWizard), from which all wizards inherit, and which maintains the frame and long-duration metadata associated with wizarding.
  • The WizardController, which handles events from the frame and its contents and, in turn, packages up the actual information of the event into well-typed messages sent to the Wizard.
  • The WizardStep definition, which describes a single step and its metadata to be used by the Wizard for navigation and to provide the renderer of a Step’s content.

The Application Wizard

The Application Wizard, which inherits from AKWizard and implements the business logic for gathering the data sent to it by its steps and deciding whether to permit forward navigation. It also provides a context for the information gathered by the Wizard. The context allows the Steps to self-render without requiring internal prop-drilling to get it there.

The BasePanel, which provides the ContextConsumer and a customized event dispatcher, further reducing the burden on each Step for how much code needs to be written for the step to be coherent.

Aside from that, the additions are the steps for the Application, the Provider, the various subtypes of providers (LDAP, OAuth, Radius, SAML, SCIM, Proxy), and the commit phase. The forms here are generally short: mostly just the renderer, with a rare custom event handler for some special cases, and a just as rare constructor for pulling down enumerated lists from the server during construction.

Tests

I’ve also provided a series of “simple,” “happy path” e2e tests that log in to the server, find the wizard, and run each of the different application types through a very basic set of paces. The good news is that the form objects for each provider type are independent and can be mixed into any testing system, so these form objects can be used to test the old Providers wizard just as readily, and the previous commit illustrated that.

Checklist

  • Local tests pass (ak test authentik/)
  • The code has been formatted (make lint-fix)

If an API change has been made

  • The API schema has been updated (make gen-build)

If changes to the frontend have been made

  • The code has been formatted (make web)
  • The translation files have been updated (make i18n-extract)

If applicable

  • The documentation has been updated
  • The documentation has been formatted (make website)

kensternberg-authentik and others added 30 commits July 28, 2023 18:10
This is a pretty good result.  By using the LightDOM setting, this
provides the existing Authentik form manager with access to the
ak-form-horizontal-element components without having to do any
cross-border magic.  It's not ideal, and it shows up just how badly
we've got patternfly splattered everywhere, but the actual results
are remarkable.  The patterns for text, switch, radio, textarea,
file, and even select are smaller and easier here.

I'm still noodling on what an unspread search-select element would
look like.  It's just dependency injection, so it ought to be as
straightforward as that.
I become frustrated with my inability to make any progress on this project, so I decided to reach
for a tool that I consider highly reliable but also incredibly time-consuming and boring: test
driven development.

In this case, I wrote a story about how I wanted to see the first page rendered: just put the HTML
tag, completely unadorned, that will handle the first page of the wizard. Then, add an event handler
that will send the updated content to some parent object, since what we really want is to
orchestrate the state of the user's input with a centralized location. Then, rather than fiddling
with the attributes and properties of the various pages, I wanted them to be able to "look up" the
values they want, much as we'd expect a standalone form to be able to pull its values from the
server, so I added a context object that receives the update event and incorporates the new
knowledge about the state of the process into itself.

The result is surprisingly satisfying: the first page renders cleanly, displays the content that we
want, and as we fiddle with, we can *watch in real time* as the results of the context are updated
and retransmitted to all receiving objects. And the sending object gets the results so it
re-renders, but it ends up looking the same as it was before the render.
…s working, but there is a bug:

the radio is sending the wrong value !?!?!?. Track that down, dammit. The search wrappers now resend
their events as standard `input` events, and that actually seems to work well; the browser is
decorating it with the right target, with the right `name` attribute, and since we have good
definitions of the `value` as a string (the real value of any search object is its UUID4), that
works quite well. Added search wrappers for CoreGroup and CryptoCertificate (CertificateKeyPairs),
and the latter has flags for "use the first one if it's the only one" and "allow the display of
keyless certificates."

Not sure why `state()` is blocking the transmission of typing information from the typed element
to the context handler, but it's a bug in the typechecker, and it's not a problem so far.
…s working, but there is a bug:

the radio is sending the wrong value !?!?!?. Track that down, dammit. The search wrappers now resend
their events as standard `input` events, and that actually seems to work well; the browser is
decorating it with the right target, with the right `name` attribute, and since we have good
definitions of the `value` as a string (the real value of any search object is its UUID4), that
works quite well. Added search wrappers for CoreGroup and CryptoCertificate (CertificateKeyPairs),
and the latter has flags for "use the first one if it's the only one" and "allow the display of
keyless certificates."

Not sure why `state()` is blocking the transmission of typing information from the typed element
to the context handler, but it's a bug in the typechecker, and it's not a problem so far.
Because radio inputs are actually multiples, the events handling for
radio is... wonky.  If we want our `<ak-radio>` component to be a
unitary event dispatcher, saying "This is the element selected," we
needed to do more than what was currently being handled.

I've intercepted the events that we care about and have placed
them into a controller that dictates both the setting and the
re-render of the component.  This makes it "controlled" (to use the
Angular/React/Vue) language and depends on Lit's reactiveElement
lifecycle to work, rather than trust the browser, but the browser's
experience with respect to the `<input type=radio` is pretty bad:
both input elements fire events, one for "losing selection" and
one for "gaining selection".  That can be very confusing to handle,
so we funnel them down in our aggregate radio element to a single
event, "selection changed".

As a quality-of-life measure, I've also set the label to be
unselectable; this means that a click on the label will trigger the
selection event, and a long click will not disable selection or
confuse the selection event generator.
…he body.

This isn't really a very good hack; what it does is say that every story is
responsible for hacking its theme into the parent.  This is very annoying, but
it does mean that we can at least show our components in the best light.
1. Fixed `eventEmitter` so that if the detail object is a scalar, it will not attempt to "objectify"
   it.  This was causing a bug where retrofitting the eventEmitter to some older components resulted
   in a detail of "some" being translated into ['s', 'o', 'm', 'e'].  Not what is wanted.
2. Removed the "transitional form" from the existing components; they had a two-step where the web
   component class was just a wrapper around an independent rendering function.  While this worked,
   it was only to make the case that they *were* independent rendering objects and could be
   supported with the right web component framework.  We're halfway there now; the last step will be
   to transform the horizontal-element and various input CSS into componentized CSS, the way
   Patternfly-Elements is currently doing.
3. Fixed the `help` field so that it could take a string or a TemplateResult, and if the latter,
   don't bother wrapping it in the helper text functionality; just let it be its own thing.  This
   supports the multi-line help of redirectURI as well as the `ak-utils-time-delta` capability.
4. Transform Oauth2ProviderForm to use the new components, to the best of our ability.  Also used
   the `provider = this.wizard.provider` and `provider = this.instance` syntax to make the render
   function *completely portable*; it's the exact same text that is dropped into...
5. The complete `ak-application-wizard-authentication-by-oauth` component. They're so similar part
   of me wonders if I could push them both out to a common reference, or a collection of common
   references.  Both components use the PropertyMapping and Sources, and both use the same
   collection of searches (Crypto, Flow).
6. A Storybook for `ak-application-wizard-authentication-by-oauth`, showing the works working.
7. New mocks for `authorizationFlow`, `propertyMappings`, and `hasJWKs`.

This sequence has revealed a bug in the radio control.  (It's always the radio control.)  If the
default doesn't match the current setting, the radio control doesn't behave as expected; it won't
change when you fully expect that it should.  I'll investigate how to harmonize those tomorrow.
* main:
  blueprints: prevent duplicate password stage in default flow when using combined identification stage (#6432)
  website/integrations: cite better (#6431)
  root: add generated Source docs (#5323)
  website/docs: add architecture and persistence (#6250)
  core: bump paramiko from 3.2.0 to 3.3.1 (#6428)
  website: fix sidebar sizing (#6430)
  ci: update dependabot labels (#6423)
  website: fix sidebar layout (#6421)
* main: (36 commits)
  website/blog: add github user name links (#6468)
  website/developer-docs: add new template for procedures (#6390)
  website/blogs: blog to celebrate hackathon (#6457)
  web/flows: add more stories (#6444)
  web: bump prettier from 3.0.0 to 3.0.1 in /web (#6465)
  core: bump debugpy from 1.6.7 to 1.6.8 (#6458)
  ci: bump peter-evans/create-pull-request from 4 to 5 (#6459)
  web: bump lit from 2.7.6 to 2.8.0 in /web (#6460)
  web: bump @fortawesome/fontawesome-free from 6.4.0 to 6.4.2 in /web (#6461)
  web: bump chart.js from 4.3.2 to 4.3.3 in /web (#6462)
  web: bump @lit-labs/task from 2.1.2 to 3.0.0 in /web (#6463)
  web, website: compress images (#6121)
  core: bump cryptography from 41.0.2 to 41.0.3 (#6456)
  root: replace builtin psycopg libpq binary implementation with distro… (#6448)
  website: fix broken links in NewsBar
  core: bump github.com/getsentry/sentry-go from 0.22.0 to 0.23.0 (#6449)
  core: bump goauthentik.io/api/v3 from 3.2023061.6 to 3.2023061.7 (#6450)
  web: bump pyright from 1.1.319 to 1.1.320 in /web (#6451)
  core: bump ruff from 0.0.281 to 0.0.282 (#6453)
  core: bump golang from 1.20.6-bullseye to 1.20.7-bullseye (#6454)
  ...
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit replaces various ad-hoc implementations of the Patternfly Toggle Group HTML with a web
component that encapsulates all of the needed behavior and exposes a single API with a single event
handler, return the value of the option clicked.

The results are: Lots of visual clutter is eliminated.  A single link of:

```
<div class="pf-c-toggle-group__item">
  <button
      class="pf-c-toggle-group__button ${this.mode === ProxyMode.Proxy
          ? "pf-m-selected"
          : ""}"
      type="button"
      @click=${() => {
          this.mode = ProxyMode.Proxy;
      }}>
      <span class="pf-c-toggle-group__text">${msg("Proxy")}</span>
  </button>
</div>
<div class="pf-c-divider pf-m-vertical" role="separator"></div>
```

Now looks like:

```
<option value=${ProxyMode.Proxy}>${msg("Proxy")}</option>
```

This also means that the three pages that used the Patternfly Toggle Group could eliminate all of
their Patternfly PFToggleGroup needs, as well as the `justify-content: center` extension, which also
eliminated the `css` import.

The savings aren't as spectacular as I'd hoped: removed 178 lines, but added 123; total savings 55
lines of code.  I still count this a win: we need never write another toggle component again, and
any bugs, extensions or features we may want to add can be centralized or forked without risking the
whole edifice.
…ects

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* main:
  website: bump react-tooltip from 5.19.0 to 5.20.0 in /website (#6471)
  website: bump prettier from 3.0.0 to 3.0.1 in /website (#6472)
…to-certeficate-search

This commit replaces various ad-hoc implementations of `search-select` for CryptoCertificateKeyPairs
with a web component that encapsulates all of the needed behavior and exposes a single API.

The results are: Lots of visual clutter is eliminated.  A single search of:

```HTML
<ak-search-select
    .fetchObjects=${async (query?: string): Promise<CertificateKeyPair[]> => {
        const args: CryptoCertificatekeypairsListRequest = {
            ordering: "name",
            hasKey: true,
            includeDetails: false,
        };
        if (query !== undefined) {
            args.search = query;
        }
        const certificates = await new CryptoApi(
            DEFAULT_CONFIG,
        ).cryptoCertificatekeypairsList(args);
        return certificates.results;
    }}
    .renderElement=${(item: CertificateKeyPair): string => {
        return item.name;
    }}
    .value=${(item: CertificateKeyPair | undefined): string | undefined => {
        return item?.pk;
    }}
    .selected=${(item: CertificateKeyPair): boolean => {
        return this.instance?.tlsVerification === item.pk;
    }}
    ?blankable=${true}
>
</ak-search-select>
```

Now looks like:

```HTML
<ak-crypto-certificate-search certificate=${this.instance?.tlsVerification}>
</ak-crypto-certificate-search>
```

There are three searches that do not require there to be a valid key with the certificate; these are
supported with the boolean property `nokey`; likewise, there is one search (in SAMLProviderForm)
that states that if there is no current certificate in the SAMLProvider and only one certificate can
be found in the Authentik database, use that one; this is supported with the boolean property
`singleton`.

These changes replace 382 lines of object-oriented invocations with 36 lines of declarative
configuration, and 98 lines for the class.  Overall, the code for "find a crypto certificate" has
been reduced by 46%.

Suggestions for a better word than `singleton` are welcome!
This adds a Storybook for the CryptoCertificateKeypair search, including
a mock fetch of the data.  In the course of running the tests, we discovered
that including the SearchSelect _class_ won't include the customElement declaration
unless you include the whole file!  Other bugs found: including the CSS from
Storybook is different from that of LitElement native, so much so that the
adapter needed to be included.  FlowSearch had a similar bug.  The problem
only manifests when building via Webpack (which Storybook uses) and not
Rollup, but we should support both in distribution.
* main:
  web/flows: fix identification stage band color (#6489)
  providers/proxy: only intercept auth header when a value is set (#6488)
  web: bump @goauthentik/api from 2023.6.1-1691242648 to 2023.6.1-1691266058 in /web (#6486)
  providers/proxy: set outpost session cookie to httponly and secure wh… (#6482)
  web: bump @esbuild/linux-arm64 from 0.18.17 to 0.18.18 in /web (#6483)
  web/admin: fix user sorting by active field (#6485)
  web: bump @esbuild/darwin-arm64 from 0.18.17 to 0.18.18 in /web (#6484)
  web: bump storybook (#6481)
  web: bump the sentry group in /web with 2 updates (#6480)
  web: bump API Client version (#6479)
  api: optimise pagination in API schema (#6478)
  website/dev-docs: tweaks to template (#6474)
  website: bump react-tooltip from 5.19.0 to 5.20.0 in /website (#6471)
  website: bump prettier from 3.0.0 to 3.0.1 in /website (#6472)
preventing the radio from reflecting the default correctly.
The observed behavior was that the radio wouldn't "activate"
until the item selected during the render pass was clicked on
first.
* ak-toggle-group:
  Bugs found by CI/CD.
  web: adding a storybook for the ak-toggle-group component
  web: minor code formatting issue.
  web: Replace ad-hoc toggle control with ak-toggle-group
BeryJu and others added 9 commits October 9, 2023 22:36
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
…roxy

1. Forward Domain Proxy.  I wasn't sure if this method was appropriate for the wizard,
   but Jens says it is.  I've added it.

2. In the process of doing so, I decided that the Provider.converter field was overly
   complexified; I tried too hard to reduce the number of functions I needed to define,
   but in the process outsourced some of the logic of converting the Wizard's dataset
   into a property typed request to the `commit` phase, which was inappropriate.  All
   of the logic about a provider, aside from its display, should be here with the code
   that distinguishes between providers.  This commit makes it so.

3. Small CSS fix: the fields inherited from the Proxy provider forms had some unexpected
   CSS which was causing a bit of a weird indent.  That has been rectified.
…2-with-api-and-tests' into application-wizard-2-with-api-and-tests

* refs/remotes/origin/application-wizard-2-with-api-and-tests:
  fix lint errors
  SCIM Manuel -> SCIM
  fix label in dark mode
* main:
  web: bump pyright from 1.1.330 to 1.1.331 in /web (#7143)
  core: bump golang from 1.21.2-bookworm to 1.21.3-bookworm (#7142)
  core: bump gitpython from 3.1.35 to 3.1.37 (#7140)
  core: bump goauthentik.io/api/v3 from 3.2023083.5 to 3.2023083.6 (#7124)
  website/docs: fix PowerDNS Docker Hub repo name (#7134)
  website/blog: Fix typo in SCIM post (#7136)
  providers/proxy: fix redis cookies missing strict path (#7135)
  web: bump @lit-labs/task from 3.0.2 to 3.1.0 in /web (#7132)
  web: bump @lit/localize-tools from 0.6.10 to 0.7.0 in /web (#7133)
  web: bump the eslint group in /tests/wdio with 2 updates (#7128)
  core: bump structlog from 23.1.0 to 23.2.0 (#7125)
  core: bump selenium from 4.13.0 to 4.14.0 (#7126)
  web: bump the eslint group in /web with 2 updates (#7127)
  web: bump the wdio group in /tests/wdio with 4 updates (#7129)
* main:
  web: patternfly hints as ak-web-component (#7120)
  web: fix form default submit handler (#7122)
  web/admin: add additional Flow info (#7155)
  tests: fix potential infinite wait in tests spinning up a container (#7153)
  ci: disable ghcr retention schedule while it's broken (#7154)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in de (#7151)
  core: bump golang.org/x/net from 0.16.0 to 0.17.0 (#7148)
  web: bump the babel group in /web with 5 updates (#7149)
  core: bump sentry-sdk from 1.31.0 to 1.32.0 (#7150)
  website: make get started on pricing page go to customer portal (#7147)
* main:
  web: change 'Attributes' to 'Custom attributes' on Invitation Field (#7145)
There were some HEAVY merge bugs in the translation files.

* main:
  providers/scim: remove preview (#7166)
  web: bump the wdio group in /tests/wdio with 4 updates (#7160)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#7162)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#7161)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#7158)
  website/docs: Balok pr for User docs (#7139)
* main: (23 commits)
  ci: test with postgres 16
  translate: Updates for file web/xliff/en.xlf in fr (#7189)
  web: bump the esbuild group in /web with 2 updates (#7195)
  web: bump the eslint group in /tests/wdio with 2 updates (#7192)
  core: bump ruff from 0.0.292 to 0.1.0 (#7194)
  web: bump the eslint group in /web with 2 updates (#7193)
  web: the return of pseudolocalization (#7190)
  rbac: revisions (#7188)
  website: bump @babel/traverse from 7.21.4 to 7.23.2 in /website (#7187)
  web: bump API Client version (#7186)
  core: Initial RBAC (#6806)
  lifecycle: re-fix system migrations (#7185)
  outposts: use channel groups instead of saving channel names (#7183)
  sources/ldap: made ldap_sync_single calls from ldap_sync_all asynchronous (#6862)
  website/docs: fix API OAuth token usage (#7159)
  web: bump rollup from 4.1.3 to 4.1.4 in /web (#7181)
  web: bump @formatjs/intl-listformat from 7.4.2 to 7.5.0 in /web (#7182)
  web: bump @rollup/plugin-replace from 5.0.3 to 5.0.4 in /web (#7177)
  web: bump the sentry group in /web with 2 updates (#7175)
  web: bump @rollup/plugin-commonjs from 25.0.5 to 25.0.7 in /web (#7178)
  ...
The "ApplicationWizardHint" now correctly uses the localstorage and allows the user to navigate back
and see the message after it's been hidden, so that it will always be available during the test
phase.

The ApplicationList's old "Create Application Form" button has been restored for the purposes of the
test phase.

The ApplicationWizard is now available on both the ApplicationList and ProviderList pages.

Tana and I discussed the microcopy, putting a stronger second-person "You can do..." twist onto the
language, to give the user the sense of empowerment.

The ShowHintController now has both "hide" and "show" operations, to support the hint restoration.
* main:
  web: Updates to the Context and Tasks libraries from lit. (#7168)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#7197)
…mple wizard" is configured in source code and tested with storybook.
Anyway, this was a very stupid bug, because by definition function
definition arguments don't have uses, they're being defined, not
implemented.  Fixed, conf fixed to compensate, and consequences
conquered.
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* main:
  website/docs: added Note in Beta docs (#7203)
  web: bump the wdio group in /tests/wdio with 4 updates (#7199)
  core: bump black from 23.9.1 to 23.10.0 (#7200)
  core: bump urllib3 from 2.0.6 to 2.0.7 (#7201)
…2-with-api-and-tests' into application-wizard-2-with-api-and-tests

* refs/remotes/origin/application-wizard-2-with-api-and-tests:
  move context from labs to main
* main:
  enterprise: bump license usage task frequency (#7215)
  web: bump the storybook group in /web with 5 updates (#7212)
  web: bump the sentry group in /web with 2 updates (#7211)
  Revert "web: Updates to the Context and Tasks libraries from lit. (#7168)"
  web: bump @types/codemirror from 5.60.10 to 5.60.11 in /web (#7209)
  web: bump @types/chart.js from 2.9.38 to 2.9.39 in /web (#7206)
  web: bump pyright from 1.1.331 to 1.1.332 in /web (#7208)
  web: bump @types/grecaptcha from 3.0.5 to 3.0.6 in /web (#7207)
I was very unhappy with the "update this dot-path" mechanism I was using earlier; it was hard
for me to read and understand what was happening, and I wrote the darned thing.  I decided instead
to go with a hard substitution model; each phase of the wizard is responsible for updating the
*entire* payload, mostly by creating a new payload and substituting the field value associated
with the event.

On the receiver, we have to do that *again* to handle the swapping of providers when the user
chooses one and then another.  It looks clunky, and it is, but it's *legible*; a junior dev
could understand what it's doing, and that's the goal.
…2-with-api-and-tests' into application-wizard-2-with-api-and-tests

* refs/remotes/origin/application-wizard-2-with-api-and-tests:
  Revert "move context from labs to main"
@kensternberg-authentik kensternberg-authentik merged commit 3a7283c into main Oct 18, 2023
67 checks passed
@kensternberg-authentik kensternberg-authentik deleted the application-wizard-2-with-api-and-tests branch October 18, 2023 19:43
kensternberg-authentik added a commit that referenced this pull request Oct 19, 2023
* main: (57 commits)
  stages/email: Fix query parameters getting lost in Email links (#5376)
  core/rbac: fix missing field when removing perm, add delete from object page (#7226)
  website/integrations: grafana: add Helm and Terraform config examples (#7121)
  web: bump @types/codemirror from 5.60.11 to 5.60.12 in /web (#7223)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#7224)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#7225)
  website/blogs: blog about sso tax (#7202)
  web: Application wizard v2 with tests (#7004)
  web: bump API Client version (#7220)
  core: bump goauthentik.io/api/v3 from 3.2023083.7 to 3.2023083.8 (#7221)
  providers/radius: TOTP MFA support (#7217)
  web: bump API Client version (#7218)
  stage/deny: add custom message (#7144)
  docs: update full-dev-setup docs (#7205)
  enterprise: bump license usage task frequency (#7215)
  web: bump the storybook group in /web with 5 updates (#7212)
  web: bump the sentry group in /web with 2 updates (#7211)
  Revert "web: Updates to the Context and Tasks libraries from lit. (#7168)"
  web: bump @types/codemirror from 5.60.10 to 5.60.11 in /web (#7209)
  web: bump @types/chart.js from 2.9.38 to 2.9.39 in /web (#7206)
  ...
kensternberg-authentik added a commit that referenced this pull request Oct 19, 2023
* main: (119 commits)
  stages/email: Fix query parameters getting lost in Email links (#5376)
  core/rbac: fix missing field when removing perm, add delete from object page (#7226)
  website/integrations: grafana: add Helm and Terraform config examples (#7121)
  web: bump @types/codemirror from 5.60.11 to 5.60.12 in /web (#7223)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#7224)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#7225)
  website/blogs: blog about sso tax (#7202)
  web: Application wizard v2 with tests (#7004)
  web: bump API Client version (#7220)
  core: bump goauthentik.io/api/v3 from 3.2023083.7 to 3.2023083.8 (#7221)
  providers/radius: TOTP MFA support (#7217)
  web: bump API Client version (#7218)
  stage/deny: add custom message (#7144)
  docs: update full-dev-setup docs (#7205)
  enterprise: bump license usage task frequency (#7215)
  web: bump the storybook group in /web with 5 updates (#7212)
  web: bump the sentry group in /web with 2 updates (#7211)
  Revert "web: Updates to the Context and Tasks libraries from lit. (#7168)"
  web: bump @types/codemirror from 5.60.10 to 5.60.11 in /web (#7209)
  web: bump @types/chart.js from 2.9.38 to 2.9.39 in /web (#7206)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants