Commit Graph

31 Commits

Author SHA1 Message Date
bc4b07d57b web/admin: remove all special cases of slug handling, replace with a "smart slug" component (#14983)
* web: Add InvalidationFlow to Radius Provider dialogues

## What

- Bugfix: adds the InvalidationFlow to the Radius Provider dialogues
  - Repairs: `{"invalidation_flow":["This field is required."]}` message, which was *not* propagated
    to the Notification.
- Nitpick: Pretties `?foo=${true}` expressions: `s/\?([^=]+)=\$\{true\}/\1/`

## Note

Yes, I know I'm going to have to do more magic when we harmonize the forms, and no, I didn't add the
Property Mappings to the wizard, and yes, I know I'm going to have pain with the *new* version of
the wizard. But this is a serious bug; you can't make Radius servers with *either* of the current
dialogues at the moment.

* This (temporary) change is needed to prevent the unit tests from failing.

\# What

\# Why

\# How

\# Designs

\# Test Steps

\# Other Notes

* Revert "This (temporary) change is needed to prevent the unit tests from failing."

This reverts commit dddde09be5.

* web/components: Remove all special cases of slug handling, replace with a "smart slug" component

This commit removes all special handling for the `slug` attribute in our text. A variant of the text
input control that can handle formatting-as-slugs has replaced all the slugificiation code; simply
drop it onto a page and tell it the (must be unique) selector from which to get the data to be
slugified. It only looks up one tier of the DOM so be careful that both the text input and its slug
accessory occupy the same DOM context.

## Details

### The Component

Now that we know a (lot) more about Lit, this component has been slightly updated to meet our
current standards.

- web/src/components/ak-slug-input.ts

Changes made:

- The "listen for the source object" has been moved to the `firstUpdated`, so that it no longer has
  to wait for the end of a render.
 - The `dirtyFlag` handler now uses the `@input` syntax.
- Updated the slug formatter to permit trailing dashes.
- Uses the `@bound` decorator, eliminating the need to do binding in the constructor (and so
  eliminating the constructor completely).

### Component uses:

The following components were revised to use `ak-slug-input` instead of a plain text input with the
slug-handling added by our forms manager.

- applications/ApplicationForm.ts
- flows/FlowForm.ts
- sources/kerberos/KerberosSourceForm.ts
- sources/ldap/LDAPSourceForm.ts
- sources/oauth/OAuthSourceForm.ts
- sources/plex/PlexSourceForm.ts
- sources/saml/SAMLSourceForm.ts
- sources/scim/SCIMSourceForm.ts

### Remove the redundant special slug handling code

- web/src/elements/forms/Form.ts
- web/src/elements/forms/HorizontalFormElement.ts

### A special case among special cases

- web/src/admin/stages/invitation/InvitationForm.ts

This form is our one case where we have a slug input field with no corresponding text source. Adding
a simple event handler to validate the value whenever it changed and write back a "clean" slug was
the most straightforward solution. I added a help line; it seemed "surprising" to ask someone for a
name and not follow the same rules as "names" everywhere else in our UI without explanation.

* After writing the commit message, I realized some of the comments I made MUST be added to the component.

* The `source` attribute needed its own comment to indicate that a `query()` compatible selector is expected.

* Added public/private/protected/# indicators to all fields.  Trying to balance between getting it 'right' and leaving an opening for harmonizing style-sharing and state-sharing between (text / textarea), slug, password and (visible / hidden / secret).

* Removed the ids as requested; the default "look for this" matches the original behavior without requiring it be hard-coded and unchangable.
2025-06-16 09:04:00 -07:00
9a03bdeaf1 web/maintenance: remove writeOnly hacks from Form and HorizontalFormElement (#14649)
* web: Add InvalidationFlow to Radius Provider dialogues

## What

- Bugfix: adds the InvalidationFlow to the Radius Provider dialogues
  - Repairs: `{"invalidation_flow":["This field is required."]}` message, which was *not* propagated
    to the Notification.
- Nitpick: Pretties `?foo=${true}` expressions: `s/\?([^=]+)=\$\{true\}/\1/`

## Note

Yes, I know I'm going to have to do more magic when we harmonize the forms, and no, I didn't add the
Property Mappings to the wizard, and yes, I know I'm going to have pain with the *new* version of
the wizard. But this is a serious bug; you can't make Radius servers with *either* of the current
dialogues at the moment.

* This (temporary) change is needed to prevent the unit tests from failing.

\# What

\# Why

\# How

\# Designs

\# Test Steps

\# Other Notes

* Revert "This (temporary) change is needed to prevent the unit tests from failing."

This reverts commit dddde09be5.

* web/standards: use attribute naming scheme for attributes

## What

Renamed the 'inputHint' attribute to 'input-hint', because it is an attribute, not a property.
Properties are camelCased, but attributes are kebab-cased.

Updated all instances where this appears with the usual magic:

```
$ perl -pi.bak -e 's/inputHint="code"/input-hint="code"/' $(rg -l 'inputHint="code"')
```

This fix is in preparation for both the Patternfly 5 project and the Schema-Driven Forms project.

* web/maintenance: remove `writeOnly` hacks from Form and HorizontalFormElement

## What

The `writeOnly` hack substituted an obscuring, read-only field for secret keys and passwords that an
admin should never be able to see/read, only *write*, but allowed the user to click on and replace
the key or password. The hack performed this substitution within `HorizontalFormElement` and
dispersed a flag throughout the code to enforce it. Another hack within `Form` directed the API to
not update / write changes to that field if the field had never been activated.

This commit replaces the `writeOnly` hack with a pair of purpose-built components,
`ak-private-text-input` and `ak-private-textarea-input`, that perform the exact same functionality
but without having to involve the HorizontalFormElement, which really should just be layout and
generic functionality.  It also replaces all the `writeOnly` hackery in Form with a simple
`doNotProcess` flag, which extends and genericizes this capability to any and all input fields.

The only major protocol change is that `?writeOnly` was a *positive* flag; you controlled it by
saying `this.instance !== undefined`; `?revealed` is a *positive* flog; you reveal the working input
field when `this.instance === undefined`.

It is not necessary to specify the monospace, autocomplete, and spell-check features; those are
enabled or disabled automatically when the `input-hint="code"` flag is passed.

## Why

Removing special cases from processing code is an important step toward the Authentik Elements NPM
package, as well as the Schema-Driven Forms update.

## Note

This is actually a very significant change; this is important functionality that I have hand-tested
quite a bit, but could wish for automated testing that also checks the database back-end to ensure
the fixes made write the keys and passwords as required. Checking the back-end directly is important
since these fields are never re-sent to the front-end after being saved!

Things like `placeholder`, `required`, and getting the `name`, `label` or `help` are all issues very
subject to Last-Line Effect, so give this the hairiest eyeball you've got, please.

* Found a few small things, like a missing import that might have broken something.

* web/admin: Update `private-text` field to pass new linting requirement.

\# What

\# Why

\# How

\# Designs

\# Test Steps

\# Other Notes
2025-06-06 15:11:49 -07:00
f70635c295 web: Clean up browser-only module imports that crash WebDriverIO. (#14330)
* web: Clean up browser-only module imports that crash WebDriverIO.

* web: Clarify slug format output.
2025-05-02 20:04:05 -04:00
85bb638243 security: fix CVE 2024 52289 (#12113)
* initial migration

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* migrate tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix loading

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* start dynamic ui

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* initial ui

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add serialize

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add error message handling

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix/add tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* prepare docs

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* migrate to new input

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-11-21 14:46:43 +01:00
ee58cf0c1c web: add HTMLTagNameElementMaps to everything to activate lit analyzer (#10217)
* web: fix esbuild issue with style sheets

Getting ESBuild, Lit, and Storybook to all agree on how to read and parse stylesheets is a serious
pain. This fix better identifies the value types (instances) being passed from various sources in
the repo to the three *different* kinds of style processors we're using (the native one, the
polyfill one, and whatever the heck Storybook does internally).

Falling back to using older CSS instantiating techniques one era at a time seems to do the trick.
It's ugly, but in the face of the aggressive styling we use to avoid Flashes of Unstyled Content
(FLoUC), it's the logic with which we're left.

In standard mode, the following warning appears on the console when running a Flow:

```
Autofocus processing was blocked because a document already has a focused element.
```

In compatibility mode, the following **error** appears on the console when running a Flow:

```
crawler-inject.js:1106 Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.
    at initDomMutationObservers (crawler-inject.js:1106:18)
    at crawler-inject.js:1114:24
    at Array.forEach (<anonymous>)
    at initDomMutationObservers (crawler-inject.js:1114:10)
    at crawler-inject.js:1549:1
initDomMutationObservers @ crawler-inject.js:1106
(anonymous) @ crawler-inject.js:1114
initDomMutationObservers @ crawler-inject.js:1114
(anonymous) @ crawler-inject.js:1549
```

Despite this error, nothing seems to be broken and flows work as anticipated.

* web: add more linting

* A reliable test for the extra code needed in analyzer, passing shellcheck

* web: re-enable custom-element-manifest and enable component checking in Typescript

This commit includes a monkeypatch to allow custom-element-manifest (CEM) to work correctly again
despite our rich collection of mixins, reactive controllers, symbol-oriented event handlers, and the
like. With that monkeypatch in place, we can now create the CEM manifest file and then exploit it so
that IDEs and the Typescript compilation pass can tell when a component is being used incorrectly;
when the wrong types are being passed to it, or when a required attribute is not initialized.

* Added building the manifest to the build process, rather than storing it.  It is not appreciably slow.

* web: the most boring PR in the universe: Add HTMLTagNameElementMap to everyhing

This commit adds HTMLTagNameElementMap entries to every web component in the front end. Activating
and associating the HTMLTagNamElementMap with its class has enabled
[LitAnalyzer](https://github.com/runem/lit-analyzer/tree/master/packages/lit-analyzer) to reveal a
*lot* of basic problems within the UI, the most popular of which is "missing import." We usually get
away with it because the object being imported was already registered with the browser elsewhere,
but it still surprises me that we haven't gotten any complaints over things like:

```
./src/flow/stages/base.ts
Missing import for <ak-form-static>
96:  <ak-form-static
no-missing-import
```

Given how early and fundamental that seems to be in our code, I'd have expected to hear _something_
about it.

I have not enabled most of the possible checks because, well, there are just a ton of warnings when
I do.  I'd like to get in and fix those.

Aside from this, I have also _removed_ `customElement` declarations from anything declared as an
`abstract class`. It makes no sense to try and instantiate something that cannot, by definition, be
instantiated.  If the class is capable of running on its own, it's not abstract, it just needs to be
overridden in child classes.  Before removing the declaration I did check to make sure no other
piece of code was even *trying* to instantiate it, and so far I have detected no failures.  Those
elements were:

- elements/forms/Form.ts
- element-/wizard/WizardFormPage.ts

The one that blows my mind, though, is this:

```
src/elements/forms/ProxyForm.ts
6-@customElement("ak-proxy-form")
7:export abstract class ProxyForm extends Form<unknown> {
```

Which, despite being `abstract`, is somehow instantiable?

```
src/admin/outposts/ServiceConnectionListPage.ts:    <ak-proxy-form
src/admin/providers/ProviderListPage.ts:    <ak-proxy-form
src/admin/sources/SourceWizard.ts:    <ak-proxy-form
src/admin/sources/SourceListPage.ts:    <ak-proxy-form
src/admin/providers/ProviderWizard.ts:    <ak-proxy-form type=${type.component}></ak-proxy-form>
src/admin/stages/StageListPage.ts:    <ak-proxy-form
```

I've made a note to investigate.

I've started a new folder where all of my one-off tools for *how* a certain PR was run.  It has a
README describing what it's for, and the first tool, `add-htmlelementtagnamemaps-to-everything`, is
its first entry.  That tool is also documented internally.

``` Gilbert & Sullivan

I've got a little list,
I've got a little list,
Of all the code that would never be missed,
The duplicate code of cute-and-paste,
The weak abstractions that lead to waste,
The embedded templates-- you get the gist,
There ain't none of 'em that will ever be missed,
And that's why I've got them on my list!

```
2024-07-15 10:54:22 -07:00
5f1ba45966 web: provide dual-list multiselect with pagination (#8004)
* web: revise css-import-maps to need only a single entry, rather than dual-entry

Given that the difference Vite/Storybook cares about is whether or not there's a
sigil at the end of the CSS string, it seemed silly to require devs to enter
both the raw and sigiled string; just do an in-line text-and-replace.

* web: provide a "select / select all" tool for the dual list multiselect

**This commit**

Provides one of several of the sub-controls needed to make the multi-list multi-select thing work.
This is the simplest control, and I decided to go with it first because it's all presentation; all
it does is show the buttons and send events from those buttons.

A Storybook component is provided to show how well it works.

* web: provide a "select / select all" tool for the dual list multiselect

**This commit**

This commit provides the following new features for dual list multiselect:

- The "available" pane, which has all of the entries that are available to be selected.  Items that
  are already selected will remain, but they're marked with a checkmark and can neither be selected
  or moved.
- The "selected" pane, which has *all* of the entries that have been selected.
- The Pagination control, which in this case only sends an event upstream.

**Plan**:

The plan is to have a master control that marries the available-pane, selected-pane,
select-controls, and pagination-controls into a single component that receives the list of
"currently visible" available entries and keeps the list of "currently selected" entries, as well as
a pass-through for the pagination value that allows it to hide the pagination control if there is
only one page.

A master component *above that* will provide the list of currently visible entries and, at need,
read the value of the master control object for the "selected" list. That component will mostly be
data-only; it's render will probably just be `<slot></slot>`; its duty will be only to map entries
to string keys Lit can use, and to provide the lists we want to provide and the pagination ranges we
want to show.

Some judicious use of grid will allow me size the controls properly with/without the pagination
control.

Status and Title are going to be in the master control.

A <slot> will be provided for Search, but I have no plans to integrate that into this control as of
yet.

There is already a planned fallback control; the multi-select experience on mobile is actually
excellent, and we should exploit that appropriately.

* web: provide a "select / select all" tool for the dual list multiselect

**This commit**

1. Re-arrange the contents of the folder so that the sub-components are in their own folder. This
   reduces the clutter and makes it easier to understand where to look for certain things.
2. Re-arranges the contents of the folder so that all the Storybook stories are in their own folder.
   Again, this reduces the clutter; it also helps the compiler understand what not to compile.
3. Strips down the "Available items pane" to a minimal amount of interactivity and annotates the
   passed-in properties as `readonly`, since the purpose of this component is to display those. The
   only internal state kept is the list of items marked-to-move.
4. Does the same thing with the "Selected items pane".
5. Added comments to help guide future maintainers.
6. Restructured the CSS, taking a _lot_ of it into our own hands. Patternfly continues to act as if
   all components are fully available all the time, and that's simply not true in a shadowDOM
   environment. By separating out the global CSS Custom Properties from the grid and style
   definitions of `pf-c-dual-list-selector`, I was able to construct a more simple and
   straightforward grid (with nested grids for the columns inside).
7. Added "Delete ALL Selected" to the controls
8. Added "double-click" as a "move this one NOW" feature.

* web: provide a "select / select all" tool for the dual list multiselect

**This commit**

- Fixes the bug whereby pagination would leave the 'some moves available' state visible by clearing
  the 'to-move' state when the list of options changes.
- Fixes the bug whereby a change of 'options' in available would also cause an update to
  `selectedKeys`, causing the entire selected field to clear. Fixed by making `selectedKeys` a
  static object updated only when `selected` is generated rather than generating it anew with each
  re-rerender. (Hey, kids, can you say "functional programming and immutability" five time fast? I
  knew you could!)
- Fixes the bug whereby the change of outpost type would not cause an update of the `options`
  collection.
- Fixes the bug whereby the CSS was not creating enough whitespace separation between the whole
  component and its siblings. Host components are coded `span:static` unless otherwise styled to be
  `block`; we want `block` most of the time.
- Fixes the bug whereby the list of existing objects wasn't being passed to the handler correctly.
- Updates the Form Handler to recognize this new input object.
- Fixes the bug whereby changing outpost type doesn't handle the list of selected applications well.
- Fixes the bug whereby the identity of the outpost type's associated `fetch()` function loses
  identity -- necessary to maintain the selected outpost type switch.
- Fixes the CSS bug whereby horizontal scrolling would not enable correctly when the application's
  name overflows the listbox.
- Completes this assignment.  :-)

* web: last-minute pre-commit cleanup.

* running localize extract

* web: codeql found an issue with one of my tests.

* web: multi-select

Modified the display so that if it's a template we display it
correctly opposite the text, and provide classes that can be used
in the display to differentiate between the main label and the
descriptive label.

Added a sort key, so the select can sort the right-hand pane correctly.

Fixed the `this.selected` setters to use Arrays instead of maps.
Theoretically, this is terribly inefficient, as it makes it
theoretically O(n^2) rather than O(1), but in practice even if both
lists were 10,000 elements long a modern desktop could perform the
entire scan in 150ms or so.

* fix lint error

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* update strings slightly

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* start on dark theme support

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* web: Add searchbar and enable it for "selected"

"Available" requires a round-trip to the provider level, so that's next.

* web: provide a search for the dual list multiselect

**This commit**

- Includes a new widget that represents the basic, Patternfly-designed search bar.  It just emits
  events of search request updates.
- Changes the definition of a data provider to take an optional search string.
- Changes the handler in the *independent* layer so that it catches search requests and those
  requests work on the "selected" collection.
- Changes the handler of the `authentik` interface layer so that it catches search requests and
  those requests are sent to the data provider.
- Provides a debounce function for the `authentik` interface layer to not hammer the Django instance
  too much.
- Updates the data providers in the example for `OutpostForm` to handle search requests.
- Provides a property in the `authentik` interface layer so that the debounce can be tuned.

* web: always trim the search string passed.

* web: code quality pass, extra comments, pre-commit check.

* Serious (and bizarre) merge bug.  I guess it doesn't like XML that much.

* Attempting to reason with whatever eslint GitHub is using.

* Prettier has opinions.

* Enable better dark mode.

There were two issues: the dark mode didn't reach into the "search"
bar, and there were several hover states that weren't handled well.

This commit handles both.  The color scheme mirrors the one we
currently use, but it's a bit backwards from Patternfly 5.  Dunno
how we're gonna reconcile all that.

* Prettier fixes and locale extraction

* web: update pagination type to use generic, provided type

* web: fixed a few comment typos

* Discordant version numbers for @go-authentik/api were causing build failures.

* What is up with CI/CD?

* web: missed a lint issue that prevented the build from running successfully

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2024-01-25 10:08:00 -08:00
3b171a02b7 web: laying the groundwork for future expansion (#7045)
* web: laying the groundwork for future expansion

This commit is a hodge-podge of updates and changes to the web.  Functional changes:

- Makefile: Fixed a bug in the `help` section that prevented the WIDTH from being accurately
  calculated if `help` was included rather than in-lined.

- ESLint: Modified the "unused vars" rule so that variables starting with an underline are not
  considered by the rule.  This allows for elided variables in event handlers.  It's not a perfect
  solution-- a better one would be to use Typescript's function-specialization typing, but there are
  too many places where we elide or ignore some variables in a function's usage that switching over
  to specialization would be a huge lift.

- locale: It turns out, lit-locale does its own context management.  We don't need to have a context
  at all in this space, and that's one less listener we need to attach t othe DOM.

- ModalButton: A small thing, but using `nothing` instead of "html``" allows lit better control over
  rendering and reduces the number of actual renders of the page.

- FormGroup: Provided a means to modify the aria-label, rather than stick with the just the word
  "Details."  Specializing this field will both help users of screen readers in the future, and will
  allow test suites to find specific form groups now.

- RadioButton: provide a more consistent interface to the RadioButton.  First, we dispatch the
  events to the outside world, and we set the value locally so that the current `Form.ts` continues
  to behave as expected.  We also prevent the "button lost value" event from propagating; this
  presents a unified select-like interface to users of the RadioButtonGroup.  The current value
  semantics are preserved; other clients of the RadioButton do not see a change in behavior.

- EventEmitter: If the custom event detail is *not* an object, do not use the object-like semantics
  for forwarding it; just send it as-is.

- Comments: In the course of laying the groundwork for the application wizard, I throw a LOT of
  comments into the code, describing APIs, interfaces, class and function signatures, to better
  document the behavior inside and as signposts for future work.

* web: permit arrays to be sent in custom events without interpolation.

* actually use assignValue or rather serializeFieldRecursive

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2023-10-02 13:33:27 -07:00
d0f0f9b29e web: Add storybook (#5865)
* \#\# Details

web: replace lingui with lit/localize

\#\# Changes

This rather massive shift replaces the lingui and `t()` syntax with lit-localize, XLIFF, and the `msg()`
syntax used by lit-localize.  90% of this work was mechanized; simple perl scripts found and replaced
all uses of `t()` with the appropriate corresponding syntax for `msg()` and `msg(str())`.

The XLIFF files were auto-generated from the PO files.  They have not been audited, and they should be
checked over by professional translators.  The actual _strings_ have not been changed, but as this was
a mechanized change there is always the possibility of mis-translation-- not by the translator, but by
the script.

* web: revise lit/localize: fix two installation issues.

* web: revise localization

TL;DR:

- Replaced all of Lingui's `t()` syntax with `msg()` syntax.
- Mechanically (i.e with a script) converted all of the PO files to XLIFF files
- Refactored the localization code to be a bit smarter:
  - the function `getBestMatchLocale` takes the locale lists and a requested locale, and returns the
    first match of:
    - The locale's code exactly matches the requested locale
    - The locale code exactly matches the prefix of the requested locale (i.e the "en" part of "en-US")
    - the locale code's prefix exactly matches the prefix of the requested locale
    This function is passed to lit-locate's `loadLocale()`.
  - `activateLocale()` just calls `loadLocale()` now.
  - `autodetectLanguage` searches the following, and picks the first that returns a valid locale
    object, before passing it to `loadLocale()`:
    - The User's settings
    - A `?locale=` component found in `window.location.search`
    - The `window.navigator.language` field
    - English

The `msg()` only runs when it's run.  This seems obvious, but it means that you cannot cache
strings at load time; they must be kept inside functions that are re-run so that the `msg()` engine
can look up the strings in the preferred language of the user at that moment.

You can use thunks-of-strings if you really need them that way.

* Including the 'xliff-converter' in case anyone wants to review it.

* The xliff-converter is tagged as 'xliff-converter', but has been
deleted.

\#\# Details

-   Resolves #5171

\#\# Changes

\#\#\# New Features

-   Adds a "Add an Application" to the LibraryView if there are no applications and the user is an administrator.

\#\#\# Breaking Changes

-   Adds breaking change which causes \<issue\>.

\#\# 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`)

* web: fix redundant locales for zh suite.

* web: prettier pass for locale update

* web: localization moderization

Changed the names of the lit-localize commands to make it clear they're
part of the localization effort, and not just "build" and "extract".

* web: add storybook to test components

* update transifex config

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix package lock?

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* use build not compile

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* web: conversion to lit-localize

The CI produced a list of problems that I hadn't caught earlier,
due to a typo ("localize build" is correct, "localize compile" is
not) I had left in package.json.  They were minor and linty, but
it was still wise to fix them.

* web: replace lingui with lit/locale

This commit fixes some minor linting issues that were hidden by a typo in package.json.  The
issues were not apparently problematic from a Javascript point of view, but they pointed
to sloppy thinking in the progression of types through the system, so I cleaned them
up and formalized the types from LocaleModule to AkLocale.

* web: replace lingui with lit/localize

One problem that has repeatedly come up is that localize's templates do not produce
JavaScript that conforms with our shop style.  I've replaced `build-locale` with
a two-step that builds the locale *and* ensures that it conforms to the shop style
via `prettier` every time.

* web: replace lingui with lit-locale

This commit applies the most recent bundle of translations to the
new lit-locale aspect component.  It also revises the algorithm
for *finding* the correct locale, replacing the complex fall-back
with some rather straightforward regular expressions.

In the case of Chinese, the fallback comes at the end of the
selection list, which may not be, er, politically valuable
(since Taiwan and Hong Kong come before, being exceptions that
need to be tested).  If we need a different order for presentation,
that'll be a future feature.

* web: replace lingui with lit/locale

Well, that was embarassing.

* web: add storybook

The delta on this didn't make any sense; putting it back causes no behavioral
changes.

* web: add Storybook

Fixed a typo in the package.json that prevented the TSC check
from passing.

* web: incorporate storybook

This commit includes a number of type and definitional changes needed to make lit-analyze pass. In
most cases, it was a matter of reassuring Lit that we were using the right type and the right type
converter, or configuring the property such that it should never be called as an attribute.

The most controversial change is adding the 'no-incompatible-type-binding' to the LIT analyzer
configuration (found in `tsconfig.json`). This "routes around" lit-analyzer not doing very well
understanding that some HTML objects can have generic property types, as long as the renderer is
configured correctly.

The 'no-missing-import: off' setting is required as lit-analyzer also does not use the tsconfig
`paths` setting correctly and cannot find objects defined via aliases.

It's a shame JSON can't support comments; these should be in the tsconfig.json file directly.  As it
is, I've started a README file that includes a section to record configuration decisions.

Deleted the lingui.config file as we're not using it anymore

* ignore storybook build in git

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2023-06-07 13:05:33 +02:00
44a057ed9c web: Replace lingui.js with lit-localize (#5761)
* \#\# Details

web: replace lingui with lit/localize

\#\# Changes

This rather massive shift replaces the lingui and `t()` syntax with lit-localize, XLIFF, and the `msg()`
syntax used by lit-localize.  90% of this work was mechanized; simple perl scripts found and replaced
all uses of `t()` with the appropriate corresponding syntax for `msg()` and `msg(str())`.

The XLIFF files were auto-generated from the PO files.  They have not been audited, and they should be
checked over by professional translators.  The actual _strings_ have not been changed, but as this was
a mechanized change there is always the possibility of mis-translation-- not by the translator, but by
the script.

* web: revise lit/localize: fix two installation issues.

* web: revise localization

TL;DR:

- Replaced all of Lingui's `t()` syntax with `msg()` syntax.
- Mechanically (i.e with a script) converted all of the PO files to XLIFF files
- Refactored the localization code to be a bit smarter:
  - the function `getBestMatchLocale` takes the locale lists and a requested locale, and returns the
    first match of:
    - The locale's code exactly matches the requested locale
    - The locale code exactly matches the prefix of the requested locale (i.e the "en" part of "en-US")
    - the locale code's prefix exactly matches the prefix of the requested locale
    This function is passed to lit-locate's `loadLocale()`.
  - `activateLocale()` just calls `loadLocale()` now.
  - `autodetectLanguage` searches the following, and picks the first that returns a valid locale
    object, before passing it to `loadLocale()`:
    - The User's settings
    - A `?locale=` component found in `window.location.search`
    - The `window.navigator.language` field
    - English

The `msg()` only runs when it's run.  This seems obvious, but it means that you cannot cache
strings at load time; they must be kept inside functions that are re-run so that the `msg()` engine
can look up the strings in the preferred language of the user at that moment.

You can use thunks-of-strings if you really need them that way.

* Including the 'xliff-converter' in case anyone wants to review it.

* The xliff-converter is tagged as 'xliff-converter', but has been
deleted.

\#\# Details

-   Resolves #5171

\#\# Changes

\#\#\# New Features

-   Adds a "Add an Application" to the LibraryView if there are no applications and the user is an administrator.

\#\#\# Breaking Changes

-   Adds breaking change which causes \<issue\>.

\#\# 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`)

* web: fix redundant locales for zh suite.

* web: prettier pass for locale update

* web: localization moderization

Changed the names of the lit-localize commands to make it clear they're
part of the localization effort, and not just "build" and "extract".

* update transifex config

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix package lock?

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* use build not compile

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* web: conversion to lit-localize

The CI produced a list of problems that I hadn't caught earlier,
due to a typo ("localize build" is correct, "localize compile" is
not) I had left in package.json.  They were minor and linty, but
it was still wise to fix them.

* web: replace lingui with lit/locale

This commit fixes some minor linting issues that were hidden by a typo in package.json.  The
issues were not apparently problematic from a Javascript point of view, but they pointed
to sloppy thinking in the progression of types through the system, so I cleaned them
up and formalized the types from LocaleModule to AkLocale.

* web: replace lingui with lit/localize

One problem that has repeatedly come up is that localize's templates do not produce
JavaScript that conforms with our shop style.  I've replaced `build-locale` with
a two-step that builds the locale *and* ensures that it conforms to the shop style
via `prettier` every time.

* web: replace lingui with lit-locale

This commit applies the most recent bundle of translations to the
new lit-locale aspect component.  It also revises the algorithm
for *finding* the correct locale, replacing the complex fall-back
with some rather straightforward regular expressions.

In the case of Chinese, the fallback comes at the end of the
selection list, which may not be, er, politically valuable
(since Taiwan and Hong Kong come before, being exceptions that
need to be tested).  If we need a different order for presentation,
that'll be a future feature.

* web: replace lingui with lit/locale

Well, that was embarassing.

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2023-06-02 08:08:36 -07:00
9dbd54690c web/elements: fix search select inconsistency (#4989)
* web/elements: fix search-select inconsistency

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* web/common: fix config having to be json converted everywhere

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* web/elements: refactor form without iron-form

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* web/admin: fix misc

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-03-17 13:48:34 +01:00
b6b820f6f1 web: toggle dark/light theme manually (#4876) 2023-03-09 23:17:53 +01:00
ba5cd6e719 web/admin: add Radio control, search-select fixes (#4333)
* move search select to forms folder

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* add radio, migrate smaller lists

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* move dropdown when scrolling, hide when container out of frame

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2023-01-02 14:51:44 +01:00
4a91a7d2e2 web: re-organise frontend and cleanup common code (#3572)
* fix repo in api client

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web: re-organise files to match their interface

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* core: include version in script tags

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* cleanup maybe broken

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* revert rename

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web: get rid of Client.ts

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* move more to common

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* more moving

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* format

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* unfuck files that vscode fucked, thanks

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* move more

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* finish moving (maybe)

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* ok more moving

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* fix more stuff that vs code destroyed

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* get rid "web" prefix for virtual package

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* fix locales

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* use custom base element

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* fix css file

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* don't run autoDetectLanguage when importing locale

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* fix circular dependencies

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web: fix build

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-09-15 00:05:21 +02:00
11334cf638 web: re-cleanup imports not being absolute
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-09-06 19:02:40 +02:00
a8c04f96d2 web: use absolute imports with path rewrite instead of relative imports (#3149) 2022-06-25 17:44:17 +02:00
3184a64482 web: live-convert to slug in fields where only slugs are allowed
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-26 18:49:08 +01:00
4f4f954693 core: customisable user settings (#2397)
* tenants: add user_settings flow, add basic flow and basic new executor

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web/user: use flow PromptStage instead of custom stage

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web/flows: add tenant to StageHost interface

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web/user: fix form missing component

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web/user: re-add success message

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web/user: improve support for multiple error messages

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* stages/prompt: allow expressions in prompt placeholders

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* stages/prompt: add tests

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* flows: always set pending user

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* flows: never cache stage configuration flow plans

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* stages/user_write: fix error when pending user is anonymous user

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web/admin: add checkbox for prompt placeholder expression

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* website/docs: add prompt expression docs

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* stages/prompt: add ak-locale field type

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* tenants: fix default policy

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web/user: add function to do global refresh

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* web/flows: fix rendering of ak-locale

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* tenants: fix default policy, add error handling to placeholder, fix locale attribute

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* add tests

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-03-03 00:13:06 +01:00
61f7db314a web/admin: use searchable select field for users and groups in policy binding form
closes #2285

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-02-26 17:49:04 +01:00
e587c53e18 web: remove deprecated rollup-plugin-node-resolve
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-11-04 22:34:48 +01:00
73733b20b6 build(deps): bump @trivago/prettier-plugin-sort-imports from 2.0.4 to 3.0.0 in /web (#1684)
* build(deps): bump @trivago/prettier-plugin-sort-imports in /web

Bumps [@trivago/prettier-plugin-sort-imports](https://github.com/trivago/prettier-plugin-sort-imports) from 2.0.4 to 3.0.0.
- [Release notes](https://github.com/trivago/prettier-plugin-sort-imports/releases)
- [Changelog](https://github.com/trivago/prettier-plugin-sort-imports/blob/master/CHANGELOG.md)
- [Commits](https://github.com/trivago/prettier-plugin-sort-imports/commits)

---
updated-dependencies:
- dependency-name: "@trivago/prettier-plugin-sort-imports"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* web: update prettier config

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-10-28 09:48:51 +02:00
da7635ae5c web: sort imports
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-09-21 11:33:51 +02:00
a92a0fb60a web: migrate to lit 2
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-09-21 11:19:26 +02:00
00a666856d web: expand parent FormGroup when containing element has error
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-08-21 15:24:31 +02:00
2c60ec50be web: re-format with prettier
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-08-03 17:52:21 +02:00
c133f16371 web/elements: move table search to table
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-10 20:13:19 +02:00
85121de9d7 web/admin: only set ?writeOnly when editing an object
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-04 20:11:57 +02:00
93b362570d web/elements: add ?writeOnly flag for passwords etc
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-04-04 20:07:46 +02:00
d5281d2023 web: set name on ak-form-element-horizontal for error messages
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-03-29 18:24:56 +02:00
d71d45b958 web/admin: use shadowroot for codemirror, remove styles
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-03-29 12:21:00 +02:00
12bfa404c8 web: rudimentary lazy loading for modals
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-03-29 11:59:30 +02:00
76e571ea0a web: use custom-element as wrapper
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-03-29 10:09:43 +02:00