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/admin: add application bindings to the application wizard #11462

Open
wants to merge 133 commits into
base: web/update-provider-forms-for-invalidation
Choose a base branch
from

Conversation

kensternberg-authentik
Copy link
Contributor

@kensternberg-authentik kensternberg-authentik commented Sep 20, 2024

web: wizard for applications, now with bindings!

What

Purpose

  • Add policy bindings to the application wizard

The Wizard Base:

  • Restructures the Wizard base code.
    • ak-wizard-steps holds the steps and listens for NavigationRequest events to move from one step to the next.
    • WizardStep is a base class (no component registration provided) that provides the whole frame, not just the form. It receives the navigation content for the sidebar from ak-wizard-steps, and provides the styling for the header, footer, sidebar, and main form. It has abstractions for buttons, renderMain(), handleButton(), handleEnable(), in a section well-marked as “Public API”. Steps inherit from this class.

Conceptually:

  • A wizard is a series of pages (“steps”) with a distinct beginning and end, linked in a series, to complete a task.
  • Later steps in the series are inaccessible until an earlier steps has granted access to it.
  • Access is predicated on the earlier step being complete and valid. The developer is responsible for determining what “complete and valid” means.
  • The series is visible, giving the customer a sense of how much effort is needed to complete the task.
  • A parent object maintains (and can modify as needed) the list of steps. It can maintain the information being collected from the user. Alternatively, that information can be kept in each step.

Details:

  • Keeping with the Lit paradigm, “requests to change the system flow up, information changed by valid requests flows down.”
  • The information flows up using events: WizardNavigation, WizardUpdate, WizardClose.
  • The information flows down using properties.

The Application Wizard

  • ak-application-wizard-main holds the list of steps, providing a unique slot name for each.
    • It maintains the ApplicationWizardState object.
  • ApplicationWizardStep inherits from WizardStep and provides:
    • A means of extraction information from forms
    • A convenience method for updating the ApplicationWizardState object, enabling future steps, and navigating to a future step, in the correct order.
    • A method for cleaning error from the error reporting mechanism as the user navigates from an error-handling state.
    • The title, description, and cancelability of the wizard.
  • Steps:
    • step: Handles the application. A good starting point for understanding the point of the Wizard. Check the handleButton() method to understand how we enable or disable access to future steps.
    • provider-choice: Just a list. Shows validation without the form.
    • provider: Uses a very esoteric Lit feature, unsafeStaticTag, which enables the display to show anything that conforms to the expectations of ApplicationWizardProviderForm.
      • ApplicationWizardProviderForm repeats some of the base of ApplicationWizardStep, but allows us to provide multiple variants on a single form without having to create separate steps for each form.
      • The forms (provider-for-ldap, provider-for-radius) are therefore just the form and any fetchers needed to populate it.
    • bindings: Shows the table of bindings. Has a custom display for “This table is empty.”
    • edit-binding: Showcase for the SearchSelectEZ configuration format. Has an override on the handleButton feature to figure out which binding is about to be overridden. Is also a .hidden page; it doesn’t show up on the navigation sidebar, as is only navigable-to by buttons not associated with the button bar at the bottom.
    • submit: Has a lot of machinery of state: Reviewing with errors, reviewing without errors, running submission, and success. Uses ts-pattern a lot to make sure the state/request pairs make sense.

Why !?!?!?

The key insight is that, even though a wizard is a series in order, that order can’t be simply maintained in a list. The parent needs various strategies for swapping pages in and out of the sequence, while still maintaining a coherent idea of “flow” and providing the visual cues the user needs to feel confident that the work can be completed and completed quickly. The entire mechanism for using an array and index to navigate, with index numbering, blocked the implementation of the bindings pages.

One thing led to another. Sigh Really wish this hadn’t been as much of a mess as it turned out. The end result is pretty good, though. Definitely re-usable.

One important feature to note is that the wizard is not tied to the ModalButton object; it’s simply embedded in a modal as-needed. This allows us to use wizards in other places, such as just being in a DIV, or just a page on its own.

Checklist

  • The code has been formatted (make web)

…from the backend

Provide an alternative, readonly, disabled, unindexed input object with the text "Loading...", to be
replaced with the _real_ input element after the content is loaded.

This provides the correct appearance and spacing so the content doesn't jiggle about between the
start of loading and the SearchSelect element being finalized.  It was visually distracting and
unappealing.
- Add a unit test to ensure the "Loading..." element is displayed correctly before data arrives
- Demo how to mock a `fetchObjects()` call in testing. Very cool.
- Make distinguishing rule sets for code, tests, and scripts in nightmare mode
- In SearchSelect, Move the `styles()` declaration to the top of the class for consistency.

- To test for the FLOUC issue in SearchSelect.

This is both an exercise in mocking @BeryJu's `fetchObjects()` protocol, and shows how we can unit
test generic components that render API objects.
…select-table

* web/bug/search-select-flouc-issue:
  web: test for flash of unstructured content
  web: comment on state management in API layer, move file to point to correct component under test.
  web: fix Flash of Unstructured Content while SearchSelect is loading from the backend
Mostly these tests assert that the table renders and that the content we give it
is where we expect it to be after sorting. For select tables, it also asserts that
the overall value of the table is what we expect it to be when we click on a
single row, or on the "select all" button.
* main:
  website/docs: cve release notes (#11026)
  security: fix CVE-2024-42490 (#11022)
  web: bump API Client version (#11021)
  providers/scim: optimize sending all members within a group (#9968)
  providers/scim: add API endpoint to sync single user (#8486)
  web: bump chromedriver from 127.0.3 to 128.0.0 in /tests/wdio (#11017)
  web: dual-select uses, part 2: dual-select harder (#9377)
  web: fix flash of unstructured content, add tests for it (#11013)
  core: bump drf-orjson-renderer from 1.7.2 to 1.7.3 (#11015)
  core: bump github.com/gorilla/sessions from 1.3.0 to 1.4.0 (#11002)
  website/docs: Correct the forward authentication configuration template for Caddy (#11012)
Includes documentation updates and better tests for select-table.
…manipulate test DOMs directly in a browser.exec call so they run in the proper context and be await()ed properly
* main: (30 commits)
  website/docs: prepare release notes for 2024.8 (#11011)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#11070)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#11071)
  web: bump mermaid from 10.9.1 to 11.0.2 in /web (#11066)
  core: bump github.com/jellydator/ttlcache/v3 from 3.2.0 to 3.2.1 (#11059)
  Fix incorrect size redefinition for Discord avatar acquisition code. (#11050)
  core, web: update translations (#11051)
  website: bump micromatch from 4.0.5 to 4.0.8 in /website (#11052)
  core: bump django-pglock from 1.5.1 to 1.6.0 (#11058)
  core: bump goauthentik.io/api/v3 from 3.2024063.13 to 3.2024064.1 (#11060)
  core: bump github.com/prometheus/client_golang from 1.20.1 to 1.20.2 (#11061)
  web: bump the swc group across 2 directories with 11 updates (#11062)
  web: bump tslib from 2.6.3 to 2.7.0 in /web (#11063)
  web: bump @eslint/js from 9.9.0 to 9.9.1 in /web (#11064)
  web: bump syncpack from 12.4.0 to 13.0.0 in /web (#11065)
  web: bump @goauthentik/api from 2024.6.3-1724337552 to 2024.6.3-1724414734 in /web/sfe (#11067)
  web: Provide tests for the aggregate cards, fix a few minor things (#9744)
  enterprise: fix license status progress bar (#11048)
  root: backport version bump (#11045)
  web/flows: update flow background (#11044)
  ...
* main: (92 commits)
  internal: fix go paginator not setting page correctly (#11253)
  core: bump google-api-python-client from 2.143.0 to 2.144.0 (#11241)
  core: bump twilio from 9.2.4 to 9.3.0 (#11242)
  core: bump github.com/prometheus/client_golang from 1.20.2 to 1.20.3 (#11243)
  core: bump ruff from 0.6.3 to 0.6.4 (#11244)
  core: bump pydantic from 2.8.2 to 2.9.0 (#11245)
  core: bump msgraph-sdk from 1.5.4 to 1.6.0 (#11246)
  web: bump the rollup group across 2 directories with 1 update (#11248)
  core: fix missing argument name escaping for property mapping (#11231)
  providers/ldap: rework search_group migration to work with read replicas (#11228)
  core, web: update translations (#11220)
  website: bump postcss from 8.4.44 to 8.4.45 in /website (#11221)
  core: bump golang.org/x/oauth2 from 0.22.0 to 0.23.0 (#11222)
  core: bump django-model-utils from 4.5.1 to 5.0.0 (#11223)
  web: bump @changesets/cli from 2.27.7 to 2.27.8 in /web (#11224)
  web: bump @types/node from 22.5.3 to 22.5.4 in /web (#11225)
  web/admin: improve error handling (#11212)
  providers/ldap: fix incorrect permission check for search access (#11217)
  web/admin: fix missing Sync object button SCIM Provider (#11211)
  website/docs: add note about terraform provider (#11206)
  ...
* main: (25 commits)
  web: bump rapidoc from 9.3.4 to 9.3.5 in /web (#11410)
  website: bump dompurify from 3.0.6 to 3.1.6 in /website (#11402)
  website: bump @types/react from 18.3.5 to 18.3.6 in /website (#11405)
  core: bump goauthentik.io/api/v3 from 3.2024081.1 to 3.2024082.1 (#11406)
  web: bump the storybook group across 1 directory with 7 updates (#11408)
  web: bump typescript-eslint from 8.5.0 to 8.6.0 in /tests/wdio (#11409)
  web: bump typescript-eslint from 8.5.0 to 8.6.0 in /web (#11411)
  web: bump mermaid from 11.2.0 to 11.2.1 in /web (#11412)
  website/docs: upgrade: fix helm command (#11403)
  web: bump API Client version (#11396)
  release: 2024.8.2 (#11395)
  website/docs: prepare release notes for 2024.8.2 (#11394)
  core: bump paramiko from 3.4.1 to 3.5.0 (#11388)
  stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs (#11383)
  core, web: update translations (#11375)
  core: bump django-pglock from 1.6.1 to 1.6.2 (#11389)
  website: bump postcss from 8.4.45 to 8.4.47 in /website (#11390)
  core: bump ruff from 0.6.4 to 0.6.5 (#11391)
  core: bump psycopg from 3.2.1 to 3.2.2 (#11392)
  web: bump @floating-ui/dom from 1.6.10 to 1.6.11 in /web (#11393)
  ...
Got the binding editor in.  The tests complete.  Removed sonarjs.
Copy link

netlify bot commented Sep 20, 2024

Deploy Preview for authentik-docs canceled.

Name Link
🔨 Latest commit 29362ea
🔍 Latest deploy log https://app.netlify.com/sites/authentik-docs/deploys/673542ff63e7e300081cd9e5

Copy link

netlify bot commented Sep 20, 2024

Deploy Preview for authentik-storybook ready!

Name Link
🔨 Latest commit 59b74e9
🔍 Latest deploy log https://app.netlify.com/sites/authentik-storybook/deploys/672506d1828b980008793657
😎 Deploy Preview https://deploy-preview-11462--authentik-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

codecov bot commented Sep 20, 2024

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
1591 1 1590 1
View the top 1 failed tests by shortest run time
authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI test_create_transactional_bindings
Stack Traces | 0.372s run time
self = <unittest.case._Outcome object at 0x7f41db06df70>
test_case = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
subTest = False

    @contextlib.contextmanager
    def testPartExecutor(self, test_case, subTest=False):
        old_success = self.success
        self.success = True
        try:
>           yield

.../hostedtoolcache/Python/3.12.7................../x64/lib/python3.12/unittest/case.py:58: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
result = <TestCaseFunction test_create_transactional_bindings>

    def run(self, result=None):
        if result is None:
            result = self.defaultTestResult()
            startTestRun = getattr(result, 'startTestRun', None)
            stopTestRun = getattr(result, 'stopTestRun', None)
            if startTestRun is not None:
                startTestRun()
        else:
            stopTestRun = None
    
        result.startTest(self)
        try:
            testMethod = getattr(self, self._testMethodName)
            if (getattr(self.__class__, "__unittest_skip__", False) or
                getattr(testMethod, "__unittest_skip__", False)):
                # If the class or method was skipped.
                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
                            or getattr(testMethod, '__unittest_skip_why__', ''))
                _addSkip(result, self, skip_why)
                return result
    
            expecting_failure = (
                getattr(self, "__unittest_expecting_failure__", False) or
                getattr(testMethod, "__unittest_expecting_failure__", False)
            )
            outcome = _Outcome(result)
            start_time = time.perf_counter()
            try:
                self._outcome = outcome
    
                with outcome.testPartExecutor(self):
                    self._callSetUp()
                if outcome.success:
                    outcome.expecting_failure = expecting_failure
                    with outcome.testPartExecutor(self):
>                       self._callTestMethod(testMethod)

.../hostedtoolcache/Python/3.12.7................../x64/lib/python3.12/unittest/case.py:634: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
method = <bound method TestTransactionalApplicationsAPI.test_create_transactional_bindings of <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>>

    def _callTestMethod(self, method):
>       if method() is not None:

.../hostedtoolcache/Python/3.12.7................../x64/lib/python3.12/unittest/case.py:589: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>

    def test_create_transactional_bindings(self):
        """Test transactional Application + provider creation"""
        assign_perm("authentik_policies.add_policybinding", self.user)
        self.client.force_login(self.user)
        uid = generate_id()
        group = Group.objects.create(name=generate_id())
        authorization_flow = create_test_flow()
        response = self.client.put(
            reverse("authentik_api:core-transactional-application"),
            data={
                "app": {
                    "name": uid,
                    "slug": uid,
                },
                "provider_model": "authentik_providers_oauth2.oauth2provider",
                "provider": {
                    "name": uid,
                    "authorization_flow": str(authorization_flow.pk),
                },
                "policy_bindings": [{"group": group.pk, "order": 0}],
            },
        )
>       self.assertJSONEqual(response.content.decode(), {"applied": True, "logs": []})

.../core/tests/test_transactional_applications_api.py:70: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
raw = '{"provider":{"invalidation_flow":["This field is required."]}}'
expected_data = {'applied': True, 'logs': []}, msg = None

    def assertJSONEqual(self, raw, expected_data, msg=None):
        """
        Assert that the JSON fragments raw and expected_data are equal.
        Usual JSON non-significant whitespace rules apply as the heavyweight
        is delegated to the json library.
        """
        try:
            data = json.loads(raw)
        except json.JSONDecodeError:
            self.fail("First argument is not valid JSON: %r" % raw)
        if isinstance(expected_data, str):
            try:
                expected_data = json.loads(expected_data)
            except ValueError:
                self.fail("Second argument is not valid JSON: %r" % expected_data)
>       self.assertEqual(data, expected_data, msg=msg)

../../../..../pypoetry/virtualenvs/authentik-xvtLQ9eE-py3.12/lib/python3.12.../django/test/testcases.py:922: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
first = {'provider': {'invalidation_flow': ['This field is required.']}}
second = {'applied': True, 'logs': []}, msg = None

    def assertEqual(self, first, second, msg=None):
        """Fail if the two objects are unequal as determined by the '=='
           operator.
        """
        assertion_func = self._getAssertEqualityFunc(first, second)
>       assertion_func(first, second, msg=msg)

.../hostedtoolcache/Python/3.12.7................../x64/lib/python3.12/unittest/case.py:885: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
d1 = {'provider': {'invalidation_flow': ['This field is required.']}}
d2 = {'applied': True, 'logs': []}, msg = None

    def assertDictEqual(self, d1, d2, msg=None):
        self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
        self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
    
        if d1 != d2:
            standardMsg = '%s != %s' % _common_shorten_repr(d1, d2)
            diff = ('\n' + '\n'.join(difflib.ndiff(
                           pprint.pformat(d1).splitlines(),
                           pprint.pformat(d2).splitlines())))
            standardMsg = self._truncateMessage(standardMsg, diff)
>           self.fail(self._formatMessage(msg, standardMsg))

.../hostedtoolcache/Python/3.12.7................../x64/lib/python3.12/unittest/case.py:1184: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
msg = "{'provider': {'invalidation_flow': ['This field is required.']}} != {'applied': True, 'logs': []}\n- {'provider': {'invalidation_flow': ['This field is required.']}}\n+ {'applied': True, 'logs': []}"

    def fail(self, msg=None):
        """Fail immediately, with the given message."""
>       raise self.failureException(msg)
E       AssertionError: {'provider': {'invalidation_flow': ['This field is required.']}} != {'applied': True, 'logs': []}
E       - {'provider': {'invalidation_flow': ['This field is required.']}}
E       + {'applied': True, 'logs': []}

.../hostedtoolcache/Python/3.12.7................../x64/lib/python3.12/unittest/case.py:715: AssertionError

To view individual test run time comparison to the main branch, go to the Test Analytics Dashboard

Copy link
Contributor

github-actions bot commented Sep 20, 2024

authentik PR Installation instructions

Instructions for docker-compose

Add the following block to your .env file:

AUTHENTIK_IMAGE=ghcr.io/goauthentik/dev-server
AUTHENTIK_TAG=gh-ec020955a16da695260b3ff661c2579ffd0ea2b9
AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE=ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s

For arm64, use these values:

AUTHENTIK_IMAGE=ghcr.io/goauthentik/dev-server
AUTHENTIK_TAG=gh-ec020955a16da695260b3ff661c2579ffd0ea2b9-arm64
AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE=ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s

Afterwards, run the upgrade commands from the latest release notes.

Instructions for Kubernetes

Add the following block to your values.yml file:

authentik:
    outposts:
        container_image_base: ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
global:
    image:
        repository: ghcr.io/goauthentik/dev-server
        tag: gh-ec020955a16da695260b3ff661c2579ffd0ea2b9

For arm64, use these values:

authentik:
    outposts:
        container_image_base: ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
global:
    image:
        repository: ghcr.io/goauthentik/dev-server
        tag: gh-ec020955a16da695260b3ff661c2579ffd0ea2b9-arm64

Afterwards, run the upgrade commands from the latest release notes.

* web/element/ak-select-table:
  web: repeat is needed to make sure sub-elements move around correctly. Map does not do full tracking.
  Provide unit test accessibility to Firefox and Safari; wrap calls to manipulate test DOMs directly in a browser.exec call so they run in the proper context and be await()ed properly
  web: finalize testing for tables
  web: added basic unit testing to API-free tables
  web: interim commit of the basic sortable & selectable table.
  web: test for flash of unstructured content
  web: comment on state management in API layer, move file to point to correct component under test.
  web: fix Flash of Unstructured Content while SearchSelect is loading from the backend
…'delete'. TODO: Fix error reporting on home page, the edit button is ugly, and the height is off somehow, but I'm not yet sure how. I just know it bugs my eyes.
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
especially since we'll be using the wizard as default in the future, it shouldn't be superuser only

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
… into web/policy-wizard-3

* origin/core/app-transactional/bindings: (47 commits)
  improve permission checks
  core: add support to set policy bindings in transactional endpoint
  web/admin: fix Authentication flow being required (#11496)
  web: bump the wdio group across 2 directories with 5 updates (#11494)
  web: bump turnstile-types from 1.2.2 to 1.2.3 in /web (#11495)
  web: bump the swc group across 2 directories with 11 updates (#11493)
  web: bump the eslint group across 2 directories with 5 updates (#11492)
  web: bump the storybook group across 1 directory with 7 updates (#11491)
  core: bump bandit from 1.7.9 to 1.7.10 (#11485)
  web: bump the rollup group across 2 directories with 3 updates (#11487)
  web: bump @types/node from 22.5.5 to 22.6.1 in /web (#11490)
  website/docs: use a more consistent version requirement notice (#11400)
  website/docs: clarify API browser access (#11373)
  website/integrations: Glitchtip: update redirect URL (#11438)
  web: bump knip from 5.30.4 to 5.30.5 in /web (#11479)
  fix: proxy provider - docker traefik label (#11460)
  website: the requirements for Go and Node required updating. (#11419)
  web: bump the esbuild group across 1 directory with 3 updates (#11470)
  web: bump @sentry/browser from 8.30.0 to 8.31.0 in /web in the sentry group across 1 directory (#11478)
  web: bump the eslint group across 2 directories with 1 update (#11469)
  ...
* main: (146 commits)
  website: bump @types/react from 18.3.8 to 18.3.9 in /website (#11502)
  core: bump debugpy from 1.8.5 to 1.8.6 (#11503)
  core: bump google-api-python-client from 2.146.0 to 2.147.0 (#11504)
  web: bump @types/node from 22.6.1 to 22.7.0 in /web (#11505)
  core, web: update translations (#11500)
  sources/ldap: fix mapping check, fix debug endpoint (#11442)
  web/admin: fix Authentication flow being required (#11496)
  web: bump the wdio group across 2 directories with 5 updates (#11494)
  web: bump turnstile-types from 1.2.2 to 1.2.3 in /web (#11495)
  web: bump the swc group across 2 directories with 11 updates (#11493)
  web: bump the eslint group across 2 directories with 5 updates (#11492)
  web: bump the storybook group across 1 directory with 7 updates (#11491)
  core: bump bandit from 1.7.9 to 1.7.10 (#11485)
  web: bump the rollup group across 2 directories with 3 updates (#11487)
  web: bump @types/node from 22.5.5 to 22.6.1 in /web (#11490)
  website/docs: use a more consistent version requirement notice (#11400)
  website/docs: clarify API browser access (#11373)
  website/integrations: Glitchtip: update redirect URL (#11438)
  web: bump knip from 5.30.4 to 5.30.5 in /web (#11479)
  fix: proxy provider - docker traefik label (#11460)
  ...
- Replace `th` with `td` in `thead` components. Because Patternfly.
- Add @BeryJu's styling to the tables, which make it much better looking
- Add policy bindings to the application wizard

- Restructures the Wizard base code.
  - ak-wizard-steps holds the steps and listens for NavigationRequest events to move
    from one step to the next.
  - WizardStep is a base class (no component registration provided) that provides the *whole frame*,
    not just the form.  It receives the navigation content for the sidebar from ak-wizard-steps,
    and provides the styling for the header, footer, sidebar, and main form.  It has abstractions
    for `buttons`, `renderMain()`, `handleButton()`, `handleEnable()`, in a section well-marked as
    "Public API".  Steps inherit from this class.

Conceptually:

- A wizard is a series of pages ("steps") with a distinct beginning and end, linked in a series,
  to complete a task.
- Later steps in the series are inaccessible until an earlier steps has granted access to it.
- Access is predicated on the earlier step being complete and valid. The developer is responsible
  for determining what "complete and valid" means.
- The series is visible, giving the customer a sense of how much effort is needed to complete the
  task.
- A parent object maintains (and can modify as needed) the list of steps. It *can* maintain the
  information being collected from the user. Alternatively, that information can be kept in each
  step.

Details:

- Keeping with the Lit paradigm, "requests to change the system flow up, information changed by
  valid requests flows down."
- The information flows up using events: WizardNavigation, WizardUpdate, WizardClose.
- The information flows down using properties.

- ak-application-wizard-main holds the list of steps, providing a unique slot name for each.
  - It maintains the ApplicationWizardState object.
- ApplicationWizardStep inherits from WizardStep and provides:
  - A means of extraction information from forms
  - A convenience method for updating the ApplicationWizardState object, enabling future steps, and
    navigating to a future step, in the correct order.
  - A method for cleaning error from the error reporting mechanism as the user navigates from an
    error-handling state.
  - The title, description, and cancelability of the wizard.
- Steps:
  - step: Handles the application. A good starting point for understanding the point of
    the Wizard.  Check the `handleButton()` method to understand how we enable or disable access to
    future steps.
  - provider-choice: Just a list. Shows validation without the form.
  - provider: Uses a *very* esoteric Lit feature, `unsafeStaticTag`, which enables
    the display to show anything that conforms to the expectations of ApplicationWizardProviderForm.
    - ApplicationWizardProviderForm repeats some of the base of ApplicationWizardStep, but allows us
      to provide multiple variants on a single form without having to create separate steps for each
      form.
    - The forms (`provider-for-ldap`, `provider-for-radius`) are therefore *just* the form and any
      fetchers needed to populate it.
  - bindings: Shows the table of bindings.  Has a custom display for "This table is empty."
  - edit-binding: Showcase for the `SearchSelectEZ` configuration format. Has an override on the
    `handleButton` feature to figure out which binding is about to be overridden. Is also a
    `.hidden` page; it doesn't show up on the navigation sidebar, as is only navigable-to by buttons
    not associated with the button bar at the bottom.
  - submit: Has a lot of machinery of state: Reviewing with errors, reviewing without errors,
    running submission, and success. Uses `ts-pattern` a lot to make sure the state/request pairs
    make sense.

The key insight is that, even though a wizard is a series in order, that order can't be simply
maintained in a list. The parent needs various strategies for swapping pages in and out of the
sequence, while still maintaining a coherent idea of "flow" and providing the visual cues the user
needs to feel confident that the work can be completed and completed quickly. The entire mechanism
for using an array and index to navigate, with index numbering, blocked the implementation of the
bindings pages.

One thing led to another.  *Sigh*  Really wish this hadn't been as much of a mess as it turned out.
The end result is pretty good, though.  Definitely re-usable.

One important feature to note is that the wizard is *not* tied to the ModalButton object; it's
simply embedded in a modal as-needed.  This allows us to use wizards in other places, such as just
being in a DIV, or just a page on its own.
@kensternberg-authentik kensternberg-authentik marked this pull request as ready for review September 26, 2024 17:57
dependabot bot and others added 18 commits November 8, 2024 16:38
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.8.0 to 0.9.0.
- [Commits](golang/sync@v0.8.0...v0.9.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.47 to 8.4.48.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](postcss/postcss@8.4.47...8.4.48)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps the docusaurus group in /website with 9 updates:

| Package | From | To |
| --- | --- | --- |
| [@docusaurus/core](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus) | `3.6.0` | `3.6.1` |
| [@docusaurus/plugin-client-redirects](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-plugin-client-redirects) | `3.6.0` | `3.6.1` |
| [@docusaurus/plugin-content-docs](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-plugin-content-docs) | `3.6.0` | `3.6.1` |
| [@docusaurus/preset-classic](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-preset-classic) | `3.6.0` | `3.6.1` |
| [@docusaurus/theme-common](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-theme-common) | `3.6.0` | `3.6.1` |
| [@docusaurus/theme-mermaid](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-theme-mermaid) | `3.6.0` | `3.6.1` |
| [@docusaurus/module-type-aliases](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-module-type-aliases) | `3.6.0` | `3.6.1` |
| [@docusaurus/tsconfig](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-tsconfig) | `3.6.0` | `3.6.1` |
| [@docusaurus/types](https://github.com/facebook/docusaurus/tree/HEAD/packages/docusaurus-types) | `3.6.0` | `3.6.1` |


Updates `@docusaurus/core` from 3.6.0 to 3.6.1
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.6.1/packages/docusaurus)

Updates `@docusaurus/plugin-client-redirects` from 3.6.0 to 3.6.1
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.6.1/packages/docusaurus-plugin-client-redirects)

Updates `@docusaurus/plugin-content-docs` from 3.6.0 to 3.6.1
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.6.1/packages/docusaurus-plugin-content-docs)

Updates `@docusaurus/preset-classic` from 3.6.0 to 3.6.1
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.6.1/packages/docusaurus-preset-classic)

Updates `@docusaurus/theme-common` from 3.6.0 to 3.6.1
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.6.1/packages/docusaurus-theme-common)

Updates `@docusaurus/theme-mermaid` from 3.6.0 to 3.6.1
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.6.1/packages/docusaurus-theme-mermaid)

Updates `@docusaurus/module-type-aliases` from 3.6.0 to 3.6.1
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.6.1/packages/docusaurus-module-type-aliases)

Updates `@docusaurus/tsconfig` from 3.6.0 to 3.6.1
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.6.1/packages/docusaurus-tsconfig)

Updates `@docusaurus/types` from 3.6.0 to 3.6.1
- [Release notes](https://github.com/facebook/docusaurus/releases)
- [Changelog](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/docusaurus/commits/v3.6.1/packages/docusaurus-types)

---
updated-dependencies:
- dependency-name: "@docusaurus/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: docusaurus
- dependency-name: "@docusaurus/plugin-client-redirects"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: docusaurus
- dependency-name: "@docusaurus/plugin-content-docs"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: docusaurus
- dependency-name: "@docusaurus/preset-classic"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: docusaurus
- dependency-name: "@docusaurus/theme-common"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: docusaurus
- dependency-name: "@docusaurus/theme-mermaid"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: docusaurus
- dependency-name: "@docusaurus/module-type-aliases"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: docusaurus
- dependency-name: "@docusaurus/tsconfig"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: docusaurus
- dependency-name: "@docusaurus/types"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: docusaurus
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [msgraph-sdk](https://github.com/microsoftgraph/msgraph-sdk-python) from 1.11.0 to 1.12.0.
- [Release notes](https://github.com/microsoftgraph/msgraph-sdk-python/releases)
- [Changelog](https://github.com/microsoftgraph/msgraph-sdk-python/blob/main/CHANGELOG.md)
- [Commits](microsoftgraph/msgraph-sdk-python@v1.11.0...v1.12.0)

---
updated-dependencies:
- dependency-name: msgraph-sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.7.2 to 0.7.3.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](astral-sh/ruff@0.7.2...0.7.3)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [packaging](https://github.com/pypa/packaging) from 24.1 to 24.2.
- [Release notes](https://github.com/pypa/packaging/releases)
- [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst)
- [Commits](pypa/packaging@24.1...24.2)

---
updated-dependencies:
- dependency-name: packaging
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
* initial turnstile frame

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

* add interactive flag

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

* add interactive support for all

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

* fix missing migration

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

* don't hide in identification stage if interactive

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

* fixup

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

* require less hacky css

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

* update docs

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* add password policy to default password change flow

This change complies with the minimal compositional requirements by
NIST SP 800-63 Digital Identity Guidelines. See
https://pages.nist.gov/800-63-4/sp800-63b.html#password

More work is needed to comply with other parts of the Guidelines,
specifically

> If the chosen password is found on the blocklist, the CSP or verifier
> [...] SHALL provide the reason for rejection.

and

> Verifiers SHALL offer guidance to the subscriber to assist the user in
> choosing a strong password. This is particularly important following
> the rejection of a password on the blocklist as it discourages trivial
> modification of listed weak passwords.

* add docs for default Password policy

* remove HIBP from default Password policy

* add zxcvbn to default Password policy

* add fallback password error message to password policy, fix validation policy

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

* reword docs

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>

* add HIBP caveat

Co-authored-by: Jens L. <jens@goauthentik.io>
Signed-off-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>

* separate policy into separate blueprint

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

* use password policy for oobe flow

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

* kiss

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
Bumps [postcss](https://github.com/postcss/postcss) from 8.4.48 to 8.4.49.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](postcss/postcss@8.4.48...8.4.49)

---
updated-dependencies:
- dependency-name: postcss
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
* core: add prompt_data to auth flow (#11702)

I added the prompt_data and user_path to the auth flow. This allows us to more easily sync users details whenever they're logged in through a Source by using the Write stage, identical to an  Enrolment flow.

This makes sure that mappings etc are automatically taken into consideration, and are passed to the Authentication flow.

While I was at it, I made the code consistent with the `handle_enroll` method.

Signed-off-by: Wouter van Os <wouter0100@gmail.com>

* updates

* and remove errant .py file that somwhow snuck into the PR! also removed errant api ref files remove old images

* tweak to bumb build

* tweaks

* more tweaks

* removed extraneous old settings

* Update website/integrations/services/vmware-vcenter/index.md

Co-authored-by: Jens L. <jens@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/integrations/services/vmware-vcenter/index.md

Co-authored-by: Jens L. <jens@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/integrations/services/vmware-vcenter/index.md

Co-authored-by: Jens L. <jens@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/integrations/services/vmware-vcenter/index.md

Co-authored-by: Jens L. <jens@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/integrations/services/vmware-vcenter/index.md

Co-authored-by: Jens L. <jens@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/integrations/services/vmware-vcenter/index.md

Co-authored-by: Jens L. <jens@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/integrations/services/vmware-vcenter/index.md

Co-authored-by: Jens L. <jens@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/integrations/services/vmware-vcenter/index.md

Co-authored-by: Jens L. <jens@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/integrations/services/vmware-vcenter/index.md

Co-authored-by: Jens L. <jens@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Update website/integrations/services/vmware-vcenter/index.md

Co-authored-by: Jens L. <jens@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* formatting

* tweak

* why not saved before argh

---------

Signed-off-by: Wouter van Os <wouter0100@gmail.com>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Wouter van Os <wouter0100@gmail.com>
Co-authored-by: Tana M Berry <tana@goauthentik.com>
Co-authored-by: Jens L. <jens@goauthentik.io>
* core: add ability to provide reason for impersonation

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* tenants api things

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* add missing implem

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* A tooltip needs a DOM object to determine the coordinates where it should render.  A solitary string is not enough; a  is needed here.

* web: user impersonation reason

To determine where to render the Tooltip content, the object associated with the Tooltip must be a DOM object with an HTML tag.  A naked string is not enough; a `<span>` will do nicely here.

Also, fixed a build failure: PFSize was not defined in RelatedUserList.

* add and fix tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* avoid migration change

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* small fixes

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

---------

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
Co-authored-by: Ken Sternberg <ken@goauthentik.io>
* sources/kerberos: use new python-kadmin implementation

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* skip spnego on macos

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

---------

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Copy link
Contributor Author

@kensternberg-authentik kensternberg-authentik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's legit. :-)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
@rissson
Copy link
Member

rissson commented Nov 13, 2024

Btw, this PR won't work with deploy_me until conflicts are resolved

* main: (55 commits)
  web: bump API Client version (#11997)
  sources/kerberos: use new python-kadmin implementation (#11932)
  core: add ability to provide reason for impersonation (#11951)
  website/integrations:  update vcenter integration docs (#11768)
  core, web: update translations (#11995)
  website: bump postcss from 8.4.48 to 8.4.49 in /website (#11996)
  web: bump API Client version (#11992)
  blueprints: add default Password policy (#11793)
  stages/captcha: Run interactive captcha in Frame (#11857)
  core, web: update translations (#11979)
  core: bump packaging from 24.1 to 24.2 (#11985)
  core: bump ruff from 0.7.2 to 0.7.3 (#11986)
  core: bump msgraph-sdk from 1.11.0 to 1.12.0 (#11987)
  website: bump the docusaurus group in /website with 9 updates (#11988)
  website: bump postcss from 8.4.47 to 8.4.48 in /website (#11989)
  stages/password: use recovery flow from brand (#11953)
  core: bump golang.org/x/sync from 0.8.0 to 0.9.0 (#11962)
  web: bump cookie, swagger-client and express in /web (#11966)
  core, web: update translations (#11959)
  core: bump debugpy from 1.8.7 to 1.8.8 (#11961)
  ...
@kensternberg-authentik kensternberg-authentik requested a review from a team as a code owner November 13, 2024 23:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deploy_me Deploy the PR changes on a test environment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants