* main:
web: dark/light theme fixes (#7872)
web: replace 'description-list' with list of descriptions (#7392)
web: expressing success (#7830)
web: fix turnstile types after update (#7854)
core: bump github.com/google/uuid from 1.4.0 to 1.5.0 (#7866)
website: bump @types/react from 18.2.43 to 18.2.45 in /website (#7865)
web: bump wdio-wait-for from 3.0.9 to 3.0.10 in /tests/wdio (#7867)
website/blog: okta part two blog (#7863)
web: bump lit-analyzer from 2.0.1 to 2.0.2 in /web (#7858)
web: bump the babel group in /web with 4 updates (#7856)
web: bump the eslint group in /web with 2 updates (#7857)
web: bump rollup from 4.7.0 to 4.8.0 in /web (#7859)
web: bump the eslint group in /tests/wdio with 2 updates (#7860)
web: refactor the table renderer for legibility (#7433)
documentation: Improve explanation of `kubernetes_json_patches` (#7832)
root: update security policy to include link to cure53 report (#7853)
* web: break circular dependency between AKElement & Interface.
This commit changes the way the root node of the web application shell is
discovered by child components, such that the base class shared by both
no longer results in a circular dependency between the two models.
I've run this in isolation and have seen no failures of discovery; the identity
token exists as soon as the Interface is constructed and is found by every item
on the page.
* web: fix broken typescript references
This built... and then it didn't? Anyway, the current fix is to
provide type information the AkInterface for the data that consumers
require.
* web: description lists as functions
One thing I hate is clutter. Just tell me what you're going to do. "Description Lists" in our code are
renderings of Patternfly's DescriptionList; we use only four of
their idioms: horizontal, compact, 2col, and 3col. With that in mind, I've stripped out the DescriptionList
rendering code from UserViewPage and replaced it with a list of "Here's what to render" and a function call
to render them. The calling code is still responsible for having the right styles available, as this is
not a component or an attempt at isolation; it is *just* a function (at this point).
* web: fix issue that prevented the classMap from being rendered properly
* web: added comments to the description list.
* web: analyze & prettier had opinions
* web: Fix description-list demo
This commit re-instals the demo for the "description list" of user fields.
* web: prettier had opinions.
* any -> unknown
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
---------
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
* web: expressing success
Ever see an idiom that just, I dunno, *annoyed* you?
Automated tools for the win.
* web: repetition, repetition, repetition! [throws chair]
* web: giving the de-duplication treatment to policy mappings.
* Created a BaseStageForm with success message and canonical primary key type for for Providers, Sources, and Stages.
* web: fix turnstile types after update
After running 'npm update' on the dev tree, the build started to
fail with these options and types no longer being set correctly in
the source tree.
I have explicitly included the Turnstile object as a sub-component
of Window, and modified the CaptchaStage to understand the
TurnstileObject and TurnstileOptions, and the build now completes.
* eslint says to prefer this format
* Google recaptcha (aka Turnstile) doesn't understand the "invisible" setting; that's purely
an HCaptcha thing.
* web: removing the typecast means I no longer need the type.
* Locking pyright to 1.1.338 and maintaining it.
* web: locking down hard
After reading [this
guide](https://medium.com/@anjusha.khandavalli/decoding-commonly-used-symbols-in-package-json-file-e08f3939c9e4),
I've locked down the version of pyright to a specific and immovable
version until we can get a better read on how the Pyright upgrade
breaks things.
* Update is specific to package-lock.json.
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
---------
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* web: break circular dependency between AKElement & Interface.
This commit changes the way the root node of the web application shell is
discovered by child components, such that the base class shared by both
no longer results in a circular dependency between the two models.
I've run this in isolation and have seen no failures of discovery; the identity
token exists as soon as the Interface is constructed and is found by every item
on the page.
* web: fix broken typescript references
This built... and then it didn't? Anyway, the current fix is to
provide type information the AkInterface for the data that consumers
require.
* Refactor the Table component for legiibility.
This commit does not change the functionality of the Table, nor does it require any changes to
existing uses of the Table.
It will probably be easier to review this by looking at the `View Code` in the upper-right-hand
corner of GitHub's reviewer; that or side-by-side, if your monitor is wide-enough.
The existing Table component is used 49 times (at last count) in authentik, and those uses are
wide-ranging and complex, but they all come down to a couple of entries:
- Displaying a row of summary information
- Permitting the display of more complex ("expanded") information
- Displaying a collection of rows
- Displaying a collection of rows grouped by some header
- Pagination of many rows
- Permitting an action on the visible rows
- *Not* blocking events that may happen on a cell or expansion
- Providing a toolbar
- Providing a display of "selected items" when using the table as a multi-select with many pages of
items (chips display)
- Providing sort functionality on columns
- Providing the ability to filter the table from the back-end
This commit changes none of that.
What this commit does is re-arrange the innards of Table.ts into smaller units:
- The RowGroup's "checkbox" and "expansion" segments are pulled out into their own functions, which
makes the RowGroup's actual functionality much easier to see and understand. The same is true of
the rowGroup's selection and expansion handlers.
- Almost all in-line decisions and event handlers have been extracted and named, to make it easier
to see and understand what's happening inside what is otherwise a jumble of HTML.
- The TablePagination code was duplicated-- and one of the duplicates was wrong! So I've
deduplicated it and fixed the bug.
- In many cases, the conditional code grew organically, resulting in some pretty hard-to-understand
conditions.
- A really good example is the `itemSelectHandler`; there are two possible events that result in a
change, and the consequences of that change may be that *all* checkboxes are unchecked. In all
cases where there's an add/remove option, I've opted to remove the specific object always (even
if it's not present!), and then add it if it's actually an add. Logically coherent as long as
the accessors are not also mutators.
It was not possible to redefine the `columns()` function to take anything other than a TableColumn
object; I wanted to be able to replace all of the `new TableColumn("Foo")` with just `"Foo"`,
building the TableColumn dynamically at construction time. Unfortunately, some of our most complex
tables dynamically re-arrange the columns (RBAC, for example, draws an empty table, fetches the
content, then redraws with the columns based on what was retrieved), and detecting that change and
rebuilding those columns proved more difficult than anticipated. I may contemplate an alternative
column specification if I find myself building a lot of tables.
Likewise, it was not possible to replace all of our uses of the empty `html` declaration with the
Lit-preferred `nothing` sigil; hard-coded `TemplateResult` entries scattered throughout the code
caused massive type inconsistencies, since a type of `TemplateResult | nothing` is unique thanks to
`nothing`'s underlying Symbol. It is for this issue that Typescript itself recommends you "prefer
allowing Typescript infer the return type." I may revisit this issue later.
I've added a `prequick` command to `package.json`; this one runs *only* the Typescript type checker,
lit-analyse, and `eslint:precommit`, the last of which lints only the files touched since the last
commit. This is fast, intended to support quick checks of code quality not normally displayed in the
IDE.
* web: refactor table
After talking to Jens, I've put back the positional variable and eslint escape; it's better
to document existing practices than try to force something.
I also misunderstood the role of `inner` in one bit of code, and have restored its functionality.
Looking through the code, though, I can see a case where it will fail; it's expecting `inner` to
be either undefined or a TemplateResult; if there's no error message, the error message defaults
to a blank TemplateResult, which is _not_ undefined, and will result in a blank table.
This will only happen under very weird network failures, but...
* 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
* dev: (72 commits)
web/flows: show logo in card (#7824)
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
...
web/user: fix app not updating
so when using two classes in a classMap directive, the update fails (basically saying that each class must be separated), however this error only shows when directly calling requestUpdate and is swallowed somewhere when relying on the default render cycle
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* web: break circular dependency between AKElement & Interface.
This commit changes the way the root node of the web application shell is
discovered by child components, such that the base class shared by both
no longer results in a circular dependency between the two models.
I've run this in isolation and have seen no failures of discovery; the identity
token exists as soon as the Interface is constructed and is found by every item
on the page.
* web: fix broken typescript references
This built... and then it didn't? Anyway, the current fix is to
provide type information the AkInterface for the data that consumers
require.
* web: extract the form processing from the form submission process
Our forms have a lot of customized value handling, and the function `serializeForm` takes
our input structures and creates a JSON object ready for submission across the wire for
the various models provided by the API.
That function was embedded in the `ak-form` object, but it has no actual dependencies on
the state of that object; aside from identifying the input elements, which is done at the
very start of processing, this large block of code stands alone. Separating out the
"processing the form" from "identifying the form" allows us to customize our form handling
and preserve form information on the client for transactional purposes such as our wizard.
w
* web: multi-select, but there's a styling issue.
* web: provide a closed control for multi-select
This commit creates a new control, using the ak-form-element-horizontal as a *CLOSED*
object, for our multi-select. This control right now is limited to what we expect to
be using in the wizard, but that doesn't mean it can't be smarter in the future.
* web: hung up by a silly spelling error
* web: update the form-handling method
With the `serializeForm` method extracted, it's much easier to examine and parse
every *form* with every keystroke, preserving them against the changes that
happen as the customer navigates the Wizard. With that in place, it became
straightforward to retrofit the "handle changes to the application, to the provider, and to the providerType"
into the three pages of the wizard, and to provide *all* of the form elements in a base class
such that no specialized handling needs to happen to any of the child pages.
Fixed an ugly typo in the oauth2 provider, as well.
* web: wizard should work with multi-select and should reflect default values
(Note: This commit is predicated on both the "Extract serializeForm function from Form.ts" and
"Provide a controlled multi-select input control" PRs.)
The initial attempt at the wizard was woefully naive in its implementation, missing some critical
details along the way. This revision starts off with one stronger assumption: trust that Jens knows
what he's doing, and knew what he was building when he wrote the initial `Form` handler.
The problem with the `Form` handler, and the reason I avoided it, was simply that it does too many
things, especially in its ModelForm variant: it receives a model from the back-end, renders a
(hand-written) form for that model, allows the user to interact with that model, and facilitates
saving it to the back-end again, complete with on-page notifications of success or failure.
The Wizard could not use all of that. It needs to gather the information for *two* models (an
Application and a Provider, plus the ProviderType) and has a new and specialized end-point for a
transaction that allows the committing or roll back of both models to happen simultaneously,
predicated on success or failure respectively.
With "Extract `serializeForm` completed, it was possible to repurpose the forms that already
existed, stripping them down to just their input components, and eventing the entire thing in a
single event loop of "events flow up, data flows down." In this case, the *entire form* is
serialized on a per-event basis and pushed up the to the orchestration layer, which saves them off.
Writing a parent `BasePanel` class that has accessors for `formValues` and `valid` means that the
state of every page is accessible with a simple query. This simplified the `BaseProviderPanel` class
to just specialize the `dispatchUpdate` method to send the wizard update with the new provider
information filled out.
Because the *form* is being treated as the source of truth about the state of a `Partial<Application>`
or `Partial<*Provider>` object, the defaults are now being captured as expected.
Likewise, this simplified the `providerCache` layer which preserves customer input in the event that
the customer starts filling out the wrong provider to a simple conditional clause in the
orchestrator. The Wizard has much fewer smarts because it doesn't (and probably never did) need
them.
Along with the above changes, the following has also been done:
For SAML and SCIM, the providerMappings now works. They weren't being managed as `state` objects,
so they weren't receiving updates when the update event retrieved the information from the back-end.
In order to make clear what's happening, I have extracted the loops from the original definition and
built them as named objects: `propertyMappings`, `pmUserValues`, `pmGroupValues` and so on, which I
then pass into the new multi-select component.
I fixed a really embarrassing typo in Oauth2's "advanced settings" block.
I have extracted the CoreGroup search-select into a custom component.
I deleted the `merge` function. That was a faulty experiment with non-deterministic outcomes, and I
was never happy with it. I'm glad its gone.
I've added a title header to each of the providers, so the user can be sure that they're looking
at the right provider type when they start filling out the form.
I've created a new token, `data-ak-control`, with which we can mark all objects that we can treat as
Authentik value-producing components, the form value of which is available through a `json()`
method. I've added this bit of intelligence to the `serializeForm` function, short-circuiting the
complex processing and putting the "this is the shape of the value we expect from this input" *onto
the input itself*. Which is where it belongs.
* web: add error handling to wizard.
* web: improve error handling in light components
Rather than reproduce the error handling across all of the LightComponents,
I've made a parent class that takes the common fields to distribute between
the ak-form-element-horizontal and the input object itself. This made it
much easier to properly display errors in freeform input fields in the
wizard, as well as working with the routine error handling in Form.ts
* Added the radio control to the list of LightComponents.
* Fix bug where event was recorded twice.
* Fixed merge bug (?) that somehow deleted the Authorization Select block in OAuth2.
* web: prettier had opinions
* web: added error handling and display
* web: bump @lit-labs/context from 0.4.1 to 0.5.1 in /web
Bumps [@lit-labs/context](https://github.com/lit/lit/tree/HEAD/packages/labs/context) from 0.4.1 to 0.5.1.
- [Release notes](https://github.com/lit/lit/releases)
- [Changelog](https://github.com/lit/lit/blob/main/packages/labs/context/CHANGELOG.md)
- [Commits](https://github.com/lit/lit/commits/@lit-labs/context@0.5.1/packages/labs/context)
---
updated-dependencies:
- dependency-name: "@lit-labs/context"
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
* web: updated wizard to run with latest package.json configuration
Apparently, there were stale dependencies in package-lock.json that were conflicting
with the requests in our package.json. By running `npm update`, I was able to resolve
the conflict.
I have also removed the default names from the context names collection; they weren't doing
any good, and they permit frictionless renaming of dependencies, which is never a good
idea.
* web: schlepping on the errors messages
During testing, I realized I was unhappy with the error messages. They're not very helpful.
By adding links to navigate back to the place where the error occurred, and providing better
context for what the error could have been, I hope to help the use correct their errors.
* make package the same as main
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
---------
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
* Revert "web: bump the storybook group in /web with 5 updates (#7750)"
This reverts commit 8898709a9a.
* Revert "web: bump the storybook group in /web with 5 updates (#7733)"
This reverts commit f559d2531f.
This commit implements a three-tier sidebar with subcategories.
The first thing is that we've refactored the Sidebar into a holistic entity; rather than be built in
pieces, it's constructed declaratively from a tree of entries, much in the same way routes are, and
for much the same reason<sup>1</sup>.
The AdminSidebar element only provides the list of entries to show and some of the controls
necessary to show/hide the sidebar. Because the sidebar requires a rich collection of objects
retrieved from the back-end, to avoid cluttering the AdminSidebar each of those sublists of
TypeCreate have been isolated into their own controllers.
The SidebarTypeController isn't even a strongly reactive controller; all it does is fetch the
TypeCreate collection and notify the client object that the fetch has completed. The client can then
call the `.entries()` method on the controller to get the sub-tree of entries for the TypeCreate
object.
The Sidebar has been slightly (!) refactored so that it's emphatic about what it does: it shows the
brand, nav, and user sections of the sidebar. The styling has been moved to a separate file, the
better to emphasize this.
The SidebarItems file is where all the magic-- and a lot of ugly-- is hidden.
The main purpose of the SidebarItems is to render the tree of entries passed to it. That's it. But
it also has to be able to read the URL and highlight which entry is currently being shown by the
router, and it has to be able to open up all the parent objects of the "current" link so that the
user gets a clear sense of where they are navigationally.
Most messy: the `reclick()` function intercepts clicks on anchors and, using the same logic as the
router, decides if the router would *not* handle the navigation event. If the router would not, it
takes on the responsibility for reaching into the currently visible table, modifying the filter and
triggering a new `.fetch()`.
Somewhere along the way I boyscoutted another `switch` statement or two into lookup expressions.
---
<sup>1</sup> One of the reasons for this is that the Administrator Application's sidebar,
routes, and command palette will all get their data from a single source of truth, and that single
source will be independent of any of those. This is a step in that direction.