Compare commits

...

93 Commits

Author SHA1 Message Date
5b9bb12822 web: confirmation prompt updated to the latest version 2024-06-13 09:43:05 -07:00
8f09955d58 Merge branch 'main' into 5165-password-strength-indicator
* main: (2701 commits)
  website/developer-docs: add a baby Style Guide (#9900)
  website/integrations: gitlab: update certificate key pair location and specify sha (#9925)
  root: handle asgi exception (#10085)
  website: bump prettier from 3.3.1 to 3.3.2 in /website (#10082)
  web: bump prettier from 3.3.1 to 3.3.2 in /web (#10081)
  core: bump google-api-python-client from 2.132.0 to 2.133.0 (#10083)
  web: bump prettier from 3.3.1 to 3.3.2 in /tests/wdio (#10079)
  web: bump chromedriver from 125.0.3 to 126.0.0 in /tests/wdio (#10078)
  web: bump @sentry/browser from 8.8.0 to 8.9.1 in /web in the sentry group (#10080)
  web: bump braces from 3.0.2 to 3.0.3 in /web (#10077)
  website: bump braces from 3.0.2 to 3.0.3 in /website (#10076)
  web: bump braces from 3.0.2 to 3.0.3 in /tests/wdio (#10075)
  core: bump azure-identity from 1.16.0 to 1.16.1 (#10071)
  rbac: filters: fix missing attribute for unauthenticated requests (#10061)
  tests/e2e: docker-compose.yml: remove version element forgotten last time (#10067)
  providers/microsoft_entra: fix error when updating connection attributes (#10039)
  website/integrations: aws: fix about service link (#10062)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in it (#10060)
  core: bump github.com/redis/go-redis/v9 from 9.5.2 to 9.5.3 (#10046)
  core: bump github.com/gorilla/websocket from 1.5.1 to 1.5.2 (#10047)
  ...
2024-06-13 08:17:33 -07:00
8f82dac84e website/developer-docs: add a baby Style Guide (#9900)
* draft style guide

* broken links

* rename partial file

* added content to style guide, more links

* sidebar and link

* polish

* typo

* forgot to save

* kens formatting trick

* typo

* Jens' edits

* tweak

* simplify formatting for variables

* edits from 4d62

* fixed link

* more edits

* tweak re formatting command

* tweak re formatting command

---------

Co-authored-by: Tana M Berry <tana@goauthentik.com>
2024-06-13 09:10:59 -05:00
89c08f2588 website/integrations: gitlab: update certificate key pair location and specify sha (#9925)
* website/integrations: gitlab: update certificate key pair location and specify sha

Signed-off-by: 4d62 <ext@4d62.me>

* i prefer the previous wording

Signed-off-by: 4d62 <ext@4d62.me>

* suggest

Co-authored-by: Jens L. <jens@beryju.org>
Signed-off-by: 4d62 <ext@4d62.me>

* Update website/integrations/services/gitlab/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: 4d62 <ext@4d62.me>

* p

---------

Signed-off-by: 4d62 <ext@4d62.me>
Co-authored-by: Jens L. <jens@beryju.org>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2024-06-12 16:37:45 -05:00
113d6cc45f root: handle asgi exception (#10085) 2024-06-12 16:56:18 +09:00
05cfbca5f2 website: bump prettier from 3.3.1 to 3.3.2 in /website (#10082)
Bumps [prettier](https://github.com/prettier/prettier) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.3.1...3.3.2)

---
updated-dependencies:
- dependency-name: prettier
  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>
2024-06-12 15:40:28 +09:00
385f9bcbac web: bump prettier from 3.3.1 to 3.3.2 in /web (#10081)
Bumps [prettier](https://github.com/prettier/prettier) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.3.1...3.3.2)

---
updated-dependencies:
- dependency-name: prettier
  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>
2024-06-12 15:40:07 +09:00
86bc5b4cdb core: bump google-api-python-client from 2.132.0 to 2.133.0 (#10083)
Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.132.0 to 2.133.0.
- [Release notes](https://github.com/googleapis/google-api-python-client/releases)
- [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.132.0...v2.133.0)

---
updated-dependencies:
- dependency-name: google-api-python-client
  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>
2024-06-12 15:39:44 +09:00
8d5d9f35ef web: bump prettier from 3.3.1 to 3.3.2 in /tests/wdio (#10079)
Bumps [prettier](https://github.com/prettier/prettier) from 3.3.1 to 3.3.2.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.3.1...3.3.2)

---
updated-dependencies:
- dependency-name: prettier
  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>
2024-06-12 13:33:25 +09:00
439169d5e7 web: bump chromedriver from 125.0.3 to 126.0.0 in /tests/wdio (#10078)
Bumps [chromedriver](https://github.com/giggio/node-chromedriver) from 125.0.3 to 126.0.0.
- [Commits](https://github.com/giggio/node-chromedriver/compare/125.0.3...126.0.0)

---
updated-dependencies:
- dependency-name: chromedriver
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-12 13:33:15 +09:00
e405b33f9f web: bump @sentry/browser from 8.8.0 to 8.9.1 in /web in the sentry group (#10080)
web: bump @sentry/browser in /web in the sentry group

Bumps the sentry group in /web with 1 update: [@sentry/browser](https://github.com/getsentry/sentry-javascript).


Updates `@sentry/browser` from 8.8.0 to 8.9.1
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/8.8.0...8.9.1)

---
updated-dependencies:
- dependency-name: "@sentry/browser"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: sentry
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-12 13:33:00 +09:00
a9c13d4d10 web: bump braces from 3.0.2 to 3.0.3 in /web (#10077)
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-12 13:30:03 +09:00
12b16b17a2 website: bump braces from 3.0.2 to 3.0.3 in /website (#10076)
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-12 13:29:46 +09:00
3473abee32 web: bump braces from 3.0.2 to 3.0.3 in /tests/wdio (#10075)
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-12 13:29:35 +09:00
b5a0b3a521 core: bump azure-identity from 1.16.0 to 1.16.1 (#10071)
Bumps [azure-identity](https://github.com/Azure/azure-sdk-for-python) from 1.16.0 to 1.16.1.
- [Release notes](https://github.com/Azure/azure-sdk-for-python/releases)
- [Changelog](https://github.com/Azure/azure-sdk-for-python/blob/main/doc/esrp_release.md)
- [Commits](https://github.com/Azure/azure-sdk-for-python/compare/azure-identity_1.16.0...azure-identity_1.16.1)

---
updated-dependencies:
- dependency-name: azure-identity
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-12 12:54:59 +09:00
837a0325ca rbac: filters: fix missing attribute for unauthenticated requests (#10061) 2024-06-11 14:36:09 +00:00
b1050e8825 tests/e2e: docker-compose.yml: remove version element forgotten last time (#10067) 2024-06-11 16:16:24 +02:00
7bb90b1661 providers/microsoft_entra: fix error when updating connection attributes (#10039)
* providers/microsoft_entra: fix error when updating connection attributes

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

* include URL to field references

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

* only set gws user password when creating by default

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

* merge instead of replace connection attributes

an update might not return all attributes so we don't want to fully replace the attributes

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-06-11 16:03:23 +09:00
8f755785ea website/integrations: aws: fix about service link (#10062)
Signed-off-by: 4d62 <ext@4d62.me>
2024-06-11 14:33:57 +09:00
adc0ec8ee4 translate: Updates for file locale/en/LC_MESSAGES/django.po in it (#10060)
Translate locale/en/LC_MESSAGES/django.po in it

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'it'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-10 13:31:22 +00:00
9379b3d178 core: bump github.com/redis/go-redis/v9 from 9.5.2 to 9.5.3 (#10046)
Bumps [github.com/redis/go-redis/v9](https://github.com/redis/go-redis) from 9.5.2 to 9.5.3.
- [Release notes](https://github.com/redis/go-redis/releases)
- [Changelog](https://github.com/redis/go-redis/blob/master/CHANGELOG.md)
- [Commits](https://github.com/redis/go-redis/compare/v9.5.2...v9.5.3)

---
updated-dependencies:
- dependency-name: github.com/redis/go-redis/v9
  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>
2024-06-10 20:32:11 +09:00
18eef8ae05 core: bump github.com/gorilla/websocket from 1.5.1 to 1.5.2 (#10047)
Bumps [github.com/gorilla/websocket](https://github.com/gorilla/websocket) from 1.5.1 to 1.5.2.
- [Release notes](https://github.com/gorilla/websocket/releases)
- [Commits](https://github.com/gorilla/websocket/compare/v1.5.1...v1.5.2)

---
updated-dependencies:
- dependency-name: github.com/gorilla/websocket
  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>
2024-06-10 20:31:55 +09:00
f0e22fd08b translate: Updates for file locale/en/LC_MESSAGES/django.po in ru (#10058)
Translate locale/en/LC_MESSAGES/django.po in ru

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'ru'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-10 20:31:18 +09:00
ce5297a6cd core: bump sentry-sdk from 2.5.0 to 2.5.1 (#10048)
Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 2.5.0 to 2.5.1.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-python/compare/2.5.0...2.5.1)

---
updated-dependencies:
- dependency-name: sentry-sdk
  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>
2024-06-10 20:30:54 +09:00
74c8df8782 core: bump django-cte from 1.3.2 to 1.3.3 (#10049)
Bumps [django-cte](https://github.com/dimagi/django-cte) from 1.3.2 to 1.3.3.
- [Changelog](https://github.com/dimagi/django-cte/blob/master/CHANGELOG.md)
- [Commits](https://github.com/dimagi/django-cte/commits)

---
updated-dependencies:
- dependency-name: django-cte
  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>
2024-06-10 20:30:36 +09:00
2d897fac48 core: bump packaging from 24.0 to 24.1 (#10050)
Bumps [packaging](https://github.com/pypa/packaging) from 24.0 to 24.1.
- [Release notes](https://github.com/pypa/packaging/releases)
- [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pypa/packaging/compare/24.0...24.1)

---
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>
2024-06-10 20:25:14 +09:00
2eb47c9efa web: bump yaml from 2.4.3 to 2.4.5 in /web (#10054)
Bumps [yaml](https://github.com/eemeli/yaml) from 2.4.3 to 2.4.5.
- [Release notes](https://github.com/eemeli/yaml/releases)
- [Commits](https://github.com/eemeli/yaml/compare/v2.4.3...v2.4.5)

---
updated-dependencies:
- dependency-name: yaml
  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>
2024-06-10 20:24:59 +09:00
9852041f38 web: bump @sentry/browser from 8.7.0 to 8.8.0 in /web in the sentry group (#10051)
web: bump @sentry/browser in /web in the sentry group

Bumps the sentry group in /web with 1 update: [@sentry/browser](https://github.com/getsentry/sentry-javascript).


Updates `@sentry/browser` from 8.7.0 to 8.8.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/8.7.0...8.8.0)

---
updated-dependencies:
- dependency-name: "@sentry/browser"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: sentry
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-10 20:24:28 +09:00
7f74936212 web: bump esbuild from 0.21.4 to 0.21.5 in /web (#10053)
Bumps [esbuild](https://github.com/evanw/esbuild) from 0.21.4 to 0.21.5.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.21.4...v0.21.5)

---
updated-dependencies:
- dependency-name: esbuild
  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>
2024-06-10 20:20:53 +09:00
4f40b1e27c crypto: update fingerprint at same time as certificate (#10036)
Previously the fingerprint was only set when initially adding a key, if it
changed for any reason (like a renewed certificate) then every execution of
`Get` would lead to a full update. The certificate itself got cached, but the
fingerprint remained stale for next time.

This increased the chance of a fatal race during the cache update.

closes #9907
2024-06-10 20:16:35 +09:00
041e407153 translate: Updates for file locale/en/LC_MESSAGES/django.po in ru (#10056)
* Translate locale/en/LC_MESSAGES/django.po in ru

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'ru'.

* Translate locale/en/LC_MESSAGES/django.po in ru

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'ru'.

---------

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-10 12:24:02 +02:00
31b891428e website/integrations: gitea: fix helm values (#10043) 2024-06-10 09:29:17 +00:00
4ab8247847 core, web: update translations (#10038)
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2024-06-10 11:23:00 +02:00
af24edf8c1 translate: Updates for file locale/en/LC_MESSAGES/django.po in ru (#10040)
* Translate locale/en/LC_MESSAGES/django.po in ru

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'ru'.

* Translate locale/en/LC_MESSAGES/django.po in ru

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'ru'.

---------

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-10 11:22:51 +02:00
f8bfd12e31 docs/troubleshooting: upgrade docker: erroneous command (#10044) 2024-06-10 11:06:41 +02:00
993fc4b77b core: bump tornado from 6.4 to 6.4.1 (#10014)
Bumps [tornado](https://github.com/tornadoweb/tornado) from 6.4 to 6.4.1.
- [Changelog](https://github.com/tornadoweb/tornado/blob/master/docs/releases.rst)
- [Commits](https://github.com/tornadoweb/tornado/compare/v6.4.0...v6.4.1)

---
updated-dependencies:
- dependency-name: tornado
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-08 21:45:10 +09:00
3ee2be09bf core: bump twilio from 9.1.0 to 9.1.1 (#10016)
Bumps [twilio](https://github.com/twilio/twilio-python) from 9.1.0 to 9.1.1.
- [Release notes](https://github.com/twilio/twilio-python/releases)
- [Changelog](https://github.com/twilio/twilio-python/blob/main/CHANGES.md)
- [Commits](https://github.com/twilio/twilio-python/compare/9.1.0...9.1.1)

---
updated-dependencies:
- dependency-name: twilio
  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>
2024-06-08 21:44:42 +09:00
b3e3948f44 core: bump sentry-sdk from 2.4.0 to 2.5.0 (#10017)
Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 2.4.0 to 2.5.0.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-python/compare/2.4.0...2.5.0)

---
updated-dependencies:
- dependency-name: sentry-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>
2024-06-08 21:44:31 +09:00
117a5cd88d core: bump kubernetes from 29.0.0 to 30.1.0 (#10018)
Bumps [kubernetes](https://github.com/kubernetes-client/python) from 29.0.0 to 30.1.0.
- [Release notes](https://github.com/kubernetes-client/python/releases)
- [Changelog](https://github.com/kubernetes-client/python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/kubernetes-client/python/compare/v29.0.0...v30.1.0)

---
updated-dependencies:
- dependency-name: kubernetes
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-08 21:44:05 +09:00
342a40212e translate: Updates for file locale/en/LC_MESSAGES/django.po in pl (#10029)
Translate locale/en/LC_MESSAGES/django.po in pl

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'pl'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-08 21:37:46 +09:00
15ae11d9d5 translate: Updates for file web/xliff/en.xlf in pl (#10030)
Translate web/xliff/en.xlf in pl

100% translated source file: 'web/xliff/en.xlf'
on 'pl'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-08 21:37:30 +09:00
e11df56f21 core, web: update translations (#10031)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2024-06-08 21:37:06 +09:00
3771af5282 translate: Updates for file web/xliff/en.xlf in zh_CN (#10032)
Translate web/xliff/en.xlf in zh_CN

100% translated source file: 'web/xliff/en.xlf'
on 'zh_CN'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-08 21:36:53 +09:00
0718053c56 translate: Updates for file web/xliff/en.xlf in zh-Hans (#10033)
Translate web/xliff/en.xlf in zh-Hans

100% translated source file: 'web/xliff/en.xlf'
on 'zh-Hans'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-08 21:36:40 +09:00
3e5014bfea web/admin: fix scim provider user list (#10028) 2024-06-07 19:48:11 +00:00
78f49ddc04 translate: Updates for file web/xliff/en.xlf in fr (#10024)
Translate web/xliff/en.xlf in fr

100% translated source file: 'web/xliff/en.xlf'
on 'fr'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-07 18:20:51 +02:00
744bc54231 stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs (#10025)
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>
2024-06-07 18:20:20 +02:00
44ba30ad75 translate: Updates for file locale/en/LC_MESSAGES/django.po in fr (#10022)
Translate locale/en/LC_MESSAGES/django.po in fr

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'fr'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-07 14:52:38 +02:00
63b991f137 core, web: update translations (#10015)
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2024-06-07 13:15:03 +02:00
7f9acb8a2b translate: Updates for file locale/en/LC_MESSAGES/django.po in pl (#10019)
* Translate locale/en/LC_MESSAGES/django.po in pl

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'pl'.

* Translate locale/en/LC_MESSAGES/django.po in pl

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'pl'.

---------

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-07 13:14:44 +02:00
ce3ba32044 translate: Updates for file locale/en/LC_MESSAGES/django.po in pl (#10011)
Translate locale/en/LC_MESSAGES/django.po in pl

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'pl'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-06 20:49:42 +09:00
25e6a69331 providers/sync: update attributes on update (#10012)
* unrelated

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

* providers/sync: update attributes in connection updates after updating remote object

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-06-06 20:49:33 +09:00
78d07cc355 website: bump prettier from 3.3.0 to 3.3.1 in /website (#10005)
Bumps [prettier](https://github.com/prettier/prettier) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.3.0...3.3.1)

---
updated-dependencies:
- dependency-name: prettier
  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>
2024-06-06 14:17:22 +09:00
3c4df47fe3 web: bump the babel group in /web with 7 updates (#10006)
Bumps the babel group in /web with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) | `7.24.6` | `7.24.7` |
| [@babel/plugin-proposal-decorators](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-proposal-decorators) | `7.24.6` | `7.24.7` |
| [@babel/plugin-transform-private-methods](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-private-methods) | `7.24.6` | `7.24.7` |
| [@babel/plugin-transform-private-property-in-object](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-private-property-in-object) | `7.24.6` | `7.24.7` |
| [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) | `7.24.6` | `7.24.7` |
| [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) | `7.24.6` | `7.24.7` |
| [@babel/preset-typescript](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-typescript) | `7.24.6` | `7.24.7` |


Updates `@babel/core` from 7.24.6 to 7.24.7
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.24.7/packages/babel-core)

Updates `@babel/plugin-proposal-decorators` from 7.24.6 to 7.24.7
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.24.7/packages/babel-plugin-proposal-decorators)

Updates `@babel/plugin-transform-private-methods` from 7.24.6 to 7.24.7
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.24.7/packages/babel-plugin-transform-private-methods)

Updates `@babel/plugin-transform-private-property-in-object` from 7.24.6 to 7.24.7
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.24.7/packages/babel-plugin-transform-private-property-in-object)

Updates `@babel/plugin-transform-runtime` from 7.24.6 to 7.24.7
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.24.7/packages/babel-plugin-transform-runtime)

Updates `@babel/preset-env` from 7.24.6 to 7.24.7
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.24.7/packages/babel-preset-env)

Updates `@babel/preset-typescript` from 7.24.6 to 7.24.7
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.24.7/packages/babel-preset-typescript)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: babel
- dependency-name: "@babel/plugin-proposal-decorators"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: babel
- dependency-name: "@babel/plugin-transform-private-methods"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: babel
- dependency-name: "@babel/plugin-transform-private-property-in-object"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: babel
- dependency-name: "@babel/plugin-transform-runtime"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: babel
- dependency-name: "@babel/preset-env"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: babel
- dependency-name: "@babel/preset-typescript"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: babel
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-06 14:17:13 +09:00
8ed1805cb8 web: bump prettier from 3.3.0 to 3.3.1 in /tests/wdio (#10003)
Bumps [prettier](https://github.com/prettier/prettier) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.3.0...3.3.1)

---
updated-dependencies:
- dependency-name: prettier
  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>
2024-06-06 14:17:02 +09:00
4d23db73ca web: bump the storybook group in /web with 7 updates (#10007)
Bumps the storybook group in /web with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [@storybook/addon-essentials](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/essentials) | `8.1.5` | `8.1.6` |
| [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/links) | `8.1.5` | `8.1.6` |
| [@storybook/blocks](https://github.com/storybookjs/storybook/tree/HEAD/code/ui/blocks) | `8.1.5` | `8.1.6` |
| [@storybook/manager-api](https://github.com/storybookjs/storybook/tree/HEAD/code/lib/manager-api) | `8.1.5` | `8.1.6` |
| [@storybook/web-components](https://github.com/storybookjs/storybook/tree/HEAD/code/renderers/web-components) | `8.1.5` | `8.1.6` |
| [@storybook/web-components-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/web-components-vite) | `8.1.5` | `8.1.6` |
| [storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/lib/cli) | `8.1.5` | `8.1.6` |


Updates `@storybook/addon-essentials` from 8.1.5 to 8.1.6
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.1.6/code/addons/essentials)

Updates `@storybook/addon-links` from 8.1.5 to 8.1.6
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.1.6/code/addons/links)

Updates `@storybook/blocks` from 8.1.5 to 8.1.6
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.1.6/code/ui/blocks)

Updates `@storybook/manager-api` from 8.1.5 to 8.1.6
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.1.6/code/lib/manager-api)

Updates `@storybook/web-components` from 8.1.5 to 8.1.6
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.1.6/code/renderers/web-components)

Updates `@storybook/web-components-vite` from 8.1.5 to 8.1.6
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.1.6/code/frameworks/web-components-vite)

Updates `storybook` from 8.1.5 to 8.1.6
- [Release notes](https://github.com/storybookjs/storybook/releases)
- [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md)
- [Commits](https://github.com/storybookjs/storybook/commits/v8.1.6/code/lib/cli)

---
updated-dependencies:
- dependency-name: "@storybook/addon-essentials"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/addon-links"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/blocks"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/manager-api"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/web-components"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/web-components-vite"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: storybook
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: storybook
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-06 14:16:52 +09:00
72783953fb web: bump @rollup/plugin-replace from 5.0.6 to 5.0.7 in /web in the rollup group (#10008)
web: bump @rollup/plugin-replace in /web in the rollup group

Bumps the rollup group in /web with 1 update: [@rollup/plugin-replace](https://github.com/rollup/plugins/tree/HEAD/packages/replace).


Updates `@rollup/plugin-replace` from 5.0.6 to 5.0.7
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/replace/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/replace-v5.0.7/packages/replace)

---
updated-dependencies:
- dependency-name: "@rollup/plugin-replace"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: rollup
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-06 14:16:42 +09:00
3b0fdb3dbd web: bump prettier from 3.3.0 to 3.3.1 in /web (#10009)
Bumps [prettier](https://github.com/prettier/prettier) from 3.3.0 to 3.3.1.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.3.0...3.3.1)

---
updated-dependencies:
- dependency-name: prettier
  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>
2024-06-06 14:16:32 +09:00
23161eed12 core: bump goauthentik.io/api/v3 from 3.2024042.10 to 3.2024042.11 (#10001)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2024042.10 to 3.2024042.11.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2024042.10...v3.2024042.11)

---
updated-dependencies:
- dependency-name: goauthentik.io/api/v3
  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>
2024-06-06 13:22:19 +09:00
8918427588 core: bump ruff from 0.4.7 to 0.4.8 (#10002)
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.4.7 to 0.4.8.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/v0.4.7...v0.4.8)

---
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>
2024-06-06 13:22:05 +09:00
5d858020f6 stages/email: fix sanitization of email addresses (#9999)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-06-06 13:20:26 +09:00
198e8b98a8 web: bump API Client version (#10000)
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>
2024-06-06 04:10:13 +00:00
88e9c9b669 providers/sync: improve v3 (#9966)
* make external id field externally visible

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

* catch up scim provider

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

* add missing views to scim provider

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

* make neither user nor group required for mapping testing

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

* improve SkipObject handling

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

* allow deletion of connection objects

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

* make entra logs less noisy

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

* make event_matcher less noisy

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-06-06 12:47:48 +09:00
0c652a210d core: groups api: always prefetch users (#9974)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2024-06-06 12:47:33 +09:00
105a90d2e7 core, web: update translations (#9998)
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2024-06-06 00:30:01 +00:00
68f5abe318 translate: Updates for file web/xliff/en.xlf in zh_CN (#9992)
Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-05 13:06:30 +02:00
59d4c18636 translate: Updates for file locale/en/LC_MESSAGES/django.po in zh_CN (#9991)
Translate locale/en/LC_MESSAGES/django.po in zh_CN

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'zh_CN'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-05 13:06:16 +02:00
b67e2a1144 translate: Updates for file web/xliff/en.xlf in zh-Hans (#9993)
Translate web/xliff/en.xlf in zh-Hans

100% translated source file: 'web/xliff/en.xlf'
on 'zh-Hans'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-05 13:06:09 +02:00
fc025651ce translate: Updates for file locale/en/LC_MESSAGES/django.po in zh-Hans (#9994)
Translate django.po in zh-Hans

100% translated source file: 'django.po'
on 'zh-Hans'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2024-06-05 13:06:01 +02:00
7cedc840b0 core: bump golang.org/x/oauth2 from 0.20.0 to 0.21.0 (#9986)
Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.20.0 to 0.21.0.
- [Commits](https://github.com/golang/oauth2/compare/v0.20.0...v0.21.0)

---
updated-dependencies:
- dependency-name: golang.org/x/oauth2
  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>
2024-06-05 14:13:18 +09:00
5ba731e48b core, web: update translations (#9979)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2024-06-05 14:09:09 +09:00
c792534a50 web: bump @lit/context from 1.1.1 to 1.1.2 in /web (#9981)
Bumps [@lit/context](https://github.com/lit/lit/tree/HEAD/packages/context) from 1.1.1 to 1.1.2.
- [Release notes](https://github.com/lit/lit/releases)
- [Changelog](https://github.com/lit/lit/blob/main/packages/context/CHANGELOG.md)
- [Commits](https://github.com/lit/lit/commits/@lit/context@1.1.2/packages/context)

---
updated-dependencies:
- dependency-name: "@lit/context"
  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>
2024-06-05 14:08:17 +09:00
a136fd8b54 core: bump sentry-sdk from 2.3.1 to 2.4.0 (#9985)
Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 2.3.1 to 2.4.0.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-python/compare/2.3.1...2.4.0)

---
updated-dependencies:
- dependency-name: sentry-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>
2024-06-05 14:07:41 +09:00
fb63c1f3e9 core: bump goauthentik.io/api/v3 from 3.2024042.9 to 3.2024042.10 (#9987)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2024042.9 to 3.2024042.10.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2024042.9...v3.2024042.10)

---
updated-dependencies:
- dependency-name: goauthentik.io/api/v3
  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>
2024-06-05 14:07:09 +09:00
0b15ab3f27 core: bump google-api-python-client from 2.131.0 to 2.132.0 (#9988)
Bumps [google-api-python-client](https://github.com/googleapis/google-api-python-client) from 2.131.0 to 2.132.0.
- [Release notes](https://github.com/googleapis/google-api-python-client/releases)
- [Commits](https://github.com/googleapis/google-api-python-client/compare/v2.131.0...v2.132.0)

---
updated-dependencies:
- dependency-name: google-api-python-client
  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>
2024-06-05 14:06:58 +09:00
f9fd67c2b8 core: bump pytest from 8.2.1 to 8.2.2 (#9989)
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.2.1 to 8.2.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.2.1...8.2.2)

---
updated-dependencies:
- dependency-name: pytest
  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>
2024-06-05 14:06:26 +09:00
4ac19f9d44 core: bump cryptography from 42.0.7 to 42.0.8 (#9990)
Bumps [cryptography](https://github.com/pyca/cryptography) from 42.0.7 to 42.0.8.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/42.0.7...42.0.8)

---
updated-dependencies:
- dependency-name: cryptography
  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>
2024-06-05 14:05:17 +09:00
74d3e92bac web: bump tslib from 2.6.2 to 2.6.3 in /web (#9984)
Bumps [tslib](https://github.com/Microsoft/tslib) from 2.6.2 to 2.6.3.
- [Release notes](https://github.com/Microsoft/tslib/releases)
- [Commits](https://github.com/Microsoft/tslib/compare/v2.6.2...v2.6.3)

---
updated-dependencies:
- dependency-name: tslib
  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>
2024-06-05 14:04:49 +09:00
207fa13405 web: bump country-flag-icons from 1.5.11 to 1.5.12 in /web (#9983)
Bumps [country-flag-icons](https://gitlab.com/catamphetamine/country-flag-icons) from 1.5.11 to 1.5.12.
- [Changelog](https://gitlab.com/catamphetamine/country-flag-icons/blob/master/CHANGELOG.md)
- [Commits](https://gitlab.com/catamphetamine/country-flag-icons/compare/v1.5.11...v1.5.12)

---
updated-dependencies:
- dependency-name: country-flag-icons
  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>
2024-06-05 13:32:49 +09:00
208e4a8bed web: bump @rollup/plugin-replace from 5.0.5 to 5.0.6 in /web in the rollup group (#9980)
web: bump @rollup/plugin-replace in /web in the rollup group

Bumps the rollup group in /web with 1 update: [@rollup/plugin-replace](https://github.com/rollup/plugins/tree/HEAD/packages/replace).


Updates `@rollup/plugin-replace` from 5.0.5 to 5.0.6
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/replace/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/replace-v5.0.6/packages/replace)

---
updated-dependencies:
- dependency-name: "@rollup/plugin-replace"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: rollup
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-05 13:32:31 +09:00
ee245ab390 web: bump lit from 3.1.3 to 3.1.4 in /web (#9982)
Bumps [lit](https://github.com/lit/lit/tree/HEAD/packages/lit) from 3.1.3 to 3.1.4.
- [Release notes](https://github.com/lit/lit/releases)
- [Changelog](https://github.com/lit/lit/blob/main/packages/lit/CHANGELOG.md)
- [Commits](https://github.com/lit/lit/commits/lit@3.1.4/packages/lit)

---
updated-dependencies:
- dependency-name: lit
  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>
2024-06-05 13:32:15 +09:00
60c8837082 web: bump API Client version (#9967)
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>
2024-06-04 18:31:21 +09:00
6cf418a37e stages/captcha: rework (#9959)
* stages/captcha: rework

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

* update form with continue option

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

* update docs, add notes for scores

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

* also only raise error from success if needed

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

* return full data

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2024-06-04 18:25:38 +09:00
254761e930 website/docs: fixed broken links to helm repo (#9960)
fixed broken links to helm repo

the links to the helm repos were broken, the changes in b93bc6bb8e changed the name of the files.

Signed-off-by: Kenneth Foster <42386206+kefoster951@users.noreply.github.com>
2024-06-04 18:04:15 +09:00
d85f8758fe core: bump pydantic from 2.7.2 to 2.7.3 (#9962)
Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.7.2 to 2.7.3.
- [Release notes](https://github.com/pydantic/pydantic/releases)
- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md)
- [Commits](https://github.com/pydantic/pydantic/compare/v2.7.2...v2.7.3)

---
updated-dependencies:
- dependency-name: pydantic
  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>
2024-06-04 15:50:17 +09:00
84bfb37b60 web: bump the wdio group in /tests/wdio with 4 updates (#9963)
Bumps the wdio group in /tests/wdio with 4 updates: [@wdio/cli](https://github.com/webdriverio/webdriverio/tree/HEAD/packages/wdio-cli), [@wdio/local-runner](https://github.com/webdriverio/webdriverio/tree/HEAD/packages/wdio-local-runner), [@wdio/mocha-framework](https://github.com/webdriverio/webdriverio/tree/HEAD/packages/wdio-mocha-framework) and [@wdio/spec-reporter](https://github.com/webdriverio/webdriverio/tree/HEAD/packages/wdio-spec-reporter).


Updates `@wdio/cli` from 8.38.1 to 8.38.2
- [Release notes](https://github.com/webdriverio/webdriverio/releases)
- [Changelog](https://github.com/webdriverio/webdriverio/blob/v8.38.2/CHANGELOG.md)
- [Commits](https://github.com/webdriverio/webdriverio/commits/v8.38.2/packages/wdio-cli)

Updates `@wdio/local-runner` from 8.38.0 to 8.38.2
- [Release notes](https://github.com/webdriverio/webdriverio/releases)
- [Changelog](https://github.com/webdriverio/webdriverio/blob/v8.38.2/CHANGELOG.md)
- [Commits](https://github.com/webdriverio/webdriverio/commits/v8.38.2/packages/wdio-local-runner)

Updates `@wdio/mocha-framework` from 8.38.0 to 8.38.2
- [Release notes](https://github.com/webdriverio/webdriverio/releases)
- [Changelog](https://github.com/webdriverio/webdriverio/blob/v8.38.2/CHANGELOG.md)
- [Commits](https://github.com/webdriverio/webdriverio/commits/v8.38.2/packages/wdio-mocha-framework)

Updates `@wdio/spec-reporter` from 8.38.0 to 8.38.2
- [Release notes](https://github.com/webdriverio/webdriverio/releases)
- [Changelog](https://github.com/webdriverio/webdriverio/blob/v8.38.2/CHANGELOG.md)
- [Commits](https://github.com/webdriverio/webdriverio/commits/v8.38.2/packages/wdio-spec-reporter)

---
updated-dependencies:
- dependency-name: "@wdio/cli"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: wdio
- dependency-name: "@wdio/local-runner"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: wdio
- dependency-name: "@wdio/mocha-framework"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: wdio
- dependency-name: "@wdio/spec-reporter"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: wdio
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-04 15:50:00 +09:00
465820b002 Merge branch 'main' into 5165-password-strength-indicator
* main: (160 commits)
  website: update hackathon with prize pool (#6170)
  web: bump @babel/plugin-transform-runtime from 7.22.6 to 7.22.7 in /web (#6166)
  web: bump @babel/core from 7.22.6 to 7.22.7 in /web (#6165)
  web: bump @babel/plugin-proposal-decorators from 7.22.6 to 7.22.7 in /web (#6167)
  web: bump @babel/preset-env from 7.22.6 to 7.22.7 in /web (#6168)
  website: bump prettier from 2.8.8 to 3.0.0 in /website (#6155)
  web: bump storybook from 7.0.25 to 7.0.26 in /web (#6162)
  core: bump goauthentik.io/api/v3 from 3.2023054.2 to 3.2023054.4 (#6154)
  core: bump golang.org/x/oauth2 from 0.9.0 to 0.10.0 (#6153)
  web: bump @storybook/addon-essentials from 7.0.25 to 7.0.26 in /web (#6158)
  ci: bump actions/setup-node from 3.6.0 to 3.7.0 (#6156)
  web: bump core-js from 3.31.0 to 3.31.1 in /web (#6160)
  web: bump @storybook/addon-links from 7.0.25 to 7.0.26 in /web (#6159)
  web: bump @storybook/web-components-vite from 7.0.25 to 7.0.26 in /web (#6163)
  web: bump lit from 2.7.5 to 2.7.6 in /web (#6161)
  core: bump lxml from 4.9.2 to 4.9.3 (#6151)
  web: bump @babel/core from 7.22.5 to 7.22.6 in /web (#6143)
  web: bump @babel/plugin-transform-runtime from 7.22.5 to 7.22.6 in /web (#6142)
  web: bump @babel/preset-env from 7.22.5 to 7.22.6 in /web (#6144)
  web: bump @babel/plugin-proposal-decorators from 7.22.5 to 7.22.6 in /web (#6141)
  ...
2023-07-06 08:05:05 -07:00
a75c9434d9 Merge branch 'main' into 5165-password-strength-indicator
* main: (23 commits)
  web: bump API Client version (#5935)
  sources/ldap: add support for cert based auth (#5850)
  ci: replace status with state for auto-deployment
  ci: don't write CI status to file
  ci: add workflow to automatically update next branch (#5921)
  providers/ldap: fix Outpost provider listing excluding backchannel providers (#5933)
  root: revert to use secret_key for JWT signing (#5934)
  sources/ldap: fix duplicate bind when authenticating user directly to… (#5927)
  web: bump core-js from 3.30.2 to 3.31.0 in /web (#5928)
  core: bump pytest from 7.3.1 to 7.3.2 (#5929)
  web: bump @rollup/plugin-commonjs from 25.0.0 to 25.0.1 in /web (#5931)
  web: bump @formatjs/intl-listformat from 7.3.0 to 7.4.0 in /web (#5932)
  core: bump github.com/go-ldap/ldap/v3 from 3.4.4 to 3.4.5 (#5930)
  website/integrations: Fix header in dokuwiki instructions (#5926)
  providers/oauth2: launch url: if URL parsing fails, return no launch URL (#5918)
  web: bump @babel/core from 7.22.1 to 7.22.5 in /web (#5909)
  web: bump @babel/plugin-proposal-decorators from 7.22.3 to 7.22.5 in /web (#5910)
  web: bump @babel/preset-typescript from 7.21.5 to 7.22.5 in /web (#5912)
  web: bump @babel/preset-env from 7.22.4 to 7.22.5 in /web (#5915)
  core: bump requests-mock from 1.10.0 to 1.11.0 (#5911)
  ...
2023-06-12 09:55:35 -07:00
4ea9b69ab5 web: fix out-of-date comment 2023-06-08 14:38:45 -07:00
c48eee0ebf web: add visualizing and testing for the FieldRenderers 2023-06-08 13:43:13 -07:00
0d94373f10 web: password quality indicators
Resolves issue 5165

This commit updates the password match indicator so that the user, and not
the component, makes decisions about the names of the initial and confirmation
inputs.
2023-06-08 11:25:13 -07:00
1c85dc512f Merge branch 'main' into 5165-password-strength-indicator
* main:
  providers/ldap: rework Schema and DSE (#5838)
  web/flows: update default flow background (#5905)
  web: bump @formatjs/intl-listformat from 7.2.2 to 7.3.0 in /web (#5866)
  website/integrations: add account linking note for WriteFreely (#5804)
  web: bump @storybook/addon-essentials from 7.0.18 to 7.0.20 in /web (#5894)
  web: bump @storybook/web-components-vite from 7.0.18 to 7.0.20 in /web (#5895)
  web: bump @storybook/blocks from 7.0.18 to 7.0.20 in /web (#5893)
  web: bump storybook from 7.0.18 to 7.0.20 in /web (#5896)
  website/docs: correct LDAP StartTLS documentation (#5886)
  core: bump python from 3.11.3-slim-bullseye to 3.11.4-slim-bullseye (#5891)
  ci: bump docker/setup-qemu-action from 2.1.0 to 2.2.0 (#5892)
  core: bump selenium from 4.9.1 to 4.10.0 (#5897)
  web: bump pyright from 1.1.312 to 1.1.313 in /web (#5898)
  web: bump @storybook/addon-links from 7.0.18 to 7.0.20 in /web (#5899)
  web: bump @storybook/web-components from 7.0.18 to 7.0.20 in /web (#5900)
  core: bump urllib3 from 2.0.2 to 2.0.3 (#5901)
  core: bump ruff from 0.0.271 to 0.0.272 (#5902)
  core: bump sentry-sdk from 1.25.0 to 1.25.1 (#5903)
2023-06-08 08:42:11 -07:00
a71778651f web: improve password experience
This commit disassembles PromptStage and places function that don't
need a reference to the PromptStage object into a collection of
maps between the Stage type and the prompt associated with it.  (In
a better world, this would be a great place to try some post-Midgard
mplementation of itemtype/itemid/itemprop).

This surfaced the nature of the relationship between Password and
Password (Repeat), allowing us to modify both to show password
strength and password matching for the "change password" dialog.
2023-06-08 08:35:23 -07:00
117 changed files with 11678 additions and 7023 deletions

View File

@ -58,7 +58,7 @@ from authentik.outposts.models import OutpostServiceConnection
from authentik.policies.models import Policy, PolicyBindingModel
from authentik.policies.reputation.models import Reputation
from authentik.providers.oauth2.models import AccessToken, AuthorizationCode, RefreshToken
from authentik.providers.scim.models import SCIMGroup, SCIMUser
from authentik.providers.scim.models import SCIMProviderGroup, SCIMProviderUser
from authentik.sources.scim.models import SCIMSourceGroup, SCIMSourceUser
from authentik.stages.authenticator_webauthn.models import WebAuthnDeviceType
from authentik.tenants.models import Tenant
@ -97,8 +97,8 @@ def excluded_models() -> list[type[Model]]:
# FIXME: these shouldn't need to be explicitly listed, but rather based off of a mixin
FlowToken,
LicenseUsage,
SCIMGroup,
SCIMUser,
SCIMProviderGroup,
SCIMProviderUser,
Tenant,
SystemTask,
ConnectionToken,

View File

@ -2,6 +2,7 @@
from json import loads
from django.db.models import Prefetch
from django.http import Http404
from django_filters.filters import CharFilter, ModelMultipleChoiceFilter
from django_filters.filterset import FilterSet
@ -166,8 +167,14 @@ class GroupViewSet(UsedByMixin, ModelViewSet):
def get_queryset(self):
base_qs = Group.objects.all().select_related("parent").prefetch_related("roles")
if self.serializer_class(context={"request": self.request})._should_include_users:
base_qs = base_qs.prefetch_related("users")
else:
base_qs = base_qs.prefetch_related(
Prefetch("users", queryset=User.objects.all().only("id"))
)
return base_qs
@extend_schema(

View File

@ -80,8 +80,10 @@ class PropertyMappingViewSet(
class PropertyMappingTestSerializer(PolicyTestSerializer):
"""Test property mapping execution for a user/group with context"""
user = PrimaryKeyRelatedField(queryset=User.objects.all(), required=False)
group = PrimaryKeyRelatedField(queryset=Group.objects.all(), required=False)
user = PrimaryKeyRelatedField(queryset=User.objects.all(), required=False, allow_null=True)
group = PrimaryKeyRelatedField(
queryset=Group.objects.all(), required=False, allow_null=True
)
queryset = PropertyMapping.objects.select_subclasses()
serializer_class = PropertyMappingSerializer

View File

@ -39,12 +39,12 @@ def get_delete_action(manager: Manager) -> str:
"""Get the delete action from the Foreign key, falls back to cascade"""
if hasattr(manager, "field"):
if manager.field.remote_field.on_delete.__name__ == SET_NULL.__name__:
return DeleteAction.SET_NULL.name
return DeleteAction.SET_NULL.value
if manager.field.remote_field.on_delete.__name__ == SET_DEFAULT.__name__:
return DeleteAction.SET_DEFAULT.name
return DeleteAction.SET_DEFAULT.value
if hasattr(manager, "source_field"):
return DeleteAction.CASCADE_MANY.name
return DeleteAction.CASCADE.name
return DeleteAction.CASCADE_MANY.value
return DeleteAction.CASCADE.value
class UsedByMixin:

View File

@ -241,7 +241,7 @@ class TestCrypto(APITestCase):
"model_name": "oauth2provider",
"pk": str(provider.pk),
"name": str(provider),
"action": DeleteAction.SET_NULL.name,
"action": DeleteAction.SET_NULL.value,
}
],
)

View File

@ -19,6 +19,7 @@ class GoogleWorkspaceProviderGroupSerializer(ModelSerializer):
model = GoogleWorkspaceProviderGroup
fields = [
"id",
"google_id",
"group",
"group_obj",
"provider",

View File

@ -19,6 +19,7 @@ class GoogleWorkspaceProviderUserSerializer(ModelSerializer):
model = GoogleWorkspaceProviderUser
fields = [
"id",
"google_id",
"user",
"user_obj",
"provider",

View File

@ -92,12 +92,14 @@ class GoogleWorkspaceGroupClient(
google_group = self.to_schema(group, connection)
self.check_email_valid(google_group["email"])
try:
return self._request(
response = self._request(
self.directory_service.groups().update(
groupKey=connection.google_id,
body=google_group,
)
)
connection.attributes = response
connection.save()
except NotFoundSyncException:
# Resource missing is handled by self.write, which will re-create the group
raise

View File

@ -88,9 +88,11 @@ class GoogleWorkspaceUserClient(GoogleWorkspaceSyncClient[User, GoogleWorkspaceP
self.check_email_valid(
google_user["primaryEmail"], *[x["address"] for x in google_user.get("emails", [])]
)
self._request(
response = self._request(
self.directory_service.users().update(userKey=connection.google_id, body=google_user)
)
connection.attributes = response
connection.save()
def discover(self):
"""Iterate through all users and connect them with authentik users if possible"""

View File

@ -19,6 +19,7 @@ class MicrosoftEntraProviderGroupSerializer(ModelSerializer):
model = MicrosoftEntraProviderGroup
fields = [
"id",
"microsoft_id",
"group",
"group_obj",
"provider",

View File

@ -19,6 +19,7 @@ class MicrosoftEntraProviderUserSerializer(ModelSerializer):
model = MicrosoftEntraProviderUser
fields = [
"id",
"microsoft_id",
"user",
"user_obj",
"provider",

View File

@ -23,6 +23,7 @@ from msgraph.graph_service_client import GraphServiceClient
from msgraph_core import GraphClientFactory
from authentik.enterprise.providers.microsoft_entra.models import MicrosoftEntraProvider
from authentik.events.utils import sanitize_item
from authentik.lib.sync.outgoing import HTTP_CONFLICT
from authentik.lib.sync.outgoing.base import BaseOutgoingSyncClient
from authentik.lib.sync.outgoing.exceptions import (
@ -106,4 +107,4 @@ class MicrosoftEntraSyncClient[TModel: Model, TConnection: Model, TSchema: dict]
we can't JSON serialize"""
raw_data = asdict(entity)
raw_data.pop("backing_store", None)
return raw_data
return sanitize_item(raw_data)

View File

@ -1,3 +1,4 @@
from deepmerge import always_merger
from django.db import transaction
from msgraph.generated.groups.groups_request_builder import GroupsRequestBuilder
from msgraph.generated.models.group import Group as MSGroup
@ -104,9 +105,12 @@ class MicrosoftEntraGroupClient(
microsoft_group = self.to_schema(group, connection)
microsoft_group.id = connection.microsoft_id
try:
return self._request(
response = self._request(
self.client.groups.by_group_id(connection.microsoft_id).patch(microsoft_group)
)
if response:
always_merger.merge(connection.attributes, self.entity_as_dict(response))
connection.save()
except NotFoundSyncException:
# Resource missing is handled by self.write, which will re-create the group
raise

View File

@ -1,3 +1,4 @@
from deepmerge import always_merger
from django.db import transaction
from msgraph.generated.models.user import User as MSUser
from msgraph.generated.users.users_request_builder import UsersRequestBuilder
@ -110,7 +111,12 @@ class MicrosoftEntraUserClient(MicrosoftEntraSyncClient[User, MicrosoftEntraProv
"""Update existing user"""
microsoft_user = self.to_schema(user, connection)
self.check_email_valid(microsoft_user.user_principal_name)
self._request(self.client.users.by_user_id(connection.microsoft_id).patch(microsoft_user))
response = self._request(
self.client.users.by_user_id(connection.microsoft_id).patch(microsoft_user)
)
if response:
always_merger.merge(connection.attributes, self.entity_as_dict(response))
connection.save()
def discover(self):
"""Iterate through all users and connect them with authentik users if possible"""

View File

@ -102,6 +102,8 @@ def get_logger_config():
"gunicorn": "INFO",
"requests_mock": "WARNING",
"hpack": "WARNING",
"httpx": "WARNING",
"azure": "WARNING",
}
for handler_name, level in handler_level_map.items():
base_config["loggers"][handler_name] = {

View File

@ -57,6 +57,8 @@ class PropertyMappingManager:
mapping.set_context(user, request, **kwargs)
try:
value = mapping.evaluate(mapping.model.expression)
except PropertyMappingExpressionException as exc:
raise exc from exc
except Exception as exc:
raise PropertyMappingExpressionException(exc, mapping.model) from exc
if value is None:

View File

@ -91,10 +91,9 @@ class BaseOutgoingSyncClient[
}
eval_kwargs.setdefault("user", None)
for value in self.mapper.iter_eval(**eval_kwargs):
try:
always_merger.merge(raw_final_object, value)
except SkipObjectException as exc:
raise exc from exc
always_merger.merge(raw_final_object, value)
except SkipObjectException as exc:
raise exc from exc
except PropertyMappingExpressionException as exc:
# Value error can be raised when assigning invalid data to an attribute
Event.new(
@ -104,7 +103,7 @@ class BaseOutgoingSyncClient[
).save()
raise StopSync(exc, obj, exc.mapping) from exc
if not raw_final_object:
raise StopSync(ValueError("No user mappings configured"), obj)
raise StopSync(ValueError("No mappings configured"), obj)
for key, value in defaults.items():
raw_final_object.setdefault(key, value)
return raw_final_object

View File

@ -14,6 +14,7 @@ from authentik.core.models import Group, User
from authentik.events.logs import LogEvent
from authentik.events.models import TaskStatus
from authentik.events.system_tasks import SystemTask
from authentik.events.utils import sanitize_item
from authentik.lib.sync.outgoing import PAGE_SIZE, PAGE_TIMEOUT
from authentik.lib.sync.outgoing.base import Direction
from authentik.lib.sync.outgoing.exceptions import (
@ -125,6 +126,7 @@ class SyncTasks:
try:
client.write(obj)
except SkipObjectException:
self.logger.debug("skipping object due to SkipObject", obj=obj)
continue
except BadRequestSyncException as exc:
self.logger.warning("failed to sync object", exc=exc, obj=obj)
@ -144,8 +146,8 @@ class SyncTasks:
)
),
log_level="warning",
logger="",
attributes={"arguments": exc.args[1:]},
logger=f"{provider._meta.verbose_name}@{object_type}",
attributes={"arguments": exc.args[1:], "obj": sanitize_item(obj)},
)
)
)
@ -167,7 +169,8 @@ class SyncTasks:
)
),
log_level="warning",
logger="",
logger=f"{provider._meta.verbose_name}@{object_type}",
attributes={"obj": sanitize_item(obj)},
)
)
)
@ -184,7 +187,8 @@ class SyncTasks:
)
),
log_level="warning",
logger="",
logger=f"{provider._meta.verbose_name}@{object_type}",
attributes={"obj": sanitize_item(obj)},
)
)
)

View File

@ -102,7 +102,7 @@ class EventMatcherPolicy(Policy):
result = checker(request, event)
if result is None:
continue
LOGGER.info(
LOGGER.debug(
"Event matcher check result",
checker=checker.__name__,
result=result,

View File

@ -0,0 +1,43 @@
"""SCIMProviderGroup API Views"""
from rest_framework import mixins
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.users import UserGroupSerializer
from authentik.providers.scim.models import SCIMProviderGroup
class SCIMProviderGroupSerializer(ModelSerializer):
"""SCIMProviderGroup Serializer"""
group_obj = UserGroupSerializer(source="group", read_only=True)
class Meta:
model = SCIMProviderGroup
fields = [
"id",
"scim_id",
"group",
"group_obj",
"provider",
]
class SCIMProviderGroupViewSet(
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
"""SCIMProviderGroup Viewset"""
queryset = SCIMProviderGroup.objects.all().select_related("group")
serializer_class = SCIMProviderGroupSerializer
filterset_fields = ["provider__id", "group__name", "group__group_uuid"]
search_fields = ["provider__name", "group__name"]
ordering = ["group__name"]

View File

@ -0,0 +1,43 @@
"""SCIMProviderUser API Views"""
from rest_framework import mixins
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import GenericViewSet
from authentik.core.api.groups import GroupMemberSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.providers.scim.models import SCIMProviderUser
class SCIMProviderUserSerializer(ModelSerializer):
"""SCIMProviderUser Serializer"""
user_obj = GroupMemberSerializer(source="user", read_only=True)
class Meta:
model = SCIMProviderUser
fields = [
"id",
"scim_id",
"user",
"user_obj",
"provider",
]
class SCIMProviderUserViewSet(
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
"""SCIMProviderUser Viewset"""
queryset = SCIMProviderUser.objects.all().select_related("user")
serializer_class = SCIMProviderUserSerializer
filterset_fields = ["provider__id", "user__username", "user__id"]
search_fields = ["provider__name", "user__username"]
ordering = ["user__username"]

View File

@ -19,13 +19,18 @@ from authentik.providers.scim.clients.exceptions import (
)
from authentik.providers.scim.clients.schema import SCIM_GROUP_SCHEMA, PatchRequest
from authentik.providers.scim.clients.schema import Group as SCIMGroupSchema
from authentik.providers.scim.models import SCIMGroup, SCIMMapping, SCIMProvider, SCIMUser
from authentik.providers.scim.models import (
SCIMMapping,
SCIMProvider,
SCIMProviderGroup,
SCIMProviderUser,
)
class SCIMGroupClient(SCIMClient[Group, SCIMGroup, SCIMGroupSchema]):
class SCIMGroupClient(SCIMClient[Group, SCIMProviderGroup, SCIMGroupSchema]):
"""SCIM client for groups"""
connection_type = SCIMGroup
connection_type = SCIMProviderGroup
connection_type_query = "group"
mapper: PropertyMappingManager
@ -37,7 +42,7 @@ class SCIMGroupClient(SCIMClient[Group, SCIMGroup, SCIMGroupSchema]):
["group", "provider", "connection"],
)
def to_schema(self, obj: Group, connection: SCIMGroup) -> SCIMGroupSchema:
def to_schema(self, obj: Group, connection: SCIMProviderGroup) -> SCIMGroupSchema:
"""Convert authentik user into SCIM"""
raw_scim_group = super().to_schema(
obj,
@ -52,7 +57,7 @@ class SCIMGroupClient(SCIMClient[Group, SCIMGroup, SCIMGroupSchema]):
scim_group.externalId = str(obj.pk)
users = list(obj.users.order_by("id").values_list("id", flat=True))
connections = SCIMUser.objects.filter(provider=self.provider, user__pk__in=users)
connections = SCIMProviderUser.objects.filter(provider=self.provider, user__pk__in=users)
members = []
for user in connections:
members.append(
@ -66,7 +71,7 @@ class SCIMGroupClient(SCIMClient[Group, SCIMGroup, SCIMGroupSchema]):
def delete(self, obj: Group):
"""Delete group"""
scim_group = SCIMGroup.objects.filter(provider=self.provider, group=obj).first()
scim_group = SCIMProviderGroup.objects.filter(provider=self.provider, group=obj).first()
if not scim_group:
self.logger.debug("Group does not exist in SCIM, skipping")
return None
@ -88,9 +93,11 @@ class SCIMGroupClient(SCIMClient[Group, SCIMGroup, SCIMGroupSchema]):
scim_id = response.get("id")
if not scim_id or scim_id == "":
raise StopSync("SCIM Response with missing or invalid `id`")
return SCIMGroup.objects.create(provider=self.provider, group=group, scim_id=scim_id)
return SCIMProviderGroup.objects.create(
provider=self.provider, group=group, scim_id=scim_id
)
def update(self, group: Group, connection: SCIMGroup):
def update(self, group: Group, connection: SCIMProviderGroup):
"""Update existing group"""
scim_group = self.to_schema(group, connection)
scim_group.id = connection.scim_id
@ -158,16 +165,16 @@ class SCIMGroupClient(SCIMClient[Group, SCIMGroup, SCIMGroupSchema]):
"""Add users in users_set to group"""
if len(users_set) < 1:
return
scim_group = SCIMGroup.objects.filter(provider=self.provider, group=group).first()
scim_group = SCIMProviderGroup.objects.filter(provider=self.provider, group=group).first()
if not scim_group:
self.logger.warning(
"could not sync group membership, group does not exist", group=group
)
return
user_ids = list(
SCIMUser.objects.filter(user__pk__in=users_set, provider=self.provider).values_list(
"scim_id", flat=True
)
SCIMProviderUser.objects.filter(
user__pk__in=users_set, provider=self.provider
).values_list("scim_id", flat=True)
)
if len(user_ids) < 1:
return
@ -184,16 +191,16 @@ class SCIMGroupClient(SCIMClient[Group, SCIMGroup, SCIMGroupSchema]):
"""Remove users in users_set from group"""
if len(users_set) < 1:
return
scim_group = SCIMGroup.objects.filter(provider=self.provider, group=group).first()
scim_group = SCIMProviderGroup.objects.filter(provider=self.provider, group=group).first()
if not scim_group:
self.logger.warning(
"could not sync group membership, group does not exist", group=group
)
return
user_ids = list(
SCIMUser.objects.filter(user__pk__in=users_set, provider=self.provider).values_list(
"scim_id", flat=True
)
SCIMProviderUser.objects.filter(
user__pk__in=users_set, provider=self.provider
).values_list("scim_id", flat=True)
)
if len(user_ids) < 1:
return

View File

@ -9,13 +9,13 @@ from authentik.policies.utils import delete_none_values
from authentik.providers.scim.clients.base import SCIMClient
from authentik.providers.scim.clients.schema import SCIM_USER_SCHEMA
from authentik.providers.scim.clients.schema import User as SCIMUserSchema
from authentik.providers.scim.models import SCIMMapping, SCIMProvider, SCIMUser
from authentik.providers.scim.models import SCIMMapping, SCIMProvider, SCIMProviderUser
class SCIMUserClient(SCIMClient[User, SCIMUser, SCIMUserSchema]):
class SCIMUserClient(SCIMClient[User, SCIMProviderUser, SCIMUserSchema]):
"""SCIM client for users"""
connection_type = SCIMUser
connection_type = SCIMProviderUser
connection_type_query = "user"
mapper: PropertyMappingManager
@ -27,7 +27,7 @@ class SCIMUserClient(SCIMClient[User, SCIMUser, SCIMUserSchema]):
["provider", "connection"],
)
def to_schema(self, obj: User, connection: SCIMUser) -> SCIMUserSchema:
def to_schema(self, obj: User, connection: SCIMProviderUser) -> SCIMUserSchema:
"""Convert authentik user into SCIM"""
raw_scim_user = super().to_schema(
obj,
@ -44,7 +44,7 @@ class SCIMUserClient(SCIMClient[User, SCIMUser, SCIMUserSchema]):
def delete(self, obj: User):
"""Delete user"""
scim_user = SCIMUser.objects.filter(provider=self.provider, user=obj).first()
scim_user = SCIMProviderUser.objects.filter(provider=self.provider, user=obj).first()
if not scim_user:
self.logger.debug("User does not exist in SCIM, skipping")
return None
@ -66,9 +66,9 @@ class SCIMUserClient(SCIMClient[User, SCIMUser, SCIMUserSchema]):
scim_id = response.get("id")
if not scim_id or scim_id == "":
raise StopSync("SCIM Response with missing or invalid `id`")
return SCIMUser.objects.create(provider=self.provider, user=user, scim_id=scim_id)
return SCIMProviderUser.objects.create(provider=self.provider, user=user, scim_id=scim_id)
def update(self, user: User, connection: SCIMUser):
def update(self, user: User, connection: SCIMProviderUser):
"""Update existing user"""
scim_user = self.to_schema(user, connection)
scim_user.id = connection.scim_id

View File

@ -0,0 +1,24 @@
# Generated by Django 5.0.6 on 2024-06-04 07:45
from django.conf import settings
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("authentik_core", "0035_alter_group_options_and_more"),
("authentik_providers_scim", "0007_scimgroup_scim_id_scimuser_scim_id_and_more"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.RenameModel(
old_name="SCIMGroup",
new_name="SCIMProviderGroup",
),
migrations.RenameModel(
old_name="SCIMUser",
new_name="SCIMProviderUser",
),
]

View File

@ -10,6 +10,7 @@ from django.utils.translation import gettext_lazy as _
from rest_framework.serializers import Serializer
from authentik.core.models import BackchannelProvider, Group, PropertyMapping, User, UserTypes
from authentik.lib.models import SerializerModel
from authentik.lib.sync.outgoing.base import BaseOutgoingSyncClient
from authentik.lib.sync.outgoing.models import OutgoingSyncProvider
@ -106,7 +107,7 @@ class SCIMMapping(PropertyMapping):
verbose_name_plural = _("SCIM Mappings")
class SCIMUser(models.Model):
class SCIMProviderUser(SerializerModel):
"""Mapping of a user and provider to a SCIM user ID"""
id = models.UUIDField(primary_key=True, editable=False, default=uuid4)
@ -114,14 +115,20 @@ class SCIMUser(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
provider = models.ForeignKey(SCIMProvider, on_delete=models.CASCADE)
@property
def serializer(self) -> type[Serializer]:
from authentik.providers.scim.api.users import SCIMProviderUserSerializer
return SCIMProviderUserSerializer
class Meta:
unique_together = (("scim_id", "user", "provider"),)
def __str__(self) -> str:
return f"SCIM User {self.user_id} to {self.provider_id}"
return f"SCIM Provider User {self.user_id} to {self.provider_id}"
class SCIMGroup(models.Model):
class SCIMProviderGroup(SerializerModel):
"""Mapping of a group and provider to a SCIM user ID"""
id = models.UUIDField(primary_key=True, editable=False, default=uuid4)
@ -129,8 +136,14 @@ class SCIMGroup(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
provider = models.ForeignKey(SCIMProvider, on_delete=models.CASCADE)
@property
def serializer(self) -> type[Serializer]:
from authentik.providers.scim.api.groups import SCIMProviderGroupSerializer
return SCIMProviderGroupSerializer
class Meta:
unique_together = (("scim_id", "group", "provider"),)
def __str__(self) -> str:
return f"SCIM Group {self.group_id} to {self.provider_id}"
return f"SCIM Provider Group {self.group_id} to {self.provider_id}"

View File

@ -1,9 +1,17 @@
"""API URLs"""
from authentik.providers.scim.api.groups import (
SCIMProviderGroupViewSet,
)
from authentik.providers.scim.api.property_mappings import SCIMMappingViewSet
from authentik.providers.scim.api.providers import SCIMProviderViewSet
from authentik.providers.scim.api.users import (
SCIMProviderUserViewSet,
)
api_urlpatterns = [
("providers/scim", SCIMProviderViewSet),
("providers/scim_users", SCIMProviderUserViewSet),
("providers/scim_groups", SCIMProviderGroupViewSet),
("propertymappings/scim", SCIMMappingViewSet),
]

View File

@ -25,7 +25,7 @@ class ObjectFilter(ObjectPermissionsFilter):
# Outposts (which are the only objects using internal service accounts)
# except requests to return an empty list when they have no objects
# assigned
if request.user.type == UserTypes.INTERNAL_SERVICE_ACCOUNT:
if getattr(request.user, "type", None) == UserTypes.INTERNAL_SERVICE_ACCOUNT:
return queryset
if not queryset.exists():
# User doesn't have direct permission to all objects

View File

@ -147,3 +147,11 @@ class TestAPIPerms(APITestCase):
},
)
self.assertEqual(res.status_code, 403)
def test_anonymous_user_denied(self):
"""Test anonymous user denied"""
res = self.client.get(reverse("authentik_api:invitation-list"))
self.assertEqual(res.status_code, 403)
res = self.client.get(reverse("authentik_api:user-detail", kwargs={"pk": self.user.pk}))
self.assertEqual(res.status_code, 403)

View File

@ -5,6 +5,7 @@ from hashlib import sha512
from time import perf_counter, time
from typing import Any
from channels.exceptions import DenyConnection
from django.conf import settings
from django.contrib.sessions.backends.base import UpdateError
from django.contrib.sessions.exceptions import SessionInterrupted
@ -271,7 +272,11 @@ class ChannelsLoggingMiddleware:
async def __call__(self, scope, receive, send):
self.log(scope)
return await self.inner(scope, receive, send)
try:
return await self.inner(scope, receive, send)
except Exception as exc:
LOGGER.warning("Exception in ASGI application", exc=exc)
raise DenyConnection() from None
def log(self, scope: dict, **kwargs):
"""Log request"""

View File

@ -161,19 +161,18 @@ class BaseLDAPSynchronizer:
dn=object_dn,
source=self._source,
):
try:
if isinstance(value, (bytes)):
self._logger.warning("property mapping returned bytes", mapping=mapping)
continue
object_field = mapping.object_field
if object_field.startswith("attributes."):
# Because returning a list might desired, we can't
# rely on flatten here. Instead, just save the result as-is
set_path_in_dict(properties, object_field, value)
else:
properties[object_field] = flatten(value)
except SkipObjectException as exc:
raise exc from exc
if isinstance(value, (bytes)):
self._logger.warning("property mapping returned bytes", mapping=mapping)
continue
object_field = mapping.object_field
if object_field.startswith("attributes."):
# Because returning a list might desired, we can't
# rely on flatten here. Instead, just save the result as-is
set_path_in_dict(properties, object_field, value)
else:
properties[object_field] = flatten(value)
except SkipObjectException as exc:
raise exc from exc
except PropertyMappingExpressionException as exc:
# Value error can be raised when assigning invalid data to an attribute
Event.new(

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,7 +12,15 @@ class CaptchaStageSerializer(StageSerializer):
class Meta:
model = CaptchaStage
fields = StageSerializer.Meta.fields + ["public_key", "private_key", "js_url", "api_url"]
fields = StageSerializer.Meta.fields + [
"public_key",
"private_key",
"js_url",
"api_url",
"score_min_threshold",
"score_max_threshold",
"error_on_invalid_score",
]
extra_kwargs = {"private_key": {"write_only": True}}

View File

@ -0,0 +1,31 @@
# Generated by Django 5.0.6 on 2024-06-03 15:18
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_stages_captcha", "0002_captchastage_api_url_captchastage_js_url_and_more"),
]
operations = [
migrations.AddField(
model_name="captchastage",
name="error_on_invalid_score",
field=models.BooleanField(
default=True,
help_text="When enabled and the received captcha score is outside of the given threshold, the stage will show an error message. When not enabled, the flow will continue, but the data from the captcha will be available in the context for policy decisions",
),
),
migrations.AddField(
model_name="captchastage",
name="score_max_threshold",
field=models.FloatField(default=1.0),
),
migrations.AddField(
model_name="captchastage",
name="score_min_threshold",
field=models.FloatField(default=0.5),
),
]

View File

@ -14,6 +14,18 @@ class CaptchaStage(Stage):
public_key = models.TextField(help_text=_("Public key, acquired your captcha Provider."))
private_key = models.TextField(help_text=_("Private key, acquired your captcha Provider."))
score_min_threshold = models.FloatField(default=0.5) # Default values for reCaptcha
score_max_threshold = models.FloatField(default=1.0) # Default values for reCaptcha
error_on_invalid_score = models.BooleanField(
default=True,
help_text=_(
"When enabled and the received captcha score is outside of the given threshold, "
"the stage will show an error message. When not enabled, the flow will continue, "
"but the data from the captcha will be available in the context for policy decisions"
),
)
js_url = models.TextField(default="https://www.recaptcha.net/recaptcha/api.js")
api_url = models.TextField(default="https://www.recaptcha.net/recaptcha/api/siteverify")

View File

@ -1,6 +1,7 @@
"""authentik captcha stage"""
from django.http.response import HttpResponse
from django.utils.translation import gettext_lazy as _
from requests import RequestException
from rest_framework.fields import CharField
from rest_framework.serializers import ValidationError
@ -16,6 +17,8 @@ from authentik.lib.utils.http import get_http_session
from authentik.root.middleware import ClientIPMiddleware
from authentik.stages.captcha.models import CaptchaStage
PLAN_CONTEXT_CAPTCHA = "captcha"
class CaptchaChallenge(WithUserInfoChallenge):
"""Site public key"""
@ -48,11 +51,24 @@ class CaptchaChallengeResponse(ChallengeResponse):
)
response.raise_for_status()
data = response.json()
if not data.get("success", False):
raise ValidationError(f"Failed to validate token: {data.get('error-codes', '')}")
except RequestException as exc:
raise ValidationError("Failed to validate token") from exc
return token
if stage.error_on_invalid_score:
if not data.get("success", False):
raise ValidationError(
_(
"Failed to validate token: {error}".format(
error=data.get("error-codes", _("Unknown error"))
)
)
)
if "score" in data:
score = float(data.get("score"))
if stage.score_max_threshold > -1 and score > stage.score_max_threshold:
raise ValidationError(_("Invalid captcha response"))
if stage.score_min_threshold > -1 and score < stage.score_min_threshold:
raise ValidationError(_("Invalid captcha response"))
except (RequestException, TypeError) as exc:
raise ValidationError(_("Failed to validate token")) from exc
return data
class CaptchaStageView(ChallengeStageView):
@ -69,5 +85,10 @@ class CaptchaStageView(ChallengeStageView):
}
)
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
def challenge_valid(self, response: CaptchaChallengeResponse) -> HttpResponse:
response = response.validated_data["token"]
self.executor.plan.context[PLAN_CONTEXT_CAPTCHA] = {
"response": response,
"stage": self.executor.current_stage,
}
return self.executor.stage_ok()

View File

@ -1,6 +1,7 @@
"""captcha tests"""
from django.urls import reverse
from requests_mock import Mocker
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
from authentik.flows.markers import StageMarker
@ -30,8 +31,89 @@ class TestCaptchaStage(FlowTestCase):
)
self.binding = FlowStageBinding.objects.create(target=self.flow, stage=self.stage, order=2)
def test_valid(self):
@Mocker()
def test_valid(self, mock: Mocker):
"""Test valid captcha"""
mock.post(
"https://www.recaptcha.net/recaptcha/api/siteverify",
json={
"success": True,
"score": 0.5,
},
)
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
{"token": "PASSED"},
)
self.assertEqual(response.status_code, 200)
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
@Mocker()
def test_invalid_score_high(self, mock: Mocker):
"""Test invalid captcha (score too high)"""
mock.post(
"https://www.recaptcha.net/recaptcha/api/siteverify",
json={
"success": True,
"score": 99,
},
)
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
{"token": "PASSED"},
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
component="ak-stage-captcha",
response_errors={"token": [{"string": "Invalid captcha response", "code": "invalid"}]},
)
@Mocker()
def test_invalid_score_low(self, mock: Mocker):
"""Test invalid captcha (score too low)"""
mock.post(
"https://www.recaptcha.net/recaptcha/api/siteverify",
json={
"success": True,
"score": -3,
},
)
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
response = self.client.post(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
{"token": "PASSED"},
)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
component="ak-stage-captcha",
response_errors={"token": [{"string": "Invalid captcha response", "code": "invalid"}]},
)
@Mocker()
def test_invalid_score_low_continue(self, mock: Mocker):
"""Test invalid captcha (score too low, but continue)"""
self.stage.error_on_invalid_score = False
self.stage.save()
mock.post(
"https://www.recaptcha.net/recaptcha/api/siteverify",
json={
"success": True,
"score": -3,
},
)
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
session = self.client.session
session[SESSION_KEY_PLAN] = plan

View File

@ -96,7 +96,7 @@ class TestEmailStageTemplates(FlowTestCase):
"""Test addresses are correctly parsed"""
message = TemplateEmailMessage(to=[("foo@bar.baz", "foo@bar.baz")])
[sanitize_address(addr, "utf-8") for addr in message.recipients()]
self.assertEqual(message.recipients(), ["foo@bar.baz"])
self.assertEqual(message.recipients(), ['"foo@bar.baz" <foo@bar.baz>'])
message = TemplateEmailMessage(to=[("some-name", "foo@bar.baz")])
[sanitize_address(addr, "utf-8") for addr in message.recipients()]
self.assertEqual(message.recipients(), ["some-name <foo@bar.baz>"])

View File

@ -5,6 +5,7 @@ from functools import lru_cache
from pathlib import Path
from django.core.mail import EmailMultiAlternatives
from django.core.mail.message import sanitize_address
from django.template.exceptions import TemplateDoesNotExist
from django.template.loader import render_to_string
from django.utils import translation
@ -31,10 +32,7 @@ class TemplateEmailMessage(EmailMultiAlternatives):
sanitized_to = []
# Ensure that all recipients are valid
for recipient_name, recipient_email in to:
if recipient_name == recipient_email:
sanitized_to.append(recipient_email)
else:
sanitized_to.append(f"{recipient_name} <{recipient_email}>")
sanitized_to.append(sanitize_address((recipient_name, recipient_email), "utf-8"))
super().__init__(to=sanitized_to, **kwargs)
if not template_name:
return

View File

@ -6164,6 +6164,19 @@
"type": "string",
"minLength": 1,
"title": "Api url"
},
"score_min_threshold": {
"type": "number",
"title": "Score min threshold"
},
"score_max_threshold": {
"type": "number",
"title": "Score max threshold"
},
"error_on_invalid_score": {
"type": "boolean",
"title": "Error on invalid score",
"description": "When enabled and the received captcha score is outside of the given threshold, the stage will show an error message. When not enabled, the flow will continue, but the data from the captcha will be available in the context for policy decisions"
}
},
"required": []

View File

@ -9,8 +9,9 @@ entries:
model: authentik_providers_google_workspace.googleworkspaceprovidermapping
attrs:
name: "authentik default Google Workspace Mapping: User"
# https://developers.google.com/admin-sdk/directory/reference/rest/v1/users#User
expression: |
# Field reference:
# https://developers.google.com/admin-sdk/directory/reference/rest/v1/users#User
# Google require givenName and familyName to be set
givenName, familyName = request.user.name, " "
formatted = request.user.name + " "
@ -20,23 +21,26 @@ entries:
if " " in request.user.name:
givenName, _, familyName = request.user.name.partition(" ")
formatted = request.user.name
return {
user = {
"name": {
"fullName": formatted,
"familyName": familyName.strip(),
"givenName": givenName.strip(),
"displayName": formatted,
},
"password": request.user.password,
"suspended": not request.user.is_active,
}
if not connection:
user["password"] = request.user.password
return user
- identifiers:
managed: goauthentik.io/providers/google_workspace/group
model: authentik_providers_google_workspace.googleworkspaceprovidermapping
attrs:
name: "authentik default Google Workspace Mapping: Group"
# https://developers.google.com/admin-sdk/directory/reference/rest/v1/groups#Group
expression: |
# Field reference:
# https://developers.google.com/admin-sdk/directory/reference/rest/v1/groups#Group
return {
"name": group.name,
}

View File

@ -9,8 +9,9 @@ entries:
model: authentik_providers_microsoft_entra.microsoftentraprovidermapping
attrs:
name: "authentik default Microsoft Entra Mapping: User"
# https://learn.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-1.0
expression: |
# Field reference: (note that keys have to converted to snake_case)
# https://learn.microsoft.com/en-us/graph/api/resources/user?view=graph-rest-1.0
from msgraph.generated.models.password_profile import PasswordProfile
user = {
@ -35,8 +36,9 @@ entries:
model: authentik_providers_microsoft_entra.microsoftentraprovidermapping
attrs:
name: "authentik default Microsoft Entra Mapping: Group"
# https://learn.microsoft.com/en-us/graph/api/group-post-groups?view=graph-rest-1.0&tabs=http#request-body
expression: |
# Field reference: (note that keys have to converted to snake_case)
# https://learn.microsoft.com/en-us/graph/api/group-post-groups?view=graph-rest-1.0&tabs=http#request-body
return {
"display_name": group.name,
"mail_enabled": False,

8
go.mod
View File

@ -16,21 +16,21 @@ require (
github.com/gorilla/mux v1.8.1
github.com/gorilla/securecookie v1.1.2
github.com/gorilla/sessions v1.2.2
github.com/gorilla/websocket v1.5.1
github.com/gorilla/websocket v1.5.2
github.com/jellydator/ttlcache/v3 v3.2.0
github.com/mitchellh/mapstructure v1.5.0
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484
github.com/pires/go-proxyproto v0.7.0
github.com/prometheus/client_golang v1.19.1
github.com/redis/go-redis/v9 v9.5.2
github.com/redis/go-redis/v9 v9.5.3
github.com/sethvargo/go-envconfig v1.0.3
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0
github.com/stretchr/testify v1.9.0
github.com/wwt/guac v1.3.2
goauthentik.io/api/v3 v3.2024042.9
goauthentik.io/api/v3 v3.2024042.11
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
golang.org/x/oauth2 v0.20.0
golang.org/x/oauth2 v0.21.0
golang.org/x/sync v0.7.0
gopkg.in/yaml.v2 v2.4.0
layeh.com/radius v0.0.0-20210819152912-ad72663a72ab

16
go.sum
View File

@ -176,8 +176,8 @@ github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/z
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/gorilla/websocket v1.5.2 h1:qoW6V1GT3aZxybsbC6oLnailWnB+qTMVwMreOso9XUw=
github.com/gorilla/websocket v1.5.2/go.mod h1:0n9H61RBAcf5/38py2MCYbxzPIY9rOkpvvMT24Rqs30=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
@ -242,8 +242,8 @@ github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSz
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/redis/go-redis/v9 v9.5.2 h1:L0L3fcSNReTRGyZ6AqAEN0K56wYeYAwapBIhkvh0f3E=
github.com/redis/go-redis/v9 v9.5.2/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/redis/go-redis/v9 v9.5.3 h1:fOAp1/uJG+ZtcITgZOfYFmTKPE7n4Vclj1wZFgRciUU=
github.com/redis/go-redis/v9 v9.5.3/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
@ -294,8 +294,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
goauthentik.io/api/v3 v3.2024042.9 h1:zj3nqmOEHNBsfANTv7Ec4yLZA755GKHU+WLz2t+nfaI=
goauthentik.io/api/v3 v3.2024042.9/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
goauthentik.io/api/v3 v3.2024042.11 h1:cGgUz1E8rlMphGvv04VI7i+MgT8eidZbxTpza5zd96I=
goauthentik.io/api/v3 v3.2024042.11/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@ -382,8 +382,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

View File

@ -38,7 +38,6 @@ func (cs *CryptoStore) AddKeypair(uuid string) error {
if err != nil {
return err
}
cs.fingerprints[uuid] = cs.getFingerprint(uuid)
return nil
}
@ -73,6 +72,7 @@ func (cs *CryptoStore) Fetch(uuid string) error {
return err
}
cs.certificates[uuid] = &x509cert
cs.fingerprints[uuid] = cfp
return nil
}

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-03 00:08+0000\n"
"POT-Creation-Date: 2024-06-05 00:07+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -2363,6 +2363,14 @@ msgstr ""
msgid "Private key, acquired your captcha Provider."
msgstr ""
#: authentik/stages/captcha/models.py
msgid ""
"When enabled and the received captcha score is outside of the given "
"threshold, the stage will show an error message. When not enabled, the flow "
"will continue, but the data from the captcha will be available in the "
"context for policy decisions"
msgstr ""
#: authentik/stages/captcha/models.py
msgid "Captcha Stage"
msgstr ""
@ -2371,6 +2379,23 @@ msgstr ""
msgid "Captcha Stages"
msgstr ""
#: authentik/stages/captcha/stage.py
msgid "Unknown error"
msgstr ""
#: authentik/stages/captcha/stage.py
#, python-brace-format
msgid "Failed to validate token: {error}"
msgstr ""
#: authentik/stages/captcha/stage.py
msgid "Invalid captcha response"
msgstr ""
#: authentik/stages/captcha/stage.py
msgid "Failed to validate token"
msgstr ""
#: authentik/stages/consent/models.py
msgid ""
"Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."

Binary file not shown.

View File

@ -19,7 +19,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-05-03 00:08+0000\n"
"POT-Creation-Date: 2024-06-05 00:07+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: Marc Schmitt, 2024\n"
"Language-Team: French (https://app.transifex.com/authentik/teams/119923/fr/)\n"
@ -106,12 +106,14 @@ msgid "Brands"
msgstr "Marques"
#: authentik/core/api/providers.py
msgid "SAML Provider from Metadata"
msgstr "Fournisseur SAML depuis métadonnées"
#: authentik/core/api/providers.py
msgid "Create a SAML Provider by importing its Metadata."
msgstr "Créer un fournisseur SAML en important ses métadonnées."
msgid ""
"When not set all providers are returned. When set to true, only backchannel "
"providers are returned. When set to false, backchannel providers are "
"excluded"
msgstr ""
"Si non défini, tous les fournisseurs sont retournés. Si vrai, seul les "
"fournisseurs backchannels sont retournés. Si faux, les fournisseurs "
"backchannels sont exclus"
#: authentik/core/api/users.py
msgid "No leading or trailing slashes allowed."
@ -466,6 +468,74 @@ msgstr "Entreprise est requis pour accéder à cette fonctionnalité."
msgid "Feature only accessible for internal users."
msgstr "Fonctionnalité accessible aux utilisateurs internes uniquement."
#: authentik/enterprise/providers/google_workspace/models.py
#: authentik/enterprise/providers/microsoft_entra/models.py
#: authentik/providers/scim/models.py authentik/sources/ldap/models.py
msgid "Property mappings used for group creation/updating."
msgstr ""
"Mappages de propriétés utilisés lors de la création et de la mise à jour des"
" groupes."
#: authentik/enterprise/providers/google_workspace/models.py
msgid "Google Workspace Provider"
msgstr "Fournisseur Google Workspace"
#: authentik/enterprise/providers/google_workspace/models.py
msgid "Google Workspace Providers"
msgstr "Fournisseurs Google Workspace"
#: authentik/enterprise/providers/google_workspace/models.py
msgid "Google Workspace Provider Mapping"
msgstr "Mappage de propriété Google Workspace"
#: authentik/enterprise/providers/google_workspace/models.py
msgid "Google Workspace Provider Mappings"
msgstr "Mappages de propriété Google Workspace"
#: authentik/enterprise/providers/google_workspace/models.py
msgid "Google Workspace Provider User"
msgstr "Utilisateur du fournisseur Google Workspace"
#: authentik/enterprise/providers/google_workspace/models.py
msgid "Google Workspace Provider Users"
msgstr "Utilisateurs du fournisseur Google Workspace"
#: authentik/enterprise/providers/google_workspace/models.py
msgid "Google Workspace Provider Group"
msgstr "Groupe du fournisseur Google Workspace"
#: authentik/enterprise/providers/google_workspace/models.py
msgid "Google Workspace Provider Groups"
msgstr "Groupes du fournisseur Google Workspace"
#: authentik/enterprise/providers/microsoft_entra/models.py
msgid "Microsoft Entra Provider"
msgstr "Fournisseur Microsoft Entra"
#: authentik/enterprise/providers/microsoft_entra/models.py
msgid "Microsoft Entra Providers"
msgstr "Fournisseurs Microsoft Entra"
#: authentik/enterprise/providers/microsoft_entra/models.py
msgid "Microsoft Entra Provider Mapping"
msgstr "Mappage de propriété Microsoft Entra"
#: authentik/enterprise/providers/microsoft_entra/models.py
msgid "Microsoft Entra Provider Mappings"
msgstr "Mappages de propriété Microsoft Entra"
#: authentik/enterprise/providers/microsoft_entra/models.py
msgid "Microsoft Entra Provider User"
msgstr "Utilisateur du fournisseur Microsoft Entra"
#: authentik/enterprise/providers/microsoft_entra/models.py
msgid "Microsoft Entra Provider Group"
msgstr "Groupe du fournisseur Microsoft Entra"
#: authentik/enterprise/providers/microsoft_entra/models.py
msgid "Microsoft Entra Provider Groups"
msgstr "Groupes du fournisseur Microsoft Entra"
#: authentik/enterprise/providers/rac/models.py
#: authentik/stages/user_login/models.py
msgid ""
@ -838,6 +908,25 @@ msgstr "Jetons du flux"
msgid "Invalid next URL"
msgstr "URL suivante invalide"
#: authentik/lib/sync/outgoing/tasks.py
msgid "Starting full provider sync"
msgstr "Démarrage d'une synchronisation complète du fournisseur"
#: authentik/lib/sync/outgoing/tasks.py
#, python-format
msgid "Syncing page %(page)d of users"
msgstr "Synchronisation de la page %(page)d d'utilisateurs"
#: authentik/lib/sync/outgoing/tasks.py
#, python-format
msgid "Syncing page %(page)d of groups"
msgstr "Synchronisation de la page %(page)d de groupes"
#: authentik/lib/sync/outgoing/tasks.py
#, python-brace-format
msgid "Stopping sync due to error: {error}"
msgstr "Arrêt de la synchronisation due à l'erreur : {error}"
#: authentik/lib/utils/time.py
#, python-format
msgid "%(value)s is not in the correct format of 'hours=3;minutes=1'."
@ -1526,10 +1615,6 @@ msgstr "Compatibilité GitHub : accès aux adresses email"
msgid "GitHub Compatibility: Access your Groups"
msgstr "Compatibilité GitHub : accès aux groupes"
#: authentik/providers/oauth2/views/userinfo.py
msgid "authentik API Access on behalf of your user"
msgstr "Accès à l'API authentik au nom des utilisateurs"
#: authentik/providers/proxy/api.py
msgid "User and password attributes must be set when basic auth is enabled."
msgstr ""
@ -1811,6 +1896,14 @@ msgstr "Mappages de propriétés SAML"
msgid "SAML Property Mappings"
msgstr "Mappages de propriétés SAML"
#: authentik/providers/saml/models.py
msgid "SAML Provider from Metadata"
msgstr "Fournisseur SAML depuis métadonnées"
#: authentik/providers/saml/models.py
msgid "SAML Providers from Metadata"
msgstr "Fournisseurs SAML depuis métadonnées"
#: authentik/providers/scim/models.py
msgid "Base URL to SCIM requests, usually ends in /v2"
msgstr "URL de base pour les requêtes SCIM, se terminant généralement par /v2"
@ -1819,12 +1912,6 @@ msgstr "URL de base pour les requêtes SCIM, se terminant généralement par /v2
msgid "Authentication token"
msgstr "Jeton d'authentification"
#: authentik/providers/scim/models.py authentik/sources/ldap/models.py
msgid "Property mappings used for group creation/updating."
msgstr ""
"Mappages de propriétés utilisés lors de la création et de la mise à jour des"
" groupes."
#: authentik/providers/scim/models.py
msgid "SCIM Provider"
msgstr "Fournisseur SCIM"
@ -1841,39 +1928,6 @@ msgstr "Mappage SCIM"
msgid "SCIM Mappings"
msgstr "Mappages SCIM"
#: authentik/providers/scim/tasks.py
msgid "Starting full SCIM sync"
msgstr "Démarrage d'une synchronisation SCIM complète"
#: authentik/providers/scim/tasks.py
#, python-format
msgid "Syncing page %(page)d of users"
msgstr "Synchronisation de la page %(page)d d'utilisateurs"
#: authentik/providers/scim/tasks.py
#, python-format
msgid "Syncing page %(page)d of groups"
msgstr "Synchronisation de la page %(page)d de groupes"
#: authentik/providers/scim/tasks.py
#, python-brace-format
msgid "Failed to sync user {user_name} due to remote error: {error}"
msgstr ""
"Échec de synchronisation de l'utilisateur {user_name} dû à une erreur "
"distante : {error}"
#: authentik/providers/scim/tasks.py
#, python-brace-format
msgid "Stopping sync due to error: {error}"
msgstr "Arrêt de la synchronisation due à l'erreur : {error}"
#: authentik/providers/scim/tasks.py
#, python-brace-format
msgid "Failed to sync group {group_name} due to remote error: {error}"
msgstr ""
"Échec de synchronisation du groupe {group_name} dû à une erreur distante : "
"{error}"
#: authentik/rbac/models.py
msgid "Role"
msgstr "Rôle"
@ -1894,14 +1948,6 @@ msgstr "Permissions système"
msgid "Can view system info"
msgstr "Peut voir les informations du système"
#: authentik/rbac/models.py
msgid "Can view system tasks"
msgstr "Peut voir les tâches du système"
#: authentik/rbac/models.py
msgid "Can run system tasks"
msgstr "Peut lancer des tâches système"
#: authentik/rbac/models.py
msgid "Can access admin interface"
msgstr "Peut accéder à l'interface d'administration"
@ -2562,6 +2608,18 @@ msgstr "Clé publique, acquise auprès de votre fournisseur captcha."
msgid "Private key, acquired your captcha Provider."
msgstr "Clé privée, acquise auprès de votre fournisseur captcha."
#: authentik/stages/captcha/models.py
msgid ""
"When enabled and the received captcha score is outside of the given "
"threshold, the stage will show an error message. When not enabled, the flow "
"will continue, but the data from the captcha will be available in the "
"context for policy decisions"
msgstr ""
"Si activé et le score captcha reçu est hors de la limite donnée, l'étape "
"affichera un message d'erreur. Si désactivé, le flux continuera, mais la "
"donnée du captcha sera disponible dans le contexte pour décision dans une "
"politique."
#: authentik/stages/captcha/models.py
msgid "Captcha Stage"
msgstr "Étape de Captcha"
@ -2570,6 +2628,23 @@ msgstr "Étape de Captcha"
msgid "Captcha Stages"
msgstr "Étapes de Captcha"
#: authentik/stages/captcha/stage.py
msgid "Unknown error"
msgstr "Erreur inconnue"
#: authentik/stages/captcha/stage.py
#, python-brace-format
msgid "Failed to validate token: {error}"
msgstr "Échec de validation du jeton : {error}"
#: authentik/stages/captcha/stage.py
msgid "Invalid captcha response"
msgstr "Réponse captcha invalide"
#: authentik/stages/captcha/stage.py
msgid "Failed to validate token"
msgstr "Échec de validation du jeton"
#: authentik/stages/consent/models.py
msgid ""
"Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -9,16 +9,16 @@
# Nicholas Winterhalter, 2023
# Ренат Шарафутдинов, 2023
# Stepan Karavaev, 2024
# Anton Babenko, 2024
# Anton, 2024
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-03 00:08+0000\n"
"POT-Creation-Date: 2024-06-05 00:07+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: Anton Babenko, 2024\n"
"Last-Translator: Anton, 2024\n"
"Language-Team: Russian (https://app.transifex.com/authentik/teams/119923/ru/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -162,7 +162,7 @@ msgstr "Сбросить пароль"
#: authentik/core/models.py
msgid "Can impersonate other users"
msgstr "Может выдавать себя за других пользователей"
msgstr "Может имитировать других пользователей"
#: authentik/core/models.py authentik/rbac/models.py
msgid "Can assign permissions to users"
@ -2589,6 +2589,18 @@ msgstr "Открытый ключ, полученный от вашего про
msgid "Private key, acquired your captcha Provider."
msgstr "Закрытый ключ, полученный от вашего провайдера капчи."
#: authentik/stages/captcha/models.py
msgid ""
"When enabled and the received captcha score is outside of the given "
"threshold, the stage will show an error message. When not enabled, the flow "
"will continue, but the data from the captcha will be available in the "
"context for policy decisions"
msgstr ""
"Когда эта опция включена, и полученная оценка капчи находится за пределами "
"заданного порогового значения, на этом этапе будет показано сообщение об "
"ошибке. Когда эта опция не включена, поток будет продолжаться, но данные "
"капчи будут доступны в контексте для принятия решений политики"
#: authentik/stages/captcha/models.py
msgid "Captcha Stage"
msgstr "Этап с каптчей"
@ -2597,6 +2609,23 @@ msgstr "Этап с каптчей"
msgid "Captcha Stages"
msgstr "Этапы с каптчей"
#: authentik/stages/captcha/stage.py
msgid "Unknown error"
msgstr "Неизвестная ошибка"
#: authentik/stages/captcha/stage.py
#, python-brace-format
msgid "Failed to validate token: {error}"
msgstr "Ошибка валидации токена: {error}"
#: authentik/stages/captcha/stage.py
msgid "Invalid captcha response"
msgstr "Неверный ответ на капчу"
#: authentik/stages/captcha/stage.py
msgid "Failed to validate token"
msgstr "Ошибка валидации токена"
#: authentik/stages/consent/models.py
msgid ""
"Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
@ -3054,7 +3083,7 @@ msgstr "Разделитель: Статическая разделительн
#: authentik/stages/prompt/models.py
msgid "Hidden: Hidden field, can be used to insert data into form."
msgstr ""
"Скрытый: Скрытое поле, может быть использовано для вставки данных в форму."
"Скрыто: Скрытое поле, может быть использовано для вставки данных в форму."
#: authentik/stages/prompt/models.py
msgid "Static: Static value, displayed as-is."
@ -3086,7 +3115,7 @@ msgid ""
msgstr ""
"По желанию предварительно заполните поле ввода начальным значением. При "
"создании поля с фиксированным выбором включите интерпретацию как выражение и"
" возврат списка, чтобы вернуть несколько вариантов по умолчанию."
" возвращайте список, чтобы вернуть несколько вариантов по умолчанию."
#: authentik/stages/prompt/models.py
msgid "Prompt"

View File

@ -7,17 +7,17 @@
# Chen Zhikai, 2022
# 刘松, 2022
# Jens L. <jens@goauthentik.io>, 2024
# deluxghost, 2024
# Tianhao Chai <cth451@gmail.com>, 2024
# deluxghost, 2024
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-03 00:08+0000\n"
"POT-Creation-Date: 2024-06-05 00:07+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: Tianhao Chai <cth451@gmail.com>, 2024\n"
"Last-Translator: deluxghost, 2024\n"
"Language-Team: Chinese Simplified (https://app.transifex.com/authentik/teams/119923/zh-Hans/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -2401,6 +2401,14 @@ msgstr "公钥,从您的验证码提供商处取得。"
msgid "Private key, acquired your captcha Provider."
msgstr "私钥,从您的验证码提供商处取得。"
#: authentik/stages/captcha/models.py
msgid ""
"When enabled and the received captcha score is outside of the given "
"threshold, the stage will show an error message. When not enabled, the flow "
"will continue, but the data from the captcha will be available in the "
"context for policy decisions"
msgstr "启用时,如果接收到的验证码分数超出给定的阈值,此阶段将显示错误信息。未启用时,流程会继续,但来自验证码的数据可在上下文中用于策略决定。"
#: authentik/stages/captcha/models.py
msgid "Captcha Stage"
msgstr "验证码阶段"
@ -2409,6 +2417,23 @@ msgstr "验证码阶段"
msgid "Captcha Stages"
msgstr "验证码阶段"
#: authentik/stages/captcha/stage.py
msgid "Unknown error"
msgstr "未知错误"
#: authentik/stages/captcha/stage.py
#, python-brace-format
msgid "Failed to validate token: {error}"
msgstr "验证令牌失败:{error}"
#: authentik/stages/captcha/stage.py
msgid "Invalid captcha response"
msgstr "验证码响应无效"
#: authentik/stages/captcha/stage.py
msgid "Failed to validate token"
msgstr "验证令牌失败"
#: authentik/stages/consent/models.py
msgid ""
"Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."

View File

@ -14,7 +14,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-03 00:08+0000\n"
"POT-Creation-Date: 2024-06-05 00:07+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: deluxghost, 2024\n"
"Language-Team: Chinese (China) (https://app.transifex.com/authentik/teams/119923/zh_CN/)\n"
@ -2400,6 +2400,14 @@ msgstr "公钥,从您的验证码提供商处取得。"
msgid "Private key, acquired your captcha Provider."
msgstr "私钥,从您的验证码提供商处取得。"
#: authentik/stages/captcha/models.py
msgid ""
"When enabled and the received captcha score is outside of the given "
"threshold, the stage will show an error message. When not enabled, the flow "
"will continue, but the data from the captcha will be available in the "
"context for policy decisions"
msgstr "启用时,如果接收到的验证码分数超出给定的阈值,此阶段将显示错误信息。未启用时,流程会继续,但来自验证码的数据可在上下文中用于策略决定。"
#: authentik/stages/captcha/models.py
msgid "Captcha Stage"
msgstr "验证码阶段"
@ -2408,6 +2416,23 @@ msgstr "验证码阶段"
msgid "Captcha Stages"
msgstr "验证码阶段"
#: authentik/stages/captcha/stage.py
msgid "Unknown error"
msgstr "未知错误"
#: authentik/stages/captcha/stage.py
#, python-brace-format
msgid "Failed to validate token: {error}"
msgstr "验证令牌失败:{error}"
#: authentik/stages/captcha/stage.py
msgid "Invalid captcha response"
msgstr "验证码响应无效"
#: authentik/stages/captcha/stage.py
msgid "Failed to validate token"
msgstr "验证令牌失败"
#: authentik/stages/consent/models.py
msgid ""
"Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."

348
poetry.lock generated
View File

@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
[[package]]
name = "aiohttp"
@ -336,13 +336,13 @@ aio = ["aiohttp (>=3.0)"]
[[package]]
name = "azure-identity"
version = "1.16.0"
version = "1.16.1"
description = "Microsoft Azure Identity Library for Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "azure-identity-1.16.0.tar.gz", hash = "sha256:6ff1d667cdcd81da1ceab42f80a0be63ca846629f518a922f7317a7e3c844e1b"},
{file = "azure_identity-1.16.0-py3-none-any.whl", hash = "sha256:722fdb60b8fdd55fa44dc378b8072f4b419b56a5e54c0de391f644949f3a826f"},
{file = "azure-identity-1.16.1.tar.gz", hash = "sha256:6d93f04468f240d59246d8afde3091494a5040d4f141cad0f49fc0c399d0d91e"},
{file = "azure_identity-1.16.1-py3-none-any.whl", hash = "sha256:8fb07c25642cd4ac422559a8b50d3e77f73dcc2bbfaba419d06d6c9d7cff6726"},
]
[package.dependencies]
@ -1020,43 +1020,43 @@ toml = ["tomli"]
[[package]]
name = "cryptography"
version = "42.0.7"
version = "42.0.8"
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
optional = false
python-versions = ">=3.7"
files = [
{file = "cryptography-42.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:a987f840718078212fdf4504d0fd4c6effe34a7e4740378e59d47696e8dfb477"},
{file = "cryptography-42.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bd13b5e9b543532453de08bcdc3cc7cebec6f9883e886fd20a92f26940fd3e7a"},
{file = "cryptography-42.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a79165431551042cc9d1d90e6145d5d0d3ab0f2d66326c201d9b0e7f5bf43604"},
{file = "cryptography-42.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a47787a5e3649008a1102d3df55424e86606c9bae6fb77ac59afe06d234605f8"},
{file = "cryptography-42.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:02c0eee2d7133bdbbc5e24441258d5d2244beb31da5ed19fbb80315f4bbbff55"},
{file = "cryptography-42.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:5e44507bf8d14b36b8389b226665d597bc0f18ea035d75b4e53c7b1ea84583cc"},
{file = "cryptography-42.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7f8b25fa616d8b846aef64b15c606bb0828dbc35faf90566eb139aa9cff67af2"},
{file = "cryptography-42.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:93a3209f6bb2b33e725ed08ee0991b92976dfdcf4e8b38646540674fc7508e13"},
{file = "cryptography-42.0.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e6b8f1881dac458c34778d0a424ae5769de30544fc678eac51c1c8bb2183e9da"},
{file = "cryptography-42.0.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3de9a45d3b2b7d8088c3fbf1ed4395dfeff79d07842217b38df14ef09ce1d8d7"},
{file = "cryptography-42.0.7-cp37-abi3-win32.whl", hash = "sha256:789caea816c6704f63f6241a519bfa347f72fbd67ba28d04636b7c6b7da94b0b"},
{file = "cryptography-42.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:8cb8ce7c3347fcf9446f201dc30e2d5a3c898d009126010cbd1f443f28b52678"},
{file = "cryptography-42.0.7-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:a3a5ac8b56fe37f3125e5b72b61dcde43283e5370827f5233893d461b7360cd4"},
{file = "cryptography-42.0.7-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:779245e13b9a6638df14641d029add5dc17edbef6ec915688f3acb9e720a5858"},
{file = "cryptography-42.0.7-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d563795db98b4cd57742a78a288cdbdc9daedac29f2239793071fe114f13785"},
{file = "cryptography-42.0.7-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:31adb7d06fe4383226c3e963471f6837742889b3c4caa55aac20ad951bc8ffda"},
{file = "cryptography-42.0.7-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:efd0bf5205240182e0f13bcaea41be4fdf5c22c5129fc7ced4a0282ac86998c9"},
{file = "cryptography-42.0.7-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a9bc127cdc4ecf87a5ea22a2556cab6c7eda2923f84e4f3cc588e8470ce4e42e"},
{file = "cryptography-42.0.7-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3577d029bc3f4827dd5bf8bf7710cac13527b470bbf1820a3f394adb38ed7d5f"},
{file = "cryptography-42.0.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2e47577f9b18723fa294b0ea9a17d5e53a227867a0a4904a1a076d1646d45ca1"},
{file = "cryptography-42.0.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1a58839984d9cb34c855197043eaae2c187d930ca6d644612843b4fe8513c886"},
{file = "cryptography-42.0.7-cp39-abi3-win32.whl", hash = "sha256:e6b79d0adb01aae87e8a44c2b64bc3f3fe59515280e00fb6d57a7267a2583cda"},
{file = "cryptography-42.0.7-cp39-abi3-win_amd64.whl", hash = "sha256:16268d46086bb8ad5bf0a2b5544d8a9ed87a0e33f5e77dd3c3301e63d941a83b"},
{file = "cryptography-42.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2954fccea107026512b15afb4aa664a5640cd0af630e2ee3962f2602693f0c82"},
{file = "cryptography-42.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:362e7197754c231797ec45ee081f3088a27a47c6c01eff2ac83f60f85a50fe60"},
{file = "cryptography-42.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f698edacf9c9e0371112792558d2f705b5645076cc0aaae02f816a0171770fd"},
{file = "cryptography-42.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5482e789294854c28237bba77c4c83be698be740e31a3ae5e879ee5444166582"},
{file = "cryptography-42.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e9b2a6309f14c0497f348d08a065d52f3020656f675819fc405fb63bbcd26562"},
{file = "cryptography-42.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d8e3098721b84392ee45af2dd554c947c32cc52f862b6a3ae982dbb90f577f14"},
{file = "cryptography-42.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c65f96dad14f8528a447414125e1fc8feb2ad5a272b8f68477abbcc1ea7d94b9"},
{file = "cryptography-42.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36017400817987670037fbb0324d71489b6ead6231c9604f8fc1f7d008087c68"},
{file = "cryptography-42.0.7.tar.gz", hash = "sha256:ecbfbc00bf55888edda9868a4cf927205de8499e7fabe6c050322298382953f2"},
{file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"},
{file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"},
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"},
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"},
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"},
{file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"},
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"},
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"},
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"},
{file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"},
{file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"},
{file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"},
{file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"},
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"},
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"},
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"},
{file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"},
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"},
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"},
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"},
{file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"},
{file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"},
{file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"},
{file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"},
{file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"},
{file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"},
{file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"},
{file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"},
{file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"},
{file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"},
{file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"},
{file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"},
]
[package.dependencies]
@ -1196,13 +1196,13 @@ bcrypt = ["bcrypt"]
[[package]]
name = "django-cte"
version = "1.3.2"
version = "1.3.3"
description = "Common Table Expressions (CTE) for Django"
optional = false
python-versions = "*"
files = [
{file = "django-cte-1.3.2.tar.gz", hash = "sha256:841b264f83417d421393c8c4644f76300962c6c3ddbc37339cf99672eb3696a2"},
{file = "django_cte-1.3.2-py2.py3-none-any.whl", hash = "sha256:9ca0a900df4819bbe86447a594f27272d67069f3ef13da61e905b0ace67704e9"},
{file = "django-cte-1.3.3.tar.gz", hash = "sha256:0c1aeef067278a22886151c1d27f6f665a303952d058900e5ca82a24cde40697"},
{file = "django_cte-1.3.3-py2.py3-none-any.whl", hash = "sha256:85bbc3efb30c2f8c9ae3080ca6f0b9570e43d2cb4b6be10846c8ef9f046873fa"},
]
[[package]]
@ -1707,13 +1707,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
[[package]]
name = "google-api-python-client"
version = "2.131.0"
version = "2.133.0"
description = "Google API Client Library for Python"
optional = false
python-versions = ">=3.7"
files = [
{file = "google-api-python-client-2.131.0.tar.gz", hash = "sha256:1c03e24af62238a8817ecc24e9d4c32ddd4cb1f323b08413652d9a9a592fc00d"},
{file = "google_api_python_client-2.131.0-py2.py3-none-any.whl", hash = "sha256:e325409bdcef4604d505d9246ce7199960a010a0569ac503b9f319db8dbdc217"},
{file = "google-api-python-client-2.133.0.tar.gz", hash = "sha256:293092905b66a046d3187a99ac454e12b00cc2c70444f26eb2f1f9c1a82720b4"},
{file = "google_api_python_client-2.133.0-py2.py3-none-any.whl", hash = "sha256:396fe676ea0dfed066654dcf9f8dea77a1342f9d9bb23bb88e45b7b81e773926"},
]
[package.dependencies]
@ -2172,13 +2172,13 @@ zookeeper = ["kazoo (>=2.8.0)"]
[[package]]
name = "kubernetes"
version = "29.0.0"
version = "30.1.0"
description = "Kubernetes python client"
optional = false
python-versions = ">=3.6"
files = [
{file = "kubernetes-29.0.0-py2.py3-none-any.whl", hash = "sha256:ab8cb0e0576ccdfb71886366efb102c6a20f268d817be065ce7f9909c631e43e"},
{file = "kubernetes-29.0.0.tar.gz", hash = "sha256:c4812e227ae74d07d53c88293e564e54b850452715a59a927e7e1bc6b9a60459"},
{file = "kubernetes-30.1.0-py2.py3-none-any.whl", hash = "sha256:e212e8b7579031dd2e512168b617373bc1e03888d41ac4e04039240a292d478d"},
{file = "kubernetes-30.1.0.tar.gz", hash = "sha256:41e4c77af9f28e7a6c314e3bd06a8c6229ddd787cad684e0ab9f69b498e98ebc"},
]
[package.dependencies]
@ -3019,13 +3019,13 @@ attrs = ">=19.2.0"
[[package]]
name = "packaging"
version = "24.0"
version = "24.1"
description = "Core utilities for Python packages"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"},
{file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"},
{file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
{file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
]
[[package]]
@ -3376,19 +3376,19 @@ files = [
[[package]]
name = "pydantic"
version = "2.7.2"
version = "2.7.3"
description = "Data validation using Python type hints"
optional = false
python-versions = ">=3.8"
files = [
{file = "pydantic-2.7.2-py3-none-any.whl", hash = "sha256:834ab954175f94e6e68258537dc49402c4a5e9d0409b9f1b86b7e934a8372de7"},
{file = "pydantic-2.7.2.tar.gz", hash = "sha256:71b2945998f9c9b7919a45bde9a50397b289937d215ae141c1d0903ba7149fd7"},
{file = "pydantic-2.7.3-py3-none-any.whl", hash = "sha256:ea91b002777bf643bb20dd717c028ec43216b24a6001a280f83877fd2655d0b4"},
{file = "pydantic-2.7.3.tar.gz", hash = "sha256:c46c76a40bb1296728d7a8b99aa73dd70a48c3510111ff290034f860c99c419e"},
]
[package.dependencies]
annotated-types = ">=0.4.0"
email-validator = {version = ">=2.0.0", optional = true, markers = "extra == \"email\""}
pydantic-core = "2.18.3"
pydantic-core = "2.18.4"
typing-extensions = ">=4.6.1"
[package.extras]
@ -3396,90 +3396,90 @@ email = ["email-validator (>=2.0.0)"]
[[package]]
name = "pydantic-core"
version = "2.18.3"
version = "2.18.4"
description = "Core functionality for Pydantic validation and serialization"
optional = false
python-versions = ">=3.8"
files = [
{file = "pydantic_core-2.18.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:744697428fcdec6be5670460b578161d1ffe34743a5c15656be7ea82b008197c"},
{file = "pydantic_core-2.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37b40c05ced1ba4218b14986fe6f283d22e1ae2ff4c8e28881a70fb81fbfcda7"},
{file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:544a9a75622357076efb6b311983ff190fbfb3c12fc3a853122b34d3d358126c"},
{file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e2e253af04ceaebde8eb201eb3f3e3e7e390f2d275a88300d6a1959d710539e2"},
{file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:855ec66589c68aa367d989da5c4755bb74ee92ccad4fdb6af942c3612c067e34"},
{file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d3e42bb54e7e9d72c13ce112e02eb1b3b55681ee948d748842171201a03a98a"},
{file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6ac9ffccc9d2e69d9fba841441d4259cb668ac180e51b30d3632cd7abca2b9b"},
{file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c56eca1686539fa0c9bda992e7bd6a37583f20083c37590413381acfc5f192d6"},
{file = "pydantic_core-2.18.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:17954d784bf8abfc0ec2a633108207ebc4fa2df1a0e4c0c3ccbaa9bb01d2c426"},
{file = "pydantic_core-2.18.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:98ed737567d8f2ecd54f7c8d4f8572ca7c7921ede93a2e52939416170d357812"},
{file = "pydantic_core-2.18.3-cp310-none-win32.whl", hash = "sha256:9f9e04afebd3ed8c15d67a564ed0a34b54e52136c6d40d14c5547b238390e779"},
{file = "pydantic_core-2.18.3-cp310-none-win_amd64.whl", hash = "sha256:45e4ffbae34f7ae30d0047697e724e534a7ec0a82ef9994b7913a412c21462a0"},
{file = "pydantic_core-2.18.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b9ebe8231726c49518b16b237b9fe0d7d361dd221302af511a83d4ada01183ab"},
{file = "pydantic_core-2.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b8e20e15d18bf7dbb453be78a2d858f946f5cdf06c5072453dace00ab652e2b2"},
{file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0d9ff283cd3459fa0bf9b0256a2b6f01ac1ff9ffb034e24457b9035f75587cb"},
{file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f7ef5f0ebb77ba24c9970da18b771711edc5feaf00c10b18461e0f5f5949231"},
{file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73038d66614d2e5cde30435b5afdced2b473b4c77d4ca3a8624dd3e41a9c19be"},
{file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6afd5c867a74c4d314c557b5ea9520183fadfbd1df4c2d6e09fd0d990ce412cd"},
{file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd7df92f28d351bb9f12470f4c533cf03d1b52ec5a6e5c58c65b183055a60106"},
{file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:80aea0ffeb1049336043d07799eace1c9602519fb3192916ff525b0287b2b1e4"},
{file = "pydantic_core-2.18.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaee40f25bba38132e655ffa3d1998a6d576ba7cf81deff8bfa189fb43fd2bbe"},
{file = "pydantic_core-2.18.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9128089da8f4fe73f7a91973895ebf2502539d627891a14034e45fb9e707e26d"},
{file = "pydantic_core-2.18.3-cp311-none-win32.whl", hash = "sha256:fec02527e1e03257aa25b1a4dcbe697b40a22f1229f5d026503e8b7ff6d2eda7"},
{file = "pydantic_core-2.18.3-cp311-none-win_amd64.whl", hash = "sha256:58ff8631dbab6c7c982e6425da8347108449321f61fe427c52ddfadd66642af7"},
{file = "pydantic_core-2.18.3-cp311-none-win_arm64.whl", hash = "sha256:3fc1c7f67f34c6c2ef9c213e0f2a351797cda98249d9ca56a70ce4ebcaba45f4"},
{file = "pydantic_core-2.18.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f0928cde2ae416a2d1ebe6dee324709c6f73e93494d8c7aea92df99aab1fc40f"},
{file = "pydantic_core-2.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bee9bb305a562f8b9271855afb6ce00223f545de3d68560b3c1649c7c5295e9"},
{file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e862823be114387257dacbfa7d78547165a85d7add33b446ca4f4fae92c7ff5c"},
{file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a36f78674cbddc165abab0df961b5f96b14461d05feec5e1f78da58808b97e7"},
{file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba905d184f62e7ddbb7a5a751d8a5c805463511c7b08d1aca4a3e8c11f2e5048"},
{file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fdd362f6a586e681ff86550b2379e532fee63c52def1c666887956748eaa326"},
{file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24b214b7ee3bd3b865e963dbed0f8bc5375f49449d70e8d407b567af3222aae4"},
{file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:691018785779766127f531674fa82bb368df5b36b461622b12e176c18e119022"},
{file = "pydantic_core-2.18.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:60e4c625e6f7155d7d0dcac151edf5858102bc61bf959d04469ca6ee4e8381bd"},
{file = "pydantic_core-2.18.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4e651e47d981c1b701dcc74ab8fec5a60a5b004650416b4abbef13db23bc7be"},
{file = "pydantic_core-2.18.3-cp312-none-win32.whl", hash = "sha256:ffecbb5edb7f5ffae13599aec33b735e9e4c7676ca1633c60f2c606beb17efc5"},
{file = "pydantic_core-2.18.3-cp312-none-win_amd64.whl", hash = "sha256:2c8333f6e934733483c7eddffdb094c143b9463d2af7e6bd85ebcb2d4a1b82c6"},
{file = "pydantic_core-2.18.3-cp312-none-win_arm64.whl", hash = "sha256:7a20dded653e516a4655f4c98e97ccafb13753987434fe7cf044aa25f5b7d417"},
{file = "pydantic_core-2.18.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:eecf63195be644b0396f972c82598cd15693550f0ff236dcf7ab92e2eb6d3522"},
{file = "pydantic_core-2.18.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c44efdd3b6125419c28821590d7ec891c9cb0dff33a7a78d9d5c8b6f66b9702"},
{file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e59fca51ffbdd1638b3856779342ed69bcecb8484c1d4b8bdb237d0eb5a45e2"},
{file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:70cf099197d6b98953468461d753563b28e73cf1eade2ffe069675d2657ed1d5"},
{file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63081a49dddc6124754b32a3774331467bfc3d2bd5ff8f10df36a95602560361"},
{file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:370059b7883485c9edb9655355ff46d912f4b03b009d929220d9294c7fd9fd60"},
{file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a64faeedfd8254f05f5cf6fc755023a7e1606af3959cfc1a9285744cc711044"},
{file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19d2e725de0f90d8671f89e420d36c3dd97639b98145e42fcc0e1f6d492a46dc"},
{file = "pydantic_core-2.18.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:67bc078025d70ec5aefe6200ef094576c9d86bd36982df1301c758a9fff7d7f4"},
{file = "pydantic_core-2.18.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:adf952c3f4100e203cbaf8e0c907c835d3e28f9041474e52b651761dc248a3c0"},
{file = "pydantic_core-2.18.3-cp38-none-win32.whl", hash = "sha256:9a46795b1f3beb167eaee91736d5d17ac3a994bf2215a996aed825a45f897558"},
{file = "pydantic_core-2.18.3-cp38-none-win_amd64.whl", hash = "sha256:200ad4e3133cb99ed82342a101a5abf3d924722e71cd581cc113fe828f727fbc"},
{file = "pydantic_core-2.18.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:304378b7bf92206036c8ddd83a2ba7b7d1a5b425acafff637172a3aa72ad7083"},
{file = "pydantic_core-2.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c826870b277143e701c9ccf34ebc33ddb4d072612683a044e7cce2d52f6c3fef"},
{file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e201935d282707394f3668380e41ccf25b5794d1b131cdd96b07f615a33ca4b1"},
{file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5560dda746c44b48bf82b3d191d74fe8efc5686a9ef18e69bdabccbbb9ad9442"},
{file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b32c2a1f8032570842257e4c19288eba9a2bba4712af542327de9a1204faff8"},
{file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:929c24e9dea3990bc8bcd27c5f2d3916c0c86f5511d2caa69e0d5290115344a9"},
{file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1a8376fef60790152564b0eab376b3e23dd6e54f29d84aad46f7b264ecca943"},
{file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dccf3ef1400390ddd1fb55bf0632209d39140552d068ee5ac45553b556780e06"},
{file = "pydantic_core-2.18.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:41dbdcb0c7252b58fa931fec47937edb422c9cb22528f41cb8963665c372caf6"},
{file = "pydantic_core-2.18.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:666e45cf071669fde468886654742fa10b0e74cd0fa0430a46ba6056b24fb0af"},
{file = "pydantic_core-2.18.3-cp39-none-win32.whl", hash = "sha256:f9c08cabff68704a1b4667d33f534d544b8a07b8e5d039c37067fceb18789e78"},
{file = "pydantic_core-2.18.3-cp39-none-win_amd64.whl", hash = "sha256:4afa5f5973e8572b5c0dcb4e2d4fda7890e7cd63329bd5cc3263a25c92ef0026"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:77319771a026f7c7d29c6ebc623de889e9563b7087911b46fd06c044a12aa5e9"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:df11fa992e9f576473038510d66dd305bcd51d7dd508c163a8c8fe148454e059"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d531076bdfb65af593326ffd567e6ab3da145020dafb9187a1d131064a55f97c"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d33ce258e4e6e6038f2b9e8b8a631d17d017567db43483314993b3ca345dcbbb"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1f9cd7f5635b719939019be9bda47ecb56e165e51dd26c9a217a433e3d0d59a9"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:cd4a032bb65cc132cae1fe3e52877daecc2097965cd3914e44fbd12b00dae7c5"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f2718430098bcdf60402136c845e4126a189959d103900ebabb6774a5d9fdb"},
{file = "pydantic_core-2.18.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c0037a92cf0c580ed14e10953cdd26528e8796307bb8bb312dc65f71547df04d"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b95a0972fac2b1ff3c94629fc9081b16371dad870959f1408cc33b2f78ad347a"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a62e437d687cc148381bdd5f51e3e81f5b20a735c55f690c5be94e05da2b0d5c"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b367a73a414bbb08507da102dc2cde0fa7afe57d09b3240ce82a16d608a7679c"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ecce4b2360aa3f008da3327d652e74a0e743908eac306198b47e1c58b03dd2b"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd4435b8d83f0c9561a2a9585b1de78f1abb17cb0cef5f39bf6a4b47d19bafe3"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:616221a6d473c5b9aa83fa8982745441f6a4a62a66436be9445c65f241b86c94"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7e6382ce89a92bc1d0c0c5edd51e931432202b9080dc921d8d003e616402efd1"},
{file = "pydantic_core-2.18.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ff58f379345603d940e461eae474b6bbb6dab66ed9a851ecd3cb3709bf4dcf6a"},
{file = "pydantic_core-2.18.3.tar.gz", hash = "sha256:432e999088d85c8f36b9a3f769a8e2b57aabd817bbb729a90d1fe7f18f6f1f39"},
{file = "pydantic_core-2.18.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:f76d0ad001edd426b92233d45c746fd08f467d56100fd8f30e9ace4b005266e4"},
{file = "pydantic_core-2.18.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:59ff3e89f4eaf14050c8022011862df275b552caef8082e37b542b066ce1ff26"},
{file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a55b5b16c839df1070bc113c1f7f94a0af4433fcfa1b41799ce7606e5c79ce0a"},
{file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4d0dcc59664fcb8974b356fe0a18a672d6d7cf9f54746c05f43275fc48636851"},
{file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8951eee36c57cd128f779e641e21eb40bc5073eb28b2d23f33eb0ef14ffb3f5d"},
{file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4701b19f7e3a06ea655513f7938de6f108123bf7c86bbebb1196eb9bd35cf724"},
{file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e00a3f196329e08e43d99b79b286d60ce46bed10f2280d25a1718399457e06be"},
{file = "pydantic_core-2.18.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:97736815b9cc893b2b7f663628e63f436018b75f44854c8027040e05230eeddb"},
{file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6891a2ae0e8692679c07728819b6e2b822fb30ca7445f67bbf6509b25a96332c"},
{file = "pydantic_core-2.18.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bc4ff9805858bd54d1a20efff925ccd89c9d2e7cf4986144b30802bf78091c3e"},
{file = "pydantic_core-2.18.4-cp310-none-win32.whl", hash = "sha256:1b4de2e51bbcb61fdebd0ab86ef28062704f62c82bbf4addc4e37fa4b00b7cbc"},
{file = "pydantic_core-2.18.4-cp310-none-win_amd64.whl", hash = "sha256:6a750aec7bf431517a9fd78cb93c97b9b0c496090fee84a47a0d23668976b4b0"},
{file = "pydantic_core-2.18.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:942ba11e7dfb66dc70f9ae66b33452f51ac7bb90676da39a7345e99ffb55402d"},
{file = "pydantic_core-2.18.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b2ebef0e0b4454320274f5e83a41844c63438fdc874ea40a8b5b4ecb7693f1c4"},
{file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a642295cd0c8df1b86fc3dced1d067874c353a188dc8e0f744626d49e9aa51c4"},
{file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f09baa656c904807e832cf9cce799c6460c450c4ad80803517032da0cd062e2"},
{file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98906207f29bc2c459ff64fa007afd10a8c8ac080f7e4d5beff4c97086a3dabd"},
{file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19894b95aacfa98e7cb093cd7881a0c76f55731efad31073db4521e2b6ff5b7d"},
{file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fbbdc827fe5e42e4d196c746b890b3d72876bdbf160b0eafe9f0334525119c8"},
{file = "pydantic_core-2.18.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f85d05aa0918283cf29a30b547b4df2fbb56b45b135f9e35b6807cb28bc47951"},
{file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e85637bc8fe81ddb73fda9e56bab24560bdddfa98aa64f87aaa4e4b6730c23d2"},
{file = "pydantic_core-2.18.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2f5966897e5461f818e136b8451d0551a2e77259eb0f73a837027b47dc95dab9"},
{file = "pydantic_core-2.18.4-cp311-none-win32.whl", hash = "sha256:44c7486a4228413c317952e9d89598bcdfb06399735e49e0f8df643e1ccd0558"},
{file = "pydantic_core-2.18.4-cp311-none-win_amd64.whl", hash = "sha256:8a7164fe2005d03c64fd3b85649891cd4953a8de53107940bf272500ba8a788b"},
{file = "pydantic_core-2.18.4-cp311-none-win_arm64.whl", hash = "sha256:4e99bc050fe65c450344421017f98298a97cefc18c53bb2f7b3531eb39bc7805"},
{file = "pydantic_core-2.18.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6f5c4d41b2771c730ea1c34e458e781b18cc668d194958e0112455fff4e402b2"},
{file = "pydantic_core-2.18.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2fdf2156aa3d017fddf8aea5adfba9f777db1d6022d392b682d2a8329e087cef"},
{file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4748321b5078216070b151d5271ef3e7cc905ab170bbfd27d5c83ee3ec436695"},
{file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847a35c4d58721c5dc3dba599878ebbdfd96784f3fb8bb2c356e123bdcd73f34"},
{file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c40d4eaad41f78e3bbda31b89edc46a3f3dc6e171bf0ecf097ff7a0ffff7cb1"},
{file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:21a5e440dbe315ab9825fcd459b8814bb92b27c974cbc23c3e8baa2b76890077"},
{file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01dd777215e2aa86dfd664daed5957704b769e726626393438f9c87690ce78c3"},
{file = "pydantic_core-2.18.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4b06beb3b3f1479d32befd1f3079cc47b34fa2da62457cdf6c963393340b56e9"},
{file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:564d7922e4b13a16b98772441879fcdcbe82ff50daa622d681dd682175ea918c"},
{file = "pydantic_core-2.18.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0eb2a4f660fcd8e2b1c90ad566db2b98d7f3f4717c64fe0a83e0adb39766d5b8"},
{file = "pydantic_core-2.18.4-cp312-none-win32.whl", hash = "sha256:8b8bab4c97248095ae0c4455b5a1cd1cdd96e4e4769306ab19dda135ea4cdb07"},
{file = "pydantic_core-2.18.4-cp312-none-win_amd64.whl", hash = "sha256:14601cdb733d741b8958224030e2bfe21a4a881fb3dd6fbb21f071cabd48fa0a"},
{file = "pydantic_core-2.18.4-cp312-none-win_arm64.whl", hash = "sha256:c1322d7dd74713dcc157a2b7898a564ab091ca6c58302d5c7b4c07296e3fd00f"},
{file = "pydantic_core-2.18.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:823be1deb01793da05ecb0484d6c9e20baebb39bd42b5d72636ae9cf8350dbd2"},
{file = "pydantic_core-2.18.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebef0dd9bf9b812bf75bda96743f2a6c5734a02092ae7f721c048d156d5fabae"},
{file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae1d6df168efb88d7d522664693607b80b4080be6750c913eefb77e34c12c71a"},
{file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9899c94762343f2cc2fc64c13e7cae4c3cc65cdfc87dd810a31654c9b7358cc"},
{file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99457f184ad90235cfe8461c4d70ab7dd2680e28821c29eca00252ba90308c78"},
{file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18f469a3d2a2fdafe99296a87e8a4c37748b5080a26b806a707f25a902c040a8"},
{file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7cdf28938ac6b8b49ae5e92f2735056a7ba99c9b110a474473fd71185c1af5d"},
{file = "pydantic_core-2.18.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:938cb21650855054dc54dfd9120a851c974f95450f00683399006aa6e8abb057"},
{file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:44cd83ab6a51da80fb5adbd9560e26018e2ac7826f9626bc06ca3dc074cd198b"},
{file = "pydantic_core-2.18.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:972658f4a72d02b8abfa2581d92d59f59897d2e9f7e708fdabe922f9087773af"},
{file = "pydantic_core-2.18.4-cp38-none-win32.whl", hash = "sha256:1d886dc848e60cb7666f771e406acae54ab279b9f1e4143babc9c2258213daa2"},
{file = "pydantic_core-2.18.4-cp38-none-win_amd64.whl", hash = "sha256:bb4462bd43c2460774914b8525f79b00f8f407c945d50881568f294c1d9b4443"},
{file = "pydantic_core-2.18.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:44a688331d4a4e2129140a8118479443bd6f1905231138971372fcde37e43528"},
{file = "pydantic_core-2.18.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a2fdd81edd64342c85ac7cf2753ccae0b79bf2dfa063785503cb85a7d3593223"},
{file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86110d7e1907ab36691f80b33eb2da87d780f4739ae773e5fc83fb272f88825f"},
{file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46387e38bd641b3ee5ce247563b60c5ca098da9c56c75c157a05eaa0933ed154"},
{file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:123c3cec203e3f5ac7b000bd82235f1a3eced8665b63d18be751f115588fea30"},
{file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc1803ac5c32ec324c5261c7209e8f8ce88e83254c4e1aebdc8b0a39f9ddb443"},
{file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53db086f9f6ab2b4061958d9c276d1dbe3690e8dd727d6abf2321d6cce37fa94"},
{file = "pydantic_core-2.18.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:abc267fa9837245cc28ea6929f19fa335f3dc330a35d2e45509b6566dc18be23"},
{file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a0d829524aaefdebccb869eed855e2d04c21d2d7479b6cada7ace5448416597b"},
{file = "pydantic_core-2.18.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:509daade3b8649f80d4e5ff21aa5673e4ebe58590b25fe42fac5f0f52c6f034a"},
{file = "pydantic_core-2.18.4-cp39-none-win32.whl", hash = "sha256:ca26a1e73c48cfc54c4a76ff78df3727b9d9f4ccc8dbee4ae3f73306a591676d"},
{file = "pydantic_core-2.18.4-cp39-none-win_amd64.whl", hash = "sha256:c67598100338d5d985db1b3d21f3619ef392e185e71b8d52bceacc4a7771ea7e"},
{file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:574d92eac874f7f4db0ca653514d823a0d22e2354359d0759e3f6a406db5d55d"},
{file = "pydantic_core-2.18.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1f4d26ceb5eb9eed4af91bebeae4b06c3fb28966ca3a8fb765208cf6b51102ab"},
{file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77450e6d20016ec41f43ca4a6c63e9fdde03f0ae3fe90e7c27bdbeaece8b1ed4"},
{file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d323a01da91851a4f17bf592faf46149c9169d68430b3146dcba2bb5e5719abc"},
{file = "pydantic_core-2.18.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43d447dd2ae072a0065389092a231283f62d960030ecd27565672bd40746c507"},
{file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:578e24f761f3b425834f297b9935e1ce2e30f51400964ce4801002435a1b41ef"},
{file = "pydantic_core-2.18.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:81b5efb2f126454586d0f40c4d834010979cb80785173d1586df845a632e4e6d"},
{file = "pydantic_core-2.18.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ab86ce7c8f9bea87b9d12c7f0af71102acbf5ecbc66c17796cff45dae54ef9a5"},
{file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:90afc12421df2b1b4dcc975f814e21bc1754640d502a2fbcc6d41e77af5ec312"},
{file = "pydantic_core-2.18.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:51991a89639a912c17bef4b45c87bd83593aee0437d8102556af4885811d59f5"},
{file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:293afe532740370aba8c060882f7d26cfd00c94cae32fd2e212a3a6e3b7bc15e"},
{file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b48ece5bde2e768197a2d0f6e925f9d7e3e826f0ad2271120f8144a9db18d5c8"},
{file = "pydantic_core-2.18.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eae237477a873ab46e8dd748e515c72c0c804fb380fbe6c85533c7de51f23a8f"},
{file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:834b5230b5dfc0c1ec37b2fda433b271cbbc0e507560b5d1588e2cc1148cf1ce"},
{file = "pydantic_core-2.18.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e858ac0a25074ba4bce653f9b5d0a85b7456eaddadc0ce82d3878c22489fa4ee"},
{file = "pydantic_core-2.18.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2fd41f6eff4c20778d717af1cc50eca52f5afe7805ee530a4fbd0bae284f16e9"},
{file = "pydantic_core-2.18.4.tar.gz", hash = "sha256:ec3beeada09ff865c344ff3bc2f427f5e6c26401cc6113d77e372c3fdac73864"},
]
[package.dependencies]
@ -3624,13 +3624,13 @@ files = [
[[package]]
name = "pytest"
version = "8.2.1"
version = "8.2.2"
description = "pytest: simple powerful testing with Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "pytest-8.2.1-py3-none-any.whl", hash = "sha256:faccc5d332b8c3719f40283d0d44aa5cf101cec36f88cde9ed8f2bc0538612b1"},
{file = "pytest-8.2.1.tar.gz", hash = "sha256:5046e5b46d8e4cac199c373041f26be56fdb81eb4e67dc11d4e10811fc3408fd"},
{file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"},
{file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"},
]
[package.dependencies]
@ -4052,28 +4052,28 @@ pyasn1 = ">=0.1.3"
[[package]]
name = "ruff"
version = "0.4.7"
version = "0.4.8"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
{file = "ruff-0.4.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e089371c67892a73b6bb1525608e89a2aca1b77b5440acf7a71dda5dac958f9e"},
{file = "ruff-0.4.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:10f973d521d910e5f9c72ab27e409e839089f955be8a4c8826601a6323a89753"},
{file = "ruff-0.4.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59c3d110970001dfa494bcd95478e62286c751126dfb15c3c46e7915fc49694f"},
{file = "ruff-0.4.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa9773c6c00f4958f73b317bc0fd125295110c3776089f6ef318f4b775f0abe4"},
{file = "ruff-0.4.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07fc80bbb61e42b3b23b10fda6a2a0f5a067f810180a3760c5ef1b456c21b9db"},
{file = "ruff-0.4.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:fa4dafe3fe66d90e2e2b63fa1591dd6e3f090ca2128daa0be33db894e6c18648"},
{file = "ruff-0.4.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7c0083febdec17571455903b184a10026603a1de078428ba155e7ce9358c5f6"},
{file = "ruff-0.4.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad1b20e66a44057c326168437d680a2166c177c939346b19c0d6b08a62a37589"},
{file = "ruff-0.4.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbf5d818553add7511c38b05532d94a407f499d1a76ebb0cad0374e32bc67202"},
{file = "ruff-0.4.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:50e9651578b629baec3d1513b2534de0ac7ed7753e1382272b8d609997e27e83"},
{file = "ruff-0.4.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8874a9df7766cb956b218a0a239e0a5d23d9e843e4da1e113ae1d27ee420877a"},
{file = "ruff-0.4.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b9de9a6e49f7d529decd09381c0860c3f82fa0b0ea00ea78409b785d2308a567"},
{file = "ruff-0.4.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:13a1768b0691619822ae6d446132dbdfd568b700ecd3652b20d4e8bc1e498f78"},
{file = "ruff-0.4.7-py3-none-win32.whl", hash = "sha256:769e5a51df61e07e887b81e6f039e7ed3573316ab7dd9f635c5afaa310e4030e"},
{file = "ruff-0.4.7-py3-none-win_amd64.whl", hash = "sha256:9e3ab684ad403a9ed1226894c32c3ab9c2e0718440f6f50c7c5829932bc9e054"},
{file = "ruff-0.4.7-py3-none-win_arm64.whl", hash = "sha256:10f2204b9a613988e3484194c2c9e96a22079206b22b787605c255f130db5ed7"},
{file = "ruff-0.4.7.tar.gz", hash = "sha256:2331d2b051dc77a289a653fcc6a42cce357087c5975738157cd966590b18b5e1"},
{file = "ruff-0.4.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7663a6d78f6adb0eab270fa9cf1ff2d28618ca3a652b60f2a234d92b9ec89066"},
{file = "ruff-0.4.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eeceb78da8afb6de0ddada93112869852d04f1cd0f6b80fe464fd4e35c330913"},
{file = "ruff-0.4.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aad360893e92486662ef3be0a339c5ca3c1b109e0134fcd37d534d4be9fb8de3"},
{file = "ruff-0.4.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:284c2e3f3396fb05f5f803c9fffb53ebbe09a3ebe7dda2929ed8d73ded736deb"},
{file = "ruff-0.4.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7354f921e3fbe04d2a62d46707e569f9315e1a613307f7311a935743c51a764"},
{file = "ruff-0.4.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:72584676164e15a68a15778fd1b17c28a519e7a0622161eb2debdcdabdc71883"},
{file = "ruff-0.4.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9678d5c9b43315f323af2233a04d747409d1e3aa6789620083a82d1066a35199"},
{file = "ruff-0.4.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704977a658131651a22b5ebeb28b717ef42ac6ee3b11e91dc87b633b5d83142b"},
{file = "ruff-0.4.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d05f8d6f0c3cce5026cecd83b7a143dcad503045857bc49662f736437380ad45"},
{file = "ruff-0.4.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6ea874950daca5697309d976c9afba830d3bf0ed66887481d6bca1673fc5b66a"},
{file = "ruff-0.4.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fc95aac2943ddf360376be9aa3107c8cf9640083940a8c5bd824be692d2216dc"},
{file = "ruff-0.4.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:384154a1c3f4bf537bac69f33720957ee49ac8d484bfc91720cc94172026ceed"},
{file = "ruff-0.4.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e9d5ce97cacc99878aa0d084c626a15cd21e6b3d53fd6f9112b7fc485918e1fa"},
{file = "ruff-0.4.8-py3-none-win32.whl", hash = "sha256:6d795d7639212c2dfd01991259460101c22aabf420d9b943f153ab9d9706e6a9"},
{file = "ruff-0.4.8-py3-none-win_amd64.whl", hash = "sha256:e14a3a095d07560a9d6769a72f781d73259655919d9b396c650fc98a8157555d"},
{file = "ruff-0.4.8-py3-none-win_arm64.whl", hash = "sha256:14019a06dbe29b608f6b7cbcec300e3170a8d86efaddb7b23405cb7f7dcaf780"},
{file = "ruff-0.4.8.tar.gz", hash = "sha256:16d717b1d57b2e2fd68bd0bf80fb43931b79d05a7131aa477d66fc40fbd86268"},
]
[[package]]
@ -4130,13 +4130,13 @@ urllib3 = {version = ">=1.26,<3", extras = ["socks"]}
[[package]]
name = "sentry-sdk"
version = "2.3.1"
version = "2.5.1"
description = "Python client for Sentry (https://sentry.io)"
optional = false
python-versions = ">=3.6"
files = [
{file = "sentry_sdk-2.3.1-py2.py3-none-any.whl", hash = "sha256:c5aeb095ba226391d337dd42a6f9470d86c9fc236ecc71cfc7cd1942b45010c6"},
{file = "sentry_sdk-2.3.1.tar.gz", hash = "sha256:139a71a19f5e9eb5d3623942491ce03cf8ebc14ea2e39ba3e6fe79560d8a5b1f"},
{file = "sentry_sdk-2.5.1-py2.py3-none-any.whl", hash = "sha256:1f87acdce4a43a523ae5aa21a3fc37522d73ebd9ec04b1dbf01aa3d173852def"},
{file = "sentry_sdk-2.5.1.tar.gz", hash = "sha256:fbc40a78a8a9c6675133031116144f0d0940376fa6e4e1acd5624c90b0aaf58b"},
]
[package.dependencies]
@ -4451,22 +4451,22 @@ celery = "*"
[[package]]
name = "tornado"
version = "6.4"
version = "6.4.1"
description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed."
optional = false
python-versions = ">= 3.8"
python-versions = ">=3.8"
files = [
{file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"},
{file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"},
{file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"},
{file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"},
{file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"},
{file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"},
{file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"},
{file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"},
{file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"},
{file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"},
{file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"},
{file = "tornado-6.4.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:163b0aafc8e23d8cdc3c9dfb24c5368af84a81e3364745ccb4427669bf84aec8"},
{file = "tornado-6.4.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6d5ce3437e18a2b66fbadb183c1d3364fb03f2be71299e7d10dbeeb69f4b2a14"},
{file = "tornado-6.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e20b9113cd7293f164dc46fffb13535266e713cdb87bd2d15ddb336e96cfc4"},
{file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ae50a504a740365267b2a8d1a90c9fbc86b780a39170feca9bcc1787ff80842"},
{file = "tornado-6.4.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:613bf4ddf5c7a95509218b149b555621497a6cc0d46ac341b30bd9ec19eac7f3"},
{file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:25486eb223babe3eed4b8aecbac33b37e3dd6d776bc730ca14e1bf93888b979f"},
{file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:454db8a7ecfcf2ff6042dde58404164d969b6f5d58b926da15e6b23817950fc4"},
{file = "tornado-6.4.1-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a02a08cc7a9314b006f653ce40483b9b3c12cda222d6a46d4ac63bb6c9057698"},
{file = "tornado-6.4.1-cp38-abi3-win32.whl", hash = "sha256:d9a566c40b89757c9aa8e6f032bcdb8ca8795d7c1a9762910c722b1635c9de4d"},
{file = "tornado-6.4.1-cp38-abi3-win_amd64.whl", hash = "sha256:b24b8982ed444378d7f21d563f4180a2de31ced9d8d84443907a0a64da2072e7"},
{file = "tornado-6.4.1.tar.gz", hash = "sha256:92d3ab53183d8c50f8204a51e6f91d18a15d5ef261e84d452800d4ff6fc504e9"},
]
[[package]]
@ -4505,13 +4505,13 @@ wsproto = ">=0.14"
[[package]]
name = "twilio"
version = "9.1.0"
version = "9.1.1"
description = "Twilio API client and TwiML generator"
optional = false
python-versions = ">=3.7.0"
files = [
{file = "twilio-9.1.0-py2.py3-none-any.whl", hash = "sha256:eb4687a9f81dc3118e8981c5a46d9f8184baee135c79afed47c714c759c31bbc"},
{file = "twilio-9.1.0.tar.gz", hash = "sha256:ab2eb19c779855bf02cdca8a7e02ebaa64feee47da7b591ac9088ec07a6962e2"},
{file = "twilio-9.1.1-py2.py3-none-any.whl", hash = "sha256:cc3e090c3884db7d70e7c647358b9cf1f4d30fd3fbe0412adcae0df8459d29b0"},
{file = "twilio-9.1.1.tar.gz", hash = "sha256:cfe72b12cabac2f0997f1060d53cea14bd1196e2cbda14789e53c7dd762c4349"},
]
[package.dependencies]

View File

@ -19726,6 +19726,403 @@ paths:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
/providers/scim_groups/:
get:
operationId: providers_scim_groups_list
description: SCIMProviderGroup Viewset
parameters:
- in: query
name: group__group_uuid
schema:
type: string
format: uuid
- in: query
name: group__name
schema:
type: string
- name: ordering
required: false
in: query
description: Which field to use when ordering the results.
schema:
type: string
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
- in: query
name: provider__id
schema:
type: integer
- name: search
required: false
in: query
description: A search term.
schema:
type: string
tags:
- providers
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedSCIMProviderGroupList'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
post:
operationId: providers_scim_groups_create
description: SCIMProviderGroup Viewset
tags:
- providers
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SCIMProviderGroupRequest'
required: true
security:
- authentik: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/SCIMProviderGroup'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
/providers/scim_groups/{id}/:
get:
operationId: providers_scim_groups_retrieve
description: SCIMProviderGroup Viewset
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this scim provider group.
required: true
tags:
- providers
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SCIMProviderGroup'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
delete:
operationId: providers_scim_groups_destroy
description: SCIMProviderGroup Viewset
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this scim provider group.
required: true
tags:
- providers
security:
- authentik: []
responses:
'204':
description: No response body
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
/providers/scim_groups/{id}/used_by/:
get:
operationId: providers_scim_groups_used_by_list
description: Get a list of all objects that use this object
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this scim provider group.
required: true
tags:
- providers
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/UsedBy'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
/providers/scim_users/:
get:
operationId: providers_scim_users_list
description: SCIMProviderUser Viewset
parameters:
- name: ordering
required: false
in: query
description: Which field to use when ordering the results.
schema:
type: string
- name: page
required: false
in: query
description: A page number within the paginated result set.
schema:
type: integer
- name: page_size
required: false
in: query
description: Number of results to return per page.
schema:
type: integer
- in: query
name: provider__id
schema:
type: integer
- name: search
required: false
in: query
description: A search term.
schema:
type: string
- in: query
name: user__id
schema:
type: integer
- in: query
name: user__username
schema:
type: string
tags:
- providers
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedSCIMProviderUserList'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
post:
operationId: providers_scim_users_create
description: SCIMProviderUser Viewset
tags:
- providers
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SCIMProviderUserRequest'
required: true
security:
- authentik: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/SCIMProviderUser'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
/providers/scim_users/{id}/:
get:
operationId: providers_scim_users_retrieve
description: SCIMProviderUser Viewset
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this scim provider user.
required: true
tags:
- providers
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SCIMProviderUser'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
delete:
operationId: providers_scim_users_destroy
description: SCIMProviderUser Viewset
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this scim provider user.
required: true
tags:
- providers
security:
- authentik: []
responses:
'204':
description: No response body
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
/providers/scim_users/{id}/used_by/:
get:
operationId: providers_scim_users_used_by_list
description: Get a list of all objects that use this object
parameters:
- in: path
name: id
schema:
type: string
format: uuid
description: A UUID string identifying this scim provider user.
required: true
tags:
- providers
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/UsedBy'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
/rac/connection_tokens/:
get:
operationId: rac_connection_tokens_list
@ -34067,6 +34464,18 @@ components:
type: string
api_url:
type: string
score_min_threshold:
type: number
format: double
score_max_threshold:
type: number
format: double
error_on_invalid_score:
type: boolean
description: When enabled and the received captcha score is outside of the
given threshold, the stage will show an error message. When not enabled,
the flow will continue, but the data from the captcha will be available
in the context for policy decisions
required:
- component
- meta_model_name
@ -34101,6 +34510,18 @@ components:
api_url:
type: string
minLength: 1
score_min_threshold:
type: number
format: double
score_max_threshold:
type: number
format: double
error_on_invalid_score:
type: boolean
description: When enabled and the received captcha score is outside of the
given threshold, the stage will show an error message. When not enabled,
the flow will continue, but the data from the captcha will be available
in the context for policy decisions
required:
- name
- private_key
@ -36311,6 +36732,8 @@ components:
type: string
format: uuid
readOnly: true
google_id:
type: string
group:
type: string
format: uuid
@ -36324,6 +36747,7 @@ components:
readOnly: true
required:
- attributes
- google_id
- group
- group_obj
- id
@ -36332,12 +36756,16 @@ components:
type: object
description: GoogleWorkspaceProviderGroup Serializer
properties:
google_id:
type: string
minLength: 1
group:
type: string
format: uuid
provider:
type: integer
required:
- google_id
- group
- provider
GoogleWorkspaceProviderMapping:
@ -36460,6 +36888,8 @@ components:
type: string
format: uuid
readOnly: true
google_id:
type: string
user:
type: integer
user_obj:
@ -36472,6 +36902,7 @@ components:
readOnly: true
required:
- attributes
- google_id
- id
- provider
- user
@ -36480,11 +36911,15 @@ components:
type: object
description: GoogleWorkspaceProviderUser Serializer
properties:
google_id:
type: string
minLength: 1
user:
type: integer
provider:
type: integer
required:
- google_id
- provider
- user
Group:
@ -37979,6 +38414,8 @@ components:
type: string
format: uuid
readOnly: true
microsoft_id:
type: string
group:
type: string
format: uuid
@ -37995,11 +38432,15 @@ components:
- group
- group_obj
- id
- microsoft_id
- provider
MicrosoftEntraProviderGroupRequest:
type: object
description: MicrosoftEntraProviderGroup Serializer
properties:
microsoft_id:
type: string
minLength: 1
group:
type: string
format: uuid
@ -38007,6 +38448,7 @@ components:
type: integer
required:
- group
- microsoft_id
- provider
MicrosoftEntraProviderMapping:
type: object
@ -38125,6 +38567,8 @@ components:
type: string
format: uuid
readOnly: true
microsoft_id:
type: string
user:
type: integer
user_obj:
@ -38138,6 +38582,7 @@ components:
required:
- attributes
- id
- microsoft_id
- provider
- user
- user_obj
@ -38145,11 +38590,15 @@ components:
type: object
description: MicrosoftEntraProviderUser Serializer
properties:
microsoft_id:
type: string
minLength: 1
user:
type: integer
provider:
type: integer
required:
- microsoft_id
- provider
- user
ModelEnum:
@ -40142,6 +40591,18 @@ components:
required:
- pagination
- results
PaginatedSCIMProviderGroupList:
type: object
properties:
pagination:
$ref: '#/components/schemas/Pagination'
results:
type: array
items:
$ref: '#/components/schemas/SCIMProviderGroup'
required:
- pagination
- results
PaginatedSCIMProviderList:
type: object
properties:
@ -40154,6 +40615,18 @@ components:
required:
- pagination
- results
PaginatedSCIMProviderUserList:
type: object
properties:
pagination:
$ref: '#/components/schemas/Pagination'
results:
type: array
items:
$ref: '#/components/schemas/SCIMProviderUser'
required:
- pagination
- results
PaginatedSCIMSourceGroupList:
type: object
properties:
@ -41182,6 +41655,18 @@ components:
api_url:
type: string
minLength: 1
score_min_threshold:
type: number
format: double
score_max_threshold:
type: number
format: double
error_on_invalid_score:
type: boolean
description: When enabled and the received captcha score is outside of the
given threshold, the stage will show an error message. When not enabled,
the flow will continue, but the data from the captcha will be available
in the context for policy decisions
PatchedCertificateKeyPairRequest:
type: object
description: CertificateKeyPair Serializer
@ -44111,12 +44596,14 @@ components:
properties:
user:
type: integer
nullable: true
context:
type: object
additionalProperties: {}
group:
type: string
format: uuid
nullable: true
PropertyMappingTestResult:
type: object
description: Result of a Property-mapping test
@ -45870,6 +46357,47 @@ components:
- url
- verbose_name
- verbose_name_plural
SCIMProviderGroup:
type: object
description: SCIMProviderGroup Serializer
properties:
id:
type: string
format: uuid
readOnly: true
scim_id:
type: string
group:
type: string
format: uuid
group_obj:
allOf:
- $ref: '#/components/schemas/UserGroup'
readOnly: true
provider:
type: integer
required:
- group
- group_obj
- id
- provider
- scim_id
SCIMProviderGroupRequest:
type: object
description: SCIMProviderGroup Serializer
properties:
scim_id:
type: string
minLength: 1
group:
type: string
format: uuid
provider:
type: integer
required:
- group
- provider
- scim_id
SCIMProviderRequest:
type: object
description: SCIMProvider Serializer
@ -45906,6 +46434,45 @@ components:
- name
- token
- url
SCIMProviderUser:
type: object
description: SCIMProviderUser Serializer
properties:
id:
type: string
format: uuid
readOnly: true
scim_id:
type: string
user:
type: integer
user_obj:
allOf:
- $ref: '#/components/schemas/GroupMember'
readOnly: true
provider:
type: integer
required:
- id
- provider
- scim_id
- user
- user_obj
SCIMProviderUserRequest:
type: object
description: SCIMProviderUser Serializer
properties:
scim_id:
type: string
minLength: 1
user:
type: integer
provider:
type: integer
required:
- provider
- scim_id
- user
SCIMSource:
type: object
description: SCIMSource Serializer

View File

@ -1,5 +1,3 @@
version: '3.7'
services:
chrome:
image: docker.io/selenium/standalone-chrome:122.0

View File

@ -6,21 +6,21 @@
"": {
"name": "@goauthentik/web-tests",
"dependencies": {
"chromedriver": "^125.0.3"
"chromedriver": "^126.0.0"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0",
"@wdio/cli": "^8.38.1",
"@wdio/local-runner": "^8.38.0",
"@wdio/mocha-framework": "^8.38.0",
"@wdio/spec-reporter": "^8.38.0",
"@wdio/cli": "^8.38.2",
"@wdio/local-runner": "^8.38.2",
"@wdio/mocha-framework": "^8.38.2",
"@wdio/spec-reporter": "^8.38.2",
"eslint": "^8.57.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-sonarjs": "^0.25.1",
"npm-run-all": "^4.1.5",
"prettier": "^3.3.0",
"prettier": "^3.3.2",
"ts-node": "^10.9.2",
"typescript": "^5.4.5",
"wdio-wait-for": "^3.0.11"
@ -1189,19 +1189,19 @@
}
},
"node_modules/@wdio/cli": {
"version": "8.38.1",
"resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.38.1.tgz",
"integrity": "sha512-xif0RvJX+saXVdzrhlEafbEdptNyeyqm0pyilT4H7OI7OMa+23rWB67r2SPoIZbBrVeFv1iqtUx9hR73RRio2A==",
"version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/cli/-/cli-8.38.2.tgz",
"integrity": "sha512-p9y6jxmpmw53OoB9v/uTLwMetmz7Q0K7NewdVONgmeTY/ERpkU15qL3fMw1rXb+E+vrV8dlce4srnXroec6SFA==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.1",
"@vitest/snapshot": "^1.2.1",
"@wdio/config": "8.38.0",
"@wdio/globals": "8.38.0",
"@wdio/config": "8.38.2",
"@wdio/globals": "8.38.2",
"@wdio/logger": "8.38.0",
"@wdio/protocols": "8.38.0",
"@wdio/types": "8.37.0",
"@wdio/utils": "8.38.0",
"@wdio/types": "8.38.2",
"@wdio/utils": "8.38.2",
"async-exit-hook": "^2.0.1",
"chalk": "^5.2.0",
"chokidar": "^3.5.3",
@ -1216,7 +1216,7 @@
"lodash.union": "^4.6.0",
"read-pkg-up": "10.0.0",
"recursive-readdir": "^2.2.3",
"webdriverio": "8.38.0",
"webdriverio": "8.38.2",
"yargs": "^17.7.2"
},
"bin": {
@ -1239,14 +1239,14 @@
}
},
"node_modules/@wdio/config": {
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.38.0.tgz",
"integrity": "sha512-9eMmHYkXw/0htj8Nok2vBa8Q+IS/wj7HXbLczKb5rEmDb57SW5iPMpZutFywGki1D/GIDLvejWaZvlxmS/yfBA==",
"version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.38.2.tgz",
"integrity": "sha512-xlnapTr1vOA0h5HsHTIqj47729FbG3WjxmgHweDEQvcT4C1g9l+WKf+N3FM7DNNoIsAqxKi6rOHG02rJADQJtw==",
"dev": true,
"dependencies": {
"@wdio/logger": "8.38.0",
"@wdio/types": "8.37.0",
"@wdio/utils": "8.38.0",
"@wdio/types": "8.38.2",
"@wdio/utils": "8.38.2",
"decamelize": "^6.0.0",
"deepmerge-ts": "^5.0.0",
"glob": "^10.2.2",
@ -1257,29 +1257,29 @@
}
},
"node_modules/@wdio/globals": {
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.38.0.tgz",
"integrity": "sha512-3Lo7R305gwJrloUolrgSRaMbIFKwnj/SPoYUt94dsTF1oM3TpyWpomcVokElNQiOFx9WYjMmBla2M+YcnoGmgw==",
"version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/globals/-/globals-8.38.2.tgz",
"integrity": "sha512-iIrUF1EODfHLh3V/CSNCqbNNxUTe3ND+c86zDjzJcPFjawLX1plvAApsU/eDmtsFShcOS2KHbfSjiydFoqQG1Q==",
"dev": true,
"engines": {
"node": "^16.13 || >=18"
},
"optionalDependencies": {
"expect-webdriverio": "^4.11.2",
"webdriverio": "8.38.0"
"webdriverio": "8.38.2"
}
},
"node_modules/@wdio/local-runner": {
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.38.0.tgz",
"integrity": "sha512-++eVI+EQapBMRxtLSbeooK02uELAhIXNLzgBlC03s23OTZUUOxzl4WxFuGqaG8gpNHer5Bjg+uAy0rIbSMnklA==",
"version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/local-runner/-/local-runner-8.38.2.tgz",
"integrity": "sha512-syW+R5VUHJ3GBkQGFcNYe6MYwWRgklc9W7A83xQDTvKWFNHCetLvc8AtKZ54vs8MItBejjU+Oh94ZNbNX1pBcg==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@wdio/logger": "8.38.0",
"@wdio/repl": "8.24.12",
"@wdio/runner": "8.38.0",
"@wdio/types": "8.37.0",
"@wdio/runner": "8.38.2",
"@wdio/types": "8.38.2",
"async-exit-hook": "^2.0.1",
"split2": "^4.1.0",
"stream-buffers": "^3.0.2"
@ -1316,16 +1316,16 @@
}
},
"node_modules/@wdio/mocha-framework": {
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.38.0.tgz",
"integrity": "sha512-LWwKslKIxqhQNskdffcS6QbxN45PzJN21b5zByELbEYd9PIGNbuXXqueVE09RwEAzBHtL86ZhSpFclAB+ulsBw==",
"version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/mocha-framework/-/mocha-framework-8.38.2.tgz",
"integrity": "sha512-qJmRL5E6/ypjCUACH4hvCAAmTdU4YUrUlp9o/IKvTIAHMnZPE0/HgUFixCeu8Mop+rdzTPVBrbqxpRDdSnraYA==",
"dev": true,
"dependencies": {
"@types/mocha": "^10.0.0",
"@types/node": "^20.1.0",
"@wdio/logger": "8.38.0",
"@wdio/types": "8.37.0",
"@wdio/utils": "8.38.0",
"@wdio/types": "8.38.2",
"@wdio/utils": "8.38.2",
"mocha": "^10.0.0"
},
"engines": {
@ -1351,14 +1351,14 @@
}
},
"node_modules/@wdio/reporter": {
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.38.0.tgz",
"integrity": "sha512-7eyBM06j0PAu2g14wOwJbSmUOaT8q1pmMukzeRl1YDoW2sLpQG0zMZNzQNsQyi7+1KgltTJJnvHCec5MBZrjpw==",
"version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/reporter/-/reporter-8.38.2.tgz",
"integrity": "sha512-R78UdAtAnkaV22NYlCCcbPPhmYweiDURiw64LYhlVIQrKNuXUQcafR2kRlWKy31rZc9thSLs5LzrZDReENUlFQ==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@wdio/logger": "8.38.0",
"@wdio/types": "8.37.0",
"@wdio/types": "8.38.2",
"diff": "^5.0.0",
"object-inspect": "^1.12.0"
},
@ -1367,35 +1367,35 @@
}
},
"node_modules/@wdio/runner": {
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.38.0.tgz",
"integrity": "sha512-pmoXwRMUxWXhqce64Y3gqoMqJn0YknJ1U9aHOMxp6uB3iHfzoPA+7Mf5ziSc0uDBcEyjXtau9qMfu7iBHUz62Q==",
"version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/runner/-/runner-8.38.2.tgz",
"integrity": "sha512-5lPnKSX2BBLI2AbYW+hoGPiEUAJXj8F8I6NC2LaBVzf1CLN+w2HWZ7lUiqS14XT0b5/hlSUX6+JYwUXlDbpuuw==",
"dev": true,
"dependencies": {
"@types/node": "^20.11.28",
"@wdio/config": "8.38.0",
"@wdio/globals": "8.38.0",
"@wdio/config": "8.38.2",
"@wdio/globals": "8.38.2",
"@wdio/logger": "8.38.0",
"@wdio/types": "8.37.0",
"@wdio/utils": "8.38.0",
"@wdio/types": "8.38.2",
"@wdio/utils": "8.38.2",
"deepmerge-ts": "^5.1.0",
"expect-webdriverio": "^4.12.0",
"gaze": "^1.1.3",
"webdriver": "8.38.0",
"webdriverio": "8.38.0"
"webdriver": "8.38.2",
"webdriverio": "8.38.2"
},
"engines": {
"node": "^16.13 || >=18"
}
},
"node_modules/@wdio/spec-reporter": {
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.38.0.tgz",
"integrity": "sha512-Cuk/mqsBa+YgAL3OCtsYLUxRkGSYeaXM3LSE5muzY1mSqQlK3a/5GdAXlaOosuhYpUgI0A9xTsMiq7PQd75qHA==",
"version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/spec-reporter/-/spec-reporter-8.38.2.tgz",
"integrity": "sha512-Dntk+lmrp+0I3HRRWkkXED+smshvgsW5cdLKwJhEJ1liI48MdBpdNGf9IHTVckE6nfxcWDyFI4icD9qYv/5bFA==",
"dev": true,
"dependencies": {
"@wdio/reporter": "8.38.0",
"@wdio/types": "8.37.0",
"@wdio/reporter": "8.38.2",
"@wdio/types": "8.38.2",
"chalk": "^5.1.2",
"easy-table": "^1.2.0",
"pretty-ms": "^7.0.0"
@ -1417,9 +1417,9 @@
}
},
"node_modules/@wdio/types": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.37.0.tgz",
"integrity": "sha512-36kmSlZcVhsMlbhaSCQUfL51iG81FlbzW4Dfkz4903cDkxmh64bgxydZbRB5aPLnJzzR7tI3chIME8zSVZFR8w==",
"version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.38.2.tgz",
"integrity": "sha512-+wj1c1OSLdnN4WO5b44Ih4263dTl/eSwMGSI4/pCgIyXIuYQH38JQ+6WRa+c8vJEskUzboq2cSgEQumVZ39ozQ==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0"
@ -1429,14 +1429,14 @@
}
},
"node_modules/@wdio/utils": {
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.38.0.tgz",
"integrity": "sha512-ios7MpyJk4kGW9ZOYxbPpdwVZBI7SzccIgiirqSf8rvJi62VpDA2nfa7i7BY1rs9p7lnenF8phwnuVFGMCoL0w==",
"version": "8.38.2",
"resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.38.2.tgz",
"integrity": "sha512-y5AnBwsGcu/XuCBGCgKmlvKdwEIFyzLA+Cr+denySxY3jbWDONtPUcGaVdFALwsIa5jcIjcATqGmZcCPGnkd7g==",
"dev": true,
"dependencies": {
"@puppeteer/browsers": "^1.6.0",
"@wdio/logger": "8.38.0",
"@wdio/types": "8.37.0",
"@wdio/types": "8.38.2",
"decamelize": "^6.0.0",
"deepmerge-ts": "^5.1.0",
"edgedriver": "^5.5.0",
@ -1879,12 +1879,12 @@
}
},
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"dependencies": {
"fill-range": "^7.0.1"
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
@ -2084,9 +2084,9 @@
}
},
"node_modules/chromedriver": {
"version": "125.0.3",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-125.0.3.tgz",
"integrity": "sha512-Qzuk5Wian2o3EVGjtbz6V/jv+pT/AV9246HbG6kUljZXXjsKZLZxqJC+kHR3qEh/wdv4EJD0YwAOWV72v9hogw==",
"version": "126.0.0",
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-126.0.0.tgz",
"integrity": "sha512-rzwKp1okI9RmFtSyIzkk9+GTlTK62ai5P3/AS2qMwl86+gw84d2S/IyLkQMm5cqieFs4dgDAuqqPu0AqQACScg==",
"hasInstallScript": true,
"dependencies": {
"@testim/chrome-version": "^1.1.4",
@ -3655,9 +3655,9 @@
}
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
@ -6908,9 +6908,9 @@
}
},
"node_modules/prettier": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz",
"integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==",
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
"integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
@ -8969,18 +8969,18 @@
}
},
"node_modules/webdriver": {
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.38.0.tgz",
"integrity": "sha512-BT3sd667AqcZ1lzaOd7lphjnc7MNG3WgduAq4vUUDYlJAbs6SyjYd0EZPIPv9KUUYr0BoSJTDa0Xuyl/6PPW0Q==",
"version": "8.38.2",
"resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.38.2.tgz",
"integrity": "sha512-NGfjW0BDYwFgOIzeojOcWGn3tYloQdvHr+Y2xKKYVqa9Rs0x1mzlTjU1kWtC4DaV8DltskwaPa7o+s8hTNpuyA==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@types/ws": "^8.5.3",
"@wdio/config": "8.38.0",
"@wdio/config": "8.38.2",
"@wdio/logger": "8.38.0",
"@wdio/protocols": "8.38.0",
"@wdio/types": "8.37.0",
"@wdio/utils": "8.38.0",
"@wdio/types": "8.38.2",
"@wdio/utils": "8.38.2",
"deepmerge-ts": "^5.1.0",
"got": "^12.6.1",
"ky": "^0.33.0",
@ -8991,18 +8991,18 @@
}
},
"node_modules/webdriverio": {
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.38.0.tgz",
"integrity": "sha512-PxLtJPK8Aa+f/G/P8YGUwGH80uHowMA8cDHshhog6sKbp1BXEVB8x6PyC1AIswRlTWVijoes7cD0cUoVs6C87A==",
"version": "8.38.2",
"resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.38.2.tgz",
"integrity": "sha512-r09y5UfivyYh5JOzT2SpJJ1zDmQl/R4OTH12opUqkjvp21BibCQm/uu1mrxGy4lzSHljrvqSVrrcGI+6UA1O8w==",
"dev": true,
"dependencies": {
"@types/node": "^20.1.0",
"@wdio/config": "8.38.0",
"@wdio/config": "8.38.2",
"@wdio/logger": "8.38.0",
"@wdio/protocols": "8.38.0",
"@wdio/repl": "8.24.12",
"@wdio/types": "8.37.0",
"@wdio/utils": "8.38.0",
"@wdio/types": "8.38.2",
"@wdio/utils": "8.38.2",
"archiver": "^7.0.0",
"aria-query": "^5.0.0",
"css-shorthand-properties": "^1.1.1",
@ -9020,7 +9020,7 @@
"resq": "^1.9.1",
"rgb2hex": "0.2.5",
"serialize-error": "^11.0.1",
"webdriver": "8.38.0"
"webdriver": "8.38.2"
},
"engines": {
"node": "^16.13 || >=18"

View File

@ -6,15 +6,15 @@
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0",
"@wdio/cli": "^8.38.1",
"@wdio/local-runner": "^8.38.0",
"@wdio/mocha-framework": "^8.38.0",
"@wdio/spec-reporter": "^8.38.0",
"@wdio/cli": "^8.38.2",
"@wdio/local-runner": "^8.38.2",
"@wdio/mocha-framework": "^8.38.2",
"@wdio/spec-reporter": "^8.38.2",
"eslint": "^8.57.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-sonarjs": "^0.25.1",
"npm-run-all": "^4.1.5",
"prettier": "^3.3.0",
"prettier": "^3.3.2",
"ts-node": "^10.9.2",
"typescript": "^5.4.5",
"wdio-wait-for": "^3.0.11"
@ -32,6 +32,6 @@
"node": ">=20"
},
"dependencies": {
"chromedriver": "^125.0.3"
"chromedriver": "^126.0.0"
}
}

View File

@ -3,6 +3,15 @@
This is the default UI for the authentik server. The documentation is going to be a little sparse
for awhile, but at least let's get started.
# Standards
- Be flexible in what you accept as input, be precise in what you produce as output.
- Mis-use is always a crash. A component that takes the ID of an HTMLInputElement as an argument
should throw an exception if the element is anything but an HTMLInputElement ("anything" includes
non-existent, null, undefined, etc.).
- Single Responsibility is ideal, but not always practical. To the best of your obility, every
object in the system should do one thing and do it well.
# The Theory of the authentik UI
In Peter Naur's 1985 essay [Programming as Theory
@ -107,3 +116,7 @@ settings in JSON files, which do not support comments.
- `compilerOptions.plugins.ts-lit-plugin.rules.no-incompatible-type-binding: "warn"`: lit-analyzer
does not support generics well when parsing a subtype of `HTMLElement`. As a result, this threw
too many errors to be supportable.
- `package.json`
- `prettier` should always be the last thing run in any pre-commit pass. The `precommit` script
does this, but if you don't use `precommit`, make sure `prettier` is the _last_ thing you do
before a `git commit`.

8051
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,7 @@
"build-proxy": "run-s build-locales esbuild:build-proxy",
"watch": "run-s build-locales esbuild:watch",
"lint": "cross-env NODE_OPTIONS='--max_old_space_size=65536' eslint . --max-warnings 0 --fix",
"lint:precommit": "cross-env NODE_OPTIONS='--max_old_space_size=65536' node scripts/eslint-precommit.mjs",
"lint:precommit": "bun scripts/eslint-precommit.mjs",
"lint:spelling": "node scripts/check-spelling.mjs",
"lit-analyse": "lit-analyzer src",
"precommit": "npm-run-all --parallel tsc lit-analyse lint:spelling --sequential lint:precommit prettier",
@ -38,15 +38,15 @@
"@codemirror/theme-one-dark": "^6.1.2",
"@formatjs/intl-listformat": "^7.5.7",
"@fortawesome/fontawesome-free": "^6.5.2",
"@goauthentik/api": "^2024.4.2-1717033226",
"@goauthentik/api": "^2024.4.2-1717645682",
"@lit-labs/task": "^3.1.0",
"@lit/context": "^1.1.1",
"@lit/context": "^1.1.2",
"@lit/localize": "^0.12.1",
"@lit/reactive-element": "^2.0.4",
"@open-wc/lit-helpers": "^0.7.0",
"@patternfly/elements": "^3.0.1",
"@patternfly/patternfly": "^4.224.2",
"@sentry/browser": "^8.7.0",
"@sentry/browser": "^8.9.1",
"@webcomponents/webcomponentsjs": "^2.8.0",
"base64-js": "^1.5.1",
"chart.js": "^4.4.3",
@ -54,10 +54,10 @@
"codemirror": "^6.0.1",
"construct-style-sheets-polyfill": "^3.1.0",
"core-js": "^3.37.1",
"country-flag-icons": "^1.5.11",
"country-flag-icons": "^1.5.12",
"fuse.js": "^7.0.0",
"guacamole-common-js": "^1.5.0",
"lit": "^3.1.3",
"lit": "^3.1.4",
"md-front-matter": "^1.0.4",
"mermaid": "^10.9.1",
"rapidoc": "^9.3.4",
@ -65,42 +65,44 @@
"style-mod": "^4.1.2",
"ts-pattern": "^5.1.2",
"webcomponent-qr-code": "^1.2.0",
"yaml": "^2.4.3"
"yaml": "^2.4.5",
"zxcvbn": "^4.4.2"
},
"devDependencies": {
"@babel/core": "^7.24.6",
"@babel/core": "^7.24.7",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-decorators": "^7.24.6",
"@babel/plugin-transform-private-methods": "^7.24.6",
"@babel/plugin-transform-private-property-in-object": "^7.24.6",
"@babel/plugin-transform-runtime": "^7.24.6",
"@babel/preset-env": "^7.24.6",
"@babel/preset-typescript": "^7.24.6",
"@babel/plugin-proposal-decorators": "^7.24.7",
"@babel/plugin-transform-private-methods": "^7.24.7",
"@babel/plugin-transform-private-property-in-object": "^7.24.7",
"@babel/plugin-transform-runtime": "^7.24.7",
"@babel/preset-env": "^7.24.7",
"@babel/preset-typescript": "^7.24.7",
"@hcaptcha/types": "^1.0.3",
"@jeysal/storybook-addon-css-user-preferences": "^0.2.0",
"@lit/localize-tools": "^0.7.2",
"@rollup/plugin-replace": "^5.0.5",
"@rollup/plugin-replace": "^5.0.7",
"@spotlightjs/spotlight": "^1.2.17",
"@storybook/addon-essentials": "^8.1.5",
"@storybook/addon-links": "^8.1.5",
"@storybook/addon-essentials": "^8.1.6",
"@storybook/addon-links": "^8.1.6",
"@storybook/api": "^7.6.17",
"@storybook/blocks": "^8.0.8",
"@storybook/manager-api": "^8.1.5",
"@storybook/web-components": "^8.1.5",
"@storybook/web-components-vite": "^8.1.5",
"@storybook/manager-api": "^8.1.6",
"@storybook/web-components": "^8.1.6",
"@storybook/web-components-vite": "^8.1.6",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/chart.js": "^2.9.41",
"@types/codemirror": "5.60.15",
"@types/grecaptcha": "^3.0.9",
"@types/guacamole-common-js": "1.5.2",
"@types/showdown": "^2.0.6",
"@types/zxcvbn": "^4.4.4",
"@typescript-eslint/eslint-plugin": "^7.5.0",
"@typescript-eslint/parser": "^7.5.0",
"babel-plugin-macros": "^3.1.0",
"babel-plugin-tsconfig-paths": "^1.0.3",
"chokidar": "^3.6.0",
"cross-env": "^7.0.3",
"esbuild": "^0.21.4",
"esbuild": "^0.21.5",
"eslint": "^8.57.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-custom-elements": "0.0.8",
@ -111,16 +113,16 @@
"glob": "^10.4.1",
"lit-analyzer": "^2.0.3",
"npm-run-all": "^4.1.5",
"prettier": "^3.3.0",
"prettier": "^3.3.2",
"pseudolocale": "^2.0.0",
"react": "^18.2.0",
"react-dom": "^18.3.1",
"rollup-plugin-modify": "^3.0.0",
"rollup-plugin-postcss-lit": "^2.1.0",
"storybook": "^8.1.5",
"storybook": "^8.1.6",
"storybook-addon-mock": "^5.0.0",
"ts-lit-plugin": "^2.0.2",
"tslib": "^2.6.2",
"tslib": "^2.6.3",
"turnstile-types": "^1.2.1",
"typescript": "^5.4.5",
"vite-tsconfig-paths": "^4.3.2"

View File

@ -126,6 +126,7 @@ export class PolicyTestForm extends Form<PropertyMappingTestRequest> {
renderForm(): TemplateResult {
return html`<ak-form-element-horizontal label=${msg("User")} name="user">
<ak-search-select
blankable
.fetchObjects=${async (query?: string): Promise<User[]> => {
const args: CoreUsersListRequest = {
ordering: "username",
@ -153,6 +154,7 @@ export class PolicyTestForm extends Form<PropertyMappingTestRequest> {
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${msg("Group")} name="group">
<ak-search-select
blankable
.fetchObjects=${async (query?: string): Promise<Group[]> => {
const args: CoreGroupsListRequest = {
ordering: "name",

View File

@ -1,5 +1,6 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { uiConfig } from "@goauthentik/common/ui/config";
import "@goauthentik/elements/forms/DeleteBulkForm";
import { PaginatedResponse, Table, TableColumn } from "@goauthentik/elements/table/Table";
import { msg } from "@lit/localize";
@ -19,6 +20,26 @@ export class GoogleWorkspaceProviderGroupList extends Table<GoogleWorkspaceProvi
return true;
}
checkbox = true;
clearOnRefresh = true;
renderToolbarSelected(): TemplateResult {
const disabled = this.selectedElements.length < 1;
return html`<ak-forms-delete-bulk
objectLabel=${msg("Google Workspace Group(s)")}
.objects=${this.selectedElements}
.delete=${(item: GoogleWorkspaceProviderGroup) => {
return new ProvidersApi(DEFAULT_CONFIG).providersGoogleWorkspaceGroupsDestroy({
id: item.id,
});
}}
>
<button ?disabled=${disabled} slot="trigger" class="pf-c-button pf-m-danger">
${msg("Delete")}
</button>
</ak-forms-delete-bulk>`;
}
async apiEndpoint(page: number): Promise<PaginatedResponse<GoogleWorkspaceProviderGroup>> {
return new ProvidersApi(DEFAULT_CONFIG).providersGoogleWorkspaceGroupsList({
page: page,

View File

@ -1,5 +1,6 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { uiConfig } from "@goauthentik/common/ui/config";
import "@goauthentik/elements/forms/DeleteBulkForm";
import { PaginatedResponse, Table, TableColumn } from "@goauthentik/elements/table/Table";
import { msg } from "@lit/localize";
@ -19,6 +20,26 @@ export class GoogleWorkspaceProviderUserList extends Table<GoogleWorkspaceProvid
expandable = true;
checkbox = true;
clearOnRefresh = true;
renderToolbarSelected(): TemplateResult {
const disabled = this.selectedElements.length < 1;
return html`<ak-forms-delete-bulk
objectLabel=${msg("Google Workspace User(s)")}
.objects=${this.selectedElements}
.delete=${(item: GoogleWorkspaceProviderUser) => {
return new ProvidersApi(DEFAULT_CONFIG).providersGoogleWorkspaceUsersDestroy({
id: item.id,
});
}}
>
<button ?disabled=${disabled} slot="trigger" class="pf-c-button pf-m-danger">
${msg("Delete")}
</button>
</ak-forms-delete-bulk>`;
}
async apiEndpoint(page: number): Promise<PaginatedResponse<GoogleWorkspaceProviderUser>> {
return new ProvidersApi(DEFAULT_CONFIG).providersGoogleWorkspaceUsersList({
page: page,

View File

@ -1,5 +1,6 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { uiConfig } from "@goauthentik/common/ui/config";
import "@goauthentik/elements/forms/DeleteBulkForm";
import { PaginatedResponse, Table, TableColumn } from "@goauthentik/elements/table/Table";
import { msg } from "@lit/localize";
@ -19,6 +20,23 @@ export class MicrosoftEntraProviderGroupList extends Table<MicrosoftEntraProvide
return true;
}
renderToolbarSelected(): TemplateResult {
const disabled = this.selectedElements.length < 1;
return html`<ak-forms-delete-bulk
objectLabel=${msg("Microsoft Entra Group(s)")}
.objects=${this.selectedElements}
.delete=${(item: MicrosoftEntraProviderGroup) => {
return new ProvidersApi(DEFAULT_CONFIG).providersMicrosoftEntraGroupsDestroy({
id: item.id,
});
}}
>
<button ?disabled=${disabled} slot="trigger" class="pf-c-button pf-m-danger">
${msg("Delete")}
</button>
</ak-forms-delete-bulk>`;
}
async apiEndpoint(page: number): Promise<PaginatedResponse<MicrosoftEntraProviderGroup>> {
return new ProvidersApi(DEFAULT_CONFIG).providersMicrosoftEntraGroupsList({
page: page,

View File

@ -1,5 +1,6 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { uiConfig } from "@goauthentik/common/ui/config";
import "@goauthentik/elements/forms/DeleteBulkForm";
import { PaginatedResponse, Table, TableColumn } from "@goauthentik/elements/table/Table";
import { msg } from "@lit/localize";
@ -19,6 +20,26 @@ export class MicrosoftEntraProviderUserList extends Table<MicrosoftEntraProvider
return true;
}
checkbox = true;
clearOnRefresh = true;
renderToolbarSelected(): TemplateResult {
const disabled = this.selectedElements.length < 1;
return html`<ak-forms-delete-bulk
objectLabel=${msg("Microsoft Entra User(s)")}
.objects=${this.selectedElements}
.delete=${(item: MicrosoftEntraProviderUser) => {
return new ProvidersApi(DEFAULT_CONFIG).providersMicrosoftEntraUsersDestroy({
id: item.id,
});
}}
>
<button ?disabled=${disabled} slot="trigger" class="pf-c-button pf-m-danger">
${msg("Delete")}
</button>
</ak-forms-delete-bulk>`;
}
async apiEndpoint(page: number): Promise<PaginatedResponse<MicrosoftEntraProviderUser>> {
return new ProvidersApi(DEFAULT_CONFIG).providersMicrosoftEntraUsersList({
page: page,

View File

@ -0,0 +1,63 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { uiConfig } from "@goauthentik/common/ui/config";
import "@goauthentik/elements/forms/DeleteBulkForm";
import { PaginatedResponse, Table, TableColumn } from "@goauthentik/elements/table/Table";
import { msg } from "@lit/localize";
import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { ProvidersApi, SCIMProviderGroup } from "@goauthentik/api";
@customElement("ak-provider-scim-groups-list")
export class SCIMProviderGroupList extends Table<SCIMProviderGroup> {
@property({ type: Number })
providerId?: number;
searchEnabled(): boolean {
return true;
}
checkbox = true;
clearOnRefresh = true;
renderToolbarSelected(): TemplateResult {
const disabled = this.selectedElements.length < 1;
return html`<ak-forms-delete-bulk
objectLabel=${msg("SCIM Group(s)")}
.objects=${this.selectedElements}
.delete=${(item: SCIMProviderGroup) => {
return new ProvidersApi(DEFAULT_CONFIG).providersScimGroupsDestroy({
id: item.id,
});
}}
>
<button ?disabled=${disabled} slot="trigger" class="pf-c-button pf-m-danger">
${msg("Delete")}
</button>
</ak-forms-delete-bulk>`;
}
async apiEndpoint(page: number): Promise<PaginatedResponse<SCIMProviderGroup>> {
return new ProvidersApi(DEFAULT_CONFIG).providersScimGroupsList({
page: page,
pageSize: (await uiConfig()).pagination.perPage,
ordering: this.order,
search: this.search || "",
providerId: this.providerId,
});
}
columns(): TableColumn[] {
return [new TableColumn(msg("Name")), new TableColumn(msg("ID"))];
}
row(item: SCIMProviderGroup): TemplateResult[] {
return [
html`<a href="#/identity/groups/${item.groupObj.pk}">
<div>${item.groupObj.name}</div>
</a>`,
html`${item.id}`,
];
}
}

View File

@ -0,0 +1,64 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { uiConfig } from "@goauthentik/common/ui/config";
import "@goauthentik/elements/forms/DeleteBulkForm";
import { PaginatedResponse, Table, TableColumn } from "@goauthentik/elements/table/Table";
import { msg } from "@lit/localize";
import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { ProvidersApi, SCIMProviderUser } from "@goauthentik/api";
@customElement("ak-provider-scim-users-list")
export class SCIMProviderUserList extends Table<SCIMProviderUser> {
@property({ type: Number })
providerId?: number;
searchEnabled(): boolean {
return true;
}
checkbox = true;
clearOnRefresh = true;
renderToolbarSelected(): TemplateResult {
const disabled = this.selectedElements.length < 1;
return html`<ak-forms-delete-bulk
objectLabel=${msg("SCIM User(s)")}
.objects=${this.selectedElements}
.delete=${(item: SCIMProviderUser) => {
return new ProvidersApi(DEFAULT_CONFIG).providersScimUsersDestroy({
id: item.id,
});
}}
>
<button ?disabled=${disabled} slot="trigger" class="pf-c-button pf-m-danger">
${msg("Delete")}
</button>
</ak-forms-delete-bulk>`;
}
async apiEndpoint(page: number): Promise<PaginatedResponse<SCIMProviderUser>> {
return new ProvidersApi(DEFAULT_CONFIG).providersScimUsersList({
page: page,
pageSize: (await uiConfig()).pagination.perPage,
ordering: this.order,
search: this.search || "",
providerId: this.providerId,
});
}
columns(): TableColumn[] {
return [new TableColumn(msg("Username")), new TableColumn(msg("ID"))];
}
row(item: SCIMProviderUser): TemplateResult[] {
return [
html`<a href="#/identity/users/${item.userObj.pk}">
<div>${item.userObj.username}</div>
<small>${item.userObj.name}</small>
</a>`,
html`${item.id}`,
];
}
}

View File

@ -1,4 +1,6 @@
import "@goauthentik/admin/providers/scim/SCIMProviderForm";
import "@goauthentik/admin/providers/scim/SCIMProviderGroupList";
import "@goauthentik/admin/providers/scim/SCIMProviderUserList";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { EVENT_REFRESH } from "@goauthentik/common/constants";
import "@goauthentik/components/events/ObjectChangelog";
@ -102,6 +104,28 @@ export class SCIMProviderViewPage extends AKElement {
</div>
</div>
</section>
<section
slot="page-users"
data-tab-title="${msg("Provisioned Users")}"
class="pf-c-page__main-section pf-m-no-padding-mobile"
>
<div class="pf-l-grid pf-m-gutter">
<ak-provider-scim-users-list
providerId=${this.provider.pk}
></ak-provider-scim-users-list>
</div>
</section>
<section
slot="page-groups"
data-tab-title="${msg("Provisioned Groups")}"
class="pf-c-page__main-section pf-m-no-padding-mobile"
>
<div class="pf-l-grid pf-m-gutter">
<ak-provider-scim-groups-list
providerId=${this.provider.pk}
></ak-provider-scim-groups-list>
</div>
</section>
<ak-rbac-object-permission-page
slot="page-permissions"
data-tab-title="${msg("Permissions")}"

View File

@ -1,5 +1,7 @@
import { BaseStageForm } from "@goauthentik/admin/stages/BaseStageForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-number-input";
import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
@ -78,6 +80,40 @@ export class CaptchaStageForm extends BaseStageForm<CaptchaStage> {
)}
</p>
</ak-form-element-horizontal>
<ak-number-input
label=${msg("Score minimum threshold")}
required
name="scoreMinThreshold"
value="${ifDefined(this.instance?.scoreMinThreshold || 0.5)}"
help=${msg("Minimum required score to allow continuing")}
></ak-number-input>
<ak-number-input
label=${msg("Score maximum threshold")}
required
name="scoreMaxThreshold"
value="${ifDefined(this.instance?.scoreMaxThreshold || -1)}"
help=${msg("Maximum allowed score to allow continuing")}
></ak-number-input>
<ak-form-element-horizontal name="errorOnInvalidScore">
<label class="pf-c-switch">
<input
class="pf-c-switch__input"
type="checkbox"
?checked=${first(this.instance?.errorOnInvalidScore, true)}
/>
<span class="pf-c-switch__toggle">
<span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${msg("Error on invalid score")}</span>
</label>
<p class="pf-c-form__helper-text">
${msg(
"When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.",
)}
</p>
</ak-form-element-horizontal>
</div>
</ak-form-group>
<ak-form-group>

View File

@ -3,7 +3,7 @@ import { PFSize } from "@goauthentik/common/enums.js";
import { AKElement } from "@goauthentik/elements/Base";
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
import { Task, TaskStatus } from "@lit/task";
import { Task, TaskStatus, initialState } from "@lit/task";
import { css, html } from "lit";
import { property } from "lit/decorators.js";
@ -67,7 +67,7 @@ export abstract class BaseTaskButton extends CustomEmitterElement(AKElement) {
this.onError = this.onError.bind(this);
this.onClick = this.onClick.bind(this);
this.actionTask = new Task(this, {
task: () => this.callAction(),
task: () => this.runCallAction(),
args: () => [],
autoRun: false,
onComplete: (r: unknown) => this.onSuccess(r),
@ -77,7 +77,6 @@ export abstract class BaseTaskButton extends CustomEmitterElement(AKElement) {
onComplete() {
setTimeout(() => {
this.actionTask.status = TaskStatus.INITIAL;
this.dispatchCustomEvent(`${this.eventPrefix}-reset`);
this.requestUpdate();
}, SPINNER_TIMEOUT);
@ -97,10 +96,12 @@ export abstract class BaseTaskButton extends CustomEmitterElement(AKElement) {
this.onComplete();
}
async runCallAction() {
await this.callAction();
return initialState;
}
onClick() {
if (this.actionTask.status !== TaskStatus.INITIAL) {
return;
}
this.dispatchCustomEvent(`${this.eventPrefix}-click`);
this.actionTask.run();
}
@ -113,7 +114,7 @@ export abstract class BaseTaskButton extends CustomEmitterElement(AKElement) {
return [
...this.classList,
StatusMap.get(this.actionTask.status),
this.actionTask.status === TaskStatus.INITIAL ? "" : "working",
this.actionTask.status === TaskStatus.PENDING ? "working" : "",
]
.join(" ")
.trim();

View File

@ -0,0 +1,5 @@
import PasswordMatchIndicator from "./password-match-indicator.js";
export { PasswordMatchIndicator };
export default PasswordMatchIndicator;

View File

@ -0,0 +1,19 @@
import { html } from "lit";
import ".";
export default {
title: "Elements/Password Match Indicator",
};
export const Primary = () =>
html`<div style="background: #fff; padding: 4em">
<p>Type some text: <input id="primary-example" style="color:#000" /></p>
<p style="margin-top:0.5em">
Type some other text: <input id="primary-example_repeat" style="color:#000" />
<ak-password-match-indicator
first="#primary-example"
second="#primary-example_repeat"
></ak-password-match-indicator>
</p>
</div>`;

View File

@ -0,0 +1,94 @@
import { AKElement } from "@goauthentik/elements/Base";
import { css, html } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import findInput from "../password-strength-indicator/findInput.js";
const ELEMENT = "ak-password-match-indicator";
@customElement(ELEMENT)
export class PasswordMatchIndicator extends AKElement {
static styles = [
PFBase,
css`
:host {
display: grid;
place-items: center center;
}
`,
];
/**
* A valid selector for the first input element to observe. Attaching this to anything other
* than an HTMLInputElement will throw an exception.
*/
@property({ attribute: true })
first = "";
/**
* A valid selector for the second input element to observe. Attaching this to anything other
* than an HTMLInputElement will throw an exception.
*/
@property({ attribute: true })
second = "";
firstElement?: HTMLInputElement;
secondElement?: HTMLInputElement;
@state()
match = false;
constructor() {
super();
this.checkPasswordMatch = this.checkPasswordMatch.bind(this);
}
connectedCallback() {
super.connectedCallback();
this.firstInput.addEventListener("keyup", this.checkPasswordMatch);
this.secondInput.addEventListener("keyup", this.checkPasswordMatch);
}
disconnectedCallback() {
this.secondInput.removeEventListener("keyup", this.checkPasswordMatch);
this.firstInput.removeEventListener("keyup", this.checkPasswordMatch);
super.disconnectedCallback();
}
checkPasswordMatch() {
this.match =
this.firstInput.value.length > 0 &&
this.secondInput.value.length > 0 &&
this.firstInput.value === this.secondInput.value;
}
get firstInput() {
if (this.firstElement) {
return this.firstElement;
}
return (this.firstElement = findInput(this.getRootNode() as Element, ELEMENT, this.first));
}
get secondInput() {
if (this.secondElement) {
return this.secondElement;
}
return (this.secondElement = findInput(
this.getRootNode() as Element,
ELEMENT,
this.second,
));
}
render() {
return this.match
? html`<i class="pf-icon pf-icon-ok pf-m-success"></i>`
: html`<i class="pf-icon pf-icon-warning-triangle pf-m-warning"></i>`;
}
}
export default PasswordMatchIndicator;

View File

@ -0,0 +1,18 @@
export function findInput(root: Element, tag: string, src: string) {
const inputs = Array.from(root.querySelectorAll(src));
if (inputs.length === 0) {
throw new Error(`${tag}: no element found for 'src' ${src}`);
}
if (inputs.length > 1) {
throw new Error(`${tag}: more than one element found for 'src' ${src}`);
}
const input = inputs[0];
if (!(input instanceof HTMLInputElement)) {
throw new Error(
`${tag}: the 'src' element must be an <input> tag, found ${input.localName}`,
);
}
return input;
}
export default findInput;

View File

@ -0,0 +1,5 @@
import PasswordStrengthIndicator from "./password-strength-indicator.js";
export { PasswordStrengthIndicator };
export default PasswordStrengthIndicator;

View File

@ -0,0 +1,13 @@
import { html } from "lit";
import ".";
export default {
title: "Elements/Password Strength Indicator",
};
export const Primary = () =>
html`<div style="background: #fff; padding: 4em">
<p>Type some text: <input id="primary-example" style="color:#000" /></p>
<ak-password-strength-indicator src="#primary-example"></ak-password-strength-indicator>
</div>`;

View File

@ -0,0 +1,91 @@
import { AKElement } from "@goauthentik/elements/Base";
import zxcvbn from "zxcvbn";
import { css, html } from "lit";
import { styleMap } from "lit-html/directives/style-map.js";
import { customElement, property, state } from "lit/decorators.js";
import findInput from "./findInput";
const styles = css`
.password-meter-wrap {
margin-top: 5px;
height: 0.5em;
background-color: #ddd;
border-radius: 0.25em;
overflow: hidden;
}
.password-meter-bar {
width: 0;
height: 100%;
transition: width 400ms ease-in;
}
`;
const LEVELS = [
["20%", "#dd0000"],
["40%", "#ff5500"],
["60%", "#ffff00"],
["80%", "#a1a841"],
["100%", "#339933"],
].map(([width, backgroundColor]) => ({ width, backgroundColor }));
/**
* A simple display of the password strength.
*/
const ELEMENT = "ak-password-strength-indicator";
@customElement(ELEMENT)
export class PasswordStrengthIndicator extends AKElement {
static styles = styles;
/**
* The input element to observe. Attaching this to anything other than an HTMLInputElement will
* throw an exception.
*/
@property({ attribute: true })
src = "";
sourceInput?: HTMLInputElement;
@state()
strength = LEVELS[0];
constructor() {
super();
this.checkPasswordStrength = this.checkPasswordStrength.bind(this);
}
connectedCallback() {
super.connectedCallback();
this.input.addEventListener("keyup", this.checkPasswordStrength);
}
disconnectedCallback() {
this.input.removeEventListener("keyup", this.checkPasswordStrength);
super.disconnectedCallback();
}
checkPasswordStrength() {
const { score } = zxcvbn(this.input.value);
this.strength = LEVELS[score];
}
get input(): HTMLInputElement {
if (this.sourceInput) {
return this.sourceInput;
}
return (this.sourceInput = findInput(this.getRootNode() as Element, ELEMENT, this.src));
}
render() {
return html` <div class="password-meter-wrap">
<div class="password-meter-bar" style=${styleMap(this.strength)}></div>
</div>`;
}
}
export default PasswordStrengthIndicator;

View File

@ -15,7 +15,7 @@ import PFProgressStepper from "@patternfly/patternfly/components/ProgressStepper
import PFStack from "@patternfly/patternfly/layouts/Stack/stack.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { FlowInspection, FlowsApi, Stage } from "@goauthentik/api";
import { FlowInspection, FlowsApi, ResponseError, Stage } from "@goauthentik/api";
@customElement("ak-flow-inspector")
export class FlowInspector extends AKElement {
@ -25,7 +25,7 @@ export class FlowInspector extends AKElement {
state?: FlowInspection;
@property({ attribute: false })
error?: Response;
error?: ResponseError;
static get styles(): CSSResult[] {
return [
@ -70,6 +70,7 @@ export class FlowInspector extends AKElement {
flowSlug: this.flowSlug,
})
.then((state) => {
this.error = undefined;
this.state = state;
})
.catch((exc) => {
@ -100,7 +101,7 @@ export class FlowInspector extends AKElement {
<div class="pf-l-stack pf-m-gutter">
<div class="pf-l-stack__item">
<div class="pf-c-card">
<div class="pf-c-card__body">${this.error?.statusText}</div>
<div class="pf-c-card__body">${this.error?.message}</div>
</div>
</div>
</div>

View File

@ -0,0 +1,108 @@
import { TemplateResult, html } from "lit";
import "@patternfly/patternfly/components/Alert/alert.css";
import "@patternfly/patternfly/components/Button/button.css";
import "@patternfly/patternfly/components/Check/check.css";
import "@patternfly/patternfly/components/Form/form.css";
import "@patternfly/patternfly/components/FormControl/form-control.css";
import "@patternfly/patternfly/components/Login/login.css";
import "@patternfly/patternfly/components/Title/title.css";
import "@patternfly/patternfly/patternfly-base.css";
import { PromptTypeEnum } from "@goauthentik/api";
import type { StagePrompt } from "@goauthentik/api";
import promptRenderers from "./FieldRenderers";
import { renderContinue, renderPromptHelpText, renderPromptInner } from "./helpers";
// Storybook stories are meant to show not just that the objects work, but to document good
// practices around using them. Because of their uniform signature, the renderers can easily
// be encapsulated into containers that show them at their most functional, even without
// building Shadow DOMs with which to do it. This is 100% Light DOM work, and they still
// work well.
const baseRenderer = (prompt: TemplateResult) =>
html`<div style="background: #fff; padding: 4em; max-width: 24em;">
<style>
input,
textarea,
select,
button,
.pf-c-form__helper-text:not(.pf-m-error),
input + label.pf-c-check__label {
color: #000;
}
input[readonly],
textarea[readonly] {
color: #fff;
}
</style>
${prompt}
</div>`;
function renderer(kind: PromptTypeEnum, prompt: Partial<StagePrompt>) {
const renderer = promptRenderers.get(kind);
if (!renderer) {
throw new Error(`A renderer of type ${kind} does not exist.`);
}
return baseRenderer(html`${renderer(prompt as StagePrompt)}`);
}
const textPrompt = {
fieldKey: "test_text_field",
placeholder: "This is the placeholder",
required: false,
initialValue: "initial value",
};
export const Text = () => renderer(PromptTypeEnum.Text, textPrompt);
export const TextArea = () => renderer(PromptTypeEnum.TextArea, textPrompt);
export const TextReadOnly = () => renderer(PromptTypeEnum.TextReadOnly, textPrompt);
export const TextAreaReadOnly = () => renderer(PromptTypeEnum.TextAreaReadOnly, textPrompt);
export const Username = () => renderer(PromptTypeEnum.Username, textPrompt);
export const Password = () => renderer(PromptTypeEnum.Password, textPrompt);
const emailPrompt = { ...textPrompt, initialValue: "example@example.fun" };
export const Email = () => renderer(PromptTypeEnum.Email, emailPrompt);
const numberPrompt = { ...textPrompt, initialValue: "10" };
export const Number = () => renderer(PromptTypeEnum.Number, numberPrompt);
const datePrompt = { ...textPrompt, initialValue: "2018-06-12T19:30" };
export const Date = () => renderer(PromptTypeEnum.Date, datePrompt);
export const DateTime = () => renderer(PromptTypeEnum.DateTime, datePrompt);
const separatorPrompt = { placeholder: "😊" };
export const Separator = () => renderer(PromptTypeEnum.Separator, separatorPrompt);
const staticPrompt = { initialValue: "😊" };
export const Static = () => renderer(PromptTypeEnum.Static, staticPrompt);
const choicePrompt = {
fieldKey: "test_text_field",
placeholder: "This is the placeholder",
required: false,
initialValue: "first",
choices: ["first", "second", "third"],
};
export const Dropdown = () => renderer(PromptTypeEnum.Dropdown, choicePrompt);
export const RadioButtonGroup = () => renderer(PromptTypeEnum.RadioButtonGroup, choicePrompt);
const checkPrompt = { ...textPrompt, label: "Favorite Subtext?", subText: "(Xena & Gabrielle)" };
export const Checkbox = () => renderer(PromptTypeEnum.Checkbox, checkPrompt);
const localePrompt = { ...textPrompt, initialValue: "en" };
export const Locale = () => renderer(PromptTypeEnum.AkLocale, localePrompt);
export const PromptFailure = () =>
baseRenderer(renderPromptInner({ type: null } as unknown as StagePrompt));
export const HelpText = () =>
baseRenderer(renderPromptHelpText({ subText: "There is no subtext here." } as StagePrompt));
export const Continue = () => baseRenderer(renderContinue());
export default {
title: "Flow Components/Field Renderers",
};

View File

@ -0,0 +1,271 @@
import { rootInterface } from "@goauthentik/elements/Base";
import { LOCALES } from "@goauthentik/elements/ak-locale-context/helpers";
import "@goauthentik/elements/password-match-indicator";
import "@goauthentik/elements/password-strength-indicator";
import { msg } from "@lit/localize";
import { TemplateResult, html } from "lit";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import { CapabilitiesEnum, PromptTypeEnum, StagePrompt } from "@goauthentik/api";
export function password(prompt: StagePrompt) {
return html`<input
type="password"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
autocomplete="new-password"
class="pf-c-form-control"
?required=${prompt.required}
/><ak-password-strength-indicator
src='input[name="${prompt.fieldKey}"]'
></ak-password-strength-indicator>`;
}
const REPEAT = /_repeat/;
export function repeatPassword(prompt: StagePrompt) {
const first = `input[name="${prompt.fieldKey}"]`;
const second = `input[name="${prompt.fieldKey.replace(REPEAT, "")}"]`;
return html` <div style="display:flex; flex-direction:row; gap: 0.5em; align-content: center">
<input
style="flex:1 0"
type="password"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
autocomplete="new-password"
class="pf-c-form-control"
?required=${prompt.required}
/><ak-password-match-indicator
first="${first}"
second="${second}"
></ak-password-match-indicator>
</div>`;
}
export function renderPassword(prompt: StagePrompt) {
return REPEAT.test(prompt.fieldKey) ? repeatPassword(prompt) : password(prompt);
}
export function renderText(prompt: StagePrompt) {
return html`<input
type="text"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
autocomplete="off"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
}
export function renderTextArea(prompt: StagePrompt) {
return html`<textarea
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
autocomplete="off"
class="pf-c-form-control"
?required=${prompt.required}
>
${prompt.initialValue}</textarea
>`;
}
export function renderTextReadOnly(prompt: StagePrompt) {
return html`<input
type="text"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?readonly=${true}
value="${prompt.initialValue}"
/>`;
}
export function renderTextAreaReadOnly(prompt: StagePrompt) {
return html`<textarea
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
readonly
>
${prompt.initialValue}</textarea
>`;
}
export function renderUsername(prompt: StagePrompt) {
return html`<input
type="text"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
autocomplete="username"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
}
export function renderEmail(prompt: StagePrompt) {
return html`<input
type="email"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
}
export function renderNumber(prompt: StagePrompt) {
return html`<input
type="number"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
}
export function renderDate(prompt: StagePrompt) {
return html`<input
type="date"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
}
export function renderDateTime(prompt: StagePrompt) {
return html`<input
type="datetime"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
}
export function renderFile(prompt: StagePrompt) {
return html`<input
type="file"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
}
export function renderSeparator(prompt: StagePrompt) {
return html`<ak-divider>${prompt.placeholder}</ak-divider>`;
}
export function renderHidden(prompt: StagePrompt) {
return html`<input
type="hidden"
name="${prompt.fieldKey}"
value="${prompt.initialValue}"
class="pf-c-form-control"
?required=${prompt.required}
/>`;
}
export function renderStatic(prompt: StagePrompt) {
return html`<p>${unsafeHTML(prompt.initialValue)}</p>`;
}
export function renderDropdown(prompt: StagePrompt) {
return html`<select class="pf-c-form-control" name="${prompt.fieldKey}">
${prompt.choices?.map((choice) => {
return html`<option value="${choice}" ?selected=${prompt.initialValue === choice}>
${choice}
</option>`;
})}
</select>`;
}
export function renderRadioButtonGroup(prompt: StagePrompt) {
return html`${(prompt.choices || []).map((choice) => {
const id = `${prompt.fieldKey}-${choice}`;
return html`<div class="pf-c-check">
<input
type="radio"
class="pf-c-check__input"
name="${prompt.fieldKey}"
id="${id}"
?checked="${prompt.initialValue === choice}"
?required="${prompt.required}"
value="${choice}"
/>
<label class="pf-c-check__label" for=${id}>${choice}</label>
</div> `;
})}`;
}
export function renderCheckbox(prompt: StagePrompt) {
return html`<div class="pf-c-check">
<input
type="checkbox"
class="pf-c-check__input"
id="${prompt.fieldKey}"
name="${prompt.fieldKey}"
?checked=${prompt.initialValue !== ""}
?required=${prompt.required}
/>
<label class="pf-c-check__label" for="${prompt.fieldKey}">${prompt.label}</label>
${prompt.required
? html`<p class="pf-c-form__helper-text">${msg("Required.")}</p>`
: html``}
<p class="pf-c-form__helper-text">${unsafeHTML(prompt.subText)}</p>
</div>`;
}
export function renderAkLocale(prompt: StagePrompt) {
// TODO: External reference.
const inDebug = rootInterface()?.config?.capabilities.includes(CapabilitiesEnum.CanDebug);
const locales = inDebug ? LOCALES : LOCALES.filter((locale) => locale.code !== "debug");
const options = locales.map(
(locale) =>
html`<option value=${locale.code} ?selected=${locale.code === prompt.initialValue}>
${locale.code.toUpperCase()} - ${locale.label()}
</option> `,
);
return html`<select class="pf-c-form-control" name="${prompt.fieldKey}">
<option value="" ?selected=${prompt.initialValue === ""}>
${msg("Auto-detect (based on your browser)")}
</option>
${options}
</select>`;
}
type Renderer = (prompt: StagePrompt) => TemplateResult;
export const promptRenderers = new Map<PromptTypeEnum, Renderer>([
[PromptTypeEnum.Text, renderText],
[PromptTypeEnum.TextArea, renderTextArea],
[PromptTypeEnum.TextReadOnly, renderTextReadOnly],
[PromptTypeEnum.TextAreaReadOnly, renderTextAreaReadOnly],
[PromptTypeEnum.Username, renderUsername],
[PromptTypeEnum.Email, renderEmail],
[PromptTypeEnum.Password, renderPassword],
[PromptTypeEnum.Number, renderNumber],
[PromptTypeEnum.Date, renderDate],
[PromptTypeEnum.DateTime, renderDateTime],
[PromptTypeEnum.File, renderFile],
[PromptTypeEnum.Separator, renderSeparator],
[PromptTypeEnum.Hidden, renderHidden],
[PromptTypeEnum.Static, renderStatic],
[PromptTypeEnum.Dropdown, renderDropdown],
[PromptTypeEnum.RadioButtonGroup, renderRadioButtonGroup],
[PromptTypeEnum.Checkbox, renderCheckbox],
[PromptTypeEnum.AkLocale, renderAkLocale],
]);
export default promptRenderers;

View File

@ -1,17 +1,12 @@
import "@goauthentik/elements/Divider";
import "@goauthentik/elements/EmptyState";
import {
CapabilitiesEnum,
WithCapabilitiesConfig,
} from "@goauthentik/elements/Interface/capabilitiesProvider";
import { LOCALES } from "@goauthentik/elements/ak-locale-context/definitions";
import { WithCapabilitiesConfig } from "@goauthentik/elements/Interface/capabilitiesProvider";
import "@goauthentik/elements/forms/FormElement";
import { BaseStage } from "@goauthentik/flow/stages/base";
import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement } from "lit/decorators.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import PFAlert from "@patternfly/patternfly/components/Alert/alert.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
@ -29,6 +24,14 @@ import {
StagePrompt,
} from "@goauthentik/api";
import { renderCheckbox } from "./FieldRenderers";
import {
renderContinue,
renderPromptHelpText,
renderPromptInner,
shouldRenderInWrapper,
} from "./helpers";
@customElement("ak-stage-prompt")
export class PromptStage extends WithCapabilitiesConfig(
BaseStage<PromptChallenge, PromptChallengeResponseRequest>,
@ -53,232 +56,35 @@ export class PromptStage extends WithCapabilitiesConfig(
];
}
renderPromptInner(prompt: StagePrompt): TemplateResult {
switch (prompt.type) {
case PromptTypeEnum.Text:
return html`<input
type="text"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
autocomplete="off"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
case PromptTypeEnum.TextArea:
return html`<textarea
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
autocomplete="off"
class="pf-c-form-control"
?required=${prompt.required}
>
${prompt.initialValue}</textarea
>`;
case PromptTypeEnum.TextReadOnly:
return html`<input
type="text"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?readonly=${true}
value="${prompt.initialValue}"
/>`;
case PromptTypeEnum.TextAreaReadOnly:
return html`<textarea
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
readonly
>
${prompt.initialValue}</textarea
>`;
case PromptTypeEnum.Username:
return html`<input
type="text"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
autocomplete="username"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
case PromptTypeEnum.Email:
return html`<input
type="email"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
case PromptTypeEnum.Password:
return html`<input
type="password"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
autocomplete="new-password"
class="pf-c-form-control"
?required=${prompt.required}
/>`;
case PromptTypeEnum.Number:
return html`<input
type="number"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
case PromptTypeEnum.Date:
return html`<input
type="date"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
case PromptTypeEnum.DateTime:
return html`<input
type="datetime"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
case PromptTypeEnum.File:
return html`<input
type="file"
name="${prompt.fieldKey}"
placeholder="${prompt.placeholder}"
class="pf-c-form-control"
?required=${prompt.required}
value="${prompt.initialValue}"
/>`;
case PromptTypeEnum.Separator:
return html`<ak-divider>${prompt.placeholder}</ak-divider>`;
case PromptTypeEnum.Hidden:
return html`<input
type="hidden"
name="${prompt.fieldKey}"
value="${prompt.initialValue}"
class="pf-c-form-control"
?required=${prompt.required}
/>`;
case PromptTypeEnum.Static:
return html`<p>${unsafeHTML(prompt.initialValue)}</p>`;
case PromptTypeEnum.Dropdown:
return html`<select class="pf-c-form-control" name="${prompt.fieldKey}">
${prompt.choices?.map((choice) => {
return html`<option
value="${choice}"
?selected=${prompt.initialValue === choice}
>
${choice}
</option>`;
})}
</select>`;
case PromptTypeEnum.RadioButtonGroup:
return html`${(prompt.choices || []).map((choice) => {
const id = `${prompt.fieldKey}-${choice}`;
return html`<div class="pf-c-check">
<input
type="radio"
class="pf-c-check__input"
name="${prompt.fieldKey}"
id="${id}"
?checked="${prompt.initialValue === choice}"
?required="${prompt.required}"
value="${choice}"
/>
<label class="pf-c-check__label" for=${id}>${choice}</label>
</div> `;
})}`;
case PromptTypeEnum.AkLocale: {
const locales = this.can(CapabilitiesEnum.CanDebug)
? LOCALES
: LOCALES.filter((locale) => locale.code !== "debug");
const options = locales.map(
(locale) =>
html`<option
value=${locale.code}
?selected=${locale.code === prompt.initialValue}
>
${locale.code.toUpperCase()} - ${locale.label()}
</option> `,
);
/* TODO: Legacy: None of these refer to the `this` field. Static fields are a code smell. */
return html`<select class="pf-c-form-control" name="${prompt.fieldKey}">
<option value="" ?selected=${prompt.initialValue === ""}>
${msg("Auto-detect (based on your browser)")}
</option>
${options}
</select>`;
}
default:
return html`<p>invalid type '${prompt.type}'</p>`;
}
renderPromptInner(prompt: StagePrompt) {
return renderPromptInner(prompt);
}
renderPromptHelpText(prompt: StagePrompt): TemplateResult {
if (prompt.subText === "") {
return html``;
}
return html`<p class="pf-c-form__helper-text">${unsafeHTML(prompt.subText)}</p>`;
renderPromptHelpText(prompt: StagePrompt) {
return renderPromptHelpText(prompt);
}
shouldRenderInWrapper(prompt: StagePrompt): boolean {
// Special types that aren't rendered in a wrapper
if (
prompt.type === PromptTypeEnum.Static ||
prompt.type === PromptTypeEnum.Hidden ||
prompt.type === PromptTypeEnum.Separator
) {
return false;
}
return true;
shouldRenderInWrapper(prompt: StagePrompt) {
return shouldRenderInWrapper(prompt);
}
renderField(prompt: StagePrompt): TemplateResult {
// Checkbox is rendered differently
// Checkbox has a slightly different layout, so it must be intercepted early.
if (prompt.type === PromptTypeEnum.Checkbox) {
return html`<div class="pf-c-check">
<input
type="checkbox"
class="pf-c-check__input"
id="${prompt.fieldKey}"
name="${prompt.fieldKey}"
?checked=${prompt.initialValue !== ""}
?required=${prompt.required}
/>
<label class="pf-c-check__label" for="${prompt.fieldKey}">${prompt.label}</label>
${prompt.required
? html`<p class="pf-c-form__helper-text">${msg("Required.")}</p>`
: html``}
<p class="pf-c-form__helper-text">${unsafeHTML(prompt.subText)}</p>
</div>`;
return renderCheckbox(prompt);
}
if (this.shouldRenderInWrapper(prompt)) {
if (shouldRenderInWrapper(prompt)) {
return html`<ak-form-element
label="${prompt.label}"
?required="${prompt.required}"
class="pf-c-form__group"
.errors=${(this.challenge?.responseErrors || {})[prompt.fieldKey]}
>
${this.renderPromptInner(prompt)} ${this.renderPromptHelpText(prompt)}
${renderPromptInner(prompt)} ${renderPromptHelpText(prompt)}
</ak-form-element>`;
}
return html` ${this.renderPromptInner(prompt)} ${this.renderPromptHelpText(prompt)}`;
}
renderContinue(): TemplateResult {
return html` <div class="pf-c-form__group pf-m-action">
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
${msg("Continue")}
</button>
</div>`;
return html` ${renderPromptInner(prompt)} ${renderPromptHelpText(prompt)}`;
}
render(): TemplateResult {
@ -286,6 +92,7 @@ ${prompt.initialValue}</textarea
return html`<ak-empty-state ?loading="${true}" header=${msg("Loading")}>
</ak-empty-state>`;
}
return html`<header class="pf-c-login__main-header">
<h1 class="pf-c-title pf-m-3xl">${this.challenge.flowInfo?.title}</h1>
</header>
@ -304,7 +111,7 @@ ${prompt.initialValue}</textarea
this.challenge?.responseErrors?.non_field_errors || [],
)
: html``}
${this.renderContinue()}
${renderContinue()}
</form>
</div>
<footer class="pf-c-login__main-footer">

View File

@ -0,0 +1,37 @@
import { msg } from "@lit/localize";
import { html } from "lit";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import { PromptTypeEnum, StagePrompt } from "@goauthentik/api";
import promptRenderers from "./FieldRenderers";
export function renderPromptInner(prompt: StagePrompt) {
const renderer = promptRenderers.get(prompt.type);
if (!renderer) {
return html`<p>invalid type '${JSON.stringify(prompt.type, null, 2)}'</p>`;
}
return renderer(prompt);
}
export function renderPromptHelpText(prompt: StagePrompt) {
if (prompt.subText === "") {
return html``;
}
return html`<p class="pf-c-form__helper-text">${unsafeHTML(prompt.subText)}</p>`;
}
export function shouldRenderInWrapper(prompt: StagePrompt) {
// Special types that aren't rendered in a wrapper
const specialTypes = [PromptTypeEnum.Static, PromptTypeEnum.Hidden, PromptTypeEnum.Separator];
const special = specialTypes.find((s) => s === prompt.type);
return !special;
}
export function renderContinue() {
return html` <div class="pf-c-form__group pf-m-action">
<button type="submit" class="pf-c-button pf-m-primary pf-m-block">
${msg("Continue")}
</button>
</div>`;
}

View File

@ -6641,6 +6641,42 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s001fd928369d4ddc">
<source><x id="0" equiv-text="${versionString}"/> (FIPS)</source>
</trans-unit>
<trans-unit id="sce17c2bdea3e6ace">
<source>Score minimum threshold</source>
</trans-unit>
<trans-unit id="sf2fcb974c62625fc">
<source>Minimum required score to allow continuing</source>
</trans-unit>
<trans-unit id="s7452199a73ce8b78">
<source>Score maximum threshold</source>
</trans-unit>
<trans-unit id="s2d3a6cd50b46b44d">
<source>Maximum allowed score to allow continuing</source>
</trans-unit>
<trans-unit id="s9d6e40d9a9a58fbf">
<source>Error on invalid score</source>
</trans-unit>
<trans-unit id="s2af59e2f9f12847a">
<source>When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.</source>
</trans-unit>
<trans-unit id="s10092327ad833090">
<source>Microsoft Entra Group(s)</source>
</trans-unit>
<trans-unit id="s811c45ad24a5feae">
<source>Microsoft Entra User(s)</source>
</trans-unit>
<trans-unit id="s7d2d3d298fdccfc8">
<source>Google Workspace Group(s)</source>
</trans-unit>
<trans-unit id="s8c9cf2c004755526">
<source>Google Workspace User(s)</source>
</trans-unit>
<trans-unit id="sd000b42fea07c34a">
<source>SCIM Group(s)</source>
</trans-unit>
<trans-unit id="s146769fb55f1ee50">
<source>SCIM User(s)</source>
</trans-unit>
</body>
</file>

View File

@ -6907,6 +6907,42 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s001fd928369d4ddc">
<source><x id="0" equiv-text="${versionString}"/> (FIPS)</source>
</trans-unit>
<trans-unit id="sce17c2bdea3e6ace">
<source>Score minimum threshold</source>
</trans-unit>
<trans-unit id="sf2fcb974c62625fc">
<source>Minimum required score to allow continuing</source>
</trans-unit>
<trans-unit id="s7452199a73ce8b78">
<source>Score maximum threshold</source>
</trans-unit>
<trans-unit id="s2d3a6cd50b46b44d">
<source>Maximum allowed score to allow continuing</source>
</trans-unit>
<trans-unit id="s9d6e40d9a9a58fbf">
<source>Error on invalid score</source>
</trans-unit>
<trans-unit id="s2af59e2f9f12847a">
<source>When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.</source>
</trans-unit>
<trans-unit id="s10092327ad833090">
<source>Microsoft Entra Group(s)</source>
</trans-unit>
<trans-unit id="s811c45ad24a5feae">
<source>Microsoft Entra User(s)</source>
</trans-unit>
<trans-unit id="s7d2d3d298fdccfc8">
<source>Google Workspace Group(s)</source>
</trans-unit>
<trans-unit id="s8c9cf2c004755526">
<source>Google Workspace User(s)</source>
</trans-unit>
<trans-unit id="sd000b42fea07c34a">
<source>SCIM Group(s)</source>
</trans-unit>
<trans-unit id="s146769fb55f1ee50">
<source>SCIM User(s)</source>
</trans-unit>
</body>
</file>

View File

@ -6558,6 +6558,42 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s001fd928369d4ddc">
<source><x id="0" equiv-text="${versionString}"/> (FIPS)</source>
</trans-unit>
<trans-unit id="sce17c2bdea3e6ace">
<source>Score minimum threshold</source>
</trans-unit>
<trans-unit id="sf2fcb974c62625fc">
<source>Minimum required score to allow continuing</source>
</trans-unit>
<trans-unit id="s7452199a73ce8b78">
<source>Score maximum threshold</source>
</trans-unit>
<trans-unit id="s2d3a6cd50b46b44d">
<source>Maximum allowed score to allow continuing</source>
</trans-unit>
<trans-unit id="s9d6e40d9a9a58fbf">
<source>Error on invalid score</source>
</trans-unit>
<trans-unit id="s2af59e2f9f12847a">
<source>When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.</source>
</trans-unit>
<trans-unit id="s10092327ad833090">
<source>Microsoft Entra Group(s)</source>
</trans-unit>
<trans-unit id="s811c45ad24a5feae">
<source>Microsoft Entra User(s)</source>
</trans-unit>
<trans-unit id="s7d2d3d298fdccfc8">
<source>Google Workspace Group(s)</source>
</trans-unit>
<trans-unit id="s8c9cf2c004755526">
<source>Google Workspace User(s)</source>
</trans-unit>
<trans-unit id="sd000b42fea07c34a">
<source>SCIM Group(s)</source>
</trans-unit>
<trans-unit id="s146769fb55f1ee50">
<source>SCIM User(s)</source>
</trans-unit>
</body>
</file>

View File

@ -8604,108 +8604,191 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
</trans-unit>
<trans-unit id="s8cfd29891b2c93f0">
<source>Google Workspace Provider</source>
<target>Fournisseur Google Workspace</target>
</trans-unit>
<trans-unit id="sa817aa9f6f88a991">
<source>Credentials</source>
<target>Identifiants</target>
</trans-unit>
<trans-unit id="sc668815044e218c2">
<source>Delegated Subject</source>
<target>Sujet délégué</target>
</trans-unit>
<trans-unit id="se89a9ecf275e4343">
<source>Default group email domain</source>
<target>Domaine de courriel de groupe par défaut</target>
</trans-unit>
<trans-unit id="s64a0a6da6ed6d680">
<source>Default domain that is used to generate a group's email address. Can be customized using property mappings.</source>
<target>Domain par défaut utilisé pour générer le courriel d'un groupe. Peut être personnalisé avec des mappages de propriété.</target>
</trans-unit>
<trans-unit id="sd061e65955e036ca">
<source>User deletion action</source>
<target>Action de suppression d'un utilisateur</target>
</trans-unit>
<trans-unit id="s87f86f65b5e19ea7">
<source>User is deleted</source>
<target>L'utilisateur est supprimé</target>
</trans-unit>
<trans-unit id="s3906cd4a102867a3">
<source>Suspend</source>
<target>Suspendre</target>
</trans-unit>
<trans-unit id="s0bf5b364e2c79392">
<source>User is suspended, and connection to user in authentik is removed.</source>
<target>L'utilisateur est suspendu, et la connection à authentik est supprimée.</target>
</trans-unit>
<trans-unit id="s4acb0250d735c2a9">
<source>Do Nothing</source>
<target>Ne rien faire</target>
</trans-unit>
<trans-unit id="s5fe525d19499ed47">
<source>The connection is removed but the user is not modified</source>
<target>La connexion est supprimée mais l'utilisateur n'est pas modifié</target>
</trans-unit>
<trans-unit id="s676a0127c35d240a">
<source>Determines what authentik will do when a User is deleted.</source>
<target>Détermine ce qu'authentik fera si un utilisateur est supprimé.</target>
</trans-unit>
<trans-unit id="sd1aa04cc32caf2b0">
<source>Group deletion action</source>
<target>Action de suppression d'un groupe</target>
</trans-unit>
<trans-unit id="s874c788479481131">
<source>Group is deleted</source>
<target>Le groupe est supprimé</target>
</trans-unit>
<trans-unit id="s0983fa9b84e4a9f7">
<source>The connection is removed but the group is not modified</source>
<target>La connexion est supprimée mais le groupe n'est pas modifié</target>
</trans-unit>
<trans-unit id="sdb872a9f425937fa">
<source>Determines what authentik will do when a Group is deleted.</source>
<target>Détermine ce qu'authentik fera si un groupe est supprimé.</target>
</trans-unit>
<trans-unit id="sa5f28f1ad0bee45b">
<source>Google Workspace Provider is in preview.</source>
<target>Le fournisseur Google Workspace est en aperçu technique.</target>
</trans-unit>
<trans-unit id="s958928ab6208d748">
<source>Microsoft Entra Provider</source>
<target>Fournisseur Microsoft Entra</target>
</trans-unit>
<trans-unit id="sc7d6bc4aebb58fe9">
<source>Google Cloud credentials file.</source>
<target>Fichier d'identifiants Google Cloud.</target>
</trans-unit>
<trans-unit id="s2e707072d5a9615d">
<source>Email address of the user the actions of authentik will be delegated to.</source>
<target>Courriel de l'utilisateur auquel les actions d'authentik seront déléguées.</target>
</trans-unit>
<trans-unit id="s03a759e65ceb722d">
<source>Client ID for the app registration.</source>
<target>Client ID pour l'enregistrement de l'application.</target>
</trans-unit>
<trans-unit id="s479980cf9252628c">
<source>Client secret for the app registration.</source>
<target>Client secret pour l'enregistrement de l'application.</target>
</trans-unit>
<trans-unit id="s25c2392ffcb78df2">
<source>Tenant ID</source>
<target>Tenant ID</target>
</trans-unit>
<trans-unit id="s89e4e698cdb1187f">
<source>ID of the tenant accounts will be synced into.</source>
<target>ID du tenant dans lequel les comptes seront synchronisés.</target>
</trans-unit>
<trans-unit id="sf341f5dfc7a11633">
<source>Microsoft Entra Provider is in preview.</source>
<target>Le fournisseur Microsoft Entra est en aperçu technique.</target>
</trans-unit>
<trans-unit id="s79dd6df244c05ae9">
<source>Update Microsoft Entra Provider</source>
<target>Mettre à jour le fournisseur Microsoft Entra</target>
</trans-unit>
<trans-unit id="saf4b498d81141878">
<source>Finished successfully</source>
<target>Fini avec succès</target>
</trans-unit>
<trans-unit id="s46f1d86ffec6223c">
<source>Finished with errors</source>
<target>Fini avec erreurs</target>
</trans-unit>
<trans-unit id="sbd12ed8a1053a108">
<source>Finished <x id="0" equiv-text="${getRelativeTime(task.finishTimestamp)}"/> (<x id="1" equiv-text="${task.finishTimestamp.toLocaleString()}"/>)</source>
<target>Fini <x id="0" equiv-text="${getRelativeTime(task.finishTimestamp)}"/> (<x id="1" equiv-text="${task.finishTimestamp.toLocaleString()}"/>)</target>
</trans-unit>
<trans-unit id="sc3c334d642866997">
<source>Sync currently running</source>
<target>Synchronisation en cours</target>
</trans-unit>
<trans-unit id="sd520a4089006ca93">
<source>Update Google Workspace Provider</source>
<target>Mettre à jour le fournisseur Google Workspace</target>
</trans-unit>
<trans-unit id="sfdfa5bb4ddd99d70">
<source>Enterprise only</source>
<target>Entreprise uniquement</target>
</trans-unit>
<trans-unit id="scffa59cfac1951f2">
<source><x id="0" equiv-text="${type.name}"/> Icon</source>
<target>Icône <x id="0" equiv-text="${type.name}"/></target>
</trans-unit>
<trans-unit id="s1da3499258024860">
<source><x id="0" equiv-text="${versionString}"/> (build <x id="1" equiv-text="${this.outpostHealth.buildHash.substring(0, 8)}"/>)</source>
<target><x id="0" equiv-text="${versionString}"/> (build <x id="1" equiv-text="${this.outpostHealth.buildHash.substring(0, 8)}"/>)</target>
</trans-unit>
<trans-unit id="s001fd928369d4ddc">
<source><x id="0" equiv-text="${versionString}"/> (FIPS)</source>
<target><x id="0" equiv-text="${versionString}"/> (FIPS)</target>
</trans-unit>
<trans-unit id="sce17c2bdea3e6ace">
<source>Score minimum threshold</source>
<target>Seuil minimum du score</target>
</trans-unit>
<trans-unit id="sf2fcb974c62625fc">
<source>Minimum required score to allow continuing</source>
<target>Score minimum requis pour continuer</target>
</trans-unit>
<trans-unit id="s7452199a73ce8b78">
<source>Score maximum threshold</source>
<target>Seuil maximum du score</target>
</trans-unit>
<trans-unit id="s2d3a6cd50b46b44d">
<source>Maximum allowed score to allow continuing</source>
<target>Score maximum requis pour continuer</target>
</trans-unit>
<trans-unit id="s9d6e40d9a9a58fbf">
<source>Error on invalid score</source>
<target>Erreur sur score invalide</target>
</trans-unit>
<trans-unit id="s2af59e2f9f12847a">
<source>When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.</source>
<target>Si activé et que le score résultant est hors des seuils, l'utilisateur ne pourra pas continuer. Si désactivé, l'utilisateur pourra continuer et le score pourra être utilisé dans des politiques pour configurer les étapes suivantes.</target>
</trans-unit>
<trans-unit id="s10092327ad833090">
<source>Microsoft Entra Group(s)</source>
<target>Groupe(s) du fournisseur Microsoft Entra</target>
</trans-unit>
<trans-unit id="s811c45ad24a5feae">
<source>Microsoft Entra User(s)</source>
<target>Utilisateur(s) du fournisseur Microsoft Entra</target>
</trans-unit>
<trans-unit id="s7d2d3d298fdccfc8">
<source>Google Workspace Group(s)</source>
<target>Groupe(s) du fournisseur Google Workspace</target>
</trans-unit>
<trans-unit id="s8c9cf2c004755526">
<source>Google Workspace User(s)</source>
<target>Utilisateur(s) du fournisseur Google Workspace</target>
</trans-unit>
<trans-unit id="sd000b42fea07c34a">
<source>SCIM Group(s)</source>
<target>Groupe(s) du fournisseur SCIM</target>
</trans-unit>
<trans-unit id="s146769fb55f1ee50">
<source>SCIM User(s)</source>
<target>Utilisateur(s) du fournisseur SCIM</target>
</trans-unit>
</body>
</file>

View File

@ -8487,6 +8487,42 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s001fd928369d4ddc">
<source><x id="0" equiv-text="${versionString}"/> (FIPS)</source>
</trans-unit>
<trans-unit id="sce17c2bdea3e6ace">
<source>Score minimum threshold</source>
</trans-unit>
<trans-unit id="sf2fcb974c62625fc">
<source>Minimum required score to allow continuing</source>
</trans-unit>
<trans-unit id="s7452199a73ce8b78">
<source>Score maximum threshold</source>
</trans-unit>
<trans-unit id="s2d3a6cd50b46b44d">
<source>Maximum allowed score to allow continuing</source>
</trans-unit>
<trans-unit id="s9d6e40d9a9a58fbf">
<source>Error on invalid score</source>
</trans-unit>
<trans-unit id="s2af59e2f9f12847a">
<source>When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.</source>
</trans-unit>
<trans-unit id="s10092327ad833090">
<source>Microsoft Entra Group(s)</source>
</trans-unit>
<trans-unit id="s811c45ad24a5feae">
<source>Microsoft Entra User(s)</source>
</trans-unit>
<trans-unit id="s7d2d3d298fdccfc8">
<source>Google Workspace Group(s)</source>
</trans-unit>
<trans-unit id="s8c9cf2c004755526">
<source>Google Workspace User(s)</source>
</trans-unit>
<trans-unit id="sd000b42fea07c34a">
<source>SCIM Group(s)</source>
</trans-unit>
<trans-unit id="s146769fb55f1ee50">
<source>SCIM User(s)</source>
</trans-unit>
</body>
</file>

View File

@ -8331,6 +8331,42 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
</trans-unit>
<trans-unit id="s001fd928369d4ddc">
<source><x id="0" equiv-text="${versionString}"/> (FIPS)</source>
</trans-unit>
<trans-unit id="sce17c2bdea3e6ace">
<source>Score minimum threshold</source>
</trans-unit>
<trans-unit id="sf2fcb974c62625fc">
<source>Minimum required score to allow continuing</source>
</trans-unit>
<trans-unit id="s7452199a73ce8b78">
<source>Score maximum threshold</source>
</trans-unit>
<trans-unit id="s2d3a6cd50b46b44d">
<source>Maximum allowed score to allow continuing</source>
</trans-unit>
<trans-unit id="s9d6e40d9a9a58fbf">
<source>Error on invalid score</source>
</trans-unit>
<trans-unit id="s2af59e2f9f12847a">
<source>When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.</source>
</trans-unit>
<trans-unit id="s10092327ad833090">
<source>Microsoft Entra Group(s)</source>
</trans-unit>
<trans-unit id="s811c45ad24a5feae">
<source>Microsoft Entra User(s)</source>
</trans-unit>
<trans-unit id="s7d2d3d298fdccfc8">
<source>Google Workspace Group(s)</source>
</trans-unit>
<trans-unit id="s8c9cf2c004755526">
<source>Google Workspace User(s)</source>
</trans-unit>
<trans-unit id="sd000b42fea07c34a">
<source>SCIM Group(s)</source>
</trans-unit>
<trans-unit id="s146769fb55f1ee50">
<source>SCIM User(s)</source>
</trans-unit>
</body>
</file>

File diff suppressed because it is too large Load Diff

View File

@ -8602,4 +8602,40 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s001fd928369d4ddc">
<source><x id="0" equiv-text="${versionString}"/> (FIPS)</source>
</trans-unit>
<trans-unit id="sce17c2bdea3e6ace">
<source>Score minimum threshold</source>
</trans-unit>
<trans-unit id="sf2fcb974c62625fc">
<source>Minimum required score to allow continuing</source>
</trans-unit>
<trans-unit id="s7452199a73ce8b78">
<source>Score maximum threshold</source>
</trans-unit>
<trans-unit id="s2d3a6cd50b46b44d">
<source>Maximum allowed score to allow continuing</source>
</trans-unit>
<trans-unit id="s9d6e40d9a9a58fbf">
<source>Error on invalid score</source>
</trans-unit>
<trans-unit id="s2af59e2f9f12847a">
<source>When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.</source>
</trans-unit>
<trans-unit id="s10092327ad833090">
<source>Microsoft Entra Group(s)</source>
</trans-unit>
<trans-unit id="s811c45ad24a5feae">
<source>Microsoft Entra User(s)</source>
</trans-unit>
<trans-unit id="s7d2d3d298fdccfc8">
<source>Google Workspace Group(s)</source>
</trans-unit>
<trans-unit id="s8c9cf2c004755526">
<source>Google Workspace User(s)</source>
</trans-unit>
<trans-unit id="sd000b42fea07c34a">
<source>SCIM Group(s)</source>
</trans-unit>
<trans-unit id="s146769fb55f1ee50">
<source>SCIM User(s)</source>
</trans-unit>
</body></file></xliff>

View File

@ -6551,6 +6551,42 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s001fd928369d4ddc">
<source><x id="0" equiv-text="${versionString}"/> (FIPS)</source>
</trans-unit>
<trans-unit id="sce17c2bdea3e6ace">
<source>Score minimum threshold</source>
</trans-unit>
<trans-unit id="sf2fcb974c62625fc">
<source>Minimum required score to allow continuing</source>
</trans-unit>
<trans-unit id="s7452199a73ce8b78">
<source>Score maximum threshold</source>
</trans-unit>
<trans-unit id="s2d3a6cd50b46b44d">
<source>Maximum allowed score to allow continuing</source>
</trans-unit>
<trans-unit id="s9d6e40d9a9a58fbf">
<source>Error on invalid score</source>
</trans-unit>
<trans-unit id="s2af59e2f9f12847a">
<source>When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.</source>
</trans-unit>
<trans-unit id="s10092327ad833090">
<source>Microsoft Entra Group(s)</source>
</trans-unit>
<trans-unit id="s811c45ad24a5feae">
<source>Microsoft Entra User(s)</source>
</trans-unit>
<trans-unit id="s7d2d3d298fdccfc8">
<source>Google Workspace Group(s)</source>
</trans-unit>
<trans-unit id="s8c9cf2c004755526">
<source>Google Workspace User(s)</source>
</trans-unit>
<trans-unit id="sd000b42fea07c34a">
<source>SCIM Group(s)</source>
</trans-unit>
<trans-unit id="s146769fb55f1ee50">
<source>SCIM User(s)</source>
</trans-unit>
</body>
</file>

View File

@ -5473,6 +5473,42 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s001fd928369d4ddc">
<source><x id="0" equiv-text="${versionString}"/> (FIPS)</source>
</trans-unit>
<trans-unit id="sce17c2bdea3e6ace">
<source>Score minimum threshold</source>
</trans-unit>
<trans-unit id="sf2fcb974c62625fc">
<source>Minimum required score to allow continuing</source>
</trans-unit>
<trans-unit id="s7452199a73ce8b78">
<source>Score maximum threshold</source>
</trans-unit>
<trans-unit id="s2d3a6cd50b46b44d">
<source>Maximum allowed score to allow continuing</source>
</trans-unit>
<trans-unit id="s9d6e40d9a9a58fbf">
<source>Error on invalid score</source>
</trans-unit>
<trans-unit id="s2af59e2f9f12847a">
<source>When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.</source>
</trans-unit>
<trans-unit id="s10092327ad833090">
<source>Microsoft Entra Group(s)</source>
</trans-unit>
<trans-unit id="s811c45ad24a5feae">
<source>Microsoft Entra User(s)</source>
</trans-unit>
<trans-unit id="s7d2d3d298fdccfc8">
<source>Google Workspace Group(s)</source>
</trans-unit>
<trans-unit id="s8c9cf2c004755526">
<source>Google Workspace User(s)</source>
</trans-unit>
<trans-unit id="sd000b42fea07c34a">
<source>SCIM Group(s)</source>
</trans-unit>
<trans-unit id="s146769fb55f1ee50">
<source>SCIM User(s)</source>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -8743,6 +8743,54 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s001fd928369d4ddc">
<source><x id="0" equiv-text="${versionString}"/> (FIPS)</source>
<target><x id="0" equiv-text="${versionString}"/>FIPS</target>
</trans-unit>
<trans-unit id="sce17c2bdea3e6ace">
<source>Score minimum threshold</source>
<target>分数最小阈值</target>
</trans-unit>
<trans-unit id="sf2fcb974c62625fc">
<source>Minimum required score to allow continuing</source>
<target>允许继续所需的最小分数</target>
</trans-unit>
<trans-unit id="s7452199a73ce8b78">
<source>Score maximum threshold</source>
<target>分数最大阈值</target>
</trans-unit>
<trans-unit id="s2d3a6cd50b46b44d">
<source>Maximum allowed score to allow continuing</source>
<target>允许继续所需的最大分数</target>
</trans-unit>
<trans-unit id="s9d6e40d9a9a58fbf">
<source>Error on invalid score</source>
<target>分数无效时报错</target>
</trans-unit>
<trans-unit id="s2af59e2f9f12847a">
<source>When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.</source>
<target>启用时,如果结果分数超出阈值,用户将无法继续。禁用时,用户可以继续,分数可用于自定义下一阶段的策略。</target>
</trans-unit>
<trans-unit id="s10092327ad833090">
<source>Microsoft Entra Group(s)</source>
<target>Microsoft Entra 组</target>
</trans-unit>
<trans-unit id="s811c45ad24a5feae">
<source>Microsoft Entra User(s)</source>
<target>Microsoft Entra 用户</target>
</trans-unit>
<trans-unit id="s7d2d3d298fdccfc8">
<source>Google Workspace Group(s)</source>
<target>Google Workspace 组</target>
</trans-unit>
<trans-unit id="s8c9cf2c004755526">
<source>Google Workspace User(s)</source>
<target>Google Workspace 用户</target>
</trans-unit>
<trans-unit id="sd000b42fea07c34a">
<source>SCIM Group(s)</source>
<target>SCIM 组</target>
</trans-unit>
<trans-unit id="s146769fb55f1ee50">
<source>SCIM User(s)</source>
<target>SCIM 用户</target>
</trans-unit>
</body>
</file>

View File

@ -6599,6 +6599,42 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s001fd928369d4ddc">
<source><x id="0" equiv-text="${versionString}"/> (FIPS)</source>
</trans-unit>
<trans-unit id="sce17c2bdea3e6ace">
<source>Score minimum threshold</source>
</trans-unit>
<trans-unit id="sf2fcb974c62625fc">
<source>Minimum required score to allow continuing</source>
</trans-unit>
<trans-unit id="s7452199a73ce8b78">
<source>Score maximum threshold</source>
</trans-unit>
<trans-unit id="s2d3a6cd50b46b44d">
<source>Maximum allowed score to allow continuing</source>
</trans-unit>
<trans-unit id="s9d6e40d9a9a58fbf">
<source>Error on invalid score</source>
</trans-unit>
<trans-unit id="s2af59e2f9f12847a">
<source>When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.</source>
</trans-unit>
<trans-unit id="s10092327ad833090">
<source>Microsoft Entra Group(s)</source>
</trans-unit>
<trans-unit id="s811c45ad24a5feae">
<source>Microsoft Entra User(s)</source>
</trans-unit>
<trans-unit id="s7d2d3d298fdccfc8">
<source>Google Workspace Group(s)</source>
</trans-unit>
<trans-unit id="s8c9cf2c004755526">
<source>Google Workspace User(s)</source>
</trans-unit>
<trans-unit id="sd000b42fea07c34a">
<source>SCIM Group(s)</source>
</trans-unit>
<trans-unit id="s146769fb55f1ee50">
<source>SCIM User(s)</source>
</trans-unit>
</body>
</file>

View File

@ -8743,6 +8743,54 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s001fd928369d4ddc">
<source><x id="0" equiv-text="${versionString}"/> (FIPS)</source>
<target><x id="0" equiv-text="${versionString}"/>FIPS</target>
</trans-unit>
<trans-unit id="sce17c2bdea3e6ace">
<source>Score minimum threshold</source>
<target>分数最小阈值</target>
</trans-unit>
<trans-unit id="sf2fcb974c62625fc">
<source>Minimum required score to allow continuing</source>
<target>允许继续所需的最小分数</target>
</trans-unit>
<trans-unit id="s7452199a73ce8b78">
<source>Score maximum threshold</source>
<target>分数最大阈值</target>
</trans-unit>
<trans-unit id="s2d3a6cd50b46b44d">
<source>Maximum allowed score to allow continuing</source>
<target>允许继续所需的最大分数</target>
</trans-unit>
<trans-unit id="s9d6e40d9a9a58fbf">
<source>Error on invalid score</source>
<target>分数无效时报错</target>
</trans-unit>
<trans-unit id="s2af59e2f9f12847a">
<source>When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.</source>
<target>启用时,如果结果分数超出阈值,用户将无法继续。禁用时,用户可以继续,分数可用于自定义下一阶段的策略。</target>
</trans-unit>
<trans-unit id="s10092327ad833090">
<source>Microsoft Entra Group(s)</source>
<target>Microsoft Entra 组</target>
</trans-unit>
<trans-unit id="s811c45ad24a5feae">
<source>Microsoft Entra User(s)</source>
<target>Microsoft Entra 用户</target>
</trans-unit>
<trans-unit id="s7d2d3d298fdccfc8">
<source>Google Workspace Group(s)</source>
<target>Google Workspace 组</target>
</trans-unit>
<trans-unit id="s8c9cf2c004755526">
<source>Google Workspace User(s)</source>
<target>Google Workspace 用户</target>
</trans-unit>
<trans-unit id="sd000b42fea07c34a">
<source>SCIM Group(s)</source>
<target>SCIM 组</target>
</trans-unit>
<trans-unit id="s146769fb55f1ee50">
<source>SCIM User(s)</source>
<target>SCIM 用户</target>
</trans-unit>
</body>
</file>

View File

@ -8448,6 +8448,42 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s001fd928369d4ddc">
<source><x id="0" equiv-text="${versionString}"/> (FIPS)</source>
</trans-unit>
<trans-unit id="sce17c2bdea3e6ace">
<source>Score minimum threshold</source>
</trans-unit>
<trans-unit id="sf2fcb974c62625fc">
<source>Minimum required score to allow continuing</source>
</trans-unit>
<trans-unit id="s7452199a73ce8b78">
<source>Score maximum threshold</source>
</trans-unit>
<trans-unit id="s2d3a6cd50b46b44d">
<source>Maximum allowed score to allow continuing</source>
</trans-unit>
<trans-unit id="s9d6e40d9a9a58fbf">
<source>Error on invalid score</source>
</trans-unit>
<trans-unit id="s2af59e2f9f12847a">
<source>When enabled and the resultant score is outside the threshold, the user will not be able to continue. When disabled, the user will be able to continue and the score can be used in policies to customize further stages.</source>
</trans-unit>
<trans-unit id="s10092327ad833090">
<source>Microsoft Entra Group(s)</source>
</trans-unit>
<trans-unit id="s811c45ad24a5feae">
<source>Microsoft Entra User(s)</source>
</trans-unit>
<trans-unit id="s7d2d3d298fdccfc8">
<source>Google Workspace Group(s)</source>
</trans-unit>
<trans-unit id="s8c9cf2c004755526">
<source>Google Workspace User(s)</source>
</trans-unit>
<trans-unit id="sd000b42fea07c34a">
<source>SCIM Group(s)</source>
</trans-unit>
<trans-unit id="s146769fb55f1ee50">
<source>SCIM User(s)</source>
</trans-unit>
</body>
</file>

View File

@ -0,0 +1,81 @@
---
title: Style Guide
---
Here are a few guidelines to ensure that the documentation is easy to read and uses similar phrasing. Remember to use our [docs templates](./templates/index.md) when possible; they are already set up to follow may of the style guidelines below.
If you find any documentation that doesn't match these guidelines, feel free to either open an [Issue](https://github.com/goauthentik/authentik/issues) or a [PR](https://github.com/goauthentik/authentik/pulls) so they can be fixed.
To test how the documentation renders use the Netlify Deploy Preview, especially when using Docusaurus-specific features. Or [build it locally and test](./writing-documentation.md#set-up-your-local-build), using the `make website-watch` command.
:::info
Make sure to add any new pages to the appropriate `sidebar` file. Otherwise, the new page will not appear in the table of contents to the left.
:::
## General guidelines
- Try to order the documentation sections in the order that makes it easiest for the user to follow. That is, order the sections in the same order as the actual workflow used to accomplish the task. Use headings (sub-titles) to break up long documents, and make it easier to find a specific section.
- You can use standard [Docusaurus-specific features](https://docusaurus.io/docs/next/markdown-features), which include MDX elements such as tabs and admonitions.
## Terminology
### authentik names
- The product name authentik should always start with a lower-case "a" and end with a "k". Even if it is the first word in a sentence. :-)
- Our company name is Authentik Security, Inc. but in non-legal documentation you can shorten it to Authentik Security.
### Industry terms, technology, and other tools
- When referring to external tools, or an industry term or technology, always follow the exact capitalization that the product or company itself uses on their website, in their official documentation, or what the industry uses in consensus.
- Try to avoid using abbreviations if possible.
- Use acronyms where it makes sense (for commonly used terms like SAML or RBAC). If an acronym is less-known, spell it out in parentheses after the first use.
## Writing style
- authentik documentation strives for a friendly, but not overly so, tone. It's ok to be a little bit conversational, and to address the reader in second person: "Next, you need to configure the log in settings."
- Our documentation uses American English ("z" not "s").
- Phrasing should almost always be in present tense and active voice:
- DON'T: "The Applications page will be loaded."
- DO: "The Applications page displays."
- Phrasing should never blame the user, and should be subjective:
- DON'T: "Never modify the default file."
- DO: "We recommend that you do not modify the default file, because this can result in unexpected issues."
## Formatting
Formatting in documentation is important; it improves comprehension and readability, and allows the brain to more quickly determine what is a command or a configuration setting, what is a field name, or what is a variable.
- When referring to UI elements or components in the authentik UI, such as field names, labels, etc., use **bold** text.
- Use `code` format when referring to:
- commands
- file paths
- directory names
- code snippets (single line or a block of code)
- For variables or placeholders use _italic_ font for the variable, and use place-holder names that makes it obvious that the user needs to replace it.
Example: <kbd>https://<em>company-domain</em>/source/oauth/callback/<em>source-slug</em></kbd>
When using variables in code snippets, make sure to specify if the value is something the user needs to define, is system-defined or generated.
- When referring to authentik functionality and features, such as flows, stages, sources, or policies, do not capitalize and do not use bold or italic text. When possible link to the corresponding documentation.
### Titles and headers
- Both titles and headers (H1, H2, H3) use sentence style capitalization, meaning that only the first word is capitalized. However, if the title or header includes a proper noun (name of a product, etc) then capitalize those words.
Examples:
- Configure your provider
- Configure the Google Workspace provider

Some files were not shown because too many files have changed in this diff Show More