* main: (58 commits)
web: Replace ad-hoc toggle control with ak-toggle-group (#6470)
blueprints: fix tag values not resolved correctly (#6653)
web: bump @codemirror/lang-javascript from 6.1.9 to 6.2.0 in /web (#6647)
core: bump ruff from 0.0.285 to 0.0.286 (#6649)
web: bump the eslint group in /web with 1 update (#6646)
web: bump @rollup/plugin-typescript from 11.1.2 to 11.1.3 in /web (#6648)
core: bump python from 3.11.4-slim-bookworm to 3.11.5-slim-bookworm (#6650)
web/admin: only show token expiry when token is set to expire (#6643)
providers/proxy: fix JWKS url in embedded outpost (#6644)
providers/oauth2: fix id_token being saved incorrectly leading to lost claims (#6645)
web/user: only render expand element when required (#6641)
root: re-fix docker build paths
web/admin: set required flag to false for user attributes (#6418)
root: fix docker build
root: fix config loading for outposts (#6640)
core: compile backend translations (#6639)
translate: Updates for file locale/en/LC_MESSAGES/django.po in nl on branch main (#6635)
translate: Updates for file web/xliff/en.xlf in nl on branch main (#6634)
core: fix filtering users by type attribute (#6638)
web/elements: improve table error handling, prevent infinite loading … (#6636)
...
* web: Replace ad-hoc toggle control with ak-toggle-group
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.
* web: minor code formatting issue.
* web: adding a storybook for the ak-toggle-group component
* Bugs found by CI/CD.
* web: Replace ad-hoc search for CryptoCertificateKeyPairs with crypto-certificate-search (#6475)
* web: Replace ad-hoc search for CryptoCertificateKeyPairs with ak-crypto-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!
* web: display tests for CryptoCertificateKeypair search
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.
* sert required flag to false for user attributes
* fallback for null value
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
---------
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Tana Berry <tana@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
* web/common: make API errors more common in developer tools
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* web: default to origin for API urls, this also makes urls in logs clickable
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
---------
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit combines a working (but very unpolished) version of the Application Wizard with Jen's
code for the CoreTransactionApplicationRequest, resulting in a successful round trip.
It fixes a number of bugs with the way ContextProducer decorators were being processed, such that
they just weren't working with our current configuration (although they did work fine in Storybook);
consumers didn't need to be fixed.
It also *removes* the steps-aware context from the Wizard.
That *may* be a mistake. To re-iterate, the `WizardFrame` provides the chrome for a Wizard: the
button bar div, the breadcrumbs div, the header div, and it takes the steps object as its source of
truth for all of the content. The `WizardContent` part of the application has two parts: The
`WizardMain`, which wraps the frame and supplies the context for all the `WizardPanels`, and the
`WizardPanels` themselves, which are dependent on a context from `WizardMain` for the data that
populates each panel. YAGNI right now that the panels need to know anything about the steps, and the
`WizardMain` can just pass a fresh `.steps` object to the `WizardFrame` when they need updating.
Using props drilling may make more sense here.
It certainy does *not* make sense for the panels. They need to be renderable on-demand, and they
need to make sense of what they're rendering on-demand, so the function is
```
(panel code) => (context) => (rendered panel)
```
(Yes, that's curried notation. Deal.)
Understandings:
- To use uncontrolled inputs, which I prefer, the context object should not be a state or property
at the level of consumers; it should not automatically re-render with every keystroke, i.e. "The
React Way." We're using Web Components, [client-side
validation](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation) exists on the
platform already, and live-validation is problematic for any number of reasons.
- The trade-off is that it is now necessary to re-render the target page of the wizard de-novo, but
that's not really as big a deal as it sounds. Lit is ready to do that... and then nothing else
until we request a change-of-page. Excellent.
- The top level context *must* be a state, but it's better if it's a state never actually used by
the top-level context container. The debate about whether or not to make that container a dumb one
(`<slot></slot>`) or to merge it with the top-level object continues; here, I've merged it with
the top-level wizard object, but that object does not refer to the state variable being managed in
its render pass, so changes to it do not cause a re-render of the whole wizard. The purpose of the
top-level page is to manage the *steps*, not the *content of any step*. A step may change
dynamically based on the content of a step, but that's the same thing as *which step*. Lesson:
always know what your state is *about*.
- Deep merging is a complex subject, but here it's appropriate to our needs.
* main: (70 commits)
core: hotfix group membership check (#6584)
web: bump core-js from 3.32.0 to 3.32.1 in /web (#6581)
web: bump tslib from 2.6.1 to 2.6.2 in /web (#6583)
web: bump the storybook group in /web with 5 updates (#6580)
web/flows: update flow background (#6579)
translate: Updates for file web/xliff/en.xlf in zh_CN on branch main (#6575)
core: rework recursive group membership (#6017)
core: bump goauthentik.io/api/v3 from 3.2023061.11 to 3.2023061.12 (#6572)
core: bump ruff from 0.0.284 to 0.0.285 (#6570)
ci: bump actions/setup-node from 3.8.0 to 3.8.1
blueprints: fix blueprint importer logging potentially sensitive data (#6567)
web: bump API Client version (#6568)
stages/authenticator_static: make static token size adjustable (#6565)
root: always use persistent database connections (#6560)
website/blog: identity fun (#6564)
web: bump the storybook group in /web with 1 update (#6561)
web: bump @rollup/plugin-node-resolve from 15.1.0 to 15.2.0 in /web (#6562)
web: bump @lit-labs/task from 3.0.0 to 3.0.1 in /web (#6544)
web: bump prettier from 3.0.1 to 3.0.2 in /web (#6549)
web: bump the storybook group in /web with 5 updates (#6559)
...
* web/flows: update flow background
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* Optimised images with calibre/image-actions
* the ci is not quite as good with compression as the local sharp-cli call, but it's good enough so we can remove it
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
---------
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
reactivity broke focus by, basically, removing the reactivity and
managing the first-time-through lifecycle to prevent the update
from causing refocus. It works well! Now I just need to test it.
The idea is simple. Let's start with this picture:
```
<application-wizard .steps=${[... a collection of step objects ...]}>
<wizard-main .steps=${(steps from above)}>
<application-current-panel>
<current-form>
```
- ApplicationWizard has a Context for the ApplicationProviderPair (or whatever it's going to be).
This context does not know about the steps; it just knows about: the "application" object, the
"provider" object, and a discriminator to know *which* provider the user has selected.
- ApplicationWizard has Steps that, among other things, provides Panels for:
- Application
- Pick Provider
- Configure Provider
- Submit ApplicationProviderPair to the back-end
- The WizardFrame renders the CurrentPanel for the CurrentStep
The CurrentPanel gets its data from the ApplicationWizard in the form of a Context. It then sends
messages (events) to ApplicationWizard about the contents of each field as the user is filling out
the form, so that the ApplicationWizard can record those in the ApplicationProviderPair for later
submission.
When a CurrentForm is valid, the ApplicationWizard updates the Steps object to show that the "Next
button" on the Wizard is now available.
In this way, the user can progress through the system. When they get to the last page, we can
provide in the ApplicationWizard with the means to submit the form and/or send the user back to
the page with the validation failure.
Problem: The context is being updated in real-time, which is triggering re-renders of the form. This
leads to focus problems as the fields that are not yet valid are triggering "focus grab" behavior.
This is a classic problem with "controlled" inputs. What we really want is for the CurrentPanel to
not re-render at all, but to behave like a normal, uncontrolled form, and let the browser do most of
the work. We still want the [Next] button to enable when the form is valid enough to permit that.
---
Other details: I've ripped out a lot of Jen's work, which is probably a mistake. It's still
preserved elsewhere. I've also cleaned up the various wizardly things to try and look organized.
It *looks* like it should work, it just... doesn't. Not yet.
Found where the hook for form validity should go. Excellent! Now I just need to incorporate
that basic validation into the business logic and we're good to go.
This commit includes the first three pages of the wizard, the
completion of the wizard framework with evented handling, and control
over progression.
Some shortcomings of this design have become evident: it isn't
possible to communicate between the steps' wrappers, as they are
POJOs without access to the context. An imperative decision-making
process has to be inserted in the orchestration layer,
which is kinda annoying.
But it looks good and it behaves correctly, to the extent that I've
given it behavior. It's an excellent foundation.
Added a 'design document' that just kinda describes what I'm trying
to do, in case I don't get this done by Friday Aug 11, 2023.
I had two tables doing the same thing, so I merged them and then
wrote a few map/filters to specialize them for those two use cases.
Along the way I had to fiddle with the ESLint settings so that
underscore-prefixed unused variables would be ignored.
I cleaned up the visual appeal of the forms in the LDAP application.
I was copy/pasting the "handleProviderEvent" function, so I pulled
it out into ApplicationWizardProviderPageBase. Not so much a matter
of abstraction as just disliking that kind of duplication; it served
no purpose.
* 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
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.
* 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)
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.
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 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.
* 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)
...
remove default example stories that were broken
currently only the dark theme works due to the way storybook includes CSS files in the iframe
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
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.