Compare commits

..

188 Commits

Author SHA1 Message Date
Teffen Ellis
155b13f35d web/a11y: Accessible preference classes. 2025-11-20 18:48:56 +01:00
Connor Peshek
64965e3750 Makefile: Fix kerberos tests for brew users (#17223)
Makefile: Fix kerberos tests for brew users

Co-authored-by: connor peshek <connorpeshek@connors-MacBook-Pro.local>
2025-11-19 09:52:26 -08:00
Jens L.
cd1693be28 website/docs: add 2025.8.5 and 2025.10.2 release notes (#18268)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-11-19 15:24:06 +01:00
authentik-automation[bot]
4d0abe30f1 internal: Automated internal backport: 5000-sidebar.sec.patch to authentik-main (#18266)
Automated internal backport of patch 5000-sidebar.sec.patch to authentik-main

Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-11-19 15:21:16 +01:00
authentik-automation[bot]
9dbdfc3f1b internal: Automated internal backport: 1498-oauth2-cc-user-active.sec.patch to authentik-main (#18265)
Automated internal backport of patch 1498-oauth2-cc-user-active.sec.patch to authentik-main

Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-11-19 15:01:06 +01:00
authentik-automation[bot]
6672e6aaa4 internal: Automated internal backport: 1487-invitation-expiry.sec.patch to authentik-main (#18264)
Automated internal backport of patch 1487-invitation-expiry.sec.patch to authentik-main

Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-11-19 14:54:24 +01:00
authentik-automation[bot]
545d42572f core, web: update translations (#18241)
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-11-19 12:33:22 +00:00
dependabot[bot]
29b010b86b web: bump ts-pattern from 5.8.0 to 5.9.0 in /web (#18247)
Bumps [ts-pattern](https://github.com/gvergnaud/ts-pattern) from 5.8.0 to 5.9.0.
- [Release notes](https://github.com/gvergnaud/ts-pattern/releases)
- [Commits](https://github.com/gvergnaud/ts-pattern/compare/v5.8.0...v5.9.0)

---
updated-dependencies:
- dependency-name: ts-pattern
  dependency-version: 5.9.0
  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>
2025-11-19 11:26:52 +01:00
dependabot[bot]
cf692d635a web: bump the react group across 2 directories with 1 update (#18244)
Bumps the react group with 1 update in the /packages/docusaurus-config directory: [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react).
Bumps the react group with 1 update in the /web directory: [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react).


Updates `@types/react` from 19.2.4 to 19.2.6
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@types/react` from 19.2.4 to 19.2.6
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-version: 19.2.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.2.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-19 11:26:04 +01:00
dependabot[bot]
eebc92552f web: bump knip from 5.66.2 to 5.70.0 in /web (#18245)
Bumps [knip](https://github.com/webpro-nl/knip/tree/HEAD/packages/knip) from 5.66.2 to 5.70.0.
- [Release notes](https://github.com/webpro-nl/knip/releases)
- [Changelog](https://github.com/webpro-nl/knip/blob/main/packages/knip/.release-it.json)
- [Commits](https://github.com/webpro-nl/knip/commits/5.70.0/packages/knip)

---
updated-dependencies:
- dependency-name: knip
  dependency-version: 5.70.0
  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>
2025-11-19 11:25:39 +01:00
dependabot[bot]
31b7bada88 core: bump library/nginx from b5b9e01 to 553f64a in /website (#18253)
Bumps library/nginx from `b5b9e01` to `553f64a`.

---
updated-dependencies:
- dependency-name: library/nginx
  dependency-version: 1.29-trixie
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-19 11:25:31 +01:00
dependabot[bot]
2f1bf7824c core: bump library/golang from 27e1c92 to 728cbef (#18252)
Bumps library/golang from `27e1c92` to `728cbef`.

---
updated-dependencies:
- dependency-name: library/golang
  dependency-version: 1.25.4-trixie
  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>
2025-11-19 11:25:22 +01:00
dependabot[bot]
0c1ec687c5 core: bump goauthentik/fips-debian from 65a9f1f to 55c1514 (#18251)
Bumps goauthentik/fips-debian from `65a9f1f` to `55c1514`.

---
updated-dependencies:
- dependency-name: goauthentik/fips-debian
  dependency-version: trixie-slim-fips
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-19 11:25:12 +01:00
Teffen Ellis
e8f8785e2f web: Bump Vitest, TypeScript config (#18238)
Upgrade deps. Fix imports.
2025-11-19 00:11:21 +01:00
dependabot[bot]
f4bad6a564 web: bump js-yaml from 4.1.0 to 4.1.1 in /packages/esbuild-plugin-live-reload (#18237)
web: bump js-yaml in /packages/esbuild-plugin-live-reload

Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.0 to 4.1.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-18 23:45:06 +01:00
Teffen Ellis
b4b0142421 web/i18n: Remove English Locale (#18164) 2025-11-18 22:19:22 +01:00
dependabot[bot]
78b91fed5d web: bump js-yaml from 3.14.1 to 3.14.2 in /packages/docusaurus-config (#18239)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.14.1 to 3.14.2.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.14.1...3.14.2)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 3.14.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-18 19:26:12 +01:00
Teffen Ellis
de1b7d7d81 web/i18n: Clean up locale scripts (#18163)
* web/i81n: Clean up locale scripts.

* Fix logs, clean up caching.

* Use previous script name.

* Fix path.
2025-11-18 12:25:00 -05:00
Jens L.
0913b1050d stages/prompt: fix choices with labels causing error on submit (#18183)
* stages/prompt: fix choices with labels causing error on submit

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

* fix tests

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-11-18 18:04:45 +01:00
Teffen Ellis
5451e047c1 web: Patternfly 5 Prep: Part 2 (#18085)
* web: Fix missing block modifier. Remove redundant.

* Fix spacing.

* Fix status colors on dark themes.

* Add missing dark theme styles. Fix order of style rules.

* Only show ungrouped label when in high contrast.

* Consistent delete disable color.

* Split Patternfly variables into separate files. Prep for PF5.

* Fix contrast on light mode.

* Fix background base color.

* Fix issues surrounding color layering, overlay states, contrast, etc.

* Flesh out placeholder.

* Flesh out loading state, inspector toggle.

* Build static CSS for proxy. Remove loading entry.

* Fix types.

* some very small style adjustments

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-11-18 17:12:27 +01:00
dependabot[bot]
6f52899440 lifecycle/aws: bump aws-cdk from 2.1031.2 to 2.1032.0 in /lifecycle/aws (#18218)
Bumps [aws-cdk](https://github.com/aws/aws-cdk-cli/tree/HEAD/packages/aws-cdk) from 2.1031.2 to 2.1032.0.
- [Release notes](https://github.com/aws/aws-cdk-cli/releases)
- [Commits](https://github.com/aws/aws-cdk-cli/commits/aws-cdk@v2.1032.0/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  dependency-version: 2.1032.0
  dependency-type: direct:development
  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>
2025-11-18 15:30:55 +01:00
Marcelo Elizeche Landó
0ed903599a core: bump click from 8.3.0 to v8.3.1 (#18198) 2025-11-18 15:30:35 +01:00
dependabot[bot]
c0b5c4be22 website: bump the build group across 1 directory with 9 updates (#18231)
Bumps the build group with 9 updates in the /website directory:

| Package | From | To |
| --- | --- | --- |
| [@rspack/binding-darwin-arm64](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) | `1.6.3` | `1.6.4` |
| [@rspack/binding-linux-arm64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) | `1.6.3` | `1.6.4` |
| [@rspack/binding-linux-x64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) | `1.6.3` | `1.6.4` |
| [@swc/core-darwin-arm64](https://github.com/swc-project/swc) | `1.15.1` | `1.15.2` |
| [@swc/core-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.15.1` | `1.15.2` |
| [@swc/core-linux-x64-gnu](https://github.com/swc-project/swc) | `1.15.1` | `1.15.2` |
| [@swc/html-darwin-arm64](https://github.com/swc-project/swc) | `1.15.1` | `1.15.2` |
| [@swc/html-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.15.1` | `1.15.2` |
| [@swc/html-linux-x64-gnu](https://github.com/swc-project/swc) | `1.15.1` | `1.15.2` |



Updates `@rspack/binding-darwin-arm64` from 1.6.3 to 1.6.4
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.6.4/packages/rspack)

Updates `@rspack/binding-linux-arm64-gnu` from 1.6.3 to 1.6.4
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.6.4/packages/rspack)

Updates `@rspack/binding-linux-x64-gnu` from 1.6.3 to 1.6.4
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.6.4/packages/rspack)

Updates `@swc/core-darwin-arm64` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/core-linux-arm64-gnu` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/core-linux-x64-gnu` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/html-darwin-arm64` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/html-linux-arm64-gnu` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/html-linux-x64-gnu` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

---
updated-dependencies:
- dependency-name: "@rspack/binding-darwin-arm64"
  dependency-version: 1.6.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@rspack/binding-linux-arm64-gnu"
  dependency-version: 1.6.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@rspack/binding-linux-x64-gnu"
  dependency-version: 1.6.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-darwin-arm64"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-linux-arm64-gnu"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-linux-x64-gnu"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-darwin-arm64"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-linux-arm64-gnu"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/html-linux-x64-gnu"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-18 15:22:06 +01:00
authentik-automation[bot]
12a85ee59f core, web: update translations (#18046)
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-11-18 13:24:47 +00:00
dependabot[bot]
013b06b0b6 website: bump the eslint group in /website with 3 updates (#18214)
Bumps the eslint group in /website with 3 updates: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin), [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `@typescript-eslint/eslint-plugin` from 8.46.4 to 8.47.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.47.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.46.4 to 8.47.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.47.0/packages/parser)

Updates `typescript-eslint` from 8.46.4 to 8.47.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.47.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: typescript-eslint
  dependency-version: 8.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-18 14:23:31 +01:00
dependabot[bot]
0e6eae2e90 web: bump the eslint group across 2 directories with 3 updates (#18216)
Bumps the eslint group with 1 update in the /packages/eslint-config directory: [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).
Bumps the eslint group with 1 update in the /web directory: [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `typescript-eslint` from 8.46.4 to 8.47.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.47.0/packages/typescript-eslint)

Updates `typescript-eslint` from 8.46.4 to 8.47.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.47.0/packages/typescript-eslint)

Updates `@typescript-eslint/eslint-plugin` from 8.46.4 to 8.47.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.47.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.46.4 to 8.47.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.47.0/packages/parser)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.47.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: typescript-eslint
  dependency-version: 8.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-18 14:23:20 +01:00
Marcelo Elizeche Landó
c280558489 core: bump google-auth from 2.42.1 to v2.43.0 (#18199) 2025-11-18 14:22:59 +01:00
dependabot[bot]
d55c83a32f core: bump github.com/getsentry/sentry-go from 0.37.0 to 0.38.0 (#18212)
Bumps [github.com/getsentry/sentry-go](https://github.com/getsentry/sentry-go) from 0.37.0 to 0.38.0.
- [Release notes](https://github.com/getsentry/sentry-go/releases)
- [Changelog](https://github.com/getsentry/sentry-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-go/compare/v0.37.0...v0.38.0)

---
updated-dependencies:
- dependency-name: github.com/getsentry/sentry-go
  dependency-version: 0.38.0
  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>
2025-11-18 14:22:42 +01:00
dependabot[bot]
9dc167572b website: bump @types/react from 19.2.4 to 19.2.6 in /website (#18215)
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 19.2.4 to 19.2.6.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-version: 19.2.6
  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>
2025-11-18 14:22:25 +01:00
dependabot[bot]
b7ba388b57 web: bump the storybook group across 1 directory with 5 updates (#18217)
Bumps the storybook group with 4 updates in the /web directory: [@storybook/addon-docs](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs), [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/links), [@storybook/web-components](https://github.com/storybookjs/storybook/tree/HEAD/code/renderers/web-components) and [@storybook/web-components-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/web-components-vite).


Updates `@storybook/addon-docs` from 10.0.7 to 10.0.8
- [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/v10.0.8/code/addons/docs)

Updates `@storybook/addon-links` from 10.0.7 to 10.0.8
- [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/v10.0.8/code/addons/links)

Updates `@storybook/web-components` from 10.0.7 to 10.0.8
- [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/v10.0.8/code/renderers/web-components)

Updates `@storybook/web-components-vite` from 10.0.7 to 10.0.8
- [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/v10.0.8/code/frameworks/web-components-vite)

Updates `storybook` from 10.0.7 to 10.0.8
- [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/v10.0.8/code/core)

---
updated-dependencies:
- dependency-name: "@storybook/addon-docs"
  dependency-version: 10.0.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/addon-links"
  dependency-version: 10.0.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/web-components"
  dependency-version: 10.0.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/web-components-vite"
  dependency-version: 10.0.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: storybook
  dependency-version: 10.0.8
  dependency-type: direct:production
  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>
2025-11-18 14:22:13 +01:00
dependabot[bot]
c3f1f68adc web: bump the swc group across 1 directory with 11 updates (#18219)
Bumps the swc group with 1 update in the /web directory: [@swc/core](https://github.com/swc-project/swc).


Updates `@swc/core` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/core-darwin-arm64` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/core-darwin-x64` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/core-linux-arm-gnueabihf` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/core-linux-arm64-gnu` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/core-linux-arm64-musl` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/core-linux-x64-gnu` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/core-linux-x64-musl` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/core-win32-arm64-msvc` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/core-win32-ia32-msvc` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

Updates `@swc/core-win32-x64-msvc` from 1.15.1 to 1.15.2
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.15.1...v1.15.2)

---
updated-dependencies:
- dependency-name: "@swc/core"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: swc
- dependency-name: "@swc/core-darwin-arm64"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: swc
- dependency-name: "@swc/core-darwin-x64"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: swc
- dependency-name: "@swc/core-linux-arm-gnueabihf"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: swc
- dependency-name: "@swc/core-linux-arm64-gnu"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: swc
- dependency-name: "@swc/core-linux-arm64-musl"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: swc
- dependency-name: "@swc/core-linux-x64-gnu"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: swc
- dependency-name: "@swc/core-linux-x64-musl"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: swc
- dependency-name: "@swc/core-win32-arm64-msvc"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: swc
- dependency-name: "@swc/core-win32-ia32-msvc"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: swc
- dependency-name: "@swc/core-win32-x64-msvc"
  dependency-version: 1.15.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: swc
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-18 14:22:04 +01:00
dependabot[bot]
328c2fbca3 core: bump astral-sh/uv from 0.9.9 to 0.9.10 (#18224)
Bumps [astral-sh/uv](https://github.com/astral-sh/uv) from 0.9.9 to 0.9.10.
- [Release notes](https://github.com/astral-sh/uv/releases)
- [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/uv/compare/0.9.9...0.9.10)

---
updated-dependencies:
- dependency-name: astral-sh/uv
  dependency-version: 0.9.10
  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>
2025-11-18 14:20:12 +01:00
Marcelo Elizeche Landó
f01241421f core: bump jsii from 1.118.0 to v1.119.0 (#18201) 2025-11-18 14:07:50 +01:00
Marcelo Elizeche Landó
3a8b04ca60 core: bump pynacl from 1.6.0 to v1.6.1 (#18203) 2025-11-18 14:07:40 +01:00
Marcelo Elizeche Landó
70a65f79be core: bump boto3 from 1.40.66 to v1.40.75 (#18194) 2025-11-18 14:07:33 +01:00
Marcelo Elizeche Landó
02c8941b26 core: bump googleapis-common-protos from 1.71.0 to v1.72.0 (#18200) 2025-11-18 14:06:25 +01:00
Marcelo Elizeche Landó
4f0626a033 core: bump certifi from 2025.10.5 to v2025.11.12 (#18197) 2025-11-18 14:05:54 +01:00
Marcelo Elizeche Landó
ac5f22abe7 core: bump zope-interface from 8.0.1 to v8.1.1 (#18206) 2025-11-18 14:05:33 +01:00
Marcelo Elizeche Landó
1e552b3cbe core: bump zope-event from 6.0 to v6.1 (#18205) 2025-11-18 14:05:18 +01:00
Marcelo Elizeche Landó
db8600955f core: bump cachetools from 6.2.1 to v6.2.2 (#18195) 2025-11-18 14:05:09 +01:00
Marcelo Elizeche Landó
07fa0d90f2 core: bump rpds-py from 0.28.0 to v0.29.0 (#18204) 2025-11-18 14:05:02 +01:00
Marcelo Elizeche Landó
9d1571fd0e core: bump protobuf from 6.33.0 to v6.33.1 (#18202) 2025-11-18 14:04:41 +01:00
Marcelo Elizeche Landó
86ca79ce30 core: bump cattrs from 25.2.0 to v25.3.0 (#18196) 2025-11-18 14:04:34 +01:00
dependabot[bot]
61695adaa4 core: bump goauthentik/fips-debian from 40a1f32 to 65a9f1f (#18223)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-18 14:01:18 +01:00
dependabot[bot]
1999d60465 ci: bump actions/checkout from 5.0.0 to 5.0.1 (#18222)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-18 14:00:36 +01:00
dependabot[bot]
62f10273b5 core: bump library/nginx from 1beed3c to b5b9e01 in /website (#18225)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-18 14:00:10 +01:00
Connor Peshek
35329991ef providers/saml: fix front-end saml binding defaults (#18189)
Co-authored-by: connor peshek <connorpeshek@connors-MacBook-Pro.local>
2025-11-17 15:55:48 -08:00
Teffen Ellis
0b2cc6370c web: Hide avatars when set to "none" (#17911) 2025-11-17 23:48:14 +00:00
Marcelo Elizeche Landó
166913c6c3 website/docs: Add instructions for installing RC versions (#18099)
* Add instructions for installing RC versions

* Moves the imports to the start and changed the docker wording

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Apply suggestions from code review

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>

* Apply suggestions from code review

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>

---------

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Dominic R <dominic@sdko.org>
2025-11-17 20:17:51 -03:00
Teffen Ellis
5c0ddf368f web/a11y: Update wizard form labels, placeholders. (#17811)
web: Update wizard form labels, placeholders.
2025-11-17 18:17:16 -05:00
Jens L.
f269c24b94 web: fix outpost build (#18190)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-11-17 21:43:27 +01:00
authentik-automation[bot]
b8dfe1aae0 stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs (#18166)
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>
2025-11-17 21:26:55 +01:00
dependabot[bot]
09f4020770 build(deps): bump js-yaml from 4.1.0 to 4.1.1 (#18169)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.0 to 4.1.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-17 21:26:42 +01:00
dependabot[bot]
f6346a2823 web: bump js-yaml from 4.1.0 to 4.1.1 in /web (#18170)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.0 to 4.1.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-17 21:25:38 +01:00
dependabot[bot]
1333fff711 web: bump js-yaml from 4.1.0 to 4.1.1 in /packages/prettier-config (#18185)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.0 to 4.1.1.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-17 21:25:23 +01:00
Jake Nabasny, PhD
226b19d83c website/integrations: ubuntu landscape: remove appendix (#18188)
Remove appendix on OpenID-Connect User admin setup

Removed the appendix section detailing how to make an OpenID-Connect User an admin. Roles are now managed in the UI when you invite a user or afterwards in the Roles tab. There is no need for database edits.

Signed-off-by: Jake Nabasny, PhD <jake.nabasny@canonical.com>
2025-11-17 19:28:21 +00:00
NiceDevil
3296489790 website/integrations: FortiMail (#17900)
* New Integration Guide FortiMail

* WIP

* Fix formatting

* small typo ;)

Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>

* rearranged section above tabs

---------

Signed-off-by: NiceDevil <17103076+nicedevil007@users.noreply.github.com>
Co-authored-by: nicedevil007 <nicedevil007@users.noreply.github.com>
Co-authored-by: dewi-tik <dewi@goauthentik.io>
Co-authored-by: Tana M Berry <tana@goauthentik.io>
2025-11-17 08:24:35 -06:00
Jens L.
4caece7fef web/sfe: downgrade bootstrap that was accidentally upgraded (#18157)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-11-15 12:09:52 +01:00
Teffen Ellis
90d9b2daf9 web: Fix ESBuild hanging process (#18162) 2025-11-15 02:13:28 +01:00
NiceDevil
4c92eff521 website/integrations: macmon NAC (#17898)
* New Integration Guide macmon NAC

* Bring doc in-line with current style guide, clarifies language and changes verification section

---------

Co-authored-by: nicedevil007 <nicedevil007@users.noreply.github.com>
Co-authored-by: dewi-tik <dewi@goauthentik.io>
2025-11-14 13:39:01 -06:00
Marc 'risson' Schmitt
779d98a808 packages/django-channels-postgres/layer: fix query when subscribed to multiple channels (#18152)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-11-14 15:30:19 +01:00
Dominic R
5389709ab7 core: deduplicate user attribute constant definitions (#18138)
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-11-14 13:59:55 +00:00
dependabot[bot]
650c1f93f2 web: bump @trivago/prettier-plugin-sort-imports from 5.2.2 to 6.0.0 in /web (#18146)
web: bump @trivago/prettier-plugin-sort-imports in /web

Bumps [@trivago/prettier-plugin-sort-imports](https://github.com/trivago/prettier-plugin-sort-imports) from 5.2.2 to 6.0.0.
- [Release notes](https://github.com/trivago/prettier-plugin-sort-imports/releases)
- [Changelog](https://github.com/trivago/prettier-plugin-sort-imports/blob/main/CHANGELOG.md)
- [Commits](https://github.com/trivago/prettier-plugin-sort-imports/compare/v5.2.2...v6.0.0)

---
updated-dependencies:
- dependency-name: "@trivago/prettier-plugin-sort-imports"
  dependency-version: 6.0.0
  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>
2025-11-14 14:59:34 +01:00
Connor Peshek
2b794e616d crypto: update certificates on fs event (#18129)
Co-authored-by: connor peshek <connorpeshek@connors-MacBook-Pro.local>
2025-11-14 14:37:00 +01:00
Dewi Roberts
fd7cea1344 github: converts issue templates to forms (#18133) 2025-11-14 14:30:05 +01:00
dependabot[bot]
8fdc6e44eb core: bump github.com/getsentry/sentry-go from 0.36.2 to 0.37.0 (#18140)
Bumps [github.com/getsentry/sentry-go](https://github.com/getsentry/sentry-go) from 0.36.2 to 0.37.0.
- [Release notes](https://github.com/getsentry/sentry-go/releases)
- [Changelog](https://github.com/getsentry/sentry-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-go/compare/v0.36.2...v0.37.0)

---
updated-dependencies:
- dependency-name: github.com/getsentry/sentry-go
  dependency-version: 0.37.0
  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>
2025-11-14 13:56:16 +01:00
dependabot[bot]
fb76f3e1ac web: bump type-fest from 5.1.0 to 5.2.0 in /web (#18144)
Bumps [type-fest](https://github.com/sindresorhus/type-fest) from 5.1.0 to 5.2.0.
- [Release notes](https://github.com/sindresorhus/type-fest/releases)
- [Commits](https://github.com/sindresorhus/type-fest/compare/v5.1.0...v5.2.0)

---
updated-dependencies:
- dependency-name: type-fest
  dependency-version: 5.2.0
  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>
2025-11-14 13:56:02 +01:00
dependabot[bot]
f7e04b8bcf web: bump vite from 7.1.12 to 7.2.2 in /web (#18143)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.1.12 to 7.2.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.2.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.2.2
  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>
2025-11-14 13:55:52 +01:00
dependabot[bot]
1026601085 website: bump the build group in /website with 3 updates (#18141)
Bumps the build group in /website with 3 updates: [@rspack/binding-darwin-arm64](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack), [@rspack/binding-linux-arm64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) and [@rspack/binding-linux-x64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack).


Updates `@rspack/binding-darwin-arm64` from 1.6.2 to 1.6.3
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.6.3/packages/rspack)

Updates `@rspack/binding-linux-arm64-gnu` from 1.6.2 to 1.6.3
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.6.3/packages/rspack)

Updates `@rspack/binding-linux-x64-gnu` from 1.6.2 to 1.6.3
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.6.3/packages/rspack)

---
updated-dependencies:
- dependency-name: "@rspack/binding-darwin-arm64"
  dependency-version: 1.6.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@rspack/binding-linux-arm64-gnu"
  dependency-version: 1.6.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@rspack/binding-linux-x64-gnu"
  dependency-version: 1.6.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-14 13:50:50 +01:00
dependabot[bot]
8b7cceadec web: bump globals from 16.4.0 to 16.5.0 in /web (#18145)
Bumps [globals](https://github.com/sindresorhus/globals) from 16.4.0 to 16.5.0.
- [Release notes](https://github.com/sindresorhus/globals/releases)
- [Commits](https://github.com/sindresorhus/globals/compare/v16.4.0...v16.5.0)

---
updated-dependencies:
- dependency-name: globals
  dependency-version: 16.5.0
  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>
2025-11-14 13:50:39 +01:00
dependabot[bot]
232bc52960 core: bump astral-sh/uv from 0.9.8 to 0.9.9 (#18148)
Bumps [astral-sh/uv](https://github.com/astral-sh/uv) from 0.9.8 to 0.9.9.
- [Release notes](https://github.com/astral-sh/uv/releases)
- [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/uv/compare/0.9.8...0.9.9)

---
updated-dependencies:
- dependency-name: astral-sh/uv
  dependency-version: 0.9.9
  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>
2025-11-14 13:49:54 +01:00
dependabot[bot]
1c282c339b core: bump goauthentik/fips-debian from 5017d65 to 40a1f32 (#18149)
Bumps goauthentik/fips-debian from `5017d65` to `40a1f32`.

---
updated-dependencies:
- dependency-name: goauthentik/fips-debian
  dependency-version: trixie-slim-fips
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-14 13:43:30 +01:00
mayswind
e99e5b7355 website/integrations: Add ezBookkeeping integration (#18040)
Co-authored-by: dewi-tik <dewi@goauthentik.io>
Co-authored-by: Dominic R <dominic@sdko.org>
2025-11-14 04:26:41 +00:00
Daniel Tihanyi
9e1244f764 website/integrations: Add Joplin (#18042)
Co-authored-by: Dominic R <dominic@sdko.org>
2025-11-14 04:05:15 +00:00
Teffen Ellis
1115e6f82f web: Disable library <datalist> on Firefox. (#18103)
web: Disable library autocomplete on Firefox.
2025-11-13 22:09:25 +01:00
Jens L.
3d66864735 web/admin: link to user on invitation list page (#18132)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-11-13 22:09:17 +01:00
Dewi Roberts
1cc5fa1412 web/admin: update stage descriptions (#18118)
* Updates the description for stages to standardize lanauge and clarify.

* Add "based"

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Remove "currently"

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Fix user_write stage

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

---------

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
2025-11-13 20:40:13 +00:00
Christoph Dyllick-Brenzinger
60adbd9245 website/integrations: add SeaTable (#18115)
* website/integrations: add description for SeaTable

* fix wrong display of links in the section additional resources

* fix typo

* Change wording, update formatting, change curl command, add section headers, and bring in-line with style guide

* Spelling

* Apply suggestions from code review

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Apply suggestions from code review

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Apply suggestion from @dominic-r

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Apply suggestions from code review

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Fix missing backticks

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Remove indentation

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Remove "the"

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Add intro to certs section

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Apply suggestion from @dominic-r

Signed-off-by: Dominic R <dominic@sdko.org>

---------

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Dominic R <dominic@sdko.org>
Co-authored-by: dewi-tik <dewi@goauthentik.io>
Co-authored-by: Dominic R <dominic@sdko.org>
2025-11-13 20:38:31 +00:00
Dominic R
d4e0694cbe website/integrations: stripe: fix markdown (#18126)
* website/integrations: stripe: fix markdown

Signed-off-by: Dominic R <dominic@sdko.org>

* Linting

---------

Signed-off-by: Dominic R <dominic@sdko.org>
Co-authored-by: dewi-tik <dewi@goauthentik.io>
2025-11-13 19:57:37 +00:00
Tealk
4821198f92 web/flows: improvements for hCaptcha (#16882)
* improvements for hCaptcha
Issue #16755

* web: Format.

---------

Co-authored-by: Teffen Ellis <teffen@goauthentik.io>
2025-11-13 20:23:53 +01:00
Dewi Roberts
b791737c47 website/docs: update application description (#18125)
Update due to 2025.10 changes
2025-11-13 19:09:20 +00:00
Dewi Roberts
f419173029 revert: github: convert issue templates to forms (#18121)
Revert "github: convert issue templates to forms (#18117)"

This reverts commit 75d4c2d2ee.
2025-11-13 16:57:27 +00:00
Dewi Roberts
75d4c2d2ee github: convert issue templates to forms (#18117)
* Updates templates to forms, changes project and label handling, mentions discussions and discord for questions rather than issues.

* Apply suggestion from @dominic-r

Signed-off-by: Dominic R <dominic@sdko.org>

---------

Signed-off-by: Dominic R <dominic@sdko.org>
Co-authored-by: Dominic R <dominic@sdko.org>
2025-11-13 15:53:35 +00:00
Dewi Roberts
deb7765dee website/docs: fix wording in stages overview (#18061)
Change flow to stage
2025-11-13 15:43:03 +00:00
Marc 'risson' Schmitt
acf5b5f2ff packages/django-dramatiq-postgres: broker: ensure locking happens with the same connection (#18095) 2025-11-13 16:37:29 +01:00
Daniel Lo Nigro
9295d876a7 website/integrations: Frappe: update instructions (#18029)
* Update Frappe integration page

- Make it clearer that `provider` has to be replaced with the actual provider name.
- Add `ERPNext` into the title for SEO and clarity.

Signed-off-by: Daniel Lo Nigro <d@d.sb>

* Changed formatting of the note and added it to the authentik section

---------

Signed-off-by: Daniel Lo Nigro <d@d.sb>
Co-authored-by: dewi-tik <dewi@goauthentik.io>
2025-11-13 14:52:30 +00:00
dependabot[bot]
acbecff09c website: bump @types/react from 19.2.3 to 19.2.4 in /website (#18108)
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 19.2.3 to 19.2.4.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-version: 19.2.4
  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>
2025-11-13 13:58:41 +01:00
dependabot[bot]
d7514c022a web: bump @types/node from 24.10.0 to 24.10.1 in /packages/esbuild-plugin-live-reload (#18111)
web: bump @types/node in /packages/esbuild-plugin-live-reload

Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.10.0 to 24.10.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.10.1
  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>
2025-11-13 13:05:01 +01:00
dependabot[bot]
d53f6e1035 website: bump the build group in /website with 3 updates (#18106)
Bumps the build group in /website with 3 updates: [@rspack/binding-darwin-arm64](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack), [@rspack/binding-linux-arm64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) and [@rspack/binding-linux-x64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack).


Updates `@rspack/binding-darwin-arm64` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.6.2/packages/rspack)

Updates `@rspack/binding-linux-arm64-gnu` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.6.2/packages/rspack)

Updates `@rspack/binding-linux-x64-gnu` from 1.6.1 to 1.6.2
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.6.2/packages/rspack)

---
updated-dependencies:
- dependency-name: "@rspack/binding-darwin-arm64"
  dependency-version: 1.6.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@rspack/binding-linux-arm64-gnu"
  dependency-version: 1.6.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@rspack/binding-linux-x64-gnu"
  dependency-version: 1.6.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-13 12:47:58 +01:00
dependabot[bot]
e4e9062096 web: bump the react group across 2 directories with 2 updates (#18110)
Bumps the react group with 2 updates in the /packages/docusaurus-config directory: [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) and [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom).
Bumps the react group with 2 updates in the /web directory: [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) and [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom).


Updates `@types/react` from 19.2.3 to 19.2.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@types/react-dom` from 19.2.2 to 19.2.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

Updates `@types/react` from 19.2.3 to 19.2.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@types/react-dom` from 19.2.2 to 19.2.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-version: 19.2.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.2.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-13 12:47:07 +01:00
transifex-integration[bot]
d5bdea68c6 translate: Updates for file locale/en/LC_MESSAGES/django.po in fi (#18105)
Translate locale/en/LC_MESSAGES/django.po in fi

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

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-11-13 12:46:31 +01:00
dependabot[bot]
5415c7660f website: bump @types/react-dom from 19.2.2 to 19.2.3 in /website (#18107)
Bumps [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) from 19.2.2 to 19.2.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

---
updated-dependencies:
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.3
  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>
2025-11-13 12:46:17 +01:00
dependabot[bot]
769e22c7ed web: bump @types/node from 24.10.0 to 24.10.1 in /packages/prettier-config (#18112)
web: bump @types/node in /packages/prettier-config

Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.10.0 to 24.10.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.10.1
  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>
2025-11-13 12:43:58 +01:00
dependabot[bot]
21b085b586 web: bump @types/node from 22.15.19 to 24.10.1 in /web (#18113)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.15.19 to 24.10.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.10.1
  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>
2025-11-13 12:43:41 +01:00
transifex-integration[bot]
44ac0d0bda translate: Updates for file locale/en/LC_MESSAGES/django.po in fi (#18060)
* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

* Translate web/xliff/en.xlf in ja

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

* Update translation units. Prep Japanese.

---------

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
Co-authored-by: Teffen Ellis <teffen@goauthentik.io>
2025-11-13 03:48:07 +00:00
Teffen Ellis
c37ef6d728 web/i18n: Japanese Locale(日本語ロケール) (#17938)
web: Activate Japanese locale.
2025-11-13 03:06:31 +00:00
Teffen Ellis
7743774905 web/i18n: Locale message fixes (#17913)
* web: Fix issue where messages defined outside elements are not translated.

* web: Apply locale to Captchas.
2025-11-12 22:04:48 -05:00
Teffen Ellis
7bb593da22 web: Lit Session Context (#17903)
web: Flesh out client-side session context.
2025-11-13 02:15:32 +00:00
Teffen Ellis
bbacea5b9a web: Fix tab activation, blank provider URLs (#18031)
web: Fix tab activation.
2025-11-13 01:51:19 +00:00
Teffen Ellis
02072bda93 web: Fix RAC modal visibility. (#17941)
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-11-12 18:49:50 +01:00
Marc 'risson' Schmitt
a8327101c6 cmd/server/healthcheck: remove worker HTTP healthcheck (#18090)
* cmd/server/healthcheck: remove worker HTTP healthcheck

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

* lint

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

---------

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-11-12 14:42:30 +00:00
dependabot[bot]
1905fbb58f web: bump @sentry/browser from 10.24.0 to 10.25.0 in /web in the sentry group across 1 directory (#18079)
web: bump @sentry/browser in /web in the sentry group across 1 directory

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


Updates `@sentry/browser` from 10.24.0 to 10.25.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/10.24.0...10.25.0)

---
updated-dependencies:
- dependency-name: "@sentry/browser"
  dependency-version: 10.25.0
  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>
2025-11-12 13:26:55 +01:00
dependabot[bot]
5c05050de7 website: bump @types/react from 19.2.2 to 19.2.3 in /website (#18077)
Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 19.2.2 to 19.2.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-version: 19.2.3
  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>
2025-11-12 12:15:30 +01:00
dependabot[bot]
5bdd6815bf website: bump @types/node from 24.10.0 to 24.10.1 in /website (#18078)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.10.0 to 24.10.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.10.1
  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>
2025-11-12 12:14:45 +01:00
dependabot[bot]
40645b8abe web: bump the storybook group across 1 directory with 5 updates (#18080)
Bumps the storybook group with 4 updates in the /web directory: [@storybook/addon-docs](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs), [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/links), [@storybook/web-components](https://github.com/storybookjs/storybook/tree/HEAD/code/renderers/web-components) and [@storybook/web-components-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/web-components-vite).


Updates `@storybook/addon-docs` from 10.0.6 to 10.0.7
- [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/v10.0.7/code/addons/docs)

Updates `@storybook/addon-links` from 10.0.6 to 10.0.7
- [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/v10.0.7/code/addons/links)

Updates `@storybook/web-components` from 10.0.6 to 10.0.7
- [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/v10.0.7/code/renderers/web-components)

Updates `@storybook/web-components-vite` from 10.0.6 to 10.0.7
- [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/v10.0.7/code/frameworks/web-components-vite)

Updates `storybook` from 10.0.6 to 10.0.7
- [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/v10.0.7/code/core)

---
updated-dependencies:
- dependency-name: "@storybook/addon-docs"
  dependency-version: 10.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/addon-links"
  dependency-version: 10.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/web-components"
  dependency-version: 10.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/web-components-vite"
  dependency-version: 10.0.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: storybook
  dependency-version: 10.0.7
  dependency-type: direct:production
  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>
2025-11-12 12:14:35 +01:00
dependabot[bot]
74742ff288 web: bump the rollup group across 1 directory with 4 updates (#18082)
Bumps the rollup group with 4 updates in the /web directory: [@rollup/rollup-darwin-arm64](https://github.com/rollup/rollup), [@rollup/rollup-linux-arm64-gnu](https://github.com/rollup/rollup), [@rollup/rollup-linux-x64-gnu](https://github.com/rollup/rollup) and [rollup](https://github.com/rollup/rollup).


Updates `@rollup/rollup-darwin-arm64` from 4.52.5 to 4.53.2
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.52.5...v4.53.2)

Updates `@rollup/rollup-linux-arm64-gnu` from 4.52.5 to 4.53.2
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.52.5...v4.53.2)

Updates `@rollup/rollup-linux-x64-gnu` from 4.52.5 to 4.53.2
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.52.5...v4.53.2)

Updates `rollup` from 4.52.5 to 4.53.2
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.52.5...v4.53.2)

---
updated-dependencies:
- dependency-name: "@rollup/rollup-darwin-arm64"
  dependency-version: 4.53.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: rollup
- dependency-name: "@rollup/rollup-linux-arm64-gnu"
  dependency-version: 4.53.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: rollup
- dependency-name: "@rollup/rollup-linux-x64-gnu"
  dependency-version: 4.53.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: rollup
- dependency-name: rollup
  dependency-version: 4.53.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: rollup
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-12 12:14:16 +01:00
dependabot[bot]
d2dfcf5883 web: bump the react group across 2 directories with 1 update (#18083)
Bumps the react group with 1 update in the /packages/docusaurus-config directory: [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react).
Bumps the react group with 1 update in the /web directory: [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react).


Updates `@types/react` from 19.2.2 to 19.2.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@types/react` from 19.2.2 to 19.2.3
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-version: 19.2.3
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: react
- dependency-name: "@types/react"
  dependency-version: 19.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: react
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-12 12:13:45 +01:00
dependabot[bot]
ac5097dd14 core: bump goauthentik/fips-debian from f3228f8 to 5017d65 (#18084)
Bumps goauthentik/fips-debian from `f3228f8` to `5017d65`.

---
updated-dependencies:
- dependency-name: goauthentik/fips-debian
  dependency-version: trixie-slim-fips
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-12 12:13:35 +01:00
Jens L.
b682299edd core: improve app launch URL formatting (#18076)
* core: improve app launch URL formatting

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

* format

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-11-12 12:06:16 +01:00
Jens L.
53426293aa providers/scim: allow custom schema data (#18073)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-11-12 00:20:46 +01:00
Teffen Ellis
e426f88401 web: Fix application of global styles in style roots. (#17444)
* web: Separate global styles from element roots.

* web: Flesh out style strategy plugin, fixes for imported styles.

* web: Clean up applying of dark theme.

web: unminify.

* web: Fix alignment, rendering on high contrast.

web: Apply footer resize.

web: Fix application of global styles in style roots.

web: Fix missing layout attribute.

web: Normalize background alignment.

web: Fix layout issues, color overrides.

web: Fix alignment, colors, jank.

web: Separate method into function.

web: Clean up alignment, reflow.

web: Fix colors, compatibility mode.

web: Add content left/right support.

web: Fix colors, compatibility mode overrides.

* Fix issue where missing config throws runtime error.

* web: Refactor.

* Update tests.

* web: Fix Storybook imports.

* Fix order of theme application.

* web: Fix storybook asset paths.

* web: Flesh out tests surrounding source buttons, fix alignment,
contrast.

* Update tests, clarify errors.

* Update test selectors, assertions.

* Clarify redirect handling.

* Adjust user check.

* Update logs.

* web: Fix selector timing.

* Fix alignment.

* Fix selectors, timing.

* Log current URL content.

* Refine shadow selector, add delay.

* Replace IDs with named elements.

* Fix overlay color.

* Fix footer padding.

* Fix contrast.

* Add selectable name to button.

* Fix alignment, mobile layout.

* web: Spread exported parts to stages.

* Fix z-index order.

* Tidy colors, behaviors, layout.

* Fix overflow scroll.

* Clean up duplicate color styles.

* Clarify selector order. Fix overrides, color contrast.

* Attempt to read JSON multiple times.

* Clarify error.

* web: Fix timeouts, URL changes.

* web: Fix disabled styles.

* Fix color flip.

* Fix selector.

* Fix issue where hidden tables will alter test URLs.

* Use DOM to look for connection, rather than API. Update selectors.

* Immediately navigate to tab.

* Upgrade Dex.

* Ensure Dex redirects.

* Use same host during tests.

* web: Update package-lock.json

* Add delay.
2025-11-11 15:49:00 -05:00
Jens L.
8ff1fc10ca events: fix timezone not set for log events (#18067)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-11-11 18:49:22 +01:00
Jens L.
c11f3d9f72 ci: attempt to fix integration tests using dind (#18066)
* ci: attempt to fix integration tests using dind

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

* bump dind version

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-11-11 17:31:07 +01:00
Jens L.
364ca70724 ci: revert to upstream GHA for release (#18058)
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-11-11 13:17:42 +01:00
dependabot[bot]
89bcfef363 web: bump the swc group across 1 directory with 12 updates (#17998)
Bumps the swc group with 2 updates in the /web directory: [@swc/cli](https://github.com/swc-project/pkgs) and [@swc/core](https://github.com/swc-project/swc).


Updates `@swc/cli` from 0.7.8 to 0.7.9
- [Commits](https://github.com/swc-project/pkgs/commits)

Updates `@swc/core` from 1.13.19 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.13.19...v1.15.0)

Updates `@swc/core-darwin-arm64` from 1.13.19 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.13.19...v1.15.0)

Updates `@swc/core-darwin-x64` from 1.13.19 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.13.19...v1.15.0)

Updates `@swc/core-linux-arm-gnueabihf` from 1.13.19 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.13.19...v1.15.0)

Updates `@swc/core-linux-arm64-gnu` from 1.13.19 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.13.19...v1.15.0)

Updates `@swc/core-linux-arm64-musl` from 1.13.19 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.13.19...v1.15.0)

Updates `@swc/core-linux-x64-gnu` from 1.13.19 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.13.19...v1.15.0)

Updates `@swc/core-linux-x64-musl` from 1.13.19 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.13.19...v1.15.0)

Updates `@swc/core-win32-arm64-msvc` from 1.13.19 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.13.19...v1.15.0)

Updates `@swc/core-win32-ia32-msvc` from 1.13.19 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.13.19...v1.15.0)

Updates `@swc/core-win32-x64-msvc` from 1.13.19 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.13.19...v1.15.0)

---
updated-dependencies:
- dependency-name: "@swc/cli"
  dependency-version: 0.7.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: swc
- dependency-name: "@swc/core"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: swc
- dependency-name: "@swc/core-darwin-arm64"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: swc
- dependency-name: "@swc/core-darwin-x64"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: swc
- dependency-name: "@swc/core-linux-arm-gnueabihf"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: swc
- dependency-name: "@swc/core-linux-arm64-gnu"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: swc
- dependency-name: "@swc/core-linux-arm64-musl"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: swc
- dependency-name: "@swc/core-linux-x64-gnu"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: swc
- dependency-name: "@swc/core-linux-x64-musl"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: swc
- dependency-name: "@swc/core-win32-arm64-msvc"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: swc
- dependency-name: "@swc/core-win32-ia32-msvc"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: swc
- dependency-name: "@swc/core-win32-x64-msvc"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: swc
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 13:02:19 +01:00
TMUniversal
80b79ab901 website/docs: update discord social login script example (#18026)
update the guild membership example to no longer cause an exception from a missing import.

Closes #18025

Signed-off-by: TMUniversal <10200399+TMUniversal@users.noreply.github.com>
2025-11-11 12:55:01 +01:00
dependabot[bot]
17f229e575 core: bump goauthentik/fips-debian from 9b4cedf to f3228f8 (#17819)
Bumps goauthentik/fips-debian from `9b4cedf` to `f3228f8`.

---
updated-dependencies:
- dependency-name: goauthentik/fips-debian
  dependency-version: trixie-slim-fips
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 12:52:35 +01:00
Teffen Ellis
efc8822469 web: Make Spotlight optional. (#17904)
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-11-11 12:37:50 +01:00
dependabot[bot]
c04b491125 website: bump @types/node from 24.9.2 to 24.10.0 in /website (#17909)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.9.2 to 24.10.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.10.0
  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>
2025-11-11 12:22:10 +01:00
dependabot[bot]
0809927def web: bump @types/node from 24.9.1 to 24.10.0 in /packages/esbuild-plugin-live-reload (#17948)
web: bump @types/node in /packages/esbuild-plugin-live-reload

Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.9.1 to 24.10.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.10.0
  dependency-type: direct:development
  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>
2025-11-11 12:21:03 +01:00
dependabot[bot]
ec80106ee5 ci: bump calibreapp/image-actions from 05b1cf44e88c3b041b841452482df9497f046ef7 to 420075c115b26f8785e293c5bd5bef0911c506e5 (#17953)
ci: bump calibreapp/image-actions

Bumps [calibreapp/image-actions](https://github.com/calibreapp/image-actions) from 05b1cf44e88c3b041b841452482df9497f046ef7 to 420075c115b26f8785e293c5bd5bef0911c506e5.
- [Release notes](https://github.com/calibreapp/image-actions/releases)
- [Commits](05b1cf44e8...420075c115)

---
updated-dependencies:
- dependency-name: calibreapp/image-actions
  dependency-version: 420075c115b26f8785e293c5bd5bef0911c506e5
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 12:20:54 +01:00
Marcelo Elizeche Landó
57ea7a3454 core: bump googleapis-common-protos from 1.70.0 to v1.71.0 (#17979) 2025-11-11 12:20:32 +01:00
dependabot[bot]
39c83c5048 web: bump the sentry group across 1 directory with 2 updates (#17997)
Bumps the sentry group with 2 updates in the /web directory: [@sentry/browser](https://github.com/getsentry/sentry-javascript) and @spotlightjs/spotlight.


Updates `@sentry/browser` from 10.22.0 to 10.23.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/10.22.0...10.23.0)

Updates `@spotlightjs/spotlight` from 4.3.0 to 4.5.0

---
updated-dependencies:
- dependency-name: "@sentry/browser"
  dependency-version: 10.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: sentry
- dependency-name: "@spotlightjs/spotlight"
  dependency-version: 4.5.0
  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>
2025-11-11 12:20:13 +01:00
dependabot[bot]
413ee2dbb8 website: bump the build group across 1 directory with 9 updates (#17995)
Bumps the build group with 9 updates in the /website directory:

| Package | From | To |
| --- | --- | --- |
| [@rspack/binding-darwin-arm64](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) | `1.6.0` | `1.6.1` |
| [@rspack/binding-linux-arm64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) | `1.6.0` | `1.6.1` |
| [@rspack/binding-linux-x64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) | `1.6.0` | `1.6.1` |
| [@swc/core-darwin-arm64](https://github.com/swc-project/swc) | `1.14.0` | `1.15.0` |
| [@swc/core-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.14.0` | `1.15.0` |
| [@swc/core-linux-x64-gnu](https://github.com/swc-project/swc) | `1.14.0` | `1.15.0` |
| [@swc/html-darwin-arm64](https://github.com/swc-project/swc) | `1.14.0` | `1.15.0` |
| [@swc/html-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.14.0` | `1.15.0` |
| [@swc/html-linux-x64-gnu](https://github.com/swc-project/swc) | `1.14.0` | `1.15.0` |



Updates `@rspack/binding-darwin-arm64` from 1.6.0 to 1.6.1
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.6.1/packages/rspack)

Updates `@rspack/binding-linux-arm64-gnu` from 1.6.0 to 1.6.1
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.6.1/packages/rspack)

Updates `@rspack/binding-linux-x64-gnu` from 1.6.0 to 1.6.1
- [Release notes](https://github.com/web-infra-dev/rspack/releases)
- [Commits](https://github.com/web-infra-dev/rspack/commits/v1.6.1/packages/rspack)

Updates `@swc/core-darwin-arm64` from 1.14.0 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.14.0...v1.15.0)

Updates `@swc/core-linux-arm64-gnu` from 1.14.0 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.14.0...v1.15.0)

Updates `@swc/core-linux-x64-gnu` from 1.14.0 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.14.0...v1.15.0)

Updates `@swc/html-darwin-arm64` from 1.14.0 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.14.0...v1.15.0)

Updates `@swc/html-linux-arm64-gnu` from 1.14.0 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.14.0...v1.15.0)

Updates `@swc/html-linux-x64-gnu` from 1.14.0 to 1.15.0
- [Release notes](https://github.com/swc-project/swc/releases)
- [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/swc-project/swc/compare/v1.14.0...v1.15.0)

---
updated-dependencies:
- dependency-name: "@rspack/binding-darwin-arm64"
  dependency-version: 1.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@rspack/binding-linux-arm64-gnu"
  dependency-version: 1.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@rspack/binding-linux-x64-gnu"
  dependency-version: 1.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: build
- dependency-name: "@swc/core-darwin-arm64"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: build
- dependency-name: "@swc/core-linux-arm64-gnu"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: build
- dependency-name: "@swc/core-linux-x64-gnu"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: build
- dependency-name: "@swc/html-darwin-arm64"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: build
- dependency-name: "@swc/html-linux-arm64-gnu"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: build
- dependency-name: "@swc/html-linux-x64-gnu"
  dependency-version: 1.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: build
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 12:19:33 +01:00
transifex-integration[bot]
566969c7bf translate: Updates for file locale/en/LC_MESSAGES/django.po in fi (#18056)
Translate locale/en/LC_MESSAGES/django.po in fi

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

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-11-11 12:02:40 +01:00
dependabot[bot]
91650ea180 core: bump selenium/standalone-chromium from 141.0 to 142.0 in /tests/e2e (#17910)
core: bump selenium/standalone-chromium in /tests/e2e

Bumps selenium/standalone-chromium from 141.0 to 142.0.

---
updated-dependencies:
- dependency-name: selenium/standalone-chromium
  dependency-version: '142.0'
  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>
2025-11-11 12:00:09 +01:00
dependabot[bot]
70e70c9203 website: bump the eslint group across 1 directory with 5 updates (#17928)
Bumps the eslint group with 5 updates in the /website directory:

| Package | From | To |
| --- | --- | --- |
| [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) | `9.38.0` | `9.39.1` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.46.2` | `8.46.3` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `8.46.2` | `8.46.3` |
| [eslint](https://github.com/eslint/eslint) | `9.38.0` | `9.39.1` |
| [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.46.2` | `8.46.3` |



Updates `@eslint/js` from 9.38.0 to 9.39.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/commits/v9.39.1/packages/js)

Updates `@typescript-eslint/eslint-plugin` from 8.46.2 to 8.46.3
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.46.3/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.46.2 to 8.46.3
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.46.3/packages/parser)

Updates `eslint` from 9.38.0 to 9.39.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.38.0...v9.39.1)

Updates `typescript-eslint` from 8.46.2 to 8.46.3
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.46.3/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-version: 9.39.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.46.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.46.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: eslint
  dependency-version: 9.39.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: typescript-eslint
  dependency-version: 8.46.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 11:59:50 +01:00
dependabot[bot]
e3a374f9c0 core: bump github.com/go-openapi/runtime from 0.29.0 to 0.29.2 (#18048)
Bumps [github.com/go-openapi/runtime](https://github.com/go-openapi/runtime) from 0.29.0 to 0.29.2.
- [Release notes](https://github.com/go-openapi/runtime/releases)
- [Commits](https://github.com/go-openapi/runtime/compare/v0.29.0...v0.29.2)

---
updated-dependencies:
- dependency-name: github.com/go-openapi/runtime
  dependency-version: 0.29.2
  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>
2025-11-11 11:59:28 +01:00
dependabot[bot]
090f73b1f9 core: bump gorm.io/gorm from 1.31.0 to 1.31.1 (#17907)
Bumps [gorm.io/gorm](https://github.com/go-gorm/gorm) from 1.31.0 to 1.31.1.
- [Release notes](https://github.com/go-gorm/gorm/releases)
- [Commits](https://github.com/go-gorm/gorm/compare/v1.31.0...v1.31.1)

---
updated-dependencies:
- dependency-name: gorm.io/gorm
  dependency-version: 1.31.1
  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>
2025-11-11 11:58:34 +01:00
dependabot[bot]
6538e94961 core: bump github.com/getsentry/sentry-go from 0.36.1 to 0.36.2 (#17785)
Bumps [github.com/getsentry/sentry-go](https://github.com/getsentry/sentry-go) from 0.36.1 to 0.36.2.
- [Release notes](https://github.com/getsentry/sentry-go/releases)
- [Changelog](https://github.com/getsentry/sentry-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-go/compare/v0.36.1...v0.36.2)

---
updated-dependencies:
- dependency-name: github.com/getsentry/sentry-go
  dependency-version: 0.36.2
  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>
2025-11-11 11:58:20 +01:00
dependabot[bot]
0c9de742fc web: bump the eslint group across 2 directories with 5 updates (#18049)
Bumps the eslint group with 2 updates in the /packages/eslint-config directory: [eslint](https://github.com/eslint/eslint) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).
Bumps the eslint group with 2 updates in the /web directory: [eslint](https://github.com/eslint/eslint) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `eslint` from 9.38.0 to 9.39.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.38.0...v9.39.1)

Updates `typescript-eslint` from 8.46.2 to 8.46.4
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.46.4/packages/typescript-eslint)

Updates `eslint` from 9.38.0 to 9.39.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.38.0...v9.39.1)

Updates `typescript-eslint` from 8.46.2 to 8.46.4
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.46.4/packages/typescript-eslint)

Updates `@eslint/js` from 9.38.0 to 9.39.1
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/commits/v9.39.1/packages/js)

Updates `@typescript-eslint/eslint-plugin` from 8.46.2 to 8.46.4
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.46.4/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.46.2 to 8.46.4
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.46.4/packages/parser)

---
updated-dependencies:
- dependency-name: eslint
  dependency-version: 9.39.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: typescript-eslint
  dependency-version: 8.46.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: eslint
  dependency-version: 9.39.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: typescript-eslint
  dependency-version: 8.46.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: "@eslint/js"
  dependency-version: 9.39.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.46.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.46.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-11 11:58:02 +01:00
dependabot[bot]
5b450d07f6 web: bump the storybook group across 1 directory with 5 updates (#18050)
Bumps the storybook group with 4 updates in the /web directory: [@storybook/addon-docs](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs), [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/links), [@storybook/web-components](https://github.com/storybookjs/storybook/tree/HEAD/code/renderers/web-components) and [@storybook/web-components-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/web-components-vite).


Updates `@storybook/addon-docs` from 10.0.3 to 10.0.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/v10.0.6/code/addons/docs)

Updates `@storybook/addon-links` from 10.0.3 to 10.0.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/v10.0.6/code/addons/links)

Updates `@storybook/web-components` from 10.0.3 to 10.0.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/v10.0.6/code/renderers/web-components)

Updates `@storybook/web-components-vite` from 10.0.3 to 10.0.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/v10.0.6/code/frameworks/web-components-vite)

Updates `storybook` from 10.0.3 to 10.0.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/v10.0.6/code/core)

---
updated-dependencies:
- dependency-name: "@storybook/addon-docs"
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/addon-links"
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/web-components"
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: "@storybook/web-components-vite"
  dependency-version: 10.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: storybook
- dependency-name: storybook
  dependency-version: 10.0.6
  dependency-type: direct:production
  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>
2025-11-11 11:57:16 +01:00
dependabot[bot]
2ce0db0515 ci: bump astral-sh/setup-uv from 7.1.2 to 7.1.3 in /.github/actions/setup (#18053)
ci: bump astral-sh/setup-uv in /.github/actions/setup

Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 7.1.2 to 7.1.3.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](85856786d1...5a7eac68fb)

---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
  dependency-version: 7.1.3
  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>
2025-11-11 11:54:03 +01:00
Ken Sternberg
cbc1351ef2 website/release notes: fix broken urls (#18041)
* website: fix bad escaping of URLs in release notes

## What

Fixes bad escaping of URLs in the release notes that resulted in mangled output.

v2024.6.4 had entries that looked like this:

```
##### `GET` /providers/google_workspace/{#123;id}#125;/
```

v2025.4.md had entries that looked like this:

```
##### `GET` /policies/unique_password/{#125;#123;policy_uuid}/
```

A couple of straightforward search-and-replaces has fixed the issue.

## Notes

Two of the release notes had bad escaping of URLs. I'm not sure how the error was made or got past,
but it was obvious when visiting the page.

@Beryju suggested that the bug is due to our using `{...}` to symbolize parameters in a URL while
Docusaurus wants to interpret `{...}` as an internal template instruction, resulting in odd
behavior. In either case, docusarus interpreted the hashtagged entries as links to unrelated issues
in Github (the same two issues, which were "bump version of pylint" and "bump version of sentry"),
which could be very confusing.

The inconsistencies between the two releases, and the working releases, suggests that the error was
introduced manually.
2025-11-10 09:55:30 -08:00
authentik-automation[bot]
69000ea849 core, web: update translations (#17943)
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>
2025-11-10 16:10:04 +01:00
dependabot[bot]
2aeb1b2448 web: bump @types/node from 24.9.1 to 24.10.0 in /packages/prettier-config (#17949)
web: bump @types/node in /packages/prettier-config

Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.9.1 to 24.10.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.10.0
  dependency-type: direct:development
  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>
2025-11-10 16:09:46 +01:00
dependabot[bot]
b513baf980 core: bump library/nginx from f547e3d to 1beed3c in /website (#17955)
Bumps library/nginx from `f547e3d` to `1beed3c`.

---
updated-dependencies:
- dependency-name: library/nginx
  dependency-version: 1.29-trixie
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-10 16:09:31 +01:00
dependabot[bot]
4506b9703d core: bump goauthentik.io/api/v3 from 3.2025120.2 to 3.2025120.3 (#17945)
Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2025120.2 to 3.2025120.3.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Changelog](https://github.com/goauthentik/client-go/blob/main/model_version_history.go)
- [Commits](https://github.com/goauthentik/client-go/compare/v3.2025120.2...v3.2025120.3)

---
updated-dependencies:
- dependency-name: goauthentik.io/api/v3
  dependency-version: 3.2025120.3
  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>
2025-11-10 16:09:11 +01:00
dependabot[bot]
daf3cf9ce3 web: bump @types/node from 22.15.19 to 24.10.0 in /web (#17950)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.15.19 to 24.10.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.10.0
  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>
2025-11-10 16:08:58 +01:00
dependabot[bot]
abf5575001 ci: bump docker/setup-qemu-action from 3.6.0 to 3.7.0 (#17999)
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3.6.0 to 3.7.0.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](29109295f8...c7c5346462)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: 3.7.0
  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>
2025-11-10 15:57:48 +01:00
dependabot[bot]
dded84769f lifecycle/aws: bump aws-cdk from 2.1031.1 to 2.1031.2 in /lifecycle/aws (#18014)
Bumps [aws-cdk](https://github.com/aws/aws-cdk-cli/tree/HEAD/packages/aws-cdk) from 2.1031.1 to 2.1031.2.
- [Release notes](https://github.com/aws/aws-cdk-cli/releases)
- [Commits](https://github.com/aws/aws-cdk-cli/commits/aws-cdk@v2.1031.2/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  dependency-version: 2.1031.2
  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>
2025-11-10 15:56:59 +01:00
dependabot[bot]
fd44a206d9 core: bump golang.org/x/sync from 0.17.0 to 0.18.0 (#18033)
Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.17.0 to 0.18.0.
- [Commits](https://github.com/golang/sync/compare/v0.17.0...v0.18.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-version: 0.18.0
  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>
2025-11-10 15:56:00 +01:00
dependabot[bot]
9625270aed core: bump astral-sh/uv from 0.9.7 to 0.9.8 (#18037)
Bumps [astral-sh/uv](https://github.com/astral-sh/uv) from 0.9.7 to 0.9.8.
- [Release notes](https://github.com/astral-sh/uv/releases)
- [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/uv/compare/0.9.7...0.9.8)

---
updated-dependencies:
- dependency-name: astral-sh/uv
  dependency-version: 0.9.8
  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>
2025-11-10 14:41:35 +01:00
dependabot[bot]
2888f35e54 core: bump golang.org/x/oauth2 from 0.32.0 to 0.33.0 (#18034)
Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.32.0 to 0.33.0.
- [Commits](https://github.com/golang/oauth2/compare/v0.32.0...v0.33.0)

---
updated-dependencies:
- dependency-name: golang.org/x/oauth2
  dependency-version: 0.33.0
  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>
2025-11-10 14:40:57 +01:00
dependabot[bot]
8ed53627ff core: bump axllent/mailpit from v1.27.10 to v1.27.11 in /tests/e2e (#18035)
Bumps axllent/mailpit from v1.27.10 to v1.27.11.

---
updated-dependencies:
- dependency-name: axllent/mailpit
  dependency-version: v1.27.11
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-10 14:40:42 +01:00
dependabot[bot]
7ce46ac301 ci: bump golangci/golangci-lint-action from 8.0.0 to 9.0.0 (#18036)
Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 8.0.0 to 9.0.0.
- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
- [Commits](4afd733a84...0a35821d5c)

---
updated-dependencies:
- dependency-name: golangci/golangci-lint-action
  dependency-version: 9.0.0
  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>
2025-11-10 14:40:28 +01:00
dependabot[bot]
60dbaf1fa1 core: bump library/golang from a13297b to 27e1c92 (#18038)
* core: bump library/golang from `a13297b` to `27e1c92`

Bumps library/golang from `a13297b` to `27e1c92`.

---
updated-dependencies:
- dependency-name: library/golang
  dependency-version: 1.25.4-trixie
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* fix

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

* dont require python

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

* fix error code

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

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-11-10 14:40:11 +01:00
Jens L.
7068d4d978 ci: fix migrate-from-stable for old versions (#18019)
ci: better logic for picking previous stable version

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-11-08 13:22:10 +01:00
dependabot[bot]
ba331a093e core: bump library/golang from 1.25.3-trixie to 1.25.4-trixie (#18000)
Bumps library/golang from 1.25.3-trixie to 1.25.4-trixie.

---
updated-dependencies:
- dependency-name: library/golang
  dependency-version: 1.25.4-trixie
  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>
2025-11-07 16:15:53 +01:00
Dewi Roberts
230b1b5850 website/docs: updates img-src csp (#18010) 2025-11-06 15:53:53 -05:00
Connor Peshek
fb868a6224 providers/saml: move sp binding location and default value (#17609)
* providers/saml: move sp binding location and default value in UI

---------

Signed-off-by: Connor Peshek <connor@connorpeshek.me>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: connor peshek <connorpeshek@connors-MacBook-Pro.local>
Co-authored-by: Dominic R <dominic@sdko.org>
Co-authored-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-11-06 13:39:46 -06:00
Marcelo Elizeche Landó
9802d4bcdd core: Add example invitation blueprint (#17661)
* Add flows-invitation-enrollment.yaml blueprint example, make serializer add default anonymous user in blueprint context

* Add tests

* fix linting

* Update invitations docs

* Use custom attributes instead of fixed_data

* remove clutter

* Reworks the invitations doc to new styling standards

* Apply suggestions

* fix field

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

* fix

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

* Add manual steps for invitation creation

* add both options at the beginning

* use serializer.context in InvitationViewSet.perform_create

* Apply suggestions from code review

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>

* add description to bluprint

* Apply suggestions from code review

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>

* tweaks to structure and formatting

* Optimised images with calibre/image-actions

* Update website/docs/users-sources/user/invitations.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>

* fix linting

* imports

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

* less branch

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

* gen

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

* add docs

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Marcelo Elizeche Landó <marce@melizeche.com>
Co-authored-by: dewi-tik <dewi@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Dominic R <dominic@sdko.org>
Co-authored-by: Tana M Berry <tana@goauthentik.io>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-11-06 20:29:04 +01:00
Dominic R
221b8431ef root: settings.py: fix comment (#18006)
Signed-off-by: Dominic R <dominic@sdko.org>
2025-11-06 17:47:21 +01:00
Marcelo Elizeche Landó
367100dde6 core: bump google-auth-httplib2 from 0.2.0 to v0.2.1 (#17978) 2025-11-06 14:58:02 +00:00
Marcelo Elizeche Landó
2f50903021 core: bump protobuf from 6.32.1 to v6.33.0 (#17984) 2025-11-06 14:55:28 +00:00
Marcelo Elizeche Landó
6a13b38740 core: bump django from 5.2.7 to 5.2.8 (#17967)
* bump django from 5.2.7 to 5.2.8

* longer urls

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

* add debug statements

* Remove debug statements

* import MAX_URL_LENGTH constant from django.http.response

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2025-11-06 15:10:46 +01:00
Jesse Johnson
34279ba8a5 website/docs: Update Homarr instructions to v1.43.1. (#17992) 2025-11-06 00:46:36 +00:00
Marcelo Elizeche Landó
94886dd33d core: bump python-dotenv from 1.1.1 to v1.2.1 (#17986) 2025-11-05 18:02:43 +00:00
Marcelo Elizeche Landó
e6ef5fd663 core: bump trio from 0.31.0 to v0.32.0 (#17989) 2025-11-05 18:01:14 +00:00
Marcelo Elizeche Landó
bc9bcc44f4 core: bump autobahn from 24.4.2 to v25.10.2 (#17970) 2025-11-05 17:59:53 +00:00
Marcelo Elizeche Landó
fa6ca4ced6 core: bump cwcwidth from 0.1.10 to v0.1.12 (#17975) 2025-11-05 18:42:28 +01:00
Marcelo Elizeche Landó
4cabc3975c core: bump jsii from 1.116.0 to v1.118.0 (#17981) 2025-11-05 18:42:20 +01:00
Marcelo Elizeche Landó
9a4c3dc9c7 core: bump blessed from 1.22.0 to v1.23.0 (#17972) 2025-11-05 18:41:50 +01:00
Marcelo Elizeche Landó
7ca0a667ba core: bump azure-core from 1.35.1 to v1.36.0 (#17971) 2025-11-05 18:41:41 +01:00
Marcelo Elizeche Landó
1c8f209274 core: bump boto3 from 1.40.51 to v1.40.66 (#17973) 2025-11-05 18:41:28 +01:00
Marcelo Elizeche Landó
69a9dadc43 core: bump cbor2 from 5.7.0 to v5.7.1 (#17974) 2025-11-05 18:40:55 +01:00
Marcelo Elizeche Landó
30e1cde6a2 core: bump google-api-core from 2.26.0 to v2.28.1 (#17976) 2025-11-05 18:40:46 +01:00
Marcelo Elizeche Landó
6e957977aa core: bump google-auth from 2.41.1 to v2.42.1 (#17977) 2025-11-05 18:40:35 +01:00
Marcelo Elizeche Landó
bccaf97cb9 core: bump opentelemetry-api from 1.37.0 to v1.38.0 (#17982) 2025-11-05 18:40:27 +01:00
Marcelo Elizeche Landó
78c9936bb7 core: bump orjson from 3.11.3 to v3.11.4 (#17983) 2025-11-05 18:40:13 +01:00
Marcelo Elizeche Landó
accb41959b core: bump psycopg-pool from 3.2.6 to v3.2.7 (#17985) 2025-11-05 18:40:07 +01:00
Marcelo Elizeche Landó
fd7851bfb4 core: bump rpds-py from 0.27.1 to v0.28.0 (#17987) 2025-11-05 18:39:57 +01:00
Marcelo Elizeche Landó
8f2f680668 core: bump std-uritemplate from 2.0.6 to v2.0.8 (#17988) 2025-11-05 18:39:49 +01:00
Marcelo Elizeche Landó
335805e2ba core: bump iniconfig from 2.1.0 to v2.3.0 (#17980) 2025-11-05 18:35:28 +01:00
Marcelo Elizeche Landó
6ccdbff511 core: bump aiohttp from 3.13.0 to v3.13.2 (#17969) 2025-11-05 18:34:23 +01:00
Marcelo Elizeche Landó
f9ed24362a core: bump uvloop from 0.21.0 to v0.22.1 (#17990) 2025-11-05 18:34:08 +01:00
Dewi Roberts
8a9291a9b5 webiste/docs: remove broken info box and fix sentence (#17963)
Remove broken info box and fix sentence.
2025-11-05 14:06:12 +00:00
Dewi Roberts
547d35e992 web/admin: fixes capitalization in application wizard title (#17959)
Changes 'The' to 'the'
2025-11-05 12:45:34 +00:00
Tana M Berry
8acd670fff website/docs: added Note about email_verified scope mapping is set to false by default (#17942)
* added Note about email_verified set to false

* Update website/docs/add-secure-apps/providers/property-mappings/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* edits

* more edits

* Update website/docs/add-secure-apps/providers/property-mappings/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

---------

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Dominic R <dominic@sdko.org>
2025-11-04 19:17:23 -06:00
Connor Peshek
0b01f45b07 crypto: update certificate api and component (#17921)
* Update crypto api and front-end component

---------

Co-authored-by: connor peshek <connorpeshek@connors-MacBook-Pro.local>
2025-11-04 14:44:57 -06:00
dependabot[bot]
c45c76302d core: bump openapitools/openapi-diff from 2.1.4 to 2.1.5 in /scripts/api (#17929)
Bumps openapitools/openapi-diff from 2.1.4 to 2.1.5.

---
updated-dependencies:
- dependency-name: openapitools/openapi-diff
  dependency-version: 2.1.5
  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>
2025-11-04 19:24:18 +01:00
dependabot[bot]
0fdfd88c23 ci: bump getsentry/action-release from 3.3.0 to 3.4.0 (#17931)
Bumps [getsentry/action-release](https://github.com/getsentry/action-release) from 3.3.0 to 3.4.0.
- [Release notes](https://github.com/getsentry/action-release/releases)
- [Changelog](https://github.com/getsentry/action-release/blob/master/CHANGELOG.md)
- [Commits](4f502acc1d...128c5058bb)

---
updated-dependencies:
- dependency-name: getsentry/action-release
  dependency-version: 3.4.0
  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>
2025-11-04 19:12:00 +01:00
dependabot[bot]
08a380a875 ci: bump helm/kind-action from 1.12.0 to 1.13.0 (#17930)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-04 15:45:40 +01:00
Marc 'risson' Schmitt
52e613b368 tasks/schedules: fix rel obj not being associated or updated (#17934)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-11-04 15:04:49 +01:00
authentik-automation[bot]
c1338b0164 core, web: update translations (#17807)
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>
2025-11-04 13:44:22 +00:00
Marc 'risson' Schmitt
945c2d8032 brands: sort matched brand by match length (#17920) 2025-11-04 14:22:10 +01:00
dependabot[bot]
e2e7021b62 web: bump the storybook group across 1 directory with 5 updates (#17787)
Bumps the storybook group with 5 updates in the /web directory:

| Package | From | To |
| --- | --- | --- |
| [@storybook/addon-docs](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/docs) | `9.1.15` | `10.0.0` |
| [@storybook/addon-links](https://github.com/storybookjs/storybook/tree/HEAD/code/addons/links) | `9.1.15` | `10.0.0` |
| [@storybook/web-components](https://github.com/storybookjs/storybook/tree/HEAD/code/renderers/web-components) | `9.1.15` | `10.0.0` |
| [@storybook/web-components-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/web-components-vite) | `9.1.15` | `10.0.0` |
| [storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/core) | `9.1.15` | `10.0.0` |



Updates `@storybook/addon-docs` from 9.1.15 to 10.0.0
- [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/v10.0.0/code/addons/docs)

Updates `@storybook/addon-links` from 9.1.15 to 10.0.0
- [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/v10.0.0/code/addons/links)

Updates `@storybook/web-components` from 9.1.15 to 10.0.0
- [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/v10.0.0/code/renderers/web-components)

Updates `@storybook/web-components-vite` from 9.1.15 to 10.0.0
- [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/v10.0.0/code/frameworks/web-components-vite)

Updates `storybook` from 9.1.15 to 10.0.0
- [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/v10.0.0/code/core)

---
updated-dependencies:
- dependency-name: "@storybook/addon-docs"
  dependency-version: 10.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: storybook
- dependency-name: "@storybook/addon-links"
  dependency-version: 10.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: storybook
- dependency-name: "@storybook/web-components"
  dependency-version: 10.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: storybook
- dependency-name: "@storybook/web-components-vite"
  dependency-version: 10.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: storybook
- dependency-name: storybook
  dependency-version: 10.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: storybook
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-04 04:37:46 +00:00
Marc 'risson' Schmitt
b02a0a79b8 brands: add more matching tests (#16185)
* brands: reproduce matching error

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

* try some things

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

* fix tests

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

* fix tests

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

* Update authentik/brands/tests.py

Co-authored-by: Jens L. <jens@goauthentik.io>
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix tests again?

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

* wip

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

---------

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
Co-authored-by: Jens L. <jens@goauthentik.io>
2025-11-03 20:31:56 +01:00
445 changed files with 20772 additions and 20438 deletions

81
.github/ISSUE_TEMPLATE/1-bug-report.yml vendored Normal file
View File

@@ -0,0 +1,81 @@
name: Bug report
description: Create a report to help us improve
labels: ["bug", "triage"]
type: bug
body:
- type: markdown
attributes:
value: |
Thank you for taking the time to fill out this bug report!
- type: textarea
id: describe-the-bug
attributes:
label: Describe the bug
description: "A clear and concise description of what the bug is."
placeholder: "Describe the issue"
validations:
required: true
- type: textarea
id: how-to-reproduce
attributes:
label: How to reproduce
description: "Steps to reproduce the behavior."
placeholder: |
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: "A clear and concise description of what you expected to happen."
placeholder: "The behavior that I expect to see is [...]"
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: "If applicable, add screenshots to help explain your problem."
validations:
required: false
- type: textarea
id: additional-context
attributes:
label: Additional context
description: "Add any other context about the problem here."
placeholder: "Also note that [...]"
validations:
required: false
- type: dropdown
id: deployment-method
attributes:
label: Deployment Method
description: "What deployment method are you using for authentik? Only Docker, Kubernetes and AWS CloudFormation are supported."
options:
- Docker
- Kubernetes
- AWS CloudFormation
- Other (please specify)
default: 0
validations:
required: true
- type: input
id: version
attributes:
label: Version
description: "What version of authentik are you using?"
placeholder: "[e.g. 2025.10.1]"
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
description: "Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks."
render: shell
validations:
required: false

49
.github/ISSUE_TEMPLATE/2-docs-issue.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: Documentation suggestion/problem
description: Suggest an improvement or report a problem in our docs
labels: ["area: docs", "triage"]
type: task
body:
- type: markdown
attributes:
value: |
Thank you for taking the time to fill out this documentation issue!
- type: markdown
attributes:
value: |
**Consider opening a PR!**
If the issue is one that you can fix, or even make a good pass at, we'd appreciate a PR.
For more information about making a contribution to the docs, and using our Style Guide and our templates, refer to ["Writing documentation"](https://docs.goauthentik.io/docs/developer-docs/docs/writing-documentation).
- type: textarea
id: issue
attributes:
label: Do you see an area that can be clarified or expanded, a technical inaccuracy, or a broken link?
description: "A clear and concise description of what the problem is, or where the document can be improved."
placeholder: "I believe we need more details about [...]"
validations:
required: true
- type: input
id: link
attributes:
label: Link
description: "Provide the URL or link to the exact page in the documentation to which you are referring."
placeholder: "If there are multiple pages, list them all"
validations:
required: true
- type: textarea
id: solution
attributes:
label: Solution
description: "A clear and concise description of what you suggest as a solution"
placeholder: "This issue could be resolved by [...]"
validations:
required: true
- type: textarea
id: additional-context
attributes:
label: Additional context
description: "Add any other context or screenshots about the documentation issue here."
placeholder: "Also note that [...]"
validations:
required: false

View File

@@ -0,0 +1,41 @@
name: Feature request
description: Suggest an idea for a feature
labels: ["enhancement", "triage"]
type: feature
body:
- type: markdown
attributes:
value: |
Thank you for taking the time to fill out this feature request!
- type: textarea
id: related-to-problem
attributes:
label: Is your feature request related to a problem?
description: "A clear and concise description of what the problem is."
placeholder: "I'm always frustrated when [...]"
validations:
required: true
- type: textarea
id: feature
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen.
placeholder: "I'd like authentik to have [...]"
validations:
required: false
- type: textarea
id: alternatives
attributes:
label: Describe alternatives that you've considered
description: "A clear and concise description of any alternative solutions or features you've considered."
placeholder: "I've tried this but [...]"
validations:
required: true
- type: textarea
id: additional-context
attributes:
label: Additional context
description: "Add any other context or screenshots about the feature request here."
placeholder: "Also note that [...]"
validations:
required: false

View File

@@ -1,39 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ""
labels: bug
assignees: ""
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Logs**
Output of docker-compose logs or kubectl logs respectively
**Version and Deployment (please complete the following information):**
<!--
Notice: authentik supports installation via Docker, Kubernetes, and AWS CloudFormation only. Support is not available for other methods. For detailed installation and configuration instructions, please refer to the official documentation at https://docs.goauthentik.io/docs/install-config/.
-->
- authentik version: [e.g. 2025.2.0]
- Deployment: [e.g. docker-compose, helm]
**Additional context**
Add any other context about the problem here.

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Question
url: https://github.com/goauthentik/authentik/discussions
about: Please ask questions via GitHub Discussions rather than creating issues.
- name: authentik Discord
url: https://discord.com/invite/jg33eMhnj6
about: For community support, visit our Discord server.

View File

@@ -1,22 +0,0 @@
---
name: Documentation issue
about: Suggest an improvement or report a problem
title: ""
labels: documentation
assignees: ""
---
**Do you see an area that can be clarified or expanded, a technical inaccuracy, or a broken link? Please describe.**
A clear and concise description of what the problem is, or where the document can be improved. Ex. I believe we need more details about [...]
**Provide the URL or link to the exact page in the documentation to which you are referring.**
If there are multiple pages, list them all, and be sure to state the header or section where the content is.
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Additional context**
Add any other context or screenshots about the documentation issue here.
**Consider opening a PR!**
If the issue is one that you can fix, or even make a good pass at, we'd appreciate a PR. For more information about making a contribution to the docs, and using our Style Guide and our templates, refer to ["Writing documentation"](https://docs.goauthentik.io/docs/developer-docs/docs/writing-documentation).

View File

@@ -1,19 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ""
labels: enhancement
assignees: ""
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,17 +0,0 @@
---
name: Hackathon Idea
about: Propose an idea for the hackathon
title: ""
labels: hackathon
assignees: ""
---
**Describe the idea**
A clear concise description of the idea you want to implement
You're also free to work on existing GitHub issues, whether they be feature requests or bugs, just link the existing GitHub issue here.
<!-- Don't modify below here -->
If you want to help working on this idea or want to contribute in any other way, react to this issue with a :rocket:

View File

@@ -0,0 +1,7 @@
---
name: Blank issue
about: This issue type is only for internal use
title:
labels:
assignees:
---

View File

@@ -1,32 +0,0 @@
---
name: Question
about: Ask a question about a feature or specific configuration
title: ""
labels: question
assignees: ""
---
**Describe your question/**
A clear and concise description of what you're trying to do.
**Relevant info**
i.e. Version of other software you're using, specifics of your setup
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Logs**
Output of docker-compose logs or kubectl logs respectively
**Version and Deployment (please complete the following information):**
<!--
Notice: authentik supports installation via Docker, Kubernetes, and AWS CloudFormation only. Support is not available for other methods. For detailed installation and configuration instructions, please refer to the official documentation at https://docs.goauthentik.io/docs/install-config/.
-->
- authentik version: [e.g. 2025.2.0]
- Deployment: [e.g. docker-compose, helm]
**Additional context**
Add any other context about the problem here.

View File

@@ -21,7 +21,7 @@ runs:
sudo apt-get install --no-install-recommends -y libpq-dev openssl libxmlsec1-dev pkg-config gettext libkrb5-dev krb5-kdc krb5-user krb5-admin-server
- name: Install uv
if: ${{ contains(inputs.dependencies, 'python') }}
uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v5
uses: astral-sh/setup-uv@5a7eac68fb9809dea845d802897dc5c723910fa3 # v5
with:
enable-cache: true
- name: Setup python

View File

@@ -42,8 +42,8 @@ jobs:
# Needed for checkout
contents: read
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
- uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3
- name: prepare variables
uses: ./.github/actions/docker-push-variables

View File

@@ -49,7 +49,7 @@ jobs:
tags: ${{ steps.ev.outputs.imageTagsJSON }}
shouldPush: ${{ steps.ev.outputs.shouldPush }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
@@ -69,7 +69,7 @@ jobs:
matrix:
tag: ${{ fromJson(needs.get-tags.outputs.tags) }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: prepare variables
uses: ./.github/actions/docker-push-variables
id: ev

View File

@@ -22,7 +22,7 @@ jobs:
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
token: ${{ steps.generate_token.outputs.token }}
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v5

View File

@@ -21,7 +21,7 @@ jobs:
command:
- prettier-check
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Install Dependencies
working-directory: website/
run: npm ci
@@ -32,7 +32,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v5
with:
node-version-file: website/package.json
@@ -66,7 +66,7 @@ jobs:
- lint
- build
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v5
with:
name: api-docs

View File

@@ -21,7 +21,7 @@ jobs:
check-changes-applied:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Setup authentik env
uses: ./.github/actions/setup
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v5

View File

@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Setup authentik env
uses: ./.github/actions/setup
- name: generate docs

View File

@@ -21,7 +21,7 @@ jobs:
command:
- prettier-check
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Install dependencies
working-directory: website/
run: npm ci
@@ -32,7 +32,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v5
with:
node-version-file: website/package.json
@@ -48,7 +48,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v5
with:
node-version-file: website/package.json
@@ -69,11 +69,11 @@ jobs:
id-token: write
attestations: write
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3
- name: prepare variables

View File

@@ -18,7 +18,7 @@ jobs:
- version-2025-4
- version-2025-2
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- run: |
current="$(pwd)"
dir="/tmp/authentik/${{ matrix.version }}"

View File

@@ -37,7 +37,7 @@ jobs:
- mypy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Setup authentik env
uses: ./.github/actions/setup
- name: run job
@@ -45,7 +45,7 @@ jobs:
test-migrations:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Setup authentik env
uses: ./.github/actions/setup
- name: run migrations
@@ -71,16 +71,25 @@ jobs:
- 18-alpine
run_id: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
fetch-depth: 0
- name: checkout stable
run: |
set -e -o pipefail
# Copy current, latest config to local
cp authentik/lib/default.yml local.env.yml
cp -R .github ..
cp -R scripts ..
git checkout $(git tag --sort=version:refname | grep '^version/' | grep -vE -- '-rc[0-9]+$' | tail -n1)
# Previous stable tag
prev_stable=$(git tag --sort=version:refname | grep '^version/' | grep -vE -- '-rc[0-9]+$' | tail -n1)
# Current version family based on
current_version_family=$(cat internal/constants/VERSION | grep -vE -- 'rc[0-9]+$' || true)
if [[ -n $current_version_family ]]; then
prev_stable=$current_version_family
fi
echo "::notice::Checking out ${prev_stable} as stable version..."
git checkout $(prev_stable)
rm -rf .github/ scripts/
mv ../.github ../scripts .
- name: Setup authentik env (stable)
@@ -129,7 +138,7 @@ jobs:
- 18-alpine
run_id: [1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Setup authentik env
uses: ./.github/actions/setup
with:
@@ -149,11 +158,11 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Setup authentik env
uses: ./.github/actions/setup
- name: Create k8s Kind Cluster
uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
uses: helm/kind-action@92086f6be054225fa813e0a4b13787fc9088faab # v1.13.0
- name: run integration
run: |
uv run coverage run manage.py test tests/integration
@@ -187,7 +196,7 @@ jobs:
- name: flows
glob: tests/e2e/test_flows*
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Setup authentik env
uses: ./.github/actions/setup
- name: Setup e2e env (chrome, etc)
@@ -253,7 +262,7 @@ jobs:
pull-requests: write
timeout-minutes: 120
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: prepare variables

View File

@@ -21,7 +21,7 @@ jobs:
lint-golint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6
with:
go-version-file: "go.mod"
@@ -34,7 +34,7 @@ jobs:
- name: Generate API
run: make gen-client-go
- name: golangci-lint
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8
uses: golangci/golangci-lint-action@0a35821d5c230e903fcfe077583637dea1b27b47 # v8
with:
version: latest
args: --timeout 5000s --verbose
@@ -42,7 +42,7 @@ jobs:
test-unittest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6
with:
go-version-file: "go.mod"
@@ -86,11 +86,11 @@ jobs:
id-token: write
attestations: write
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3
- name: prepare variables
@@ -145,7 +145,7 @@ jobs:
goos: [linux]
goarch: [amd64, arm64]
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6

View File

@@ -31,7 +31,7 @@ jobs:
- command: lit-analyse
project: web
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v5
with:
node-version-file: ${{ matrix.project }}/package.json
@@ -48,7 +48,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v5
with:
node-version-file: web/package.json
@@ -76,7 +76,7 @@ jobs:
- ci-web-mark
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v5
with:
node-version-file: web/package.json

View File

@@ -33,12 +33,12 @@ jobs:
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
token: ${{ steps.generate_token.outputs.token }}
- name: Compress images
id: compress
uses: calibreapp/image-actions@05b1cf44e88c3b041b841452482df9497f046ef7 # main
uses: calibreapp/image-actions@420075c115b26f8785e293c5bd5bef0911c506e5 # main
with:
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
compressOnly: ${{ github.event_name != 'pull_request' }}

View File

@@ -20,7 +20,7 @@ jobs:
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
token: ${{ steps.generate_token.outputs.token }}
- name: Setup authentik env

View File

@@ -17,7 +17,7 @@ jobs:
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
env:
GH_APP_ID: ${{ secrets.GH_APP_ID }}
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
if: ${{ steps.app-token.outcome != 'skipped' }}
with:
fetch-depth: 0

View File

@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Cleanup
run: |

View File

@@ -30,7 +30,7 @@ jobs:
- packages/tsconfig
- packages/esbuild-plugin-live-reload
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
fetch-depth: 2
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v5

View File

@@ -24,7 +24,7 @@ jobs:
language: ["go", "javascript", "python"]
steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Setup authentik env
uses: ./.github/actions/setup
- name: Initialize CodeQL

View File

@@ -26,5 +26,5 @@ jobs:
image: semgrep/semgrep
if: (github.actor != 'dependabot[bot]')
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- run: semgrep ci

View File

@@ -34,7 +34,7 @@ jobs:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: Checkout main
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
ref: main
token: "${{ steps.app-token.outputs.token }}"
@@ -62,7 +62,7 @@ jobs:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- name: Checkout main
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
ref: main
token: ${{ steps.generate_token.outputs.token }}

View File

@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
environment: internal-production
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
ref: main
- run: |

View File

@@ -31,9 +31,9 @@ jobs:
id-token: write
attestations: write
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3
- name: prepare variables
@@ -83,12 +83,12 @@ jobs:
- radius
- rac
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6
with:
go-version-file: "go.mod"
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3
- name: prepare variables
@@ -146,7 +146,7 @@ jobs:
goos: [linux, darwin]
goarch: [amd64, arm64]
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6
with:
go-version-file: "go.mod"
@@ -186,7 +186,7 @@ jobs:
AWS_REGION: eu-central-1
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5
with:
role-to-assume: "arn:aws:iam::016170277896:role/github_goauthentik_authentik"
@@ -202,7 +202,7 @@ jobs:
- build-outpost-binary
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: Run test suite in final docker images
run: |
echo "PG_PASS=$(openssl rand 32 | base64 -w 0)" >> .env
@@ -218,7 +218,7 @@ jobs:
- build-outpost-binary
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- name: prepare variables
uses: ./.github/actions/docker-push-variables
id: ev
@@ -232,7 +232,7 @@ jobs:
container=$(docker container create ${{ steps.ev.outputs.imageMainName }})
docker cp ${container}:web/ .
- name: Create a Sentry.io release
uses: getsentry/action-release@4f502acc1df792390abe36f2dcb03612ef144818 # v3
uses: getsentry/action-release@128c5058bbbe93c8e02147fe0a9c713f166259a6 # v3
continue-on-error: true
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}

View File

@@ -50,7 +50,7 @@ jobs:
name: Pre-release test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- run: make test-docker
bump-authentik:
name: Bump authentik version
@@ -70,7 +70,7 @@ jobs:
run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: "${{ steps.app-token.outputs.token }}"
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
ref: "version-${{ needs.check-inputs.outputs.major_version }}"
token: "${{ steps.app-token.outputs.token }}"
@@ -89,7 +89,7 @@ jobs:
git tag "version/${{ inputs.version }}" HEAD -m "version/${{ inputs.version }}"
git push --follow-tags
- name: Create Release
uses: goauthentik/action-gh-release@84da137b91a625a58fe8a34f3bd6bdb034a49138
uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2
with:
token: "${{ steps.app-token.outputs.token }}"
tag_name: "version/${{ inputs.version }}"
@@ -118,7 +118,7 @@ jobs:
run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: "${{ steps.app-token.outputs.token }}"
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
repository: "${{ github.repository_owner }}/helm"
token: "${{ steps.app-token.outputs.token }}"
@@ -160,7 +160,7 @@ jobs:
run: echo "user-id=$(gh api "/users/${{ steps.app-token.outputs.app-slug }}[bot]" --jq .id)" >> "$GITHUB_OUTPUT"
env:
GH_TOKEN: "${{ steps.app-token.outputs.token }}"
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
repository: "${{ github.repository_owner }}/version"
token: "${{ steps.app-token.outputs.token }}"

View File

@@ -25,11 +25,11 @@ jobs:
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
if: ${{ github.event_name != 'pull_request' }}
with:
token: ${{ steps.generate_token.outputs.token }}
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
if: ${{ github.event_name == 'pull_request' }}
- name: Setup authentik env
uses: ./.github/actions/setup

View File

@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
if: ${{ github.event.pull_request.user.login == 'transifex-integration[bot]'}}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
- id: generate_token
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2
with:

View File

@@ -26,7 +26,7 @@ RUN npm run build && \
npm run build:sfe
# Stage 2: Build go proxy
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.25.3-trixie@sha256:7534a6264850325fcce93e47b87a0e3fddd96b308440245e6ab1325fa8a44c91 AS go-builder
FROM --platform=${BUILDPLATFORM} docker.io/library/golang:1.25.4-trixie@sha256:728cbef6ce5da50a5da2455cf8a13ddc4f71eb5a3245d9a5a3cce260f8ca9898 AS go-builder
ARG TARGETOS
ARG TARGETARCH
@@ -76,7 +76,7 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
/bin/sh -c "GEOIPUPDATE_LICENSE_KEY_FILE=/run/secrets/GEOIPUPDATE_LICENSE_KEY /usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
# Stage 4: Download uv
FROM ghcr.io/astral-sh/uv:0.9.7@sha256:ba4857bf2a068e9bc0e64eed8563b065908a4cd6bfb66b531a9c424c8e25e142 AS uv
FROM ghcr.io/astral-sh/uv:0.9.10@sha256:29bd45092ea8902c0bbb7f0a338f0494a382b1f4b18355df5be270ade679ff1d AS uv
# Stage 5: Base python image
FROM ghcr.io/goauthentik/fips-python:3.13.9-slim-trixie-fips@sha256:700fc8c1e290bd14e5eaca50b1d8e8c748c820010559cbfb4c4f8dfbe2c4c9ff AS python-base

View File

@@ -17,21 +17,20 @@ pg_user := $(shell uv run python -m authentik.lib.config postgresql.user 2>/dev/
pg_host := $(shell uv run python -m authentik.lib.config postgresql.host 2>/dev/null)
pg_name := $(shell uv run python -m authentik.lib.config postgresql.name 2>/dev/null)
UNAME := $(shell uname)
# For macOS users, add the libxml2 installed from brew libxmlsec1 to the build path
# to prevent SAML-related tests from failing and ensure correct pip dependency compilation
ifeq ($(UNAME), Darwin)
# Only add for brew users who installed libxmlsec1
BREW_EXISTS := $(shell command -v brew 2> /dev/null)
ifdef BREW_EXISTS
LIBXML2_EXISTS := $(shell brew list libxml2 2> /dev/null)
ifdef LIBXML2_EXISTS
BREW_LDFLAGS := -L$(shell brew --prefix libxml2)/lib $(LDFLAGS)
BREW_CPPFLAGS := -I$(shell brew --prefix libxml2)/include $(CPPFLAGS)
BREW_PKG_CONFIG_PATH := $(shell brew --prefix libxml2)/lib/pkgconfig:$(PKG_CONFIG_PATH)
endif
endif
# These functions are only evaluated when called in specific targets
LIBXML2_EXISTS = $(shell brew list libxml2 2> /dev/null)
KRB5_EXISTS = $(shell brew list krb5 2> /dev/null)
LIBXML2_LDFLAGS = -L$(shell brew --prefix libxml2)/lib $(LDFLAGS)
LIBXML2_CPPFLAGS = -I$(shell brew --prefix libxml2)/include $(CPPFLAGS)
LIBXML2_PKG_CONFIG = $(shell brew --prefix libxml2)/lib/pkgconfig:$(PKG_CONFIG_PATH)
KRB_PATH =
ifneq ($(KRB5_EXISTS),)
KRB_PATH = PATH="$(shell brew --prefix krb5)/sbin:$(shell brew --prefix krb5)/bin:$$PATH"
endif
all: lint-fix lint gen web test ## Lint, build, and test everything
@@ -50,7 +49,7 @@ go-test:
go test -timeout 0 -v -race -cover ./...
test: ## Run the server tests and produce a coverage report (locally)
uv run coverage run manage.py test --keepdb authentik
$(KRB_PATH) uv run coverage run manage.py test --keepdb $(or $(filter-out $@,$(MAKECMDGOALS)),authentik)
uv run coverage html
uv run coverage report
@@ -66,11 +65,11 @@ lint: ## Lint the python and golang sources
golangci-lint run -v
core-install:
ifdef LIBXML2_EXISTS
ifneq ($(LIBXML2_EXISTS),)
# Clear cache to ensure fresh compilation
uv cache clean
# Force compilation from source for lxml and xmlsec with correct environment
LDFLAGS="$(BREW_LDFLAGS)" CPPFLAGS="$(BREW_CPPFLAGS)" PKG_CONFIG_PATH="$(BREW_PKG_CONFIG_PATH)" uv sync --frozen --reinstall-package lxml --reinstall-package xmlsec --no-binary-package lxml --no-binary-package xmlsec
LDFLAGS="$(LIBXML2_LDFLAGS)" CPPFLAGS="$(LIBXML2_CPPFLAGS)" PKG_CONFIG_PATH="$(LIBXML2_PKG_CONFIG)" uv sync --frozen --reinstall-package lxml --reinstall-package xmlsec --no-binary-package lxml --no-binary-package xmlsec
else
uv sync --frozen
endif

View File

@@ -2,27 +2,23 @@
from collections.abc import Callable
from functools import wraps
from typing import ParamSpec, TypeVar
from django.apps import apps
from authentik.blueprints.apps import ManagedAppConfig
from authentik.blueprints.models import BlueprintInstance
P = ParamSpec("P")
R = TypeVar("R")
def apply_blueprint(*files: str) -> Callable[[Callable[P, R]], Callable[P, R]]:
def apply_blueprint(*files: str):
"""Apply blueprint before test"""
from authentik.blueprints.v1.importer import Importer
def wrapper_outer(func: Callable[P, R]) -> Callable[P, R]:
def wrapper_outer(func: Callable):
"""Apply blueprint before test"""
@wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
def wrapper(*args, **kwargs):
for file in files:
content = BlueprintInstance(path=file).retrieve()
Importer.from_string(content).apply()

View File

@@ -1,8 +1,11 @@
"""Test brands"""
from json import loads
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.blueprints.tests import apply_blueprint
from authentik.brands.api import Themes
from authentik.brands.models import Brand
from authentik.core.models import Application
@@ -23,6 +26,7 @@ class TestBrands(APITestCase):
_flag = flag()
if _flag.visibility == "public":
self.default_flags[_flag.key] = _flag.get()
Brand.objects.all().delete()
def test_current_brand(self):
"""Test Current brand API"""
@@ -44,7 +48,6 @@ class TestBrands(APITestCase):
def test_brand_subdomain(self):
"""Test Current brand API"""
Brand.objects.all().delete()
Brand.objects.create(domain="bar.baz", branding_title="custom")
self.assertJSONEqual(
self.client.get(
@@ -65,7 +68,6 @@ class TestBrands(APITestCase):
def test_fallback(self):
"""Test fallback brand"""
Brand.objects.all().delete()
self.assertJSONEqual(
self.client.get(reverse("authentik_api:brand-current")).content.decode(),
{
@@ -81,6 +83,109 @@ class TestBrands(APITestCase):
},
)
@apply_blueprint("default/default-brand.yaml")
def test_blueprint(self):
"""Test Current brand API"""
response = loads(self.client.get(reverse("authentik_api:brand-current")).content.decode())
response.pop("flow_authentication", None)
response.pop("flow_invalidation", None)
response.pop("flow_user_settings", None)
self.assertEqual(
response,
{
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
"branding_favicon": "/static/dist/assets/icons/icon.png",
"branding_title": "authentik",
"branding_custom_css": "",
"matched_domain": "authentik-default",
"ui_footer_links": [],
"ui_theme": Themes.AUTOMATIC,
"default_locale": "",
"flags": self.default_flags,
},
)
@apply_blueprint("default/default-brand.yaml")
def test_blueprint_with_other_brand(self):
"""Test Current brand API"""
Brand.objects.create(domain="bar.baz", branding_title="custom")
response = loads(self.client.get(reverse("authentik_api:brand-current")).content.decode())
response.pop("flow_authentication", None)
response.pop("flow_invalidation", None)
response.pop("flow_user_settings", None)
self.assertEqual(
response,
{
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
"branding_favicon": "/static/dist/assets/icons/icon.png",
"branding_title": "authentik",
"branding_custom_css": "",
"matched_domain": "authentik-default",
"ui_footer_links": [],
"ui_theme": Themes.AUTOMATIC,
"default_locale": "",
"flags": self.default_flags,
},
)
self.assertJSONEqual(
self.client.get(
reverse("authentik_api:brand-current"), HTTP_HOST="foo.bar.baz"
).content.decode(),
{
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
"branding_favicon": "/static/dist/assets/icons/icon.png",
"branding_title": "custom",
"branding_custom_css": "",
"matched_domain": "bar.baz",
"ui_footer_links": [],
"ui_theme": Themes.AUTOMATIC,
"default_locale": "",
"flags": self.default_flags,
},
)
def test_brand_subdomain_same_suffix(self):
"""Test Current brand API"""
Brand.objects.create(domain="bar.baz", branding_title="custom-weak")
Brand.objects.create(domain="foo.bar.baz", branding_title="custom-strong")
self.assertJSONEqual(
self.client.get(
reverse("authentik_api:brand-current"), HTTP_HOST="foo.bar.baz"
).content.decode(),
{
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
"branding_favicon": "/static/dist/assets/icons/icon.png",
"branding_title": "custom-strong",
"branding_custom_css": "",
"matched_domain": "foo.bar.baz",
"ui_footer_links": [],
"ui_theme": Themes.AUTOMATIC,
"default_locale": "",
"flags": self.default_flags,
},
)
def test_brand_subdomain_other_suffix(self):
"""Test Current brand API"""
Brand.objects.create(domain="bar.baz", branding_title="custom-weak")
Brand.objects.create(domain="foo.bar.baz", branding_title="custom-strong")
self.assertJSONEqual(
self.client.get(
reverse("authentik_api:brand-current"), HTTP_HOST="other.bar.baz"
).content.decode(),
{
"branding_logo": "/static/dist/assets/icons/icon_left_brand.svg",
"branding_favicon": "/static/dist/assets/icons/icon.png",
"branding_title": "custom-weak",
"branding_custom_css": "",
"matched_domain": "bar.baz",
"ui_footer_links": [],
"ui_theme": Themes.AUTOMATIC,
"default_locale": "",
"flags": self.default_flags,
},
)
def test_create_default_multiple(self):
"""Test attempted creation of multiple default brands"""
Brand.objects.create(

View File

@@ -2,8 +2,8 @@
from typing import Any
from django.db.models import F, Q
from django.db.models import Value as V
from django.db.models import Case, F, IntegerField, Q, Value, When
from django.db.models.functions import Length
from django.http.request import HttpRequest
from django.utils.html import _json_script_escapes
from django.utils.safestring import mark_safe
@@ -19,15 +19,36 @@ DEFAULT_BRAND = Brand(domain="fallback")
def get_brand_for_request(request: HttpRequest) -> Brand:
"""Get brand object for current request"""
db_brands = (
Brand.objects.annotate(host_domain=V(request.get_host()))
.filter(Q(host_domain__iendswith=F("domain")) | _q_default)
.order_by("default")
brand = (
Brand.objects.annotate(
host_domain=Value(request.get_host()),
domain_length=Length("domain"),
match_priority=Case(
When(
condition=Q(host_domain__iendswith=F("domain")),
then=F("domain_length"),
),
default=Value(-1),
output_field=IntegerField(),
),
is_default_fallback=Case(
When(
condition=Q(default=True),
then=Value(0),
),
default=Value(-2),
output_field=IntegerField(),
),
)
.filter(Q(match_priority__gt=-1) | Q(default=True))
.order_by("-match_priority", "-is_default_fallback")
.first()
)
brands = list(db_brands.all())
if len(brands) < 1:
if brand is None:
return DEFAULT_BRAND
return brands[0]
return brand
def context_processor(request: HttpRequest) -> dict[str, Any]:

View File

@@ -3,11 +3,12 @@
from types import CodeType
from typing import Any
from django.db.models import Model
from django.http import HttpRequest
from prometheus_client import Histogram
from authentik.core.expression.exceptions import SkipObjectException
from authentik.core.models import PropertyMapping, User
from authentik.core.models import User
from authentik.events.models import Event, EventAction
from authentik.lib.expression.evaluator import BaseEvaluator
from authentik.policies.types import PolicyRequest
@@ -22,13 +23,13 @@ PROPERTY_MAPPING_TIME = Histogram(
class PropertyMappingEvaluator(BaseEvaluator):
"""Custom Evaluator that adds some different context variables."""
dry_run: bool | None
model: PropertyMapping
dry_run: bool
model: Model
_compiled: CodeType | None = None
def __init__(
self,
model: PropertyMapping,
model: Model,
user: User | None = None,
request: HttpRequest | None = None,
dry_run: bool | None = False,

View File

@@ -15,7 +15,7 @@ from django.db import models
from django.db.models import Q, QuerySet, options
from django.db.models.constants import LOOKUP_SEP
from django.http import HttpRequest
from django.utils.functional import SimpleLazyObject, cached_property
from django.utils.functional import cached_property
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django_cte import CTE, with_cte
@@ -44,18 +44,19 @@ from authentik.tenants.models import DEFAULT_TOKEN_DURATION, DEFAULT_TOKEN_LENGT
from authentik.tenants.utils import get_current_tenant, get_unique_identifier
LOGGER = get_logger()
USER_ATTRIBUTE_DEBUG = "goauthentik.io/user/debug"
USER_ATTRIBUTE_GENERATED = "goauthentik.io/user/generated"
USER_ATTRIBUTE_EXPIRES = "goauthentik.io/user/expires"
USER_ATTRIBUTE_DELETE_ON_LOGOUT = "goauthentik.io/user/delete-on-logout"
USER_ATTRIBUTE_SOURCES = "goauthentik.io/user/sources"
USER_ATTRIBUTE_TOKEN_EXPIRING = "goauthentik.io/user/token-expires" # nosec
USER_ATTRIBUTE_TOKEN_MAXIMUM_LIFETIME = "goauthentik.io/user/token-maximum-lifetime" # nosec
USER_ATTRIBUTE_CHANGE_USERNAME = "goauthentik.io/user/can-change-username"
USER_ATTRIBUTE_CHANGE_NAME = "goauthentik.io/user/can-change-name"
USER_ATTRIBUTE_CHANGE_EMAIL = "goauthentik.io/user/can-change-email"
USER_PATH_SYSTEM_PREFIX = "goauthentik.io"
USER_PATH_SERVICE_ACCOUNT = USER_PATH_SYSTEM_PREFIX + "/service-accounts"
_USER_ATTR_PREFIX = f"{USER_PATH_SYSTEM_PREFIX}/user"
USER_ATTRIBUTE_DEBUG = f"{_USER_ATTR_PREFIX}/debug"
USER_ATTRIBUTE_GENERATED = f"{_USER_ATTR_PREFIX}/generated"
USER_ATTRIBUTE_EXPIRES = f"{_USER_ATTR_PREFIX}/expires"
USER_ATTRIBUTE_DELETE_ON_LOGOUT = f"{_USER_ATTR_PREFIX}/delete-on-logout"
USER_ATTRIBUTE_SOURCES = f"{_USER_ATTR_PREFIX}/sources"
USER_ATTRIBUTE_TOKEN_EXPIRING = f"{_USER_ATTR_PREFIX}/token-expires" # nosec
USER_ATTRIBUTE_TOKEN_MAXIMUM_LIFETIME = f"{_USER_ATTR_PREFIX}/token-maximum-lifetime" # nosec
USER_ATTRIBUTE_CHANGE_USERNAME = f"{_USER_ATTR_PREFIX}/can-change-username"
USER_ATTRIBUTE_CHANGE_NAME = f"{_USER_ATTR_PREFIX}/can-change-name"
USER_ATTRIBUTE_CHANGE_EMAIL = f"{_USER_ATTR_PREFIX}/can-change-email"
USER_PATH_SERVICE_ACCOUNT = f"{USER_PATH_SYSTEM_PREFIX}/service-accounts"
options.DEFAULT_NAMES = options.DEFAULT_NAMES + (
# used_by API that allows models to specify if they shadow an object
@@ -585,18 +586,16 @@ class Application(SerializerModel, PolicyBindingModel):
def get_launch_url(self, user: Optional["User"] = None) -> str | None:
"""Get launch URL if set, otherwise attempt to get launch URL based on provider."""
from authentik.core.api.users import UserSerializer
url = None
if self.meta_launch_url:
url = self.meta_launch_url
elif provider := self.get_provider():
url = provider.launch_url
if user and url:
if isinstance(user, SimpleLazyObject):
user._setup()
user = user._wrapped
try:
return url % user.__dict__
return url % UserSerializer(instance=user).data
except Exception as exc: # noqa
LOGGER.warning("Failed to format launch url", exc=exc)
return url

View File

@@ -1,11 +1,13 @@
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
<script>
<script data-id="authentik-config">
"use strict";
window.authentik = {
locale: "{{ LANGUAGE_CODE }}",
config: JSON.parse('{{ config_json|escapejs }}'),
brand: JSON.parse('{{ brand_json|escapejs }}'),
config: JSON.parse('{{ config_json|escapejs }}' || "{}"),
brand: JSON.parse('{{ brand_json|escapejs }}' || "{}"),
versionFamily: "{{ version_family }}",
versionSubdomain: "{{ version_subdomain }}",
build: "{{ build }}",

View File

@@ -0,0 +1,13 @@
{% load i18n %}
<div class="ak-c-placeholder" id="ak-placeholder" slot="placeholder">
<span
class="pf-c-spinner"
role="progressbar"
aria-valuetext="Loading..."
>
<span class="pf-c-spinner__clipper"></span>
<span class="pf-c-spinner__lead-ball"></span>
<span class="pf-c-spinner__tail-ball"></span>
</span>
</div>

View File

@@ -3,8 +3,10 @@
{% load authentik_core %}
<!DOCTYPE html>
<html>
<html
data-theme="{% if ui_theme == "dark" %}dark{% else %}light{% endif %}"
data-theme-choice="{% if ui_theme == "dark" %}dark{% elif ui_theme == "light" %}light{% else %}auto{% endif %}"
>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
@@ -18,11 +20,8 @@
{% include "base/theme.html" %}
<link rel="stylesheet" type="text/css" href="{% static 'dist/authentik.css' %}">
<style>{{ brand_css }}</style>
<style data-id="brand-css">{{ brand_css }}</style>
<script src="{% versioned_script 'dist/poly-%v.js' %}" type="module"></script>
<script src="{% versioned_script 'dist/standalone/loading/index-%v.js' %}" type="module"></script>
{% block head %}
{% endblock %}
{% for key, value in html_meta.items %}

View File

@@ -1,10 +1,45 @@
{% load static %}
{% load authentik_core %}
<link rel="stylesheet" type="text/css" href="{% versioned_script 'dist/styles/interface-%v.css' %}" />
{% if ui_theme == "dark" %}
<meta name="color-scheme" content="dark" />
<meta name="theme-color" content="#18191a">
{% elif ui_theme == "light" %}
{% elif ui_theme == "light" %}
<meta name="color-scheme" content="light" />
<meta name="theme-color" content="#ffffff">
{% else %}
<script data-id="theme-script">
"use strict";
(function () {
try {
const initialThemeChoice =
new URLSearchParams(window.location.search).get("theme") ||
window.localStorage?.getItem("theme");
const themeChoice =
initialThemeChoice || document.documentElement.dataset.themeChoice || "auto";
document.documentElement.dataset.themeChoice = themeChoice;
if (themeChoice === "auto") {
document.documentElement.dataset.theme = window.matchMedia(
"(prefers-color-scheme: dark)",
).matches
? "dark"
: "light";
} else {
document.documentElement.dataset.theme = themeChoice;
}
} catch (e) {
console.error("Failed to apply theme", e);
}
})();
</script>
<meta name="color-scheme" content="light dark" />
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#18191a" media="(prefers-color-scheme: dark)">

View File

@@ -11,6 +11,6 @@
<ak-skip-to-content></ak-skip-to-content>
<ak-message-container alignment="bottom"></ak-message-container>
<ak-interface-admin>
<ak-loading></ak-loading>
{% include "base/placeholder.html" %}
</ak-interface-admin>
{% endblock %}

View File

@@ -12,10 +12,13 @@
{% endblock %}
{% block card %}
<form method="POST" class="pf-c-form">
<div class="pf-c-form">
<p>{% trans message %}</p>
<a id="ak-back-home" href="{% url 'authentik_core:root-redirect' %}" class="pf-c-button pf-m-primary">
{% trans 'Go home' %}
</a>
</form>
<div class="pf-c-form__group">
<a id="ak-back-home" href="{% url 'authentik_core:root-redirect' %}" class="pf-c-button pf-m-primary pf-m-block">
{% trans 'Go home' %}
</a>
</div>
</div>
{% endblock %}

View File

@@ -11,6 +11,6 @@
<ak-skip-to-content></ak-skip-to-content>
<ak-message-container></ak-message-container>
<ak-interface-user>
<ak-loading></ak-loading>
{% include "base/placeholder.html" %}
</ak-interface-user>
{% endblock %}

View File

@@ -2,82 +2,66 @@
{% load static %}
{% load i18n %}
{% load authentik_core %}
{% block head_before %}
<link rel="prefetch" href="{{ request.brand.branding_default_flow_background_url }}" />
<link rel="stylesheet" type="text/css" href="{% static 'dist/patternfly.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'dist/theme-dark.css' %}" media="(prefers-color-scheme: dark)">
{% include "base/header_js.html" %}
{% endblock %}
{% block head %}
<style>
:root {
--ak-flow-background: url("{{ request.brand.branding_default_flow_background_url }}");
--pf-c-background-image--BackgroundImage: var(--ak-flow-background);
--pf-c-background-image--BackgroundImage-2x: var(--ak-flow-background);
--pf-c-background-image--BackgroundImage--sm: var(--ak-flow-background);
--pf-c-background-image--BackgroundImage--sm-2x: var(--ak-flow-background);
--pf-c-background-image--BackgroundImage--lg: var(--ak-flow-background);
}
/* Form with user */
.form-control-static {
margin-top: var(--pf-global--spacer--sm);
display: flex;
align-items: center;
justify-content: space-between;
}
.form-control-static .avatar {
display: flex;
align-items: center;
}
.form-control-static img {
margin-right: var(--pf-global--spacer--xs);
}
.form-control-static a {
padding-top: var(--pf-global--spacer--xs);
padding-bottom: var(--pf-global--spacer--xs);
line-height: var(--pf-global--spacer--xl);
}
<style data-id="static-styles">
:root {
--ak-global--background-image: url("{{ request.brand.branding_default_flow_background_url }}");
}
</style>
<link rel="stylesheet" type="text/css" href="{% versioned_script 'dist/styles/static-%v.css' %}" />
{% endblock %}
{% block body %}
<div class="pf-c-background-image">
</div>
<ak-skip-to-content></ak-skip-to-content>
<ak-message-container></ak-message-container>
<div class="pf-c-login stacked">
<div class="ak-login-container">
<main class="pf-c-login__main">
<div class="pf-c-login__main-header pf-c-brand ak-brand">
<img src="{{ brand.branding_logo_url }}" alt="authentik Logo" />
<div class="pf-c-page__drawer">
<div class="pf-c-drawer pf-m-collapsed">
<div class="pf-c-drawer__main">
<div class="pf-c-drawer__content">
<div class="pf-c-drawer__body">
<div class="pf-c-login" data-layout="stacked">
<main class="pf-c-login__main" aria-label="Authentication form">
<div class="pf-c-login__main-header pf-c-brand">
<img class="branding-logo" src="{{ brand.branding_logo_url }}" alt="authentik Logo" />
</div>
<div class="pf-c-login__main-header">
<h1 class="pf-c-title pf-m-3xl" data-test-id="card-title">
{% block card_title %}
{% endblock %}
</h1>
</div>
<div class="pf-c-login__main-body">
{% block card %}
{% endblock %}
</div>
</main>
<footer aria-label="Site footer" class="pf-c-login__footer pf-m-dark">
<ul class="pf-c-list pf-m-inline">
{% for link in footer_links %}
<li>
<a href="{{ link.href }}">{{ link.name }}</a>
</li>
{% endfor %}
<li>
<span>
{% trans 'Powered by authentik' %}
</span>
</li>
</ul>
</footer>
</div>
</div>
</div>
<header class="pf-c-login__main-header">
<h1 class="pf-c-title pf-m-3xl">
{% block card_title %}
{% endblock %}
</h1>
</header>
<div class="pf-c-login__main-body">
{% block card %}
{% endblock %}
</div>
</main>
<footer class="pf-c-login__footer">
<ul class="pf-c-list pf-m-inline">
{% for link in footer_links %}
<li>
<a href="{{ link.href }}">{{ link.name }}</a>
</li>
{% endfor %}
<li>
<span>
{% trans 'Powered by authentik' %}
</span>
</li>
</ul>
</footer>
</div>
</div>
</div>
{% endblock %}

View File

@@ -9,9 +9,14 @@ from django.http.response import HttpResponse
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from django_filters import FilterSet
from django_filters.filters import BooleanFilter
from django_filters.filters import BooleanFilter, MultipleChoiceFilter
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
from drf_spectacular.utils import (
OpenApiParameter,
OpenApiResponse,
extend_schema,
extend_schema_field,
)
from rest_framework.decorators import action
from rest_framework.exceptions import ValidationError
from rest_framework.fields import (
@@ -33,7 +38,7 @@ from authentik.core.api.utils import ModelSerializer, PassiveSerializer
from authentik.core.models import UserTypes
from authentik.crypto.apps import MANAGED_KEY
from authentik.crypto.builder import CertificateBuilder, PrivateKeyAlg
from authentik.crypto.models import CertificateKeyPair
from authentik.crypto.models import CertificateKeyPair, KeyType
from authentik.events.models import Event, EventAction
from authentik.rbac.decorators import permission_required
from authentik.rbac.filters import ObjectFilter, SecretKeyFilter
@@ -50,7 +55,7 @@ class CertificateKeyPairSerializer(ModelSerializer):
cert_expiry = SerializerMethodField()
cert_subject = SerializerMethodField()
private_key_available = SerializerMethodField()
private_key_type = SerializerMethodField()
key_type = SerializerMethodField()
certificate_download_url = SerializerMethodField()
private_key_download_url = SerializerMethodField()
@@ -90,14 +95,12 @@ class CertificateKeyPairSerializer(ModelSerializer):
"""Show if this keypair has a private key configured or not"""
return instance.key_data != "" and instance.key_data is not None
def get_private_key_type(self, instance: CertificateKeyPair) -> str | None:
"""Get the private key's type, if set"""
@extend_schema_field(ChoiceField(choices=KeyType.choices, allow_null=True))
def get_key_type(self, instance: CertificateKeyPair) -> str | None:
"""Get the key algorithm type from the certificate's public key"""
if not self._should_include_details:
return None
key = instance.private_key
if key:
return key.__class__.__name__.replace("_", "").lower().replace("privatekey", "")
return None
return instance.key_type
def get_certificate_download_url(self, instance: CertificateKeyPair) -> str:
"""Get URL to download certificate"""
@@ -161,7 +164,7 @@ class CertificateKeyPairSerializer(ModelSerializer):
"cert_expiry",
"cert_subject",
"private_key_available",
"private_key_type",
"key_type",
"certificate_download_url",
"private_key_download_url",
"managed",
@@ -198,12 +201,31 @@ class CertificateKeyPairFilter(FilterSet):
label="Only return certificate-key pairs with keys", method="filter_has_key"
)
key_type = MultipleChoiceFilter(
choices=KeyType.choices,
label="Filter by key algorithm type",
method="filter_key_type",
)
def filter_has_key(self, queryset, name, value): # pragma: no cover
"""Only return certificate-key pairs with keys"""
if not value:
return queryset
return queryset.exclude(key_data__exact="")
def filter_key_type(self, queryset, name, value): # pragma: no cover
"""Filter certificates by key type using the public key from the certificate"""
if not value:
return queryset
# value is a list of KeyType enum values from MultipleChoiceFilter
filtered_pks = []
for cert in queryset:
if cert.key_type in value:
filtered_pks.append(cert.pk)
return queryset.filter(pk__in=filtered_pks)
class Meta:
model = CertificateKeyPair
fields = ["name", "managed"]
@@ -228,6 +250,17 @@ class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):
required=False,
description="Only return certificate-key pairs with keys",
),
OpenApiParameter(
"key_type",
OpenApiTypes.STR,
required=False,
many=True,
enum=[choice[0] for choice in KeyType.choices],
description=(
"Filter by key algorithm type (RSA, EC, DSA, etc). "
"Can be specified multiple times (e.g. '?key_type=rsa&key_type=ec')"
),
),
OpenApiParameter("include_details", bool, default=True),
]
)

View File

@@ -2,6 +2,8 @@
from datetime import UTC, datetime
from dramatiq.broker import get_broker
from authentik.blueprints.apps import ManagedAppConfig
from authentik.lib.generators import generate_id
from authentik.lib.utils.time import fqdn_rand
@@ -70,6 +72,12 @@ class AuthentikCryptoConfig(ManagedAppConfig):
},
)
@ManagedAppConfig.reconcile_global
def tasks_middlewares(self):
from authentik.crypto.tasks import CertificateWatcherMiddleware
get_broker().add_middleware(CertificateWatcherMiddleware())
@property
def tenant_schedule_specs(self) -> list[ScheduleSpec]:
from authentik.crypto.tasks import certificate_discovery

View File

@@ -6,6 +6,11 @@ from uuid import uuid4
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric.dsa import DSAPublicKey
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePublicKey
from cryptography.hazmat.primitives.asymmetric.ed448 import Ed448PublicKey
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes, PublicKeyTypes
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.x509 import Certificate, load_pem_x509_certificate
@@ -20,6 +25,16 @@ from authentik.lib.models import CreatedUpdatedModel, SerializerModel
LOGGER = get_logger()
class KeyType(models.TextChoices):
"""Cryptographic key algorithm types"""
RSA = "rsa", _("RSA")
EC = "ec", _("Elliptic Curve")
DSA = "dsa", _("DSA")
ED25519 = "ed25519", _("Ed25519")
ED448 = "ed448", _("Ed448")
def fingerprint_sha256(cert: Certificate) -> str:
"""Get SHA256 Fingerprint of certificate"""
return hexlify(cert.fingerprint(hashes.SHA256()), ":").decode("utf-8")
@@ -103,6 +118,22 @@ class CertificateKeyPair(SerializerModel, ManagedModel, CreatedUpdatedModel):
else ""
) # nosec
@property
def key_type(self) -> str | None:
"""Get the key algorithm type from the certificate's public key"""
public_key = self.certificate.public_key()
if isinstance(public_key, RSAPublicKey):
return KeyType.RSA
if isinstance(public_key, EllipticCurvePublicKey):
return KeyType.EC
if isinstance(public_key, DSAPublicKey):
return KeyType.DSA
if isinstance(public_key, Ed25519PublicKey):
return KeyType.ED25519
if isinstance(public_key, Ed448PublicKey):
return KeyType.ED448
return None
def __str__(self) -> str:
return f"Certificate-Key Pair {self.name}"

View File

@@ -2,17 +2,29 @@
from glob import glob
from pathlib import Path
from sys import platform
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.x509.base import load_pem_x509_certificate
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from dramatiq.actor import actor
from dramatiq.middleware import Middleware
from structlog.stdlib import get_logger
from watchdog.events import (
FileCreatedEvent,
FileModifiedEvent,
FileSystemEvent,
FileSystemEventHandler,
)
from watchdog.observers import Observer
from authentik.crypto.models import CertificateKeyPair
from authentik.lib.config import CONFIG
from authentik.tasks.middleware import CurrentTask
from authentik.tasks.schedules.models import Schedule
from authentik.tenants.models import Tenant
LOGGER = get_logger()
@@ -35,6 +47,65 @@ def ensure_certificate_valid(body: str):
return body
class CertificateWatcherMiddleware(Middleware):
"""Middleware to start certificate file watcher"""
def start_certificate_watcher(self):
"""Start certificate file watcher"""
observer = Observer()
kwargs = {}
if platform.startswith("linux"):
kwargs["event_filter"] = (FileCreatedEvent, FileModifiedEvent)
observer.schedule(
CertificateEventHandler(),
CONFIG.get("cert_discovery_dir"),
recursive=True,
**kwargs,
)
observer.start()
def after_worker_boot(self, broker, worker):
if not settings.TEST:
self.start_certificate_watcher()
class CertificateEventHandler(FileSystemEventHandler):
"""Event handler for certificate file events"""
# We only ever get creation and modification events.
# See the creation of the Observer instance above for the event filtering.
# Even though we filter to only get file events, we might still get
# directory events as some implementations such as inotify do not support
# filtering on file/directory.
def dispatch(self, event: FileSystemEvent) -> None:
"""Call specific event handler method. Ignores directory changes."""
if event.is_directory:
return None
return super().dispatch(event)
def on_created(self, event: FileSystemEvent):
"""Process certificate file creation"""
LOGGER.debug(
"Certificate file created, triggering discovery",
file=event.src_path,
)
for tenant in Tenant.objects.filter(ready=True):
with tenant:
Schedule.dispatch_by_actor(certificate_discovery)
def on_modified(self, event: FileSystemEvent):
"""Process certificate file modification"""
LOGGER.debug(
"Certificate file modified, triggering discovery",
file=event.src_path,
)
for tenant in Tenant.objects.filter(ready=True):
with tenant:
Schedule.dispatch_by_actor(certificate_discovery)
@actor(description=_("Discover, import and update certificates from the filesystem."))
def certificate_discovery():
self = CurrentTask.get_task()
@@ -66,12 +137,35 @@ def certificate_discovery():
except (OSError, ValueError) as exc:
LOGGER.warning("Failed to open file or invalid format", exc=exc, file=path)
for name, cert_data in certs.items():
# First, try to find by filename-based managed field
cert = CertificateKeyPair.objects.filter(managed=MANAGED_DISCOVERED % name).first()
# If not found by filename and we have a private key, check for existing key match
if not cert and name in private_keys:
existing_with_key = (
CertificateKeyPair.objects.filter(
managed__startswith="goauthentik.io/crypto/discovered/",
key_data=private_keys[name],
)
.exclude(key_data="")
.first()
)
if existing_with_key:
cert = existing_with_key
# Update name and managed field to reflect the new filename
if cert.name != name:
cert.name = name
cert.managed = MANAGED_DISCOVERED % name
cert.save()
# Create new certificate if not found
if not cert:
cert = CertificateKeyPair(
name=name,
managed=MANAGED_DISCOVERED % name,
)
# Update certificate data if changed
dirty = False
if cert.certificate_data != cert_data:
cert.certificate_data = cert_data

View File

@@ -2,6 +2,7 @@
from json import loads
from os import makedirs
from pathlib import Path
from tempfile import TemporaryDirectory
from cryptography.x509.extensions import SubjectAlternativeName
@@ -319,6 +320,8 @@ class TestCrypto(APITestCase):
def test_discovery(self):
"""Test certificate discovery"""
# This test generates 2 separate cert/key combinations
# and verifies they both import properly
name = generate_id()
builder = CertificateBuilder(name)
with self.assertRaises(ValueError):
@@ -327,6 +330,15 @@ class TestCrypto(APITestCase):
subject_alt_names=[],
validity_days=3,
)
name2 = generate_id()
builder2 = CertificateBuilder(name2)
with self.assertRaises(ValueError):
builder2.save()
builder2.build(
subject_alt_names=[],
validity_days=3,
)
with TemporaryDirectory() as temp_dir:
with open(f"{temp_dir}/foo.pem", "w+", encoding="utf-8") as _cert:
_cert.write(builder.certificate)
@@ -334,9 +346,9 @@ class TestCrypto(APITestCase):
_key.write(builder.private_key)
makedirs(f"{temp_dir}/foo.bar", exist_ok=True)
with open(f"{temp_dir}/foo.bar/fullchain.pem", "w+", encoding="utf-8") as _cert:
_cert.write(builder.certificate)
_cert.write(builder2.certificate)
with open(f"{temp_dir}/foo.bar/privkey.pem", "w+", encoding="utf-8") as _key:
_key.write(builder.private_key)
_key.write(builder2.private_key)
with CONFIG.patch("cert_discovery_dir", temp_dir):
certificate_discovery.send()
keypair: CertificateKeyPair = CertificateKeyPair.objects.filter(
@@ -348,3 +360,58 @@ class TestCrypto(APITestCase):
self.assertTrue(
CertificateKeyPair.objects.filter(managed=MANAGED_DISCOVERED % "foo.bar").exists()
)
def test_discovery_updating_same_private_key(self):
"""Test certificate discovery updating certs with matching private keys"""
name = generate_id()
builder = CertificateBuilder(name)
builder.build(
subject_alt_names=[],
validity_days=3,
)
with TemporaryDirectory() as temp_dir:
# First discovery: write cert as "original"
with open(f"{temp_dir}/original.pem", "w+", encoding="utf-8") as _cert:
_cert.write(builder.certificate)
with open(f"{temp_dir}/original.key", "w+", encoding="utf-8") as _key:
_key.write(builder.private_key)
with CONFIG.patch("cert_discovery_dir", temp_dir):
certificate_discovery.send()
# Verify "original" cert was created
original = CertificateKeyPair.objects.filter(
managed=MANAGED_DISCOVERED % "original"
).first()
self.assertIsNotNone(original)
self.assertEqual(original.name, "original")
self.assertIsNotNone(original.private_key)
# Second discovery: write same cert/key as "renamed"
Path(f"{temp_dir}/original.pem").unlink()
Path(f"{temp_dir}/original.key").unlink()
with open(f"{temp_dir}/renamed.pem", "w+", encoding="utf-8") as _cert:
_cert.write(builder.certificate)
with open(f"{temp_dir}/renamed.key", "w+", encoding="utf-8") as _key:
_key.write(builder.private_key)
with CONFIG.patch("cert_discovery_dir", temp_dir):
certificate_discovery.send()
# Verify the cert was updated
renamed = CertificateKeyPair.objects.filter(
managed=MANAGED_DISCOVERED % "renamed"
).first()
self.assertIsNotNone(renamed, "Renamed certificate should exist")
self.assertEqual(renamed.name, "renamed")
self.assertEqual(renamed.pk, original.pk, "Should be same database object")
# Verify no new cert was created
final_count = CertificateKeyPair.objects.filter(
managed__startswith="goauthentik.io/crypto/discovered/"
).count()
self.assertEqual(
1, final_count, "Should not create duplicate cert for same private key"
)

View File

@@ -1,9 +1,13 @@
"""GoogleWorkspaceProviderGroup API Views"""
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.users import PartialGroupSerializer
from authentik.core.api.utils import ModelSerializer
from authentik.enterprise.providers.google_workspace.models import GoogleWorkspaceProviderGroup
from authentik.lib.sync.outgoing.api import OutgoingSyncConnectionViewSet
from authentik.lib.sync.outgoing.api import OutgoingSyncConnectionCreateMixin
class GoogleWorkspaceProviderGroupSerializer(ModelSerializer):
@@ -12,6 +16,7 @@ class GoogleWorkspaceProviderGroupSerializer(ModelSerializer):
group_obj = PartialGroupSerializer(source="group", read_only=True)
class Meta:
model = GoogleWorkspaceProviderGroup
fields = [
"id",
@@ -24,7 +29,15 @@ class GoogleWorkspaceProviderGroupSerializer(ModelSerializer):
extra_kwargs = {"attributes": {"read_only": True}}
class GoogleWorkspaceProviderGroupViewSet(OutgoingSyncConnectionViewSet):
class GoogleWorkspaceProviderGroupViewSet(
mixins.CreateModelMixin,
OutgoingSyncConnectionCreateMixin,
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
"""GoogleWorkspaceProviderGroup Viewset"""
queryset = GoogleWorkspaceProviderGroup.objects.all().select_related("group")

View File

@@ -1,13 +1,16 @@
"""Google Provider API Views"""
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.providers import ProviderSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.enterprise.api import EnterpriseRequiredMixin
from authentik.enterprise.providers.google_workspace.models import GoogleWorkspaceProvider
from authentik.enterprise.providers.google_workspace.tasks import (
google_workspace_sync,
google_workspace_sync_objects,
)
from authentik.lib.sync.outgoing.api import OutgoingSyncProviderViewSet
from authentik.lib.sync.outgoing.api import OutgoingSyncProviderStatusMixin
class GoogleWorkspaceProviderSerializer(EnterpriseRequiredMixin, ProviderSerializer):
@@ -41,16 +44,18 @@ class GoogleWorkspaceProviderSerializer(EnterpriseRequiredMixin, ProviderSeriali
extra_kwargs = {}
class GoogleWorkspaceProviderViewSet(OutgoingSyncProviderViewSet):
class GoogleWorkspaceProviderViewSet(OutgoingSyncProviderStatusMixin, UsedByMixin, ModelViewSet):
"""GoogleWorkspaceProvider Viewset"""
queryset = GoogleWorkspaceProvider.objects.all()
serializer_class = GoogleWorkspaceProviderSerializer
filterset_fields = OutgoingSyncProviderViewSet.filterset_fields + [
"delegated_subject",
]
search_fields = OutgoingSyncProviderViewSet.search_fields + [
filterset_fields = [
"name",
"exclude_users_service_account",
"delegated_subject",
"filter_group",
]
search_fields = ["name"]
ordering = ["name"]
sync_task = google_workspace_sync
sync_objects_task = google_workspace_sync_objects

View File

@@ -1,9 +1,13 @@
"""GoogleWorkspaceProviderUser API Views"""
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
from authentik.core.api.groups import PartialUserSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import ModelSerializer
from authentik.enterprise.providers.google_workspace.models import GoogleWorkspaceProviderUser
from authentik.lib.sync.outgoing.api import OutgoingSyncConnectionViewSet
from authentik.lib.sync.outgoing.api import OutgoingSyncConnectionCreateMixin
class GoogleWorkspaceProviderUserSerializer(ModelSerializer):
@@ -12,6 +16,7 @@ class GoogleWorkspaceProviderUserSerializer(ModelSerializer):
user_obj = PartialUserSerializer(source="user", read_only=True)
class Meta:
model = GoogleWorkspaceProviderUser
fields = [
"id",
@@ -24,7 +29,15 @@ class GoogleWorkspaceProviderUserSerializer(ModelSerializer):
extra_kwargs = {"attributes": {"read_only": True}}
class GoogleWorkspaceProviderUserViewSet(OutgoingSyncConnectionViewSet):
class GoogleWorkspaceProviderUserViewSet(
mixins.CreateModelMixin,
OutgoingSyncConnectionCreateMixin,
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
"""GoogleWorkspaceProviderUser Viewset"""
queryset = GoogleWorkspaceProviderUser.objects.all().select_related("user")

View File

@@ -12,6 +12,7 @@ from google.oauth2.service_account import Credentials
from rest_framework.serializers import Serializer
from authentik.core.models import (
BackchannelProvider,
Group,
PropertyMapping,
User,
@@ -83,7 +84,7 @@ class GoogleWorkspaceProviderGroup(SerializerModel):
return f"Google Workspace Provider Group {self.group_id} to {self.provider_id}"
class GoogleWorkspaceProvider(OutgoingSyncProvider):
class GoogleWorkspaceProvider(OutgoingSyncProvider, BackchannelProvider):
"""Sync users from authentik into Google Workspace."""
delegated_subject = models.EmailField()

View File

@@ -1,9 +1,13 @@
"""MicrosoftEntraProviderGroup API Views"""
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.users import PartialGroupSerializer
from authentik.core.api.utils import ModelSerializer
from authentik.enterprise.providers.microsoft_entra.models import MicrosoftEntraProviderGroup
from authentik.lib.sync.outgoing.api import OutgoingSyncConnectionViewSet
from authentik.lib.sync.outgoing.api import OutgoingSyncConnectionCreateMixin
class MicrosoftEntraProviderGroupSerializer(ModelSerializer):
@@ -12,6 +16,7 @@ class MicrosoftEntraProviderGroupSerializer(ModelSerializer):
group_obj = PartialGroupSerializer(source="group", read_only=True)
class Meta:
model = MicrosoftEntraProviderGroup
fields = [
"id",
@@ -24,7 +29,15 @@ class MicrosoftEntraProviderGroupSerializer(ModelSerializer):
extra_kwargs = {"attributes": {"read_only": True}}
class MicrosoftEntraProviderGroupViewSet(OutgoingSyncConnectionViewSet):
class MicrosoftEntraProviderGroupViewSet(
mixins.CreateModelMixin,
OutgoingSyncConnectionCreateMixin,
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
"""MicrosoftEntraProviderGroup Viewset"""
queryset = MicrosoftEntraProviderGroup.objects.all().select_related("group")

View File

@@ -1,13 +1,16 @@
"""Microsoft Provider API Views"""
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.providers import ProviderSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.enterprise.api import EnterpriseRequiredMixin
from authentik.enterprise.providers.microsoft_entra.models import MicrosoftEntraProvider
from authentik.enterprise.providers.microsoft_entra.tasks import (
microsoft_entra_sync,
microsoft_entra_sync_objects,
)
from authentik.lib.sync.outgoing.api import OutgoingSyncProviderViewSet
from authentik.lib.sync.outgoing.api import OutgoingSyncProviderStatusMixin
class MicrosoftEntraProviderSerializer(EnterpriseRequiredMixin, ProviderSerializer):
@@ -40,10 +43,17 @@ class MicrosoftEntraProviderSerializer(EnterpriseRequiredMixin, ProviderSerializ
extra_kwargs = {}
class MicrosoftEntraProviderViewSet(OutgoingSyncProviderViewSet):
class MicrosoftEntraProviderViewSet(OutgoingSyncProviderStatusMixin, UsedByMixin, ModelViewSet):
"""MicrosoftEntraProvider Viewset"""
queryset = MicrosoftEntraProvider.objects.all()
serializer_class = MicrosoftEntraProviderSerializer
filterset_fields = [
"name",
"exclude_users_service_account",
"filter_group",
]
search_fields = ["name"]
ordering = ["name"]
sync_task = microsoft_entra_sync
sync_objects_task = microsoft_entra_sync_objects

View File

@@ -1,9 +1,13 @@
"""MicrosoftEntraProviderUser API Views"""
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet
from authentik.core.api.groups import PartialUserSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import ModelSerializer
from authentik.enterprise.providers.microsoft_entra.models import MicrosoftEntraProviderUser
from authentik.lib.sync.outgoing.api import OutgoingSyncConnectionViewSet
from authentik.lib.sync.outgoing.api import OutgoingSyncConnectionCreateMixin
class MicrosoftEntraProviderUserSerializer(ModelSerializer):
@@ -12,6 +16,7 @@ class MicrosoftEntraProviderUserSerializer(ModelSerializer):
user_obj = PartialUserSerializer(source="user", read_only=True)
class Meta:
model = MicrosoftEntraProviderUser
fields = [
"id",
@@ -24,7 +29,15 @@ class MicrosoftEntraProviderUserSerializer(ModelSerializer):
extra_kwargs = {"attributes": {"read_only": True}}
class MicrosoftEntraProviderUserViewSet(OutgoingSyncConnectionViewSet):
class MicrosoftEntraProviderUserViewSet(
OutgoingSyncConnectionCreateMixin,
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.DestroyModelMixin,
UsedByMixin,
mixins.ListModelMixin,
GenericViewSet,
):
"""MicrosoftEntraProviderUser Viewset"""
queryset = MicrosoftEntraProviderUser.objects.all().select_related("user")

View File

@@ -12,6 +12,7 @@ from dramatiq.actor import Actor
from rest_framework.serializers import Serializer
from authentik.core.models import (
BackchannelProvider,
Group,
PropertyMapping,
User,
@@ -74,7 +75,7 @@ class MicrosoftEntraProviderGroup(SerializerModel):
return f"Microsoft Entra Provider Group {self.group_id} to {self.provider_id}"
class MicrosoftEntraProvider(OutgoingSyncProvider):
class MicrosoftEntraProvider(OutgoingSyncProvider, BackchannelProvider):
"""Sync users from authentik into Microsoft Entra."""
client_id = models.TextField()

View File

@@ -16,7 +16,7 @@ from authentik.stages.authenticator.models import Device
class AuthenticatorEndpointGDTCStage(ConfigurableStage, FriendlyNamedStage, Stage):
"""Setup Google Chrome Device Trust connection"""
"""Verify Google Chrome Device Trust connection for the user's browser."""
credentials = models.JSONField()

View File

@@ -10,7 +10,7 @@ from authentik.lib.utils.time import timedelta_string_validator
class SourceStage(Stage):
"""Suspend the current flow execution and send the user to a source,
"""Suspend the current flow execution and send the user to a federated source,
after which this flow execution is resumed."""
source = models.ForeignKey("authentik_core.Source", on_delete=models.CASCADE)

View File

@@ -1,7 +1,7 @@
from collections.abc import Generator
from contextlib import contextmanager
from dataclasses import dataclass, field
from datetime import datetime
from datetime import UTC, datetime
from typing import Any
from django.utils.timezone import now
@@ -28,7 +28,7 @@ class LogEvent:
def from_event_dict(item: EventDict) -> "LogEvent":
event = item.pop("event")
log_level = item.pop("level").lower()
timestamp = datetime.fromisoformat(item.pop("timestamp"))
timestamp = datetime.fromisoformat(item.pop("timestamp")).replace(tzinfo=UTC)
item.pop("pid", None)
# Sometimes log entries have both `level` and `log_level` set, but `level` is always set
item.pop("log_level", None)

View File

@@ -237,7 +237,7 @@ class Event(SerializerModel, ExpiringModel):
self.save()
return self
def save(self, *args: Any, **kwargs: Any) -> None:
def save(self, *args, **kwargs):
if self._state.adding:
LOGGER.info(
"Created Event",

View File

@@ -17,7 +17,7 @@
<meta name="sentry-trace" content="{{ sentry_trace }}" />
<link rel="prefetch" href="{{ flow_background_url }}" />
{% include "base/header_js.html" %}
<style>
<style data-id="flow-sfe">
html,
body {
height: 100%;

View File

@@ -1,35 +1,74 @@
{% extends "base/skeleton.html" %}
{% load i18n %}
{% load static %}
{% load authentik_core %}
{% block head_before %}
{{ block.super }}
<link rel="prefetch" href="{{ flow_background_url }}" />
{% if flow.compatibility_mode and not inspector %}
<script>ShadyDOM = { force: true };</script>
<script data-id="shady-dom">ShadyDOM = { force: true };</script>
{% endif %}
{% include "base/header_js.html" %}
<script>
window.authentik.flow = {
"layout": "{{ flow.layout }}",
};
<script data-id="flow-config">
"use strict";
window.authentik.flow = {
"layout": "{{ flow.layout }}",
};
</script>
<link rel="stylesheet" type="text/css" href="{% versioned_script 'dist/styles/static-%v.css' %}" />
{% endblock %}
{% block head %}
<script src="{% versioned_script 'dist/flow/FlowInterface-%v.js' %}" type="module"></script>
<style>
:root {
--ak-flow-background: url("{{ flow_background_url }}");
}
<style data-id="flow-css">
:root {
--ak-global--background-image: url("{{ flow_background_url }}");
}
</style>
{% endblock %}
{% block body %}
<ak-skip-to-content></ak-skip-to-content>
<ak-message-container></ak-message-container>
<ak-flow-executor flowSlug="{{ flow.slug }}">
<ak-loading></ak-loading>
</ak-flow-executor>
<ak-locale-context>
<div class="pf-c-page__drawer">
<div class="pf-c-drawer pf-m-collapsed" id="flow-drawer">
<div class="pf-c-drawer__main">
<div class="pf-c-drawer__content">
<div class="pf-c-drawer__body">
<ak-flow-executor
slug="{{ flow.slug }}"
class="pf-c-login"
data-layout="{{ flow.layout|default:'stacked' }}"
>
{% include "base/placeholder.html" %}
<ak-brand-links
slot="footer"
exportparts="list:brand-links-list, list-item:brand-links-list-item"
role="contentinfo"
aria-label="{% trans 'Site footer' %}"
class="pf-c-login__footer {% if flow.layout == 'stacked' %}pf-m-dark{% endif %}"
></ak-brand-links>
</ak-flow-executor>
</div>
</div>
<ak-flow-inspector
id="flow-inspector"
data-registration="lazy"
class="pf-c-drawer__panel pf-m-width-33"
slug="{{ flow.slug }}"
></ak-flow-inspector>
</div>
</div>
</div>
</div>
</ak-locale-context>
{% endblock %}

View File

@@ -3,7 +3,7 @@
from base64 import b64encode
from functools import cache as funccache
from hashlib import md5, sha256
from typing import TYPE_CHECKING, cast
from typing import TYPE_CHECKING
from urllib.parse import urlencode
from django.core.cache import cache
@@ -27,7 +27,7 @@ CACHE_KEY_GRAVATAR_AVAILABLE = "goauthentik.io/lib/avatars/gravatar_available"
GRAVATAR_STATUS_TTL_SECONDS = 60 * 60 * 8 # 8 Hours
SVG_XML_NS = "http://www.w3.org/2000/svg"
SVG_NS_MAP: dict[str, str] = cast(dict[str, str], {None: SVG_XML_NS})
SVG_NS_MAP = {None: SVG_XML_NS}
# Match fonts used in web UI
SVG_FONTS = [
"'RedHatText'",
@@ -39,7 +39,7 @@ SVG_FONTS = [
]
def avatar_mode_none(user: "User", mode: str) -> str:
def avatar_mode_none(user: "User", mode: str) -> str | None:
"""No avatar"""
return DEFAULT_AVATAR
@@ -62,7 +62,7 @@ def avatar_mode_gravatar(user: "User", mode: str) -> str | None:
full_key = CACHE_KEY_GRAVATAR + mail_hash
if cache.has_key(full_key):
cache.touch(full_key)
return cast(str | None, cache.get(full_key))
return cache.get(full_key)
try:
# Since we specify a default of 404, do a HEAD request
@@ -129,16 +129,16 @@ def generate_avatar_from_name(
bg_hex, text_hex = generate_colors(name)
half_size = size // 2
shape_type = "circle" if rounded else "rect"
shape = "circle" if rounded else "rect"
font_weight = "600" if bold else "400"
root_element = Element(f"{{{SVG_XML_NS}}}svg", nsmap=SVG_NS_MAP)
root_element: Element = Element(f"{{{SVG_XML_NS}}}svg", nsmap=SVG_NS_MAP)
root_element.attrib["width"] = f"{size}px"
root_element.attrib["height"] = f"{size}px"
root_element.attrib["viewBox"] = f"0 0 {size} {size}"
root_element.attrib["version"] = "1.1"
shape = SubElement(root_element, f"{{{SVG_XML_NS}}}{shape_type}", nsmap=SVG_NS_MAP)
shape = SubElement(root_element, f"{{{SVG_XML_NS}}}{shape}", nsmap=SVG_NS_MAP)
shape.attrib["fill"] = f"#{bg_hex}"
shape.attrib["cx"] = f"{half_size}"
shape.attrib["cy"] = f"{half_size}"
@@ -150,7 +150,7 @@ def generate_avatar_from_name(
text.attrib["x"] = "50%"
text.attrib["y"] = "50%"
text.attrib["style"] = (
f"color: #{text_hex}; line-height: 1; font-family: {','.join(SVG_FONTS)}; "
f"color: #{text_hex}; " "line-height: 1; " f"font-family: {','.join(SVG_FONTS)}; "
)
text.attrib["fill"] = f"#{text_hex}"
text.attrib["alignment-baseline"] = "middle"
@@ -197,7 +197,7 @@ def get_avatar(user: "User", request: HttpRequest | None = None) -> str:
}
tenant = None
if request:
tenant = request.tenant # type: ignore[attr-defined]
tenant = request.tenant
else:
tenant = get_current_tenant()
modes: str = tenant.avatars

View File

@@ -1,5 +1,3 @@
from typing import Any
from structlog.stdlib import get_logger
from authentik.lib.config import CONFIG
@@ -7,11 +5,11 @@ from authentik.lib.config import CONFIG
LOGGER = get_logger()
def start_debug_server(**kwargs: Any) -> bool:
def start_debug_server(**kwargs) -> bool:
"""Attempt to start a debugpy server in the current process.
Returns true if the server was started successfully, otherwise false"""
if not CONFIG.get_bool("debug") and not CONFIG.get_bool("debugger"):
return False
return
try:
import debugpy
except ImportError:

View File

@@ -145,7 +145,6 @@ worker:
consumer_listen_timeout: "seconds=30"
task_max_retries: 5
task_default_time_limit: "minutes=10"
lock_purge_interval: "minutes=1"
task_purge_interval: "days=1"
task_expiration: "days=30"
scheduler_interval: "seconds=60"

View File

@@ -13,9 +13,10 @@ from django.core.exceptions import FieldError
from django.http import HttpRequest
from django.utils.text import slugify
from django.utils.timezone import now
from guardian.utils import get_anonymous_user
from guardian.shortcuts import get_anonymous_user
from rest_framework.serializers import ValidationError
from sentry_sdk import start_span
from sentry_sdk.tracing import Span
from structlog.stdlib import get_logger
from authentik.core.models import User
@@ -54,7 +55,7 @@ class BaseEvaluator:
# Filename used for exec
_filename: str
def __init__(self, filename: str | None = None) -> None:
def __init__(self, filename: str | None = None):
self._filename = filename if filename else "BaseEvaluator"
# update website/docs/expressions/_objects.md
# update website/docs/expressions/_functions.md
@@ -132,12 +133,12 @@ class BaseEvaluator:
return re.sub(regex, repl, value)
@staticmethod
def expr_is_group_member(user: User, **group_filters: Any) -> bool:
def expr_is_group_member(user: User, **group_filters) -> bool:
"""Check if `user` is member of group with name `group_name`"""
return user.all_groups().filter(**group_filters).exists()
@staticmethod
def expr_user_by(**filters: Any) -> User | None:
def expr_user_by(**filters) -> User | None:
"""Get user by filters"""
try:
users = User.objects.filter(**filters)
@@ -159,7 +160,7 @@ class BaseEvaluator:
return False
return len(list(user_devices)) > 0
def expr_event_create(self, action: str, **kwargs: Any) -> None:
def expr_event_create(self, action: str, **kwargs):
"""Create event with supplied data and try to extract as much relevant data
from the context"""
context = self._context.copy()
@@ -180,7 +181,7 @@ class BaseEvaluator:
return
event.save()
def expr_func_call_policy(self, name: str, **kwargs: Any) -> PolicyResult:
def expr_func_call_policy(self, name: str, **kwargs) -> PolicyResult:
"""Call policy by name, with current request"""
policy = Policy.objects.filter(name=name).select_subclasses().first()
if not policy:
@@ -213,10 +214,10 @@ class BaseEvaluator:
provider=provider,
user=user,
expires=now() + timedelta_from_string(validity),
scope=scopes,
auth_time=now(),
session=session,
)
access_token.scope = scopes
access_token.id_token = IDToken.new(provider, access_token, request)
access_token.save()
return access_token.token
@@ -228,7 +229,7 @@ class BaseEvaluator:
body: str | None = None,
stage: "EmailStage | None" = None,
template: str | None = None,
context: dict[str, Any] | None = None,
context: dict | None = None,
) -> bool:
"""Send an email using authentik's email system
@@ -315,6 +316,7 @@ class BaseEvaluator:
If any exception is raised during execution, it is raised.
The result is returned without any type-checking."""
with start_span(op="authentik.lib.evaluator.evaluate") as span:
span: Span
span.description = self._filename
span.set_data("expression", expression_source)
try:
@@ -341,7 +343,7 @@ class BaseEvaluator:
raise exc
return result
def handle_error(self, exc: Exception, expression_source: str) -> None: # pragma: no cover
def handle_error(self, exc: Exception, expression_source: str): # pragma: no cover
"""Exception Handler"""
LOGGER.warning("Expression error", exc=exc)

View File

@@ -4,20 +4,20 @@ import string
from random import SystemRandom
def generate_code_fixed_length(length: int = 9) -> str:
def generate_code_fixed_length(length=9) -> str:
"""Generate a numeric code"""
rand = SystemRandom()
num = rand.randrange(1, 10**length)
return str(num).zfill(length)
def generate_id(length: int = 40) -> str:
def generate_id(length=40) -> str:
"""Generate a random client ID"""
rand = SystemRandom()
return "".join(rand.choice(string.ascii_letters + string.digits) for x in range(length))
def generate_key(length: int = 128) -> str:
def generate_key(length=128) -> str:
"""Generate a suitable client secret"""
rand = SystemRandom()
return "".join(

View File

@@ -3,11 +3,9 @@
import logging
from logging import Logger
from os import getpid
from typing import Any
import structlog
from django.db import connection
from structlog.typing import EventDict
from authentik.lib.config import CONFIG
@@ -21,9 +19,9 @@ LOG_PRE_CHAIN = [
]
def get_log_level() -> str:
def get_log_level():
"""Get log level, clamp trace to debug"""
level: str = CONFIG.get("log_level").upper()
level = CONFIG.get("log_level").upper()
# We could add a custom level to stdlib logging and structlog, but it's not easy or clean
# https://stackoverflow.com/questions/54505487/custom-log-level-not-working-with-structlog
# Additionally, the entire code uses debug as highest level
@@ -33,7 +31,7 @@ def get_log_level() -> str:
return level
def structlog_configure() -> None:
def structlog_configure():
"""Configure structlog itself"""
structlog.configure_once(
processors=[
@@ -58,11 +56,11 @@ def structlog_configure() -> None:
)
def get_logger_config() -> dict[str, Any]:
def get_logger_config():
"""Configure python stdlib's logging"""
debug = CONFIG.get_bool("debug")
global_level = get_log_level()
base_config: dict[str, Any] = {
base_config = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
@@ -123,13 +121,13 @@ def get_logger_config() -> dict[str, Any]:
return base_config
def add_process_id(logger: Logger, method_name: str, event_dict: EventDict) -> EventDict:
def add_process_id(logger: Logger, method_name: str, event_dict):
"""Add the current process ID"""
event_dict["pid"] = getpid()
return event_dict
def add_tenant_information(logger: Logger, method_name: str, event_dict: EventDict) -> EventDict:
def add_tenant_information(logger: Logger, method_name: str, event_dict):
"""Add the current tenant"""
tenant = getattr(connection, "tenant", None)
schema_name = getattr(connection, "schema_name", None)

View File

@@ -1,6 +1,6 @@
"""merge utils"""
from deepmerge import Merger # type: ignore[attr-defined]
from deepmerge import Merger
MERGE_LIST_UNIQUE = Merger(
[(list, ["append_unique"]), (dict, ["merge"]), (set, ["union"])], ["override"], ["override"]

View File

@@ -1,18 +1,16 @@
"""Migration helpers"""
from collections.abc import Callable, Collection, Generator
from collections.abc import Iterable
from django.apps.registry import Apps
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
def fallback_names(
app: str, model: str, field: str
) -> Callable[[Apps, BaseDatabaseSchemaEditor], None]:
def fallback_names(app: str, model: str, field: str):
"""Factory function that checks all instances of `app`.`model` instance's `field`
to prevent any duplicates"""
def migrator(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
def migrator(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
db_alias = schema_editor.connection.alias
klass = apps.get_model(app, model)
@@ -37,7 +35,7 @@ def fallback_names(
return migrator
def progress_bar[R](iterable: Collection[R]) -> Generator[R]:
def progress_bar(iterable: Iterable):
"""Call in a loop to create terminal progress bar
https://stackoverflow.com/questions/3173320/text-progress-bar-in-the-console"""
@@ -52,7 +50,7 @@ def progress_bar[R](iterable: Collection[R]) -> Generator[R]:
if total < 1:
return
def print_progress_bar(iteration: int) -> None:
def print_progress_bar(iteration):
"""Progress Bar Printing Function"""
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filled_length = int(length * iteration // total)

View File

@@ -1,7 +1,7 @@
"""authentik sentry integration"""
from asyncio.exceptions import CancelledError
from typing import TYPE_CHECKING, Any
from typing import Any
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation, ValidationError
@@ -34,9 +34,6 @@ from authentik.lib.utils.reflection import get_env
LOGGER = get_logger()
_root_path = CONFIG.get("web.path", "/")
if TYPE_CHECKING:
from sentry_sdk._types import Event
class SentryIgnoredException(Exception):
"""Base Class for all errors that are suppressed, and not sent to sentry."""
@@ -82,11 +79,10 @@ class SentryTransport(HttpTransport):
def __init__(self, options: dict[str, Any]) -> None:
super().__init__(options)
assert self.parsed_dsn is not None # nosec
self._auth = self.parsed_dsn.to_auth(authentik_user_agent())
def sentry_init(**sentry_init_kwargs: Any) -> None:
def sentry_init(**sentry_init_kwargs):
"""Configure sentry SDK"""
sentry_env = CONFIG.get("error_reporting.environment", "customer")
kwargs = {
@@ -120,7 +116,7 @@ def sentry_init(**sentry_init_kwargs: Any) -> None:
set_tag("authentik.component", "backend")
def traces_sampler(sampling_context: dict[str, Any]) -> float:
def traces_sampler(sampling_context: dict) -> float:
"""Custom sampler to ignore certain routes"""
path = sampling_context.get("asgi_scope", {}).get("path", "")
_type = sampling_context.get("asgi_scope", {}).get("type", "")
@@ -139,7 +135,7 @@ def should_ignore_exception(exc: Exception) -> bool:
return isinstance(exc, ignored_classes)
def before_send(event: "Event", hint: dict[str, Any]) -> "Event | None":
def before_send(event: dict, hint: dict) -> dict | None:
"""Check if error is database error, and ignore if so"""
exc_value = None
if "exc_info" in hint:
@@ -161,7 +157,7 @@ def before_send(event: "Event", hint: dict[str, Any]) -> "Event | None":
return event
def get_http_meta() -> dict[str, Any]:
def get_http_meta():
"""Get sentry-related meta key-values"""
scope = get_current_scope()
meta = {

View File

@@ -1,5 +1,4 @@
from collections.abc import Generator
from typing import Any
from django.db.models import QuerySet
from django.http import HttpRequest
@@ -21,7 +20,7 @@ class PropertyMappingManager:
_evaluators: list[PropertyMappingEvaluator]
globals: dict[str, Any]
globals: dict
__has_compiled: bool
@@ -41,7 +40,7 @@ class PropertyMappingManager:
self.globals = {}
self.__has_compiled = False
def compile(self) -> None:
def compile(self):
self._evaluators = []
for mapping in self.query_set:
if not isinstance(mapping, self.mapping_subclass):
@@ -59,8 +58,8 @@ class PropertyMappingManager:
user: User | None,
request: HttpRequest | None,
return_mapping: bool = False,
**kwargs: Any,
) -> Generator[tuple[Any, PropertyMapping]]:
**kwargs,
) -> Generator[tuple[dict, PropertyMapping]]:
"""Iterate over all mappings that were pre-compiled and
execute all of them with the given context"""
if not self.__has_compiled:

View File

@@ -1,26 +1,15 @@
from typing import Any
from django.db.models import Model
from dramatiq.actor import Actor
from dramatiq.results.errors import ResultFailure
from drf_spectacular.utils import extend_schema
from rest_framework.decorators import action
from rest_framework.fields import BooleanField, CharField, ChoiceField
from rest_framework.mixins import (
CreateModelMixin,
DestroyModelMixin,
ListModelMixin,
RetrieveModelMixin,
)
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import ModelSerializer, PassiveSerializer
from authentik.core.models import Group, User
from authentik.events.logs import LogEventSerializer
from authentik.lib.models import SerializerModel
from authentik.lib.sync.api import SyncStatusSerializer
from authentik.lib.sync.outgoing.models import OutgoingSyncProvider
from authentik.lib.utils.reflection import class_to_path, path_to_class
@@ -47,19 +36,11 @@ class SyncObjectResultSerializer(PassiveSerializer):
messages = LogEventSerializer(many=True, read_only=True)
class OutgoingSyncProviderViewSet(UsedByMixin, ModelViewSet[OutgoingSyncProvider]):
class OutgoingSyncProviderStatusMixin:
"""Common API Endpoints for Outgoing sync providers"""
sync_task: Actor[[int, Actor[[str, int, int, bool], None]], None]
sync_objects_task: Actor[[str, int, int, bool, dict[str, Any | None]], None]
filterset_fields = [
"name",
"exclude_users_service_account",
"filter_group",
]
search_fields = ["name"]
ordering = ["name"]
sync_task: Actor
sync_objects_task: Actor
@extend_schema(responses={200: SyncStatusSerializer()})
@action(
@@ -87,20 +68,20 @@ class OutgoingSyncProviderViewSet(UsedByMixin, ModelViewSet[OutgoingSyncProvider
if not sync_schedule:
return Response(SyncStatusSerializer(status).data)
last_task = (
last_task: Task = (
sync_schedule.tasks.filter(state__in=(TaskStatus.DONE, TaskStatus.REJECTED))
.order_by("-mtime")
.first()
)
last_successful_task = (
last_successful_task: Task = (
sync_schedule.tasks.filter(aggregated_status__in=(TaskStatus.DONE, TaskStatus.INFO))
.order_by("-mtime")
.first()
)
if last_task is not None:
if last_task:
status["last_sync_status"] = last_task.aggregated_status
if last_successful_task is not None:
if last_successful_task:
status["last_successful_sync"] = last_successful_task.mtime
return Response(SyncStatusSerializer(status).data)
@@ -130,7 +111,7 @@ class OutgoingSyncProviderViewSet(UsedByMixin, ModelViewSet[OutgoingSyncProvider
"page": 1,
"provider_pk": provider.pk,
"override_dry_run": params.validated_data["override_dry_run"],
"filter": {"pk": pk},
"pk": pk,
},
retries=0,
rel_obj=provider,
@@ -145,20 +126,13 @@ class OutgoingSyncProviderViewSet(UsedByMixin, ModelViewSet[OutgoingSyncProvider
return Response(SyncObjectResultSerializer(instance={"messages": task._messages}).data)
class OutgoingSyncConnectionViewSet(
CreateModelMixin,
RetrieveModelMixin,
DestroyModelMixin,
ListModelMixin,
UsedByMixin,
GenericViewSet[SerializerModel],
):
def perform_create(self, serializer: ModelSerializer) -> None: # type: ignore[override]
class OutgoingSyncConnectionCreateMixin:
"""Mixin for connection objects that fetches remote data upon creation"""
def perform_create(self, serializer: ModelSerializer):
super().perform_create(serializer)
try:
instance = serializer.instance
if instance is None:
return
client = instance.provider.client_for_model(instance.__class__)
client.update_single_attribute(instance)
instance.save()

View File

@@ -1,8 +1,7 @@
"""Basic outgoing sync Client"""
from collections.abc import MutableMapping
from enum import StrEnum
from typing import TYPE_CHECKING, Any, cast
from typing import TYPE_CHECKING
from deepmerge import always_merger
from django.db import DatabaseError
@@ -19,11 +18,11 @@ from authentik.lib.sync.outgoing.exceptions import NotFoundSyncException, StopSy
if TYPE_CHECKING:
from django.db.models import Model
from authentik.core.models import Group, User
from authentik.lib.sync.outgoing.models import OutgoingSyncProvider
class Direction(StrEnum):
add = "add"
remove = "remove"
@@ -37,10 +36,7 @@ SAFE_METHODS = [
class BaseOutgoingSyncClient[
TModel: "User | Group",
TConnection: "Model",
TSchema: MutableMapping[Any, Any],
TProvider: "OutgoingSyncProvider",
TModel: "Model", TConnection: "Model", TSchema: dict, TProvider: "OutgoingSyncProvider"
]:
"""Basic Outgoing sync client Client"""
@@ -59,17 +55,14 @@ class BaseOutgoingSyncClient[
"""Create object in remote destination"""
raise NotImplementedError()
def update(self, obj: TModel, connection: TConnection) -> None:
def update(self, obj: TModel, connection: TConnection):
"""Update object in remote destination"""
raise NotImplementedError()
def update_group(self, group: "Group", action: Direction, users_set: list[Any]) -> None:
raise NotImplementedError()
def write(self, obj: TModel) -> tuple[TConnection | None, bool]:
def write(self, obj: TModel) -> tuple[TConnection, bool]:
"""Write object to destination. Uses self.create and self.update, but
can be overwritten for further logic"""
connection = self.connection_type.objects.filter( # type: ignore[attr-defined]
connection = self.connection_type.objects.filter(
provider=self.provider, **{self.connection_type_query: obj}
).first()
try:
@@ -89,13 +82,13 @@ class BaseOutgoingSyncClient[
connection.delete()
return None, False
def delete(self, obj: TModel) -> None:
def delete(self, obj: TModel):
"""Delete object from destination"""
raise NotImplementedError()
def to_schema(self, obj: TModel, connection: TConnection | None, **defaults: Any) -> TSchema:
def to_schema(self, obj: TModel, connection: TConnection | None, **defaults) -> TSchema:
"""Convert object to destination schema"""
raw_final_object: dict[Any, Any] = {}
raw_final_object = {}
try:
eval_kwargs = {
"request": None,
@@ -104,7 +97,7 @@ class BaseOutgoingSyncClient[
obj._meta.model_name: obj,
}
eval_kwargs.setdefault("user", None)
for value in self.mapper.iter_eval(**eval_kwargs): # type: ignore[arg-type, misc]
for value in self.mapper.iter_eval(**eval_kwargs):
always_merger.merge(raw_final_object, value)
except ControlFlowException as exc:
raise exc from exc
@@ -120,16 +113,16 @@ class BaseOutgoingSyncClient[
raise StopSync(ValueError("No mappings configured"), obj)
for key, value in defaults.items():
raw_final_object.setdefault(key, value)
return cast(TSchema, raw_final_object)
return raw_final_object
def discover(self) -> None:
def discover(self):
"""Optional method. Can be used to implement a "discovery" where
upon creation of this provider, this function will be called and can
pre-link any users/groups in the remote system with the respective
object in authentik based on a common identifier"""
raise NotImplementedError()
def update_single_attribute(self, connection: TConnection) -> None:
def update_single_attribute(self, connection: TConnection):
"""Update connection attributes on a connection object, when the connection
is manually created"""
raise NotImplementedError

View File

@@ -1,5 +1,3 @@
from typing import Any
from authentik.lib.sentry import SentryIgnoredException
@@ -26,16 +24,16 @@ class BadRequestSyncException(BaseSyncException):
class DryRunRejected(BaseSyncException):
"""When dry_run is enabled and a provider dropped a mutating request"""
def __init__(self, url: str, method: str, body: dict[Any, Any]) -> None:
def __init__(self, url: str, method: str, body: dict):
super().__init__()
self.url = url
self.method = method
self.body = body
def __repr__(self) -> str:
def __repr__(self):
return self.__str__()
def __str__(self) -> str:
def __str__(self):
return f"Dry-run rejected request: {self.method} {self.url}"

View File

@@ -4,11 +4,11 @@ import pglock
from django.core.paginator import Paginator
from django.core.validators import MinValueValidator
from django.db import connection, models
from django.db.models import QuerySet, TextChoices
from django.db.models import Model, QuerySet, TextChoices
from django.utils.translation import gettext_lazy as _
from dramatiq.actor import Actor
from authentik.core.models import BackchannelProvider, Group, User
from authentik.core.models import Group, User
from authentik.lib.sync.outgoing.base import BaseOutgoingSyncClient
from authentik.lib.utils.time import fqdn_rand, timedelta_from_string, timedelta_string_validator
from authentik.tasks.schedules.common import ScheduleSpec
@@ -24,7 +24,7 @@ class OutgoingSyncDeleteAction(TextChoices):
SUSPEND = "suspend"
class OutgoingSyncProvider(ScheduledModel, BackchannelProvider):
class OutgoingSyncProvider(ScheduledModel, Model):
"""Base abstract models for providers implementing outgoing sync"""
sync_page_size = models.PositiveIntegerField(
@@ -56,7 +56,7 @@ class OutgoingSyncProvider(ScheduledModel, BackchannelProvider):
def get_object_qs[T: User | Group](self, type: type[T]) -> QuerySet[T]:
raise NotImplementedError
def get_paginator[T: User | Group](self, type: type[T]) -> "Paginator[T]":
def get_paginator[T: User | Group](self, type: type[T]) -> Paginator:
return Paginator(self.get_object_qs(type), self.sync_page_size)
def get_object_sync_time_limit_ms[T: User | Group](self, type: type[T]) -> int:
@@ -74,15 +74,13 @@ class OutgoingSyncProvider(ScheduledModel, BackchannelProvider):
def sync_lock(self) -> pglock.advisory:
"""Postgres lock for syncing to prevent multiple parallel syncs happening"""
return pglock.advisory(
lock_id=f"goauthentik.io/{connection.schema_name}/providers/outgoing-sync/{str(self.pk)}", # type: ignore[attr-defined]
lock_id=f"goauthentik.io/{connection.schema_name}/providers/outgoing-sync/{str(self.pk)}",
timeout=0,
side_effect=pglock.Return,
)
@property
def sync_actor(
self,
) -> Actor[[int, Actor[[str, int, int, bool, dict[str, Any] | None], None]], None]:
def sync_actor(self) -> Actor:
raise NotImplementedError
@property
@@ -96,6 +94,6 @@ class OutgoingSyncProvider(ScheduledModel, BackchannelProvider):
"time_limit": self.get_sync_time_limit_ms(),
},
send_on_save=True,
crontab=f"{fqdn_rand(str(self.pk))} */4 * * *",
crontab=f"{fqdn_rand(self.pk)} */4 * * *",
),
]

View File

@@ -1,7 +1,4 @@
from collections.abc import Iterable
from typing import Any, TypeVar
from uuid import UUID
from django.db.models import Model
from django.db.models.signals import m2m_changed, post_save, pre_delete
from dramatiq.actor import Actor
@@ -10,24 +7,22 @@ from authentik.lib.sync.outgoing.base import Direction
from authentik.lib.sync.outgoing.models import OutgoingSyncProvider
from authentik.lib.utils.reflection import class_to_path
ModelT = TypeVar("ModelT", bound=User | Group)
def register_signals(
provider_type: type[OutgoingSyncProvider],
task_sync_direct_dispatch: Actor[[str, Any, str], None],
task_sync_m2m_dispatch: Actor[[Any, str, list[Any], bool], None],
) -> None:
task_sync_direct_dispatch: Actor[[str, str | int, str], None],
task_sync_m2m_dispatch: Actor[[str, str, list[str], bool], None],
):
"""Register sync signals"""
uid = class_to_path(provider_type)
def model_post_save(
sender: type[ModelT],
instance: ModelT,
sender: type[Model],
instance: User | Group,
created: bool,
update_fields: Iterable[str] | None = None,
**_: Any,
) -> None:
update_fields: list[str] | None = None,
**_,
):
"""Post save handler"""
# Special case for user object; don't start sync task when we've only updated `last_login`
# This primarily happens during user login
@@ -42,7 +37,7 @@ def register_signals(
post_save.connect(model_post_save, User, dispatch_uid=uid, weak=False)
post_save.connect(model_post_save, Group, dispatch_uid=uid, weak=False)
def model_pre_delete(sender: type[ModelT], instance: ModelT, **_: Any) -> None:
def model_pre_delete(sender: type[Model], instance: User | Group, **_):
"""Pre-delete handler"""
task_sync_direct_dispatch.send(
class_to_path(instance.__class__),
@@ -54,13 +49,8 @@ def register_signals(
pre_delete.connect(model_pre_delete, Group, dispatch_uid=uid, weak=False)
def model_m2m_changed(
sender: type[ModelT],
instance: ModelT,
action: str,
pk_set: set[int | UUID],
reverse: bool,
**_: Any,
) -> None:
sender: type[Model], instance, action: str, pk_set: set, reverse: bool, **kwargs
):
"""Sync group membership"""
if action not in ["post_add", "post_remove"]:
return

View File

@@ -1,11 +1,9 @@
from typing import Any, cast
from django.core.paginator import Paginator
from django.db.models import Model, Q
from django.db.models import Model, QuerySet
from django.db.models.query import Q
from dramatiq.actor import Actor
from dramatiq.composition import group
from dramatiq.errors import Retry
from dramatiq.message import Message
from structlog.stdlib import BoundLogger, get_logger
from authentik.core.expression.exceptions import SkipObjectException
@@ -40,11 +38,11 @@ class SyncTasks:
self,
current_task: Task,
provider: OutgoingSyncProvider,
sync_objects: Actor[[str, int, int, bool, dict[str, Any] | None], None],
paginator: "Paginator[User | Group]",
sync_objects: Actor[[str, int, int, bool], None],
paginator: Paginator,
object_type: type[User | Group],
**options: Any,
) -> list[Message[None]]:
**options,
):
tasks = []
time_limit = timedelta_from_string(provider.sync_page_timeout).total_seconds() * 1000
for page in paginator.page_range:
@@ -62,14 +60,14 @@ class SyncTasks:
def sync(
self,
provider_pk: int,
sync_objects: Actor[[str, int, int, bool, dict[str, Any] | None], None],
) -> None:
sync_objects: Actor[[str, int, int, bool], None],
):
task = CurrentTask.get_task()
self.logger = get_logger().bind(
provider_type=class_to_path(self._provider_model),
provider_pk=provider_pk,
)
provider = self._provider_model.objects.filter(
provider: OutgoingSyncProvider = self._provider_model.objects.filter(
Q(backchannel_application__isnull=False) | Q(application__isnull=False),
pk=provider_pk,
).first()
@@ -84,7 +82,7 @@ class SyncTasks:
self.logger.debug("Failed to acquire sync lock, skipping", provider=provider.name)
return
try:
users_tasks = group( # type: ignore[no-untyped-call]
users_tasks = group(
self.sync_paginator(
current_task=task,
provider=provider,
@@ -93,7 +91,7 @@ class SyncTasks:
object_type=User,
)
)
group_tasks = group( # type: ignore[no-untyped-call]
group_tasks = group(
self.sync_paginator(
current_task=task,
provider=provider,
@@ -102,12 +100,12 @@ class SyncTasks:
object_type=Group,
)
)
users_tasks.run().wait(timeout=provider.get_object_sync_time_limit_ms(User)) # type: ignore[no-untyped-call]
group_tasks.run().wait(timeout=provider.get_object_sync_time_limit_ms(Group)) # type: ignore[no-untyped-call]
users_tasks.run().wait(timeout=provider.get_object_sync_time_limit_ms(User))
group_tasks.run().wait(timeout=provider.get_object_sync_time_limit_ms(Group))
except TransientSyncException as exc:
self.logger.warning("transient sync exception", exc=exc)
task.warning("Sync encountered a transient exception. Retrying", exc=exc)
raise Retry() from exc # type: ignore[no-untyped-call]
raise Retry() from exc
except StopSync as exc:
task.error(exc)
return
@@ -117,11 +115,11 @@ class SyncTasks:
object_type: str,
page: int,
provider_pk: int,
override_dry_run: bool = False,
filter: dict[str, Any] | None = None,
) -> None:
override_dry_run=False,
**filter,
):
task = CurrentTask.get_task()
_object_type: type[User | Group] = path_to_class(object_type)
_object_type: type[Model] = path_to_class(object_type)
self.logger = get_logger().bind(
provider_type=class_to_path(self._provider_model),
provider_pk=provider_pk,
@@ -142,8 +140,6 @@ class SyncTasks:
client = provider.client_for_model(_object_type)
except TransientSyncException:
return
if filter is None:
filter = {}
paginator = Paginator(
provider.get_object_qs(_object_type).filter(**filter),
provider.sync_page_size,
@@ -154,6 +150,7 @@ class SyncTasks:
self.logger.debug("starting sync for page", page=page)
task.info(f"Syncing page {page} or {_object_type._meta.verbose_name_plural}")
for obj in paginator.page(page).object_list:
obj: Model
try:
client.write(obj)
except SkipObjectException:
@@ -192,11 +189,11 @@ class SyncTasks:
def sync_signal_direct_dispatch(
self,
task_sync_signal_direct: Actor[[str, Any, int, str], None],
task_sync_signal_direct: Actor[[str, str | int, int, str], None],
model: str,
pk: Any,
pk: str | int,
raw_op: str,
) -> None:
):
model_class: type[Model] = path_to_class(model)
for provider in self._provider_model.objects.filter(
Q(backchannel_application__isnull=False) | Q(application__isnull=False)
@@ -210,19 +207,19 @@ class SyncTasks:
def sync_signal_direct(
self,
model: str,
pk: Any,
pk: str | int,
provider_pk: int,
raw_op: str,
) -> None:
):
task = CurrentTask.get_task()
self.logger = get_logger().bind(
provider_type=class_to_path(self._provider_model),
)
model_class: type[User | Group] = path_to_class(model)
model_class: type[Model] = path_to_class(model)
instance = model_class.objects.filter(pk=pk).first()
if not instance:
return
provider = self._provider_model.objects.filter(
provider: OutgoingSyncProvider = self._provider_model.objects.filter(
Q(backchannel_application__isnull=False) | Q(application__isnull=False),
pk=provider_pk,
).first()
@@ -247,7 +244,7 @@ class SyncTasks:
if operation == Direction.remove:
client.delete(instance)
except TransientSyncException as exc:
raise Retry() from exc # type: ignore[no-untyped-call]
raise Retry() from exc
except SkipObjectException:
return
except DryRunRejected as exc:
@@ -257,12 +254,12 @@ class SyncTasks:
def sync_signal_m2m_dispatch(
self,
task_sync_signal_m2m: Actor[[Any, int, str, list[Any]], None],
instance_pk: Any,
task_sync_signal_m2m: Actor[[str, int, str, list[int]], None],
instance_pk: str,
action: str,
pk_set: list[Any],
pk_set: list[int],
reverse: bool,
) -> None:
):
for provider in self._provider_model.objects.filter(
Q(backchannel_application__isnull=False) | Q(application__isnull=False)
):
@@ -284,11 +281,11 @@ class SyncTasks:
def sync_signal_m2m(
self,
group_pk: Any,
group_pk: str,
provider_pk: int,
action: str,
pk_set: list[Any],
) -> None:
pk_set: list[int],
):
task = CurrentTask.get_task()
self.logger = get_logger().bind(
provider_type=class_to_path(self._provider_model),
@@ -296,7 +293,7 @@ class SyncTasks:
group = Group.objects.filter(pk=group_pk).first()
if not group:
return
provider = self._provider_model.objects.filter(
provider: OutgoingSyncProvider = self._provider_model.objects.filter(
Q(backchannel_application__isnull=False) | Q(application__isnull=False),
pk=provider_pk,
).first()
@@ -305,7 +302,7 @@ class SyncTasks:
return
# Check if the object is allowed within the provider's restrictions
queryset = provider.get_object_qs(Group)
queryset: QuerySet = provider.get_object_qs(Group)
# The queryset we get from the provider must include the instance we've got given
# otherwise ignore this provider
if not queryset.filter(pk=group_pk).exists():
@@ -318,9 +315,9 @@ class SyncTasks:
operation = Direction.add
if action == "post_remove":
operation = Direction.remove
client.update_group(group, cast(Direction, operation), pk_set)
client.update_group(group, operation, pk_set)
except TransientSyncException as exc:
raise Retry() from exc # type: ignore[no-untyped-call]
raise Retry() from exc
except SkipObjectException:
return
except DryRunRejected as exc:

View File

@@ -1,6 +1,6 @@
"""Test Evaluator base functions"""
from unittest.mock import NonCallableMock, patch
from unittest.mock import patch
from django.test import RequestFactory, TestCase
from django.urls import reverse
@@ -17,27 +17,27 @@ from authentik.providers.oauth2.models import OAuth2Provider, ScopeMapping
class TestEvaluator(TestCase):
"""Test Evaluator base functions"""
def test_expr_regex_match(self) -> None:
def test_expr_regex_match(self):
"""Test expr_regex_match"""
self.assertFalse(BaseEvaluator.expr_regex_match("foo", "bar"))
self.assertTrue(BaseEvaluator.expr_regex_match("foo", "foo"))
def test_expr_regex_replace(self) -> None:
def test_expr_regex_replace(self):
"""Test expr_regex_replace"""
self.assertEqual(BaseEvaluator.expr_regex_replace("foo", "o", "a"), "faa")
def test_expr_user_by(self) -> None:
def test_expr_user_by(self):
"""Test expr_user_by"""
user = create_test_admin_user()
self.assertIsNotNone(BaseEvaluator.expr_user_by(username=user.username))
self.assertIsNone(BaseEvaluator.expr_user_by(username="bar"))
self.assertIsNone(BaseEvaluator.expr_user_by(foo="bar"))
def test_expr_is_group_member(self) -> None:
def test_expr_is_group_member(self):
"""Test expr_is_group_member"""
self.assertFalse(BaseEvaluator.expr_is_group_member(create_test_admin_user(), name="test"))
def test_expr_event_create(self) -> None:
def test_expr_event_create(self):
"""Test expr_event_create"""
evaluator = BaseEvaluator(generate_id())
evaluator._context = {
@@ -46,11 +46,10 @@ class TestEvaluator(TestCase):
evaluator.evaluate("ak_create_event('foo', bar='baz')")
event = Event.objects.filter(action="custom_foo").first()
self.assertIsNotNone(event)
assert event is not None # nosec
self.assertEqual(event.context, {"bar": "baz", "foo": "bar"})
@apply_blueprint("system/providers-oauth2.yaml")
def test_expr_create_jwt(self) -> None:
def test_expr_create_jwt(self):
"""Test expr_create_jwt"""
rf = RequestFactory()
user = create_test_user()
@@ -82,7 +81,7 @@ class TestEvaluator(TestCase):
self.assertEqual(decoded["preferred_username"], user.username)
@patch("authentik.stages.email.tasks.send_mails")
def test_expr_send_email_with_body(self, mock_send_mails: NonCallableMock) -> None:
def test_expr_send_email_with_body(self, mock_send_mails):
"""Test ak_send_email with body parameter"""
user = create_test_user()
evaluator = BaseEvaluator(generate_id())
@@ -109,7 +108,7 @@ class TestEvaluator(TestCase):
self.assertEqual(message.body, "Test Body")
@patch("authentik.stages.email.tasks.send_mails")
def test_expr_send_email_with_template(self, mock_send_mails: NonCallableMock) -> None:
def test_expr_send_email_with_template(self, mock_send_mails):
"""Test ak_send_email with template parameter"""
user = create_test_user()
evaluator = BaseEvaluator(generate_id())
@@ -124,7 +123,7 @@ class TestEvaluator(TestCase):
self.assertTrue(result)
mock_send_mails.assert_called_once()
def test_expr_send_email_validation_errors(self) -> None:
def test_expr_send_email_validation_errors(self):
"""Test ak_send_email validation errors"""
evaluator = BaseEvaluator(generate_id())
@@ -142,7 +141,7 @@ class TestEvaluator(TestCase):
self.assertIn("Either body or template parameter must be provided", str(cm.exception))
@patch("authentik.stages.email.tasks.send_mails")
def test_expr_send_email_with_custom_stage(self, mock_send_mails: NonCallableMock) -> None:
def test_expr_send_email_with_custom_stage(self, mock_send_mails):
"""Test ak_send_email with custom EmailStage"""
from authentik.stages.email.models import EmailStage
@@ -171,7 +170,7 @@ class TestEvaluator(TestCase):
self.assertFalse(stage.use_global_settings)
@patch("authentik.stages.email.tasks.send_mails")
def test_expr_send_email_with_context(self, mock_send_mails: NonCallableMock) -> None:
def test_expr_send_email_with_context(self, mock_send_mails):
"""Test ak_send_email with custom context parameter"""
user = create_test_user()
evaluator = BaseEvaluator(generate_id())
@@ -200,7 +199,7 @@ class TestEvaluator(TestCase):
self.assertIn("http://localhost", message.body)
@patch("authentik.stages.email.tasks.send_mails")
def test_expr_send_email_multiple_addresses(self, mock_send_mails: NonCallableMock) -> None:
def test_expr_send_email_multiple_addresses(self, mock_send_mails):
"""Test ak_send_email with multiple email addresses"""
user = create_test_user()
evaluator = BaseEvaluator(generate_id())
@@ -227,7 +226,7 @@ class TestEvaluator(TestCase):
self.assertEqual(message.to, ["user1@example.com", "user2@example.com"])
self.assertEqual(message.body, "Test Body")
def test_expr_send_email_multiple_addresses_validation(self) -> None:
def test_expr_send_email_multiple_addresses_validation(self):
"""Test ak_send_email validation with multiple addresses"""
evaluator = BaseEvaluator(generate_id())

View File

@@ -15,27 +15,27 @@ class TestHTTP(TestCase):
self.user = create_test_admin_user()
self.factory = RequestFactory()
def test_bad_request_message(self) -> None:
def test_bad_request_message(self):
"""test bad_request_message"""
request = self.factory.get("/")
self.assertEqual(bad_request_message(request, "foo").status_code, 400)
def test_normal(self) -> None:
def test_normal(self):
"""Test normal request"""
request = self.factory.get("/")
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.1")
def test_forward_for(self) -> None:
def test_forward_for(self):
"""Test x-forwarded-for request"""
request = self.factory.get("/", HTTP_X_FORWARDED_FOR="127.0.0.2")
self.assertEqual(ClientIPMiddleware.get_client_ip(request), "127.0.0.2")
def test_forward_for_invalid(self) -> None:
def test_forward_for_invalid(self):
"""Test invalid forward for"""
request = self.factory.get("/", HTTP_X_FORWARDED_FOR="foobar")
self.assertEqual(ClientIPMiddleware.get_client_ip(request), ClientIPMiddleware.default_ip)
def test_fake_outpost(self) -> None:
def test_fake_outpost(self):
"""Test faked IP which is overridden by an outpost"""
token = Token.objects.create(
identifier="test", user=self.user, intent=TokenIntents.INTENT_API
@@ -43,7 +43,7 @@ class TestHTTP(TestCase):
# Invalid, non-existent token
request = self.factory.get(
"/",
**{ # type: ignore[arg-type]
**{
ClientIPMiddleware.outpost_remote_ip_header: "1.2.3.4",
ClientIPMiddleware.outpost_token_header: "abc",
},
@@ -52,7 +52,7 @@ class TestHTTP(TestCase):
# Invalid, user doesn't have permissions
request = self.factory.get(
"/",
**{ # type: ignore[arg-type]
**{
ClientIPMiddleware.outpost_remote_ip_header: "1.2.3.4",
ClientIPMiddleware.outpost_token_header: token.key,
},
@@ -63,7 +63,7 @@ class TestHTTP(TestCase):
self.user.save()
request = self.factory.get(
"/",
**{ # type: ignore[arg-type]
**{
ClientIPMiddleware.outpost_remote_ip_header: "foobar",
ClientIPMiddleware.outpost_token_header: token.key,
},
@@ -74,7 +74,7 @@ class TestHTTP(TestCase):
self.user.save()
request = self.factory.get(
"/",
**{ # type: ignore[arg-type]
**{
ClientIPMiddleware.outpost_remote_ip_header: "1.2.3.4",
ClientIPMiddleware.outpost_token_header: token.key,
},

View File

@@ -8,10 +8,10 @@ from authentik.lib.sentry import SentryIgnoredException, should_ignore_exception
class TestSentry(TestCase):
"""test sentry integration"""
def test_error_not_sent(self) -> None:
def test_error_not_sent(self):
"""Test SentryIgnoredError not sent"""
self.assertTrue(should_ignore_exception(SentryIgnoredException()))
def test_error_sent(self) -> None:
def test_error_sent(self):
"""Test error sent"""
self.assertFalse(should_ignore_exception(ValueError()))

View File

@@ -5,6 +5,7 @@ from collections.abc import Callable
from django.test import TestCase
from rest_framework.serializers import BaseSerializer
from authentik.flows.models import Stage
from authentik.lib.models import SerializerModel
from authentik.lib.utils.reflection import all_subclasses
@@ -13,10 +14,10 @@ class TestModels(TestCase):
"""Generic model properties tests"""
def model_tester_factory(test_model: type[SerializerModel]) -> Callable[[TestModels], None]:
def model_tester_factory(test_model: type[Stage]) -> Callable:
"""Test a form"""
def tester(self: TestModels) -> None:
def tester(self: TestModels):
try:
model_class = None
if test_model._meta.abstract: # pragma: no cover
@@ -30,4 +31,4 @@ def model_tester_factory(test_model: type[SerializerModel]) -> Callable[[TestMod
for model in all_subclasses(SerializerModel):
setattr(TestModels, f"test_model_{model.__name__}", model_tester_factory(model)) # type: ignore[type-abstract]
setattr(TestModels, f"test_model_{model.__name__}", model_tester_factory(model))

View File

@@ -10,6 +10,6 @@ from authentik.lib.utils.reflection import path_to_class
class TestReflectionUtils(TestCase):
"""Test Reflection-utils"""
def test_path_to_class(self) -> None:
def test_path_to_class(self):
"""Test path_to_class"""
self.assertEqual(path_to_class("datetime.datetime"), datetime)

View File

@@ -11,20 +11,20 @@ from authentik.lib.utils.time import timedelta_from_string, timedelta_string_val
class TestTimeUtils(TestCase):
"""Test time-utils"""
def test_valid(self) -> None:
def test_valid(self):
"""Test valid expression"""
expr = "hours=3;minutes=1"
expected = timedelta(hours=3, minutes=1)
self.assertEqual(timedelta_from_string(expr), expected)
def test_invalid(self) -> None:
def test_invalid(self):
"""Test invalid expression"""
with self.assertRaises(ValueError):
timedelta_from_string("foo")
with self.assertRaises(ValueError):
timedelta_from_string("bar=baz")
def test_validation(self) -> None:
def test_validation(self):
"""Test Django model field validator"""
with self.assertRaises(ValidationError):
timedelta_string_validator("foo")

View File

@@ -2,31 +2,23 @@
from inspect import currentframe
from pathlib import Path
from typing import Any
from django.contrib.messages.middleware import MessageMiddleware
from django.contrib.sessions.middleware import SessionMiddleware
from django.core.handlers.wsgi import WSGIRequest
from django.http import HttpRequest, HttpResponse
from django.http import HttpRequest
from django.test.client import RequestFactory
from guardian.utils import get_anonymous_user
from authentik.core.models import User
def dummy_get_response(request: HttpRequest) -> HttpResponse: # pragma: no cover
def dummy_get_response(request: HttpRequest): # pragma: no cover
"""Dummy get_response for SessionMiddleware"""
return HttpResponse()
return None
def load_fixture(path: str, **kwargs: Any) -> str:
def load_fixture(path: str, **kwargs) -> str:
"""Load fixture, optionally formatting it with kwargs"""
current = currentframe()
if current is None:
return ""
parent = current.f_back
if parent is None:
return ""
calling_file_path = parent.f_globals["__file__"]
with open(Path(calling_file_path).resolve().parent / Path(path), encoding="utf-8") as _fixture:
fixture = _fixture.read()
@@ -36,17 +28,17 @@ def load_fixture(path: str, **kwargs: Any) -> str:
return fixture
def get_request(*args: Any, user: User | None = None, **kwargs: Any) -> WSGIRequest:
def get_request(*args, user=None, **kwargs):
"""Get a request with usable session"""
request = RequestFactory().get(*args, **kwargs)
if user is not None:
if user:
request.user = user
else:
request.user = get_anonymous_user()
session_middleware = SessionMiddleware(dummy_get_response)
session_middleware.process_request(request)
middleware = SessionMiddleware(dummy_get_response)
middleware.process_request(request)
request.session.save()
message_middleware = MessageMiddleware(dummy_get_response)
message_middleware.process_request(request)
middleware = MessageMiddleware(dummy_get_response)
middleware.process_request(request)
request.session.save()
return request

View File

@@ -1,22 +1,16 @@
"""authentik database utilities"""
import gc
from collections.abc import Generator
from typing import TypeVar
from django.db import reset_queries
from django.db.models import Model, QuerySet
ModelT_co = TypeVar("ModelT_co", bound=Model, covariant=True)
from django.db.models import QuerySet
def chunked_queryset(
queryset: QuerySet[ModelT_co], chunk_size: int = 1_000
) -> Generator[ModelT_co]:
def chunked_queryset(queryset: QuerySet, chunk_size: int = 1_000):
if not queryset.exists():
return
return []
def get_chunks(qs: QuerySet[ModelT_co]) -> Generator[QuerySet[ModelT_co]]:
def get_chunks(qs: QuerySet):
qs = qs.order_by("pk")
pks = qs.values_list("pk", flat=True)
start_pk = pks[0]

View File

@@ -1,14 +1,7 @@
from typing import Any, cast
type rdict[R] = dict[str, "rdict[R] | R"]
from typing import Any
def get_path_from_dict[R: Any](
root: rdict[R],
path: str,
sep: str = ".",
default: R | None = None,
) -> Any | None:
def get_path_from_dict(root: dict, path: str, sep=".", default=None) -> Any:
"""Recursively walk through `root`, checking each part of `path` separated by `sep`.
If at any point a dict does not exist, return default"""
walk: Any = root
@@ -17,10 +10,10 @@ def get_path_from_dict[R: Any](
walk = walk.get(comp)
else:
return default
return cast(R, walk)
return walk
def set_path_in_dict[R: Any](root: rdict[R], path: str, value: R, sep: str = ".") -> None:
def set_path_in_dict(root: dict, path: str, value: Any, sep="."):
"""Recursively walk through `root`, checking each part of `path` separated by `sep`
and setting the last value to `value`"""
# Walk each component of the path

View File

@@ -1,7 +1,7 @@
"""file utils"""
from django.db.models import Model
from django.http import HttpResponse, HttpResponseBadRequest
from django.http import HttpResponseBadRequest
from rest_framework.fields import BooleanField, CharField, FileField
from rest_framework.request import Request
from rest_framework.response import Response
@@ -25,7 +25,7 @@ class FilePathSerializer(PassiveSerializer):
url = CharField()
def set_file(request: Request, obj: Model, field_name: str) -> HttpResponse:
def set_file(request: Request, obj: Model, field_name: str):
"""Upload file"""
field = getattr(obj, field_name)
file = request.FILES.get("file", None)
@@ -45,7 +45,7 @@ def set_file(request: Request, obj: Model, field_name: str) -> HttpResponse:
return HttpResponseBadRequest()
def set_file_url(request: Request, obj: Model, field_name: str) -> HttpResponse:
def set_file_url(request: Request, obj: Model, field_name: str):
"""Set file field to URL"""
field = getattr(obj, field_name)
url = request.data.get("url", None)

View File

@@ -1,18 +1,13 @@
"""http helpers"""
from typing import TYPE_CHECKING, Any
from uuid import uuid4
from requests.models import Response
from requests.sessions import PreparedRequest, Session
from structlog.stdlib import get_logger
from authentik import authentik_full_version
from authentik.lib.config import CONFIG
if TYPE_CHECKING:
from requests.sessions import _Timeout
LOGGER = get_logger()
@@ -24,40 +19,50 @@ def authentik_user_agent() -> str:
class TimeoutSession(Session):
"""Always set a default HTTP request timeout"""
def __init__(self, default_timeout: int | None = None) -> None:
def __init__(self, default_timeout=None):
super().__init__()
self.timeout = default_timeout
def send(
self,
request: PreparedRequest,
request,
*,
timeout: "_Timeout | None" = None,
**kwargs: Any,
) -> Response:
stream=...,
verify=...,
proxies=...,
cert=...,
timeout=...,
allow_redirects=...,
**kwargs,
):
if not timeout and self.timeout:
timeout = self.timeout
return super().send(request, timeout=timeout, **kwargs)
return super().send(
request,
stream=stream,
verify=verify,
proxies=proxies,
cert=cert,
timeout=timeout,
allow_redirects=allow_redirects,
**kwargs,
)
class DebugSession(TimeoutSession):
"""requests session which logs http requests and responses"""
def send(
self,
request: PreparedRequest,
**kwargs: Any,
) -> Response:
def send(self, req: PreparedRequest, *args, **kwargs):
request_id = str(uuid4())
LOGGER.debug(
"HTTP request sent",
uid=request_id,
url=request.url,
method=request.method,
headers=request.headers,
body=request.body,
url=req.url,
method=req.method,
headers=req.headers,
body=req.body,
)
resp = super().send(request, **kwargs)
resp = super().send(req, *args, **kwargs)
LOGGER.debug(
"HTTP response received",
uid=request_id,

View File

@@ -1,13 +1,10 @@
"""authentik lib reflection utilities"""
import os
from collections.abc import Generator
from importlib import import_module
from pathlib import Path
from tempfile import gettempdir
from typing import cast
from django.apps.config import AppConfig
from django.conf import settings
from django.utils.module_loading import import_string
@@ -16,9 +13,9 @@ from authentik.lib.config import CONFIG
SERVICE_HOST_ENV_NAME = "KUBERNETES_SERVICE_HOST"
def all_subclasses[T: type](cls: T, sort: bool = True) -> list[T] | set[T]:
def all_subclasses[T: type](cls: T, sort=True) -> list[T] | set[T]:
"""Recursively return all subclassess of cls"""
classes: list[T] | set[T] = set(cls.__subclasses__()).union(
classes = set(cls.__subclasses__()).union(
[s for c in cls.__subclasses__() for s in all_subclasses(c, sort=sort)]
)
# Check if we're in debug mode, if not exclude classes which have `__debug_only__`
@@ -41,10 +38,10 @@ def path_to_class(path: str = "") -> type:
parts = path.split(".")
package = ".".join(parts[:-1])
_class = getattr(import_module(package), parts[-1])
return cast(type, _class)
return _class
def get_apps() -> Generator[AppConfig]:
def get_apps():
"""Get list of all authentik apps"""
from django.apps.registry import apps
@@ -68,11 +65,11 @@ def get_env() -> str:
return "custom"
def ConditionalInheritance(path: str) -> type:
def ConditionalInheritance(path: str):
"""Conditionally inherit from a class, intended for things like authentik.enterprise,
without which authentik should still be able to run"""
try:
cls = import_string(path)
return cast(type, cls)
return cls
except ModuleNotFoundError:
return object

View File

@@ -19,7 +19,7 @@ ALLOWED_KEYS = (
)
def timedelta_string_validator(value: str) -> None:
def timedelta_string_validator(value: str):
"""Validator for Django that checks if value can be parsed with `timedelta_from_string`"""
try:
timedelta_from_string(value)

View File

@@ -1,6 +1,5 @@
"""URL-related utils"""
from typing import Any
from urllib.parse import urlparse
from django.http import HttpResponse, QueryDict
@@ -11,12 +10,12 @@ from structlog.stdlib import get_logger
LOGGER = get_logger()
def is_url_absolute(url: str | bytes | bytearray | None) -> bool:
def is_url_absolute(url):
"""Check if domain is absolute to prevent user from being redirect somewhere else"""
return bool(urlparse(url).netloc)
def redirect_with_qs(view: str, qs: QueryDict | None = None, **kwargs: Any) -> HttpResponse:
def redirect_with_qs(view: str, get_query_set: QueryDict | None = None, **kwargs) -> HttpResponse:
"""Wrapper to redirect whilst keeping GET Parameters"""
try:
target = reverse(view, kwargs=kwargs)
@@ -25,14 +24,14 @@ def redirect_with_qs(view: str, qs: QueryDict | None = None, **kwargs: Any) -> H
return redirect(view)
LOGGER.warning("redirect target is not a valid view", view=view)
raise
if qs:
target += "?" + qs.urlencode()
if get_query_set:
target += "?" + get_query_set.urlencode()
return redirect(target)
def reverse_with_qs(view: str, qs: QueryDict | None = None, **kwargs: Any) -> str:
def reverse_with_qs(view: str, query: QueryDict | None = None, **kwargs) -> str:
"""Reverse a view to it's url but include get params"""
url = reverse(view, **kwargs)
if qs:
url += "?" + qs.urlencode()
if query:
url += "?" + query.urlencode()
return url

View File

@@ -1,17 +1,10 @@
"""Serializer validators"""
from typing import TYPE_CHECKING, Any, TypeVar
from django.utils.translation import gettext_lazy as _
from rest_framework.exceptions import ValidationError
from rest_framework.serializers import Serializer
from rest_framework.utils.representation import smart_repr
if TYPE_CHECKING:
from django.utils.functional import _StrPromise
_IN = TypeVar("_IN") # Instance Type
class RequiredTogetherValidator:
"""Serializer-level validator that ensures all fields in `fields` are only
@@ -19,13 +12,13 @@ class RequiredTogetherValidator:
fields: list[str]
requires_context = True
message: "str | _StrPromise" = _("The fields {field_names} must be used together.")
message = _("The fields {field_names} must be used together.")
def __init__(self, fields: list[str], message: "str | _StrPromise | None" = None) -> None:
def __init__(self, fields: list[str], message: str | None = None) -> None:
self.fields = fields
self.message = message or self.message
def __call__(self, attrs: dict[Any, Any], serializer: Serializer[_IN]) -> None:
def __call__(self, attrs: dict, serializer: Serializer):
"""Check that if any of the fields in `self.fields` are set, all of them must be set"""
if any(field in attrs for field in self.fields) and not all(
field in attrs for field in self.fields
@@ -34,5 +27,5 @@ class RequiredTogetherValidator:
message = self.message.format(field_names=field_names)
raise ValidationError(message, code="required")
def __repr__(self) -> str:
def __repr__(self):
return f"<{self.__class__.__name__}(fields={smart_repr(self.fields)})>"

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