- +
{ } renderForm(): TemplateResult { - return html` + return html` { return html` Date: Sat, 7 Jun 2025 03:01:00 +0200 Subject: [PATCH 08/47] outposts: remove duplicate startup/setup code, add pyroscope, make sentry not reconfigure every time (#14724) Signed-off-by: Jens Langhammer --- cmd/ldap/main.go | 68 ++------------------ cmd/proxy/main.go | 68 ++------------------ cmd/rac/main.go | 67 ++----------------- cmd/radius/main.go | 67 ++----------------- cmd/server/server.go | 21 ++---- go.mod | 3 + go.sum | 6 ++ internal/common/prerun.go | 17 +++++ internal/debug/debug.go | 44 ++++++++++++- internal/outpost/ak/api.go | 4 ++ internal/outpost/ak/entrypoint/entrypoint.go | 51 +++++++++++++++ internal/outpost/ak/global.go | 28 ++++---- internal/outpost/ldap/ldap.go | 2 +- internal/outpost/proxyv2/proxyv2.go | 2 +- internal/outpost/rac/rac.go | 2 +- internal/outpost/radius/radius.go | 2 +- internal/utils/web/http_tracing.go | 3 +- 17 files changed, 176 insertions(+), 279 deletions(-) create mode 100644 internal/common/prerun.go create mode 100644 internal/outpost/ak/entrypoint/entrypoint.go diff --git a/cmd/ldap/main.go b/cmd/ldap/main.go index 8b56d229a7..68e4165c01 100644 --- a/cmd/ldap/main.go +++ b/cmd/ldap/main.go @@ -2,17 +2,13 @@ package main import ( "fmt" - "net/url" "os" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "goauthentik.io/internal/common" - "goauthentik.io/internal/config" "goauthentik.io/internal/constants" - "goauthentik.io/internal/debug" - "goauthentik.io/internal/outpost/ak" + "goauthentik.io/internal/outpost/ak/entrypoint" "goauthentik.io/internal/outpost/ak/healthcheck" "goauthentik.io/internal/outpost/ldap" ) @@ -25,65 +21,15 @@ Required environment variables: - AUTHENTIK_INSECURE: Skip SSL Certificate verification` var rootCmd = &cobra.Command{ - Long: helpMessage, - Version: constants.FullVersion(), - PersistentPreRun: func(cmd *cobra.Command, args []string) { - log.SetLevel(log.DebugLevel) - log.SetFormatter(&log.JSONFormatter{ - FieldMap: log.FieldMap{ - log.FieldKeyMsg: "event", - log.FieldKeyTime: "timestamp", - }, - DisableHTMLEscape: true, - }) - }, - Run: func(cmd *cobra.Command, args []string) { - debug.EnableDebugServer() - akURL := config.Get().AuthentikHost - if akURL == "" { - fmt.Println("env AUTHENTIK_HOST not set!") - fmt.Println(helpMessage) - os.Exit(1) - } - akToken := config.Get().AuthentikToken - if akToken == "" { - fmt.Println("env AUTHENTIK_TOKEN not set!") - fmt.Println(helpMessage) - os.Exit(1) - } - - akURLActual, err := url.Parse(akURL) + Long: helpMessage, + Version: constants.FullVersion(), + PersistentPreRun: common.PreRun, + RunE: func(cmd *cobra.Command, args []string) error { + err := entrypoint.OutpostMain("authentik.outpost.ldap", ldap.NewServer) if err != nil { - fmt.Println(err) fmt.Println(helpMessage) - os.Exit(1) - } - - ex := common.Init() - defer common.Defer() - go func() { - for { - <-ex - os.Exit(0) - } - }() - - ac := ak.NewAPIController(*akURLActual, akToken) - if ac == nil { - os.Exit(1) - } - defer ac.Shutdown() - - ac.Server = ldap.NewServer(ac) - - err = ac.Start() - if err != nil { - log.WithError(err).Panic("Failed to run server") - } - - for { - <-ex } + return err }, } diff --git a/cmd/proxy/main.go b/cmd/proxy/main.go index 4bb93f1e68..24aee3c933 100644 --- a/cmd/proxy/main.go +++ b/cmd/proxy/main.go @@ -2,17 +2,13 @@ package main import ( "fmt" - "net/url" "os" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "goauthentik.io/internal/common" - "goauthentik.io/internal/config" "goauthentik.io/internal/constants" - "goauthentik.io/internal/debug" - "goauthentik.io/internal/outpost/ak" + "goauthentik.io/internal/outpost/ak/entrypoint" "goauthentik.io/internal/outpost/ak/healthcheck" "goauthentik.io/internal/outpost/proxyv2" ) @@ -28,65 +24,15 @@ Optionally, you can set these: - AUTHENTIK_HOST_BROWSER: URL to use in the browser, when it differs from AUTHENTIK_HOST` var rootCmd = &cobra.Command{ - Long: helpMessage, - Version: constants.FullVersion(), - PersistentPreRun: func(cmd *cobra.Command, args []string) { - log.SetLevel(log.DebugLevel) - log.SetFormatter(&log.JSONFormatter{ - FieldMap: log.FieldMap{ - log.FieldKeyMsg: "event", - log.FieldKeyTime: "timestamp", - }, - DisableHTMLEscape: true, - }) - }, - Run: func(cmd *cobra.Command, args []string) { - debug.EnableDebugServer() - akURL := config.Get().AuthentikHost - if akURL == "" { - fmt.Println("env AUTHENTIK_HOST not set!") - fmt.Println(helpMessage) - os.Exit(1) - } - akToken := config.Get().AuthentikToken - if akToken == "" { - fmt.Println("env AUTHENTIK_TOKEN not set!") - fmt.Println(helpMessage) - os.Exit(1) - } - - akURLActual, err := url.Parse(akURL) + Long: helpMessage, + Version: constants.FullVersion(), + PersistentPreRun: common.PreRun, + RunE: func(cmd *cobra.Command, args []string) error { + err := entrypoint.OutpostMain("authentik.outpost.proxy", proxyv2.NewProxyServer) if err != nil { - fmt.Println(err) fmt.Println(helpMessage) - os.Exit(1) - } - - ex := common.Init() - defer common.Defer() - go func() { - for { - <-ex - os.Exit(0) - } - }() - - ac := ak.NewAPIController(*akURLActual, akToken) - if ac == nil { - os.Exit(1) - } - defer ac.Shutdown() - - ac.Server = proxyv2.NewProxyServer(ac) - - err = ac.Start() - if err != nil { - log.WithError(err).Panic("Failed to run server") - } - - for { - <-ex } + return err }, } diff --git a/cmd/rac/main.go b/cmd/rac/main.go index 2aecf80bf5..b265b07964 100644 --- a/cmd/rac/main.go +++ b/cmd/rac/main.go @@ -2,16 +2,13 @@ package main import ( "fmt" - "net/url" "os" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "goauthentik.io/internal/common" "goauthentik.io/internal/constants" - "goauthentik.io/internal/debug" - "goauthentik.io/internal/outpost/ak" + "goauthentik.io/internal/outpost/ak/entrypoint" "goauthentik.io/internal/outpost/ak/healthcheck" "goauthentik.io/internal/outpost/rac" ) @@ -24,65 +21,15 @@ Required environment variables: - AUTHENTIK_INSECURE: Skip SSL Certificate verification` var rootCmd = &cobra.Command{ - Long: helpMessage, - Version: constants.FullVersion(), - PersistentPreRun: func(cmd *cobra.Command, args []string) { - log.SetLevel(log.DebugLevel) - log.SetFormatter(&log.JSONFormatter{ - FieldMap: log.FieldMap{ - log.FieldKeyMsg: "event", - log.FieldKeyTime: "timestamp", - }, - DisableHTMLEscape: true, - }) - }, - Run: func(cmd *cobra.Command, args []string) { - debug.EnableDebugServer() - akURL, found := os.LookupEnv("AUTHENTIK_HOST") - if !found { - fmt.Println("env AUTHENTIK_HOST not set!") - fmt.Println(helpMessage) - os.Exit(1) - } - akToken, found := os.LookupEnv("AUTHENTIK_TOKEN") - if !found { - fmt.Println("env AUTHENTIK_TOKEN not set!") - fmt.Println(helpMessage) - os.Exit(1) - } - - akURLActual, err := url.Parse(akURL) + Long: helpMessage, + Version: constants.FullVersion(), + PersistentPreRun: common.PreRun, + RunE: func(cmd *cobra.Command, args []string) error { + err := entrypoint.OutpostMain("authentik.outpost.rac", rac.NewServer) if err != nil { - fmt.Println(err) fmt.Println(helpMessage) - os.Exit(1) - } - - ex := common.Init() - defer common.Defer() - go func() { - for { - <-ex - os.Exit(0) - } - }() - - ac := ak.NewAPIController(*akURLActual, akToken) - if ac == nil { - os.Exit(1) - } - defer ac.Shutdown() - - ac.Server = rac.NewServer(ac) - - err = ac.Start() - if err != nil { - log.WithError(err).Panic("Failed to run server") - } - - for { - <-ex } + return err }, } diff --git a/cmd/radius/main.go b/cmd/radius/main.go index 4e728b8854..0e797fc03a 100644 --- a/cmd/radius/main.go +++ b/cmd/radius/main.go @@ -2,16 +2,13 @@ package main import ( "fmt" - "net/url" "os" - log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "goauthentik.io/internal/common" "goauthentik.io/internal/constants" - "goauthentik.io/internal/debug" - "goauthentik.io/internal/outpost/ak" + "goauthentik.io/internal/outpost/ak/entrypoint" "goauthentik.io/internal/outpost/ak/healthcheck" "goauthentik.io/internal/outpost/radius" ) @@ -24,65 +21,15 @@ Required environment variables: - AUTHENTIK_INSECURE: Skip SSL Certificate verification` var rootCmd = &cobra.Command{ - Long: helpMessage, - Version: constants.FullVersion(), - PersistentPreRun: func(cmd *cobra.Command, args []string) { - log.SetLevel(log.DebugLevel) - log.SetFormatter(&log.JSONFormatter{ - FieldMap: log.FieldMap{ - log.FieldKeyMsg: "event", - log.FieldKeyTime: "timestamp", - }, - DisableHTMLEscape: true, - }) - }, - Run: func(cmd *cobra.Command, args []string) { - debug.EnableDebugServer() - akURL, found := os.LookupEnv("AUTHENTIK_HOST") - if !found { - fmt.Println("env AUTHENTIK_HOST not set!") - fmt.Println(helpMessage) - os.Exit(1) - } - akToken, found := os.LookupEnv("AUTHENTIK_TOKEN") - if !found { - fmt.Println("env AUTHENTIK_TOKEN not set!") - fmt.Println(helpMessage) - os.Exit(1) - } - - akURLActual, err := url.Parse(akURL) + Long: helpMessage, + Version: constants.FullVersion(), + PersistentPreRun: common.PreRun, + RunE: func(cmd *cobra.Command, args []string) error { + err := entrypoint.OutpostMain("authentik.outpost.radius", radius.NewServer) if err != nil { - fmt.Println(err) fmt.Println(helpMessage) - os.Exit(1) - } - - ex := common.Init() - defer common.Defer() - go func() { - for { - <-ex - os.Exit(0) - } - }() - - ac := ak.NewAPIController(*akURLActual, akToken) - if ac == nil { - os.Exit(1) - } - defer ac.Shutdown() - - ac.Server = radius.NewServer(ac) - - err = ac.Start() - if err != nil { - log.WithError(err).Panic("Failed to run server") - } - - for { - <-ex } + return err }, } diff --git a/cmd/server/server.go b/cmd/server/server.go index 4091c20957..85556ed304 100644 --- a/cmd/server/server.go +++ b/cmd/server/server.go @@ -22,21 +22,12 @@ import ( ) var rootCmd = &cobra.Command{ - Use: "authentik", - Short: "Start authentik instance", - Version: constants.FullVersion(), - PersistentPreRun: func(cmd *cobra.Command, args []string) { - log.SetLevel(log.DebugLevel) - log.SetFormatter(&log.JSONFormatter{ - FieldMap: log.FieldMap{ - log.FieldKeyMsg: "event", - log.FieldKeyTime: "timestamp", - }, - DisableHTMLEscape: true, - }) - }, + Use: "authentik", + Short: "Start authentik instance", + Version: constants.FullVersion(), + PersistentPreRun: common.PreRun, Run: func(cmd *cobra.Command, args []string) { - debug.EnableDebugServer() + debug.EnableDebugServer("authentik.core") l := log.WithField("logger", "authentik.root") if config.Get().ErrorReporting.Enabled { @@ -99,7 +90,7 @@ func attemptProxyStart(ws *web.WebServer, u *url.URL) { }) srv := proxyv2.NewProxyServer(ac) - ws.ProxyServer = srv + ws.ProxyServer = srv.(*proxyv2.ProxyServer) ac.Server = srv l.Debug("attempting to start outpost") err := ac.StartBackgroundTasks() diff --git a/go.mod b/go.mod index f7634d255b..f854e7b1ec 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/gorilla/securecookie v1.1.2 github.com/gorilla/sessions v1.4.0 github.com/gorilla/websocket v1.5.3 + github.com/grafana/pyroscope-go v1.2.2 github.com/jellydator/ttlcache/v3 v3.3.0 github.com/mitchellh/mapstructure v1.5.0 github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484 @@ -58,8 +59,10 @@ require ( github.com/go-openapi/strfmt v0.23.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-openapi/validate v0.24.0 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect + github.com/klauspost/compress v1.18.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/ulid v1.3.1 // indirect diff --git a/go.sum b/go.sum index 61147d86ff..2d1625e2c6 100644 --- a/go.sum +++ b/go.sum @@ -178,6 +178,10 @@ github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2e github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafana/pyroscope-go v1.2.2 h1:uvKCyZMD724RkaCEMrSTC38Yn7AnFe8S2wiAIYdDPCE= +github.com/grafana/pyroscope-go v1.2.2/go.mod h1:zzT9QXQAp2Iz2ZdS216UiV8y9uXJYQiGE1q8v1FyhqU= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -262,6 +266,8 @@ github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= diff --git a/internal/common/prerun.go b/internal/common/prerun.go new file mode 100644 index 0000000000..db2dfad029 --- /dev/null +++ b/internal/common/prerun.go @@ -0,0 +1,17 @@ +package common + +import ( + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +func PreRun(cmd *cobra.Command, args []string) { + log.SetLevel(log.DebugLevel) + log.SetFormatter(&log.JSONFormatter{ + FieldMap: log.FieldMap{ + log.FieldKeyMsg: "event", + log.FieldKeyTime: "timestamp", + }, + DisableHTMLEscape: true, + }) +} diff --git a/internal/debug/debug.go b/internal/debug/debug.go index 3897df12e5..bf77a0c7b2 100644 --- a/internal/debug/debug.go +++ b/internal/debug/debug.go @@ -5,19 +5,24 @@ import ( "fmt" "net/http" "net/http/pprof" + "os" + "runtime" "github.com/gorilla/mux" + "github.com/grafana/pyroscope-go" log "github.com/sirupsen/logrus" "goauthentik.io/internal/config" "goauthentik.io/internal/utils/web" ) -func EnableDebugServer() { - l := log.WithField("logger", "authentik.go_debugger") +var l = log.WithField("logger", "authentik.debugger.go") + +func EnableDebugServer(appName string) { if !config.Get().Debug { return } h := mux.NewRouter() + enablePyroscope(appName) h.HandleFunc("/debug/pprof/", pprof.Index) h.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) h.HandleFunc("/debug/pprof/profile", pprof.Profile) @@ -54,3 +59,38 @@ func EnableDebugServer() { } }() } + +func enablePyroscope(appName string) { + p, pok := os.LookupEnv("AUTHENTIK_PYROSCOPE_HOST") + if !pok { + return + } + l.Debug("Enabling pyroscope") + runtime.SetMutexProfileFraction(5) + runtime.SetBlockProfileRate(5) + hostname, err := os.Hostname() + if err != nil { + panic(err) + } + _, err = pyroscope.Start(pyroscope.Config{ + ApplicationName: appName, + ServerAddress: p, + Logger: pyroscope.StandardLogger, + Tags: map[string]string{"hostname": hostname}, + ProfileTypes: []pyroscope.ProfileType{ + pyroscope.ProfileCPU, + pyroscope.ProfileAllocObjects, + pyroscope.ProfileAllocSpace, + pyroscope.ProfileInuseObjects, + pyroscope.ProfileInuseSpace, + pyroscope.ProfileGoroutines, + pyroscope.ProfileMutexCount, + pyroscope.ProfileMutexDuration, + pyroscope.ProfileBlockCount, + pyroscope.ProfileBlockDuration, + }, + }) + if err != nil { + panic(err) + } +} diff --git a/internal/outpost/ak/api.go b/internal/outpost/ak/api.go index 0d18fc6d1b..e68bb1e114 100644 --- a/internal/outpost/ak/api.go +++ b/internal/outpost/ak/api.go @@ -135,6 +135,10 @@ func NewAPIController(akURL url.URL, token string) *APIController { return ac } +func (a *APIController) Log() *log.Entry { + return a.logger +} + // Start Starts all handlers, non-blocking func (a *APIController) Start() error { err := a.Server.Refresh() diff --git a/internal/outpost/ak/entrypoint/entrypoint.go b/internal/outpost/ak/entrypoint/entrypoint.go new file mode 100644 index 0000000000..60a71bf090 --- /dev/null +++ b/internal/outpost/ak/entrypoint/entrypoint.go @@ -0,0 +1,51 @@ +package entrypoint + +import ( + "errors" + "net/url" + "os" + + "goauthentik.io/internal/common" + "goauthentik.io/internal/config" + "goauthentik.io/internal/debug" + "goauthentik.io/internal/outpost/ak" +) + +func OutpostMain(appName string, server func(ac *ak.APIController) ak.Outpost) error { + debug.EnableDebugServer(appName) + akURL := config.Get().AuthentikHost + if akURL == "" { + return errors.New("environment variable `AUTHENTIK_HOST` not set") + } + akToken := config.Get().AuthentikToken + if akToken == "" { + return errors.New("environment variable `AUTHENTIK_TOKEN` not set") + } + + akURLActual, err := url.Parse(akURL) + if err != nil { + return err + } + + ex := common.Init() + defer common.Defer() + + ac := ak.NewAPIController(*akURLActual, akToken) + if ac == nil { + os.Exit(1) + } + defer ac.Shutdown() + + ac.Server = server(ac) + + err = ac.Start() + if err != nil { + ac.Log().WithError(err).Panic("Failed to run server") + return err + } + + for { + <-ex + return nil + } +} diff --git a/internal/outpost/ak/global.go b/internal/outpost/ak/global.go index 4c1072082e..231f36d211 100644 --- a/internal/outpost/ak/global.go +++ b/internal/outpost/ak/global.go @@ -48,20 +48,20 @@ func doGlobalSetup(outpost api.Outpost, globalConfig *api.Config) { if globalConfig.ErrorReporting.Enabled { if !initialSetup { l.WithField("env", globalConfig.ErrorReporting.Environment).Debug("Error reporting enabled") - } - err := sentry.Init(sentry.ClientOptions{ - Dsn: globalConfig.ErrorReporting.SentryDsn, - Environment: globalConfig.ErrorReporting.Environment, - EnableTracing: true, - TracesSampler: sentryutils.SamplerFunc(float64(globalConfig.ErrorReporting.TracesSampleRate)), - Release: fmt.Sprintf("authentik@%s", constants.VERSION), - HTTPTransport: webutils.NewUserAgentTransport(constants.UserAgentOutpost(), http.DefaultTransport), - IgnoreErrors: []string{ - http.ErrAbortHandler.Error(), - }, - }) - if err != nil { - l.WithField("env", globalConfig.ErrorReporting.Environment).WithError(err).Warning("Failed to initialise sentry") + err := sentry.Init(sentry.ClientOptions{ + Dsn: globalConfig.ErrorReporting.SentryDsn, + Environment: globalConfig.ErrorReporting.Environment, + EnableTracing: true, + TracesSampler: sentryutils.SamplerFunc(float64(globalConfig.ErrorReporting.TracesSampleRate)), + Release: fmt.Sprintf("authentik@%s", constants.VERSION), + HTTPTransport: webutils.NewUserAgentTransport(constants.UserAgentOutpost(), http.DefaultTransport), + IgnoreErrors: []string{ + http.ErrAbortHandler.Error(), + }, + }) + if err != nil { + l.WithField("env", globalConfig.ErrorReporting.Environment).WithError(err).Warning("Failed to initialise sentry") + } } } diff --git a/internal/outpost/ldap/ldap.go b/internal/outpost/ldap/ldap.go index f9d4ad61bb..57d91e4ed4 100644 --- a/internal/outpost/ldap/ldap.go +++ b/internal/outpost/ldap/ldap.go @@ -26,7 +26,7 @@ type LDAPServer struct { providers []*ProviderInstance } -func NewServer(ac *ak.APIController) *LDAPServer { +func NewServer(ac *ak.APIController) ak.Outpost { ls := &LDAPServer{ log: log.WithField("logger", "authentik.outpost.ldap"), ac: ac, diff --git a/internal/outpost/proxyv2/proxyv2.go b/internal/outpost/proxyv2/proxyv2.go index 1a83081d35..690c6135f9 100644 --- a/internal/outpost/proxyv2/proxyv2.go +++ b/internal/outpost/proxyv2/proxyv2.go @@ -35,7 +35,7 @@ type ProxyServer struct { akAPI *ak.APIController } -func NewProxyServer(ac *ak.APIController) *ProxyServer { +func NewProxyServer(ac *ak.APIController) ak.Outpost { l := log.WithField("logger", "authentik.outpost.proxyv2") defaultCert, err := crypto.GenerateSelfSignedCert() if err != nil { diff --git a/internal/outpost/rac/rac.go b/internal/outpost/rac/rac.go index 1e9920305c..028ded0959 100644 --- a/internal/outpost/rac/rac.go +++ b/internal/outpost/rac/rac.go @@ -23,7 +23,7 @@ type RACServer struct { conns map[string]connection.Connection } -func NewServer(ac *ak.APIController) *RACServer { +func NewServer(ac *ak.APIController) ak.Outpost { rs := &RACServer{ log: log.WithField("logger", "authentik.outpost.rac"), ac: ac, diff --git a/internal/outpost/radius/radius.go b/internal/outpost/radius/radius.go index 2e98da0e6c..491ebff1a9 100644 --- a/internal/outpost/radius/radius.go +++ b/internal/outpost/radius/radius.go @@ -34,7 +34,7 @@ type RadiusServer struct { providers []*ProviderInstance } -func NewServer(ac *ak.APIController) *RadiusServer { +func NewServer(ac *ak.APIController) ak.Outpost { rs := &RadiusServer{ log: log.WithField("logger", "authentik.outpost.radius"), ac: ac, diff --git a/internal/utils/web/http_tracing.go b/internal/utils/web/http_tracing.go index 96c9a5211f..5ac1dbc1e8 100644 --- a/internal/utils/web/http_tracing.go +++ b/internal/utils/web/http_tracing.go @@ -2,7 +2,6 @@ package web import ( "context" - "fmt" "net/http" "github.com/getsentry/sentry-go" @@ -20,7 +19,7 @@ func NewTracingTransport(ctx context.Context, inner http.RoundTripper) *tracingT func (tt *tracingTransport) RoundTrip(r *http.Request) (*http.Response, error) { span := sentry.StartSpan(tt.ctx, "authentik.go.http_request") r.Header.Set("sentry-trace", span.ToSentryTrace()) - span.Description = fmt.Sprintf("%s %s", r.Method, r.URL.String()) + span.Description = r.Method + " " + r.URL.String() span.SetTag("url", r.URL.String()) span.SetTag("method", r.Method) defer span.Finish() From baa4deda99295ae3088fdc9eea4b32c323f79872 Mon Sep 17 00:00:00 2001 From: "Jens L." Date: Sat, 7 Jun 2025 09:31:16 +0200 Subject: [PATCH 09/47] tests/e2e: WebAuthn E2E tests (#14461) * a start of webauthn testing Signed-off-by: Jens Langhammer * separate file, just do it via localhost Signed-off-by: Jens Langhammer * remove unneeded stuff Signed-off-by: Jens Langhammer * add auth and sfe tests Signed-off-by: Jens Langhammer * auto select device challenge if only 1 Signed-off-by: Jens Langhammer * revert a thing Signed-off-by: Jens Langhammer --------- Signed-off-by: Jens Langhammer --- .../traefik_single/config-static.yaml | 2 +- .../e2e/test_flows_authenticators_webauthn.py | 97 +++++++++++++++++++ tests/e2e/test_flows_login_sfe.py | 43 ++++---- web/packages/sfe/src/index.ts | 7 +- 4 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 tests/e2e/test_flows_authenticators_webauthn.py diff --git a/tests/e2e/proxy_forward_auth/traefik_single/config-static.yaml b/tests/e2e/proxy_forward_auth/traefik_single/config-static.yaml index 6a9480f652..7006e7e16d 100644 --- a/tests/e2e/proxy_forward_auth/traefik_single/config-static.yaml +++ b/tests/e2e/proxy_forward_auth/traefik_single/config-static.yaml @@ -1,4 +1,4 @@ -# yaml-language-server: $schema=https://json.schemastore.org/traefik-v2.json +# yaml-language-server: $schema=https://json.schemastore.org/traefik-v3.json api: insecure: true debug: true diff --git a/tests/e2e/test_flows_authenticators_webauthn.py b/tests/e2e/test_flows_authenticators_webauthn.py new file mode 100644 index 0000000000..12d3fe7b39 --- /dev/null +++ b/tests/e2e/test_flows_authenticators_webauthn.py @@ -0,0 +1,97 @@ +"""test flow with WebAuthn Stage""" + +from selenium.webdriver.common.virtual_authenticator import ( + Protocol, + Transport, + VirtualAuthenticatorOptions, +) + +from authentik.blueprints.tests import apply_blueprint +from authentik.stages.authenticator_webauthn.models import ( + AuthenticatorWebAuthnStage, + WebAuthnDevice, +) +from tests.e2e.test_flows_login_sfe import login_sfe +from tests.e2e.utils import SeleniumTestCase, retry + + +class TestFlowsAuthenticatorWebAuthn(SeleniumTestCase): + """test flow with WebAuthn Stage""" + + host = "localhost" + + def register(self): + options = VirtualAuthenticatorOptions( + protocol=Protocol.CTAP2, + transport=Transport.INTERNAL, + has_resident_key=True, + has_user_verification=True, + is_user_verified=True, + ) + self.driver.add_virtual_authenticator(options) + + self.driver.get(self.url("authentik_core:if-flow", flow_slug="default-authentication-flow")) + self.login() + + self.wait_for_url(self.if_user_url("/library")) + self.assert_user(self.user) + + self.driver.get( + self.url( + "authentik_flows:configure", + stage_uuid=AuthenticatorWebAuthnStage.objects.first().stage_uuid, + ) + ) + + self.wait_for_url(self.if_user_url("/library")) + self.assertTrue(WebAuthnDevice.objects.filter(user=self.user, confirmed=True).exists()) + + @retry() + @apply_blueprint( + "default/flow-default-authentication-flow.yaml", + "default/flow-default-invalidation-flow.yaml", + ) + @apply_blueprint("default/flow-default-authenticator-webauthn-setup.yaml") + def test_webauthn_setup(self): + """Test WebAuthn setup""" + self.register() + + @retry() + @apply_blueprint( + "default/flow-default-authentication-flow.yaml", + "default/flow-default-invalidation-flow.yaml", + ) + @apply_blueprint("default/flow-default-authenticator-webauthn-setup.yaml") + def test_webauthn_authenticate(self): + """Test WebAuthn authentication""" + self.register() + self.driver.delete_all_cookies() + + self.driver.get(self.url("authentik_core:if-flow", flow_slug="default-authentication-flow")) + self.login() + + self.wait_for_url(self.if_user_url("/library")) + + self.assert_user(self.user) + + @retry() + @apply_blueprint( + "default/flow-default-authentication-flow.yaml", + "default/flow-default-invalidation-flow.yaml", + ) + @apply_blueprint("default/flow-default-authenticator-webauthn-setup.yaml") + def test_webauthn_authenticate_sfe(self): + """Test WebAuthn authentication (SFE)""" + self.register() + self.driver.delete_all_cookies() + + self.driver.get( + self.url( + "authentik_core:if-flow", + flow_slug="default-authentication-flow", + query={"sfe": True}, + ) + ) + login_sfe(self.driver, self.user) + self.wait_for_url(self.if_user_url("/library")) + self.assert_user(self.user) diff --git a/tests/e2e/test_flows_login_sfe.py b/tests/e2e/test_flows_login_sfe.py index 2200a57aa3..601aa113a8 100644 --- a/tests/e2e/test_flows_login_sfe.py +++ b/tests/e2e/test_flows_login_sfe.py @@ -4,34 +4,35 @@ from time import sleep from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys +from selenium.webdriver.remote.webdriver import WebDriver from authentik.blueprints.tests import apply_blueprint +from authentik.core.models import User from tests.e2e.utils import SeleniumTestCase, retry +def login_sfe(driver: WebDriver, user: User): + """Do entire login flow adjusted for SFE""" + flow_executor = driver.find_element(By.ID, "flow-sfe-container") + identification_stage = flow_executor.find_element(By.ID, "ident-form") + + identification_stage.find_element(By.CSS_SELECTOR, "input[name=uid_field]").click() + identification_stage.find_element(By.CSS_SELECTOR, "input[name=uid_field]").send_keys( + user.username + ) + identification_stage.find_element(By.CSS_SELECTOR, "input[name=uid_field]").send_keys( + Keys.ENTER + ) + + password_stage = flow_executor.find_element(By.ID, "password-form") + password_stage.find_element(By.CSS_SELECTOR, "input[name=password]").send_keys(user.username) + password_stage.find_element(By.CSS_SELECTOR, "input[name=password]").send_keys(Keys.ENTER) + sleep(1) + + class TestFlowsLoginSFE(SeleniumTestCase): """test default login flow""" - def login(self): - """Do entire login flow adjusted for SFE""" - flow_executor = self.driver.find_element(By.ID, "flow-sfe-container") - identification_stage = flow_executor.find_element(By.ID, "ident-form") - - identification_stage.find_element(By.CSS_SELECTOR, "input[name=uid_field]").click() - identification_stage.find_element(By.CSS_SELECTOR, "input[name=uid_field]").send_keys( - self.user.username - ) - identification_stage.find_element(By.CSS_SELECTOR, "input[name=uid_field]").send_keys( - Keys.ENTER - ) - - password_stage = flow_executor.find_element(By.ID, "password-form") - password_stage.find_element(By.CSS_SELECTOR, "input[name=password]").send_keys( - self.user.username - ) - password_stage.find_element(By.CSS_SELECTOR, "input[name=password]").send_keys(Keys.ENTER) - sleep(1) - @retry() @apply_blueprint( "default/flow-default-authentication-flow.yaml", @@ -46,6 +47,6 @@ class TestFlowsLoginSFE(SeleniumTestCase): query={"sfe": True}, ) ) - self.login() + login_sfe(self.driver, self.user) self.wait_for_url(self.if_user_url("/library")) self.assert_user(self.user) diff --git a/web/packages/sfe/src/index.ts b/web/packages/sfe/src/index.ts index 6d6372fe11..0da39dd481 100644 --- a/web/packages/sfe/src/index.ts +++ b/web/packages/sfe/src/index.ts @@ -403,6 +403,9 @@ class AuthenticatorValidateStage extends Stage } render() { + if (this.challenge.deviceChallenges.length === 1) { + this.deviceChallenge = this.challenge.deviceChallenges[0]; + } if (!this.deviceChallenge) { return this.renderChallengePicker(); } @@ -431,9 +434,7 @@ class AuthenticatorValidateStage extends Stage ${ challenges.length > 0 ? "

Select an authentication method.

" - : ` -

No compatible authentication method available

- ` + : `

No compatible authentication method available

` } ${challenges .map((challenge) => { From d54fe155113a20205338aa65a8a32f8a46303e97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 02:06:18 +0200 Subject: [PATCH 10/47] website: bump the build group across 1 directory with 9 updates (#14937) 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.3.11` | `1.3.15` | | [@rspack/binding-linux-arm64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) | `1.3.11` | `1.3.15` | | [@rspack/binding-linux-x64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) | `1.3.11` | `1.3.15` | | [@swc/core-darwin-arm64](https://github.com/swc-project/swc) | `1.11.29` | `1.11.31` | | [@swc/core-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.11.29` | `1.11.31` | | [@swc/core-linux-x64-gnu](https://github.com/swc-project/swc) | `1.11.29` | `1.11.31` | | [@swc/html-darwin-arm64](https://github.com/swc-project/swc) | `1.11.29` | `1.11.31` | | [@swc/html-linux-arm64-gnu](https://github.com/swc-project/swc) | `1.11.29` | `1.11.31` | | [@swc/html-linux-x64-gnu](https://github.com/swc-project/swc) | `1.11.29` | `1.11.31` | Updates `@rspack/binding-darwin-arm64` from 1.3.11 to 1.3.15 - [Release notes](https://github.com/web-infra-dev/rspack/releases) - [Commits](https://github.com/web-infra-dev/rspack/commits/v1.3.15/packages/rspack) Updates `@rspack/binding-linux-arm64-gnu` from 1.3.11 to 1.3.15 - [Release notes](https://github.com/web-infra-dev/rspack/releases) - [Commits](https://github.com/web-infra-dev/rspack/commits/v1.3.15/packages/rspack) Updates `@rspack/binding-linux-x64-gnu` from 1.3.11 to 1.3.15 - [Release notes](https://github.com/web-infra-dev/rspack/releases) - [Commits](https://github.com/web-infra-dev/rspack/commits/v1.3.15/packages/rspack) Updates `@swc/core-darwin-arm64` from 1.11.29 to 1.11.31 - [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.11.29...v1.11.31) Updates `@swc/core-linux-arm64-gnu` from 1.11.29 to 1.11.31 - [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.11.29...v1.11.31) Updates `@swc/core-linux-x64-gnu` from 1.11.29 to 1.11.31 - [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.11.29...v1.11.31) Updates `@swc/html-darwin-arm64` from 1.11.29 to 1.11.31 - [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.11.29...v1.11.31) Updates `@swc/html-linux-arm64-gnu` from 1.11.29 to 1.11.31 - [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.11.29...v1.11.31) Updates `@swc/html-linux-x64-gnu` from 1.11.29 to 1.11.31 - [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.11.29...v1.11.31) --- updated-dependencies: - dependency-name: "@rspack/binding-darwin-arm64" dependency-version: 1.3.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build - dependency-name: "@rspack/binding-linux-arm64-gnu" dependency-version: 1.3.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build - dependency-name: "@rspack/binding-linux-x64-gnu" dependency-version: 1.3.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build - dependency-name: "@swc/core-darwin-arm64" dependency-version: 1.11.31 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build - dependency-name: "@swc/core-linux-arm64-gnu" dependency-version: 1.11.31 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build - dependency-name: "@swc/core-linux-x64-gnu" dependency-version: 1.11.31 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build - dependency-name: "@swc/html-darwin-arm64" dependency-version: 1.11.31 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build - dependency-name: "@swc/html-linux-arm64-gnu" dependency-version: 1.11.31 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build - dependency-name: "@swc/html-linux-x64-gnu" dependency-version: 1.11.31 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- website/package-lock.json | 73 ++++++++++++++++++++------------------- website/package.json | 18 +++++----- 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/website/package-lock.json b/website/package-lock.json index 01cb83fbc9..0704dd53ac 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -19,6 +19,7 @@ "@goauthentik/docusaurus-config": "^1.1.0", "@goauthentik/tsconfig": "^1.0.4", "@mdx-js/react": "^3.1.0", + "@swc/html-linux-x64-gnu": "1.11.31", "clsx": "^2.1.1", "docusaurus-plugin-openapi-docs": "^4.4.0", "docusaurus-theme-openapi-docs": "^4.4.0", @@ -60,15 +61,15 @@ "node": ">=22.14.0" }, "optionalDependencies": { - "@rspack/binding-darwin-arm64": "1.3.11", - "@rspack/binding-linux-arm64-gnu": "1.3.11", - "@rspack/binding-linux-x64-gnu": "1.3.11", - "@swc/core-darwin-arm64": "1.11.29", - "@swc/core-linux-arm64-gnu": "1.11.29", - "@swc/core-linux-x64-gnu": "1.11.29", - "@swc/html-darwin-arm64": "1.11.29", - "@swc/html-linux-arm64-gnu": "1.11.29", - "@swc/html-linux-x64-gnu": "1.11.29", + "@rspack/binding-darwin-arm64": "1.3.15", + "@rspack/binding-linux-arm64-gnu": "1.3.15", + "@rspack/binding-linux-x64-gnu": "1.3.15", + "@swc/core-darwin-arm64": "1.11.31", + "@swc/core-linux-arm64-gnu": "1.11.31", + "@swc/core-linux-x64-gnu": "1.11.31", + "@swc/html-darwin-arm64": "1.11.31", + "@swc/html-linux-arm64-gnu": "1.11.31", + "@swc/html-linux-x64-gnu": "1.11.31", "lightningcss-darwin-arm64": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1" @@ -5036,9 +5037,9 @@ } }, "node_modules/@rspack/binding-darwin-arm64": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.3.11.tgz", - "integrity": "sha512-sGoFDXYNinubhEiPSjtA/ua3qhMj6VVBPTSDvprZj+MT18YV7tQQtwBpm+8sbqJ1P5y+a3mzsP3IphRWyIQyXw==", + "version": "1.3.15", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.3.15.tgz", + "integrity": "sha512-f+DnVRENRdVe+ufpZeqTtWAUDSTnP48jVo7x9KWsXf8XyJHUi+eHKEPrFoy1HvL1/k5yJ3HVnFBh1Hb9cNIwSg==", "cpu": [ "arm64" ], @@ -5063,9 +5064,9 @@ "peer": true }, "node_modules/@rspack/binding-linux-arm64-gnu": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.3.11.tgz", - "integrity": "sha512-NIOaIfYUmJs1XL4lbGVtcMm1KlA/6ZR6oAbs2ekofKXtJYAFQgnLTf7ZFmIwVjS0mP78BmeSNcIM6pd2w5id4w==", + "version": "1.3.15", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.3.15.tgz", + "integrity": "sha512-D/YjYk9snKvYm1Elotq8/GsEipB4ZJWVv/V8cZ+ohhFNOPzygENi6JfyI06TryBTQiN0/JDZqt/S9RaWBWnMqw==", "cpu": [ "arm64" ], @@ -5090,9 +5091,9 @@ "peer": true }, "node_modules/@rspack/binding-linux-x64-gnu": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.3.11.tgz", - "integrity": "sha512-k3OyvLneX2ZeL8z/OzPojpImqy6PgqKJD+NtOvcr/TgbgADHZ3xQttf6B2X+qnZMAgOZ+RTeTkOFrvsg9AEKmA==", + "version": "1.3.15", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.3.15.tgz", + "integrity": "sha512-qGB8ucHklrzNg6lsAS36VrBsCbOw0acgpQNqTE5cuHWrp1Pu3GFTRiFEogenxEmzoRbohMZt0Ev5grivrcgKBQ==", "cpu": [ "x64" ], @@ -5591,9 +5592,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.11.29", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.11.29.tgz", - "integrity": "sha512-whsCX7URzbuS5aET58c75Dloby3Gtj/ITk2vc4WW6pSDQKSPDuONsIcZ7B2ng8oz0K6ttbi4p3H/PNPQLJ4maQ==", + "version": "1.11.31", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.11.31.tgz", + "integrity": "sha512-NTEaYOts0OGSbJZc0O74xsji+64JrF1stmBii6D5EevWEtrY4wlZhm8SiP/qPrOB+HqtAihxWIukWkP2aSdGSQ==", "cpu": [ "arm64" ], @@ -5639,9 +5640,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.11.29", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.11.29.tgz", - "integrity": "sha512-sLoaciOgUKQF1KX9T6hPGzvhOQaJn+3DHy4LOHeXhQqvBgr+7QcZ+hl4uixPKTzxk6hy6Hb0QOvQEdBAAR1gXw==", + "version": "1.11.31", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.11.31.tgz", + "integrity": "sha512-T+vGw9aPE1YVyRxRr1n7NAdkbgzBzrXCCJ95xAZc/0+WUwmL77Z+js0J5v1KKTRxw4FvrslNCOXzMWrSLdwPSA==", "cpu": [ "arm64" ], @@ -5671,9 +5672,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.11.29", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.11.29.tgz", - "integrity": "sha512-i62vBVoPaVe9A3mc6gJG07n0/e7FVeAvdD9uzZTtGLiuIfVfIBta8EMquzvf+POLycSk79Z6lRhGPZPJPYiQaA==", + "version": "1.11.31", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.11.31.tgz", + "integrity": "sha512-DDVE0LZcXOWwOqFU1Xi7gdtiUg3FHA0vbGb3trjWCuI1ZtDZHEQYL4M3/2FjqKZtIwASrDvO96w91okZbXhvMg==", "cpu": [ "x64" ], @@ -5829,9 +5830,9 @@ } }, "node_modules/@swc/html-darwin-arm64": { - "version": "1.11.29", - "resolved": "https://registry.npmjs.org/@swc/html-darwin-arm64/-/html-darwin-arm64-1.11.29.tgz", - "integrity": "sha512-q53kn/HI0n/+pecsOB2gxqITbRAhtBG7VI520SIWuCGXHPsTQ/1VOrhLMNvyfw1xVhRyFal7BpAvfGUORCl0sw==", + "version": "1.11.31", + "resolved": "https://registry.npmjs.org/@swc/html-darwin-arm64/-/html-darwin-arm64-1.11.31.tgz", + "integrity": "sha512-/BZ7KLfkua568iNNnLAlxa88P7gBiouZ+aW7LFcqfv62ueCpjLY7YSUXcVcb8bAoGwDcB+fO2xMYz5ABHcaFZg==", "cpu": [ "arm64" ], @@ -5877,9 +5878,9 @@ } }, "node_modules/@swc/html-linux-arm64-gnu": { - "version": "1.11.29", - "resolved": "https://registry.npmjs.org/@swc/html-linux-arm64-gnu/-/html-linux-arm64-gnu-1.11.29.tgz", - "integrity": "sha512-seo+lCiBUggTR9NsHE4qVC+7+XIfLHK7yxWiIsXb8nNAXDcqVZ0Rxv8O1Y1GTeJfUlcCt1koahCG2AeyWpYFBg==", + "version": "1.11.31", + "resolved": "https://registry.npmjs.org/@swc/html-linux-arm64-gnu/-/html-linux-arm64-gnu-1.11.31.tgz", + "integrity": "sha512-3rbfgMDGeLx52iFOCGaeeK8IEj1fT7gsvTWfXACJ4ns7MPupz6v3dVoGCIuzh0yHGAZPY0QL1iVAYjPLg8TrWw==", "cpu": [ "arm64" ], @@ -5909,9 +5910,9 @@ } }, "node_modules/@swc/html-linux-x64-gnu": { - "version": "1.11.29", - "resolved": "https://registry.npmjs.org/@swc/html-linux-x64-gnu/-/html-linux-x64-gnu-1.11.29.tgz", - "integrity": "sha512-34tSms5TkRUCr+J6uuSE/11ECcfIpp5R1ODuIgxZRUd/u88pQGKzLVNLWGPLw4b3cZSjnAn+PFJl7BtaYl0UyQ==", + "version": "1.11.31", + "resolved": "https://registry.npmjs.org/@swc/html-linux-x64-gnu/-/html-linux-x64-gnu-1.11.31.tgz", + "integrity": "sha512-6w9yZ1W23y17Y8NLTqy+efaAHjnqumSdn8PdCmBvMxwFRwjo9dNkkcDJsTZ5EERBMH+DnDbVR+HkuNypd0Y7Gw==", "cpu": [ "x64" ], diff --git a/website/package.json b/website/package.json index a925224ad4..30ce319d40 100644 --- a/website/package.json +++ b/website/package.json @@ -72,15 +72,15 @@ "typescript-eslint": "^8.32.1" }, "optionalDependencies": { - "@rspack/binding-darwin-arm64": "1.3.11", - "@rspack/binding-linux-arm64-gnu": "1.3.11", - "@rspack/binding-linux-x64-gnu": "1.3.11", - "@swc/core-darwin-arm64": "1.11.29", - "@swc/core-linux-arm64-gnu": "1.11.29", - "@swc/core-linux-x64-gnu": "1.11.29", - "@swc/html-darwin-arm64": "1.11.29", - "@swc/html-linux-arm64-gnu": "1.11.29", - "@swc/html-linux-x64-gnu": "1.11.29", + "@rspack/binding-darwin-arm64": "1.3.15", + "@rspack/binding-linux-arm64-gnu": "1.3.15", + "@rspack/binding-linux-x64-gnu": "1.3.15", + "@swc/core-darwin-arm64": "1.11.31", + "@swc/core-linux-arm64-gnu": "1.11.31", + "@swc/core-linux-x64-gnu": "1.11.31", + "@swc/html-darwin-arm64": "1.11.31", + "@swc/html-linux-arm64-gnu": "1.11.31", + "@swc/html-linux-x64-gnu": "1.11.31", "lightningcss-darwin-arm64": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1" From 11666f56585d02f27f4cf7d1c330bbde49afdfe3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 02:09:41 +0200 Subject: [PATCH 11/47] core: bump golang.org/x/sync from 0.14.0 to 0.15.0 (#14936) Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.14.0 to 0.15.0. - [Commits](https://github.com/golang/sync/compare/v0.14.0...v0.15.0) --- updated-dependencies: - dependency-name: golang.org/x/sync dependency-version: 0.15.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f854e7b1ec..f00e9bf14a 100644 --- a/go.mod +++ b/go.mod @@ -31,7 +31,7 @@ require ( goauthentik.io/api/v3 v3.2025060.1 golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab golang.org/x/oauth2 v0.30.0 - golang.org/x/sync v0.14.0 + golang.org/x/sync v0.15.0 gopkg.in/yaml.v2 v2.4.0 layeh.com/radius v0.0.0-20210819152912-ad72663a72ab ) diff --git a/go.sum b/go.sum index 2d1625e2c6..dd4d6380fe 100644 --- a/go.sum +++ b/go.sum @@ -382,8 +382,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= -golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= From 355f302cb734cde6d9b30f0a8a46a85dfd581edb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 02:10:16 +0200 Subject: [PATCH 12/47] lifecycle/aws: bump aws-cdk from 2.1017.1 to 2.1018.0 in /lifecycle/aws (#14939) Bumps [aws-cdk](https://github.com/aws/aws-cdk-cli/tree/HEAD/packages/aws-cdk) from 2.1017.1 to 2.1018.0. - [Release notes](https://github.com/aws/aws-cdk-cli/releases) - [Commits](https://github.com/aws/aws-cdk-cli/commits/aws-cdk@v2.1018.0/packages/aws-cdk) --- updated-dependencies: - dependency-name: aws-cdk dependency-version: 2.1018.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- lifecycle/aws/package-lock.json | 10 +++++----- lifecycle/aws/package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lifecycle/aws/package-lock.json b/lifecycle/aws/package-lock.json index d36ba19a70..701cceeaf0 100644 --- a/lifecycle/aws/package-lock.json +++ b/lifecycle/aws/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "license": "MIT", "devDependencies": { - "aws-cdk": "^2.1017.1", + "aws-cdk": "^2.1018.0", "cross-env": "^7.0.3" }, "engines": { @@ -17,16 +17,16 @@ } }, "node_modules/aws-cdk": { - "version": "2.1017.1", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1017.1.tgz", - "integrity": "sha512-KtDdkMhfVjDeexjpMrVoSlz2mTYI5BE/KotvJ7iFbZy1G0nkpW1ImZ54TdBefeeFmZ+8DAjU3I6nUFtymyOI1A==", + "version": "2.1018.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1018.0.tgz", + "integrity": "sha512-sppVsNtFJTW4wawS/PBudHCSNHb8xwaZ2WX1mpsfwaPNyTWm0eSUVJsRbRiRBu9O/Us8pgrd4woUjfM1lgD7Kw==", "dev": true, "license": "Apache-2.0", "bin": { "cdk": "bin/cdk" }, "engines": { - "node": ">= 14.15.0" + "node": ">= 18.0.0" }, "optionalDependencies": { "fsevents": "2.3.2" diff --git a/lifecycle/aws/package.json b/lifecycle/aws/package.json index 839d552639..d6c415c9af 100644 --- a/lifecycle/aws/package.json +++ b/lifecycle/aws/package.json @@ -10,7 +10,7 @@ "node": ">=20" }, "devDependencies": { - "aws-cdk": "^2.1017.1", + "aws-cdk": "^2.1018.0", "cross-env": "^7.0.3" } } From 8a9f6fb1cef014b0ce94e829a8083dd428e7aac5 Mon Sep 17 00:00:00 2001 From: "authentik-automation[bot]" <135050075+authentik-automation[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 02:11:11 +0200 Subject: [PATCH 13/47] core, web: update translations (#14954) 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> --- locale/pt_PT/LC_MESSAGES/django.mo | Bin 35802 -> 47382 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/locale/pt_PT/LC_MESSAGES/django.mo b/locale/pt_PT/LC_MESSAGES/django.mo index f2bbdb2276c6e32e4df88640de4e13319dbc637d..55d4b4667bff43ea659c376e6b3d1040442bd1be 100644 GIT binary patch literal 47382 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 Y8`=hfhOMc09vh_2JT|IbmAJU}U!=A$5C8xG From b4d26d5092e925a4408dedd3900603c91b22bb1d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 02:11:29 +0200 Subject: [PATCH 14/47] web: bump @sentry/browser from 9.24.0 to 9.25.1 in /web in the sentry group across 1 directory (#14865) 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 9.24.0 to 9.25.1 - [Release notes](https://github.com/getsentry/sentry-javascript/releases) - [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-javascript/compare/9.24.0...9.25.1) --- updated-dependencies: - dependency-name: "@sentry/browser" dependency-version: 9.25.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: sentry ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 60 +++++++++++++++++++++---------------------- web/package.json | 2 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 6d238bc6bb..7ec672e680 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -31,7 +31,7 @@ "@open-wc/lit-helpers": "^0.7.0", "@patternfly/elements": "^4.1.0", "@patternfly/patternfly": "^4.224.2", - "@sentry/browser": "^9.24.0", + "@sentry/browser": "^9.27.0", "@spotlightjs/spotlight": "^2.13.3", "@webcomponents/webcomponentsjs": "^2.8.0", "base64-js": "^1.5.1", @@ -4470,75 +4470,75 @@ "dev": true }, "node_modules/@sentry-internal/browser-utils": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.24.0.tgz", - "integrity": "sha512-fWIrHyui8KKufnbqhGyDvvr+u9wiOEEzxXEjs/CKp+6fa+jej6Mk8K+su1f/mz7R3HVzhxvht/gZ+y193uK4qw==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-9.27.0.tgz", + "integrity": "sha512-SJa7f6Ct1BzP8rWEomnshSGN1CmT+axNKvT+StrbFPD6AyHnYfFLJpKgc2iToIJHB/pmeuOI9dUwqtzVx+5nSw==", "license": "MIT", "dependencies": { - "@sentry/core": "9.24.0" + "@sentry/core": "9.27.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/feedback": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.24.0.tgz", - "integrity": "sha512-Z9jQqKzRppwAEqiytLWNV8JOo52vlxcSGz52FjKx3KXG75PXwk0M3sBXh762WoGLisUIRLTp8LOk6304L/O8dg==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-9.27.0.tgz", + "integrity": "sha512-e7L8eG0y63RulN352lmafoCCfQGg4jLVT8YLx6096eWu/YKLkgmVpgi8livsT5WREnH+HB+iFSrejOwK7cRkhw==", "license": "MIT", "dependencies": { - "@sentry/core": "9.24.0" + "@sentry/core": "9.27.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.24.0.tgz", - "integrity": "sha512-312wMPeQI8K2vO/lA/CF6Uv5UReoZC7RarsNUJEoOKa9Bq1BXWUq929oTHzu/2NDv194H2u3eqSGsSp6xiuKTw==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-9.27.0.tgz", + "integrity": "sha512-n2kO1wOfCG7GxkMAqbYYkpgTqJM5tuVLdp0JuNCqTOLTXWvw6svWGaYKlYpKUgsK9X/GDzJYSXZmfe+Dbg+FJQ==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.24.0", - "@sentry/core": "9.24.0" + "@sentry-internal/browser-utils": "9.27.0", + "@sentry/core": "9.27.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.24.0.tgz", - "integrity": "sha512-506RdDF6iE8hMyzpzp9Vc0GM7kELxxs7UCoi/6KpvXFftcydWI3S2bru8dEZsxVoKh2hdle6SpbNgl+iPI0DSQ==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-9.27.0.tgz", + "integrity": "sha512-44rVSt3LCH6qePYRQrl4WUBwnkOk9dzinmnKmuwRksEdDOkVq5KBRhi/IDr7omwSpX8C+KrX5alfKhOx1cP0gQ==", "license": "MIT", "dependencies": { - "@sentry-internal/replay": "9.24.0", - "@sentry/core": "9.24.0" + "@sentry-internal/replay": "9.27.0", + "@sentry/core": "9.27.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry/browser": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.24.0.tgz", - "integrity": "sha512-RP+27/owvIqD4J0TibIHK1UcA7iObxLOXBEilDKjaJOZMLhv3JkpU8A+UI9pFzEYqeIGVDDaBzYgbCHrLWcoCA==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-9.27.0.tgz", + "integrity": "sha512-geR3lhRJOmUQqi1WgovLSYcD/f66zYnctdnDEa7j1BW2XIB1nlTJn0mpYyAHghXKkUN/pBpp1Z+Jk0XlVwFYVg==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "9.24.0", - "@sentry-internal/feedback": "9.24.0", - "@sentry-internal/replay": "9.24.0", - "@sentry-internal/replay-canvas": "9.24.0", - "@sentry/core": "9.24.0" + "@sentry-internal/browser-utils": "9.27.0", + "@sentry-internal/feedback": "9.27.0", + "@sentry-internal/replay": "9.27.0", + "@sentry-internal/replay-canvas": "9.27.0", + "@sentry/core": "9.27.0" }, "engines": { "node": ">=18" } }, "node_modules/@sentry/core": { - "version": "9.24.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.24.0.tgz", - "integrity": "sha512-uRWrB4Y49ZOWcDLCXqdjd2Fs6Onill0GQI+JgXMw7wa+i03+QRiQvUAUyde8O62jR4dvP3GDo9PDWnDNhi3z5A==", + "version": "9.27.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.27.0.tgz", + "integrity": "sha512-Zb2SSAdWXQjTem+sVWrrAq9L6YYfxyoTwtapaE6C6qZBR5C8Uak0wcYww8StaCFH7dDA/PSW+VxOwjNXocrQHQ==", "license": "MIT", "engines": { "node": ">=18" diff --git a/web/package.json b/web/package.json index 56a332c584..f7d1410d6f 100644 --- a/web/package.json +++ b/web/package.json @@ -102,7 +102,7 @@ "@open-wc/lit-helpers": "^0.7.0", "@patternfly/elements": "^4.1.0", "@patternfly/patternfly": "^4.224.2", - "@sentry/browser": "^9.24.0", + "@sentry/browser": "^9.27.0", "@spotlightjs/spotlight": "^2.13.3", "@webcomponents/webcomponentsjs": "^2.8.0", "base64-js": "^1.5.1", From 0b71aa43d17f0b06ea138fd7d5e802f390b90fe2 Mon Sep 17 00:00:00 2001 From: "authentik-automation[bot]" <135050075+authentik-automation[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:01:25 +0200 Subject: [PATCH 15/47] core, web: update translations (#14962) 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> From e1c47c0f00d714cfc903c1183ca0a8e8a6068eed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:03:49 +0200 Subject: [PATCH 16/47] website: bump @typescript-eslint/parser from 8.32.1 to 8.33.1 in /website (#14828) * website: bump @typescript-eslint/parser in /website Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.32.1 to 8.33.1. - [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.33.1/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.33.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * update dependabot groups for website Signed-off-by: Jens Langhammer --------- Signed-off-by: dependabot[bot] Signed-off-by: Jens Langhammer Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jens Langhammer --- .github/dependabot.yml | 7 ++ website/package-lock.json | 212 ++++++++++++++++++++++++++++++++++++-- website/package.json | 2 +- 3 files changed, 212 insertions(+), 9 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3842325578..267567d563 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -100,6 +100,13 @@ updates: goauthentik: patterns: - "@goauthentik/*" + eslint: + patterns: + - "@eslint/*" + - "@typescript-eslint/*" + - "eslint-*" + - "eslint" + - "typescript-eslint" - package-ecosystem: npm directory: "/lifecycle/aws" schedule: diff --git a/website/package-lock.json b/website/package-lock.json index 0704dd53ac..47a0921c37 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -47,7 +47,7 @@ "@types/react": "^18.3.22", "@types/semver": "^7.7.0", "@typescript-eslint/eslint-plugin": "^8.8.0", - "@typescript-eslint/parser": "^8.8.0", + "@typescript-eslint/parser": "^8.33.1", "cross-env": "^7.0.3", "eslint": "^9.11.1", "fast-glob": "^3.3.3", @@ -6871,16 +6871,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.1.tgz", - "integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.1.tgz", + "integrity": "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.32.1", - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/typescript-estree": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.1", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", "debug": "^4.3.4" }, "engines": { @@ -6895,6 +6895,160 @@ "typescript": ">=4.8.4 <5.9.0" } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", + "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", + "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.33.1", + "@typescript-eslint/tsconfig-utils": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", + "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.33.1", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.1.tgz", + "integrity": "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.33.1", + "@typescript-eslint/types": "^8.33.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, + "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "8.32.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.1.tgz", @@ -6913,6 +7067,23 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.1.tgz", + "integrity": "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" + } + }, "node_modules/@typescript-eslint/type-utils": { "version": "8.32.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.32.1.tgz", @@ -26368,6 +26539,31 @@ "typescript": ">=4.8.4 <5.9.0" } }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { + "version": "8.32.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.1.tgz", + "integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.32.1", + "@typescript-eslint/types": "8.32.1", + "@typescript-eslint/typescript-estree": "8.32.1", + "@typescript-eslint/visitor-keys": "8.32.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" + } + }, "node_modules/ufo": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", diff --git a/website/package.json b/website/package.json index 30ce319d40..79f969b674 100644 --- a/website/package.json +++ b/website/package.json @@ -61,7 +61,7 @@ "@types/react": "^18.3.22", "@types/semver": "^7.7.0", "@typescript-eslint/eslint-plugin": "^8.8.0", - "@typescript-eslint/parser": "^8.8.0", + "@typescript-eslint/parser": "^8.33.1", "cross-env": "^7.0.3", "eslint": "^9.11.1", "fast-glob": "^3.3.3", From 891907390b37ccab93525b8a3493b1c56fd81253 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:14:20 +0200 Subject: [PATCH 17/47] website: bump the eslint group in /website with 4 updates (#14967) Bumps the eslint group in /website with 4 updates: [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js), [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin), [eslint](https://github.com/eslint/eslint) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint). Updates `@eslint/js` from 9.27.0 to 9.28.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/commits/v9.28.0/packages/js) Updates `@typescript-eslint/eslint-plugin` from 8.32.1 to 8.33.1 - [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.33.1/packages/eslint-plugin) Updates `eslint` from 9.27.0 to 9.28.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v9.27.0...v9.28.0) Updates `typescript-eslint` from 8.32.1 to 8.33.1 - [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.33.1/packages/typescript-eslint) --- updated-dependencies: - dependency-name: "@eslint/js" dependency-version: 9.28.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: eslint - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.33.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: eslint - dependency-name: eslint dependency-version: 9.28.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: eslint - dependency-name: typescript-eslint dependency-version: 8.33.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: eslint ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- website/package-lock.json | 266 ++++++++------------------------------ website/package.json | 8 +- 2 files changed, 59 insertions(+), 215 deletions(-) diff --git a/website/package-lock.json b/website/package-lock.json index 47a0921c37..173ddabf26 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -19,7 +19,6 @@ "@goauthentik/docusaurus-config": "^1.1.0", "@goauthentik/tsconfig": "^1.0.4", "@mdx-js/react": "^3.1.0", - "@swc/html-linux-x64-gnu": "1.11.31", "clsx": "^2.1.1", "docusaurus-plugin-openapi-docs": "^4.4.0", "docusaurus-theme-openapi-docs": "^4.4.0", @@ -36,7 +35,7 @@ "@docusaurus/module-type-aliases": "^3.7.0", "@docusaurus/tsconfig": "^3.7.0", "@docusaurus/types": "^3.7.0", - "@eslint/js": "^9.27.0", + "@eslint/js": "^9.28.0", "@goauthentik/eslint-config": "^1.0.5", "@goauthentik/prettier-config": "^1.0.5", "@goauthentik/tsconfig": "^1.0.4", @@ -46,16 +45,16 @@ "@types/postman-collection": "^3.5.11", "@types/react": "^18.3.22", "@types/semver": "^7.7.0", - "@typescript-eslint/eslint-plugin": "^8.8.0", + "@typescript-eslint/eslint-plugin": "^8.33.1", "@typescript-eslint/parser": "^8.33.1", "cross-env": "^7.0.3", - "eslint": "^9.11.1", + "eslint": "^9.28.0", "fast-glob": "^3.3.3", "npm-run-all": "^4.1.5", "prettier": "^3.5.3", "prettier-plugin-packagejson": "^2.5.14", "typescript": "^5.8.3", - "typescript-eslint": "^8.32.1" + "typescript-eslint": "^8.33.1" }, "engines": { "node": ">=22.14.0" @@ -4308,9 +4307,9 @@ "license": "MIT" }, "node_modules/@eslint/js": { - "version": "9.27.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.27.0.tgz", - "integrity": "sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==", + "version": "9.28.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.28.0.tgz", + "integrity": "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==", "devOptional": true, "license": "MIT", "engines": { @@ -6831,17 +6830,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.1.tgz", - "integrity": "sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.1.tgz", + "integrity": "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.32.1", - "@typescript-eslint/type-utils": "8.32.1", - "@typescript-eslint/utils": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.1", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/type-utils": "8.33.1", + "@typescript-eslint/utils": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -6855,7 +6854,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "@typescript-eslint/parser": "^8.33.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } @@ -6895,124 +6894,6 @@ "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", - "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", - "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", - "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.33.1", - "@typescript-eslint/tsconfig-utils": "8.33.1", - "@typescript-eslint/types": "8.33.1", - "@typescript-eslint/visitor-keys": "8.33.1", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", - "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.33.1", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/project-service": { "version": "8.33.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.1.tgz", @@ -7035,29 +6916,15 @@ "typescript": ">=4.8.4 <5.9.0" } }, - "node_modules/@typescript-eslint/project-service/node_modules/@typescript-eslint/types": { - "version": "8.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", - "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.1.tgz", - "integrity": "sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", + "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.1" + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7085,14 +6952,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.32.1.tgz", - "integrity": "sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.1.tgz", + "integrity": "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.32.1", - "@typescript-eslint/utils": "8.32.1", + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/utils": "8.33.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -7109,9 +6976,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.32.1.tgz", - "integrity": "sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", "dev": true, "license": "MIT", "engines": { @@ -7123,14 +6990,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.1.tgz", - "integrity": "sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", + "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.1", + "@typescript-eslint/project-service": "8.33.1", + "@typescript-eslint/tsconfig-utils": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -7176,16 +7045,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.32.1.tgz", - "integrity": "sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.1.tgz", + "integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.32.1", - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/typescript-estree": "8.32.1" + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7200,13 +7069,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.1.tgz", - "integrity": "sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", + "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.32.1", + "@typescript-eslint/types": "8.33.1", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -12348,9 +12217,9 @@ } }, "node_modules/eslint": { - "version": "9.27.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.27.0.tgz", - "integrity": "sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==", + "version": "9.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.28.0.tgz", + "integrity": "sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -12360,7 +12229,7 @@ "@eslint/config-helpers": "^0.2.1", "@eslint/core": "^0.14.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.27.0", + "@eslint/js": "9.28.0", "@eslint/plugin-kit": "^0.3.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -26517,40 +26386,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.32.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.32.1.tgz", - "integrity": "sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.33.1.tgz", + "integrity": "sha512-AgRnV4sKkWOiZ0Kjbnf5ytTJXMUZQ0qhSVdQtDNYLPLnjsATEYhaO94GlRQwi4t4gO8FfjM6NnikHeKjUm8D7A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.32.1", - "@typescript-eslint/parser": "8.32.1", - "@typescript-eslint/utils": "8.32.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { - "version": "8.32.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.1.tgz", - "integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.32.1", - "@typescript-eslint/types": "8.32.1", - "@typescript-eslint/typescript-estree": "8.32.1", - "@typescript-eslint/visitor-keys": "8.32.1", - "debug": "^4.3.4" + "@typescript-eslint/eslint-plugin": "8.33.1", + "@typescript-eslint/parser": "8.33.1", + "@typescript-eslint/utils": "8.33.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" diff --git a/website/package.json b/website/package.json index 79f969b674..eb38ff06dc 100644 --- a/website/package.json +++ b/website/package.json @@ -50,7 +50,7 @@ "@docusaurus/module-type-aliases": "^3.7.0", "@docusaurus/tsconfig": "^3.7.0", "@docusaurus/types": "^3.7.0", - "@eslint/js": "^9.27.0", + "@eslint/js": "^9.28.0", "@goauthentik/eslint-config": "^1.0.5", "@goauthentik/prettier-config": "^1.0.5", "@goauthentik/tsconfig": "^1.0.4", @@ -60,16 +60,16 @@ "@types/postman-collection": "^3.5.11", "@types/react": "^18.3.22", "@types/semver": "^7.7.0", - "@typescript-eslint/eslint-plugin": "^8.8.0", + "@typescript-eslint/eslint-plugin": "^8.33.1", "@typescript-eslint/parser": "^8.33.1", "cross-env": "^7.0.3", - "eslint": "^9.11.1", + "eslint": "^9.28.0", "fast-glob": "^3.3.3", "npm-run-all": "^4.1.5", "prettier": "^3.5.3", "prettier-plugin-packagejson": "^2.5.14", "typescript": "^5.8.3", - "typescript-eslint": "^8.32.1" + "typescript-eslint": "^8.33.1" }, "optionalDependencies": { "@rspack/binding-darwin-arm64": "1.3.15", From a0b1327456feb7dfe341e7d5dbf38431454f6b26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:26:02 +0200 Subject: [PATCH 18/47] web: bump the eslint group across 2 directories with 3 updates (#14833) 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.33.0 to 8.33.1 - [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.33.1/packages/typescript-eslint) Updates `@typescript-eslint/eslint-plugin` from 8.33.0 to 8.33.1 - [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.33.1/packages/eslint-plugin) Updates `@typescript-eslint/parser` from 8.33.0 to 8.33.1 - [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.33.1/packages/parser) Updates `typescript-eslint` from 8.33.0 to 8.33.1 - [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.33.1/packages/typescript-eslint) Updates `@typescript-eslint/eslint-plugin` from 8.33.0 to 8.33.1 - [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.33.1/packages/eslint-plugin) Updates `@typescript-eslint/parser` from 8.33.0 to 8.33.1 - [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.33.1/packages/parser) --- updated-dependencies: - dependency-name: typescript-eslint dependency-version: 8.33.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: eslint - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.33.1 dependency-type: indirect update-type: version-update:semver-patch dependency-group: eslint - dependency-name: "@typescript-eslint/parser" dependency-version: 8.33.1 dependency-type: indirect update-type: version-update:semver-patch dependency-group: eslint - dependency-name: typescript-eslint dependency-version: 8.33.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: eslint - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.33.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: eslint - dependency-name: "@typescript-eslint/parser" dependency-version: 8.33.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: eslint ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- packages/eslint-config/package-lock.json | 121 +++++++++++----------- web/package-lock.json | 123 ++++++++++++----------- web/package.json | 2 +- 3 files changed, 126 insertions(+), 120 deletions(-) diff --git a/packages/eslint-config/package-lock.json b/packages/eslint-config/package-lock.json index e625ce94f1..6e8204a16a 100644 --- a/packages/eslint-config/package-lock.json +++ b/packages/eslint-config/package-lock.json @@ -576,17 +576,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.0.tgz", - "integrity": "sha512-CACyQuqSHt7ma3Ns601xykeBK/rDeZa3w6IS6UtMQbixO5DWy+8TilKkviGDH6jtWCo8FGRKEK5cLLkPvEammQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.1.tgz", + "integrity": "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.33.0", - "@typescript-eslint/type-utils": "8.33.0", - "@typescript-eslint/utils": "8.33.0", - "@typescript-eslint/visitor-keys": "8.33.0", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/type-utils": "8.33.1", + "@typescript-eslint/utils": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -600,7 +600,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.33.0", + "@typescript-eslint/parser": "^8.33.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } @@ -616,16 +616,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.0.tgz", - "integrity": "sha512-JaehZvf6m0yqYp34+RVnihBAChkqeH+tqqhS0GuX1qgPpwLvmTPheKEs6OeCK6hVJgXZHJ2vbjnC9j119auStQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.1.tgz", + "integrity": "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.33.0", - "@typescript-eslint/types": "8.33.0", - "@typescript-eslint/typescript-estree": "8.33.0", - "@typescript-eslint/visitor-keys": "8.33.0", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", "debug": "^4.3.4" }, "engines": { @@ -641,14 +641,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.0.tgz", - "integrity": "sha512-d1hz0u9l6N+u/gcrk6s6gYdl7/+pp8yHheRTqP6X5hVDKALEaTn8WfGiit7G511yueBEL3OpOEpD+3/MBdoN+A==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.1.tgz", + "integrity": "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.33.0", - "@typescript-eslint/types": "^8.33.0", + "@typescript-eslint/tsconfig-utils": "^8.33.1", + "@typescript-eslint/types": "^8.33.1", "debug": "^4.3.4" }, "engines": { @@ -657,17 +657,20 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.0.tgz", - "integrity": "sha512-LMi/oqrzpqxyO72ltP+dBSP6V0xiUb4saY7WLtxSfiNEBI8m321LLVFU9/QDJxjDQG9/tjSqKz/E3380TEqSTw==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", + "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.33.0", - "@typescript-eslint/visitor-keys": "8.33.0" + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -678,9 +681,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.0.tgz", - "integrity": "sha512-sTkETlbqhEoiFmGr1gsdq5HyVbSOF0145SYDJ/EQmXHtKViCaGvnyLqWFFHtEXoS0J1yU8Wyou2UGmgW88fEug==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.1.tgz", + "integrity": "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==", "dev": true, "license": "MIT", "engines": { @@ -695,14 +698,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.0.tgz", - "integrity": "sha512-lScnHNCBqL1QayuSrWeqAL5GmqNdVUQAAMTaCwdYEdWfIrSrOGzyLGRCHXcCixa5NK6i5l0AfSO2oBSjCjf4XQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.1.tgz", + "integrity": "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.33.0", - "@typescript-eslint/utils": "8.33.0", + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/utils": "8.33.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -719,9 +722,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.0.tgz", - "integrity": "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", "dev": true, "license": "MIT", "engines": { @@ -733,16 +736,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.0.tgz", - "integrity": "sha512-vegY4FQoB6jL97Tu/lWRsAiUUp8qJTqzAmENH2k59SJhw0Th1oszb9Idq/FyyONLuNqT1OADJPXfyUNOR8SzAQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", + "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.33.0", - "@typescript-eslint/tsconfig-utils": "8.33.0", - "@typescript-eslint/types": "8.33.0", - "@typescript-eslint/visitor-keys": "8.33.0", + "@typescript-eslint/project-service": "8.33.1", + "@typescript-eslint/tsconfig-utils": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -801,16 +804,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.0.tgz", - "integrity": "sha512-lPFuQaLA9aSNa7D5u2EpRiqdAUhzShwGg/nhpBlc4GR6kcTABttCuyjFs8BcEZ8VWrjCBof/bePhP3Q3fS+Yrw==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.1.tgz", + "integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.33.0", - "@typescript-eslint/types": "8.33.0", - "@typescript-eslint/typescript-estree": "8.33.0" + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -825,13 +828,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.0.tgz", - "integrity": "sha512-7RW7CMYoskiz5OOGAWjJFxgb7c5UNjTG292gYhWeOAcFmYCtVCSqjqSBj5zMhxbXo2JOW95YYrUWJfU0zrpaGQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", + "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.33.0", + "@typescript-eslint/types": "8.33.1", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -4032,15 +4035,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.33.0.tgz", - "integrity": "sha512-5YmNhF24ylCsvdNW2oJwMzTbaeO4bg90KeGtMjUw0AGtHksgEPLRTUil+coHwCfiu4QjVJFnjp94DmU6zV7DhQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.33.1.tgz", + "integrity": "sha512-AgRnV4sKkWOiZ0Kjbnf5ytTJXMUZQ0qhSVdQtDNYLPLnjsATEYhaO94GlRQwi4t4gO8FfjM6NnikHeKjUm8D7A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.33.0", - "@typescript-eslint/parser": "8.33.0", - "@typescript-eslint/utils": "8.33.0" + "@typescript-eslint/eslint-plugin": "8.33.1", + "@typescript-eslint/parser": "8.33.1", + "@typescript-eslint/utils": "8.33.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" diff --git a/web/package-lock.json b/web/package-lock.json index 7ec672e680..761db20f5f 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -123,7 +123,7 @@ "storybook-addon-mock": "^5.0.0", "turnstile-types": "^1.2.3", "typescript": "^5.8.3", - "typescript-eslint": "^8.33.0", + "typescript-eslint": "^8.33.1", "vite-plugin-lit-css": "^2.0.0", "vite-tsconfig-paths": "^5.0.1", "wireit": "^0.14.12" @@ -7328,17 +7328,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.0.tgz", - "integrity": "sha512-CACyQuqSHt7ma3Ns601xykeBK/rDeZa3w6IS6UtMQbixO5DWy+8TilKkviGDH6jtWCo8FGRKEK5cLLkPvEammQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.1.tgz", + "integrity": "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.33.0", - "@typescript-eslint/type-utils": "8.33.0", - "@typescript-eslint/utils": "8.33.0", - "@typescript-eslint/visitor-keys": "8.33.0", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/type-utils": "8.33.1", + "@typescript-eslint/utils": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -7352,7 +7352,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.33.0", + "@typescript-eslint/parser": "^8.33.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } @@ -7368,16 +7368,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.0.tgz", - "integrity": "sha512-JaehZvf6m0yqYp34+RVnihBAChkqeH+tqqhS0GuX1qgPpwLvmTPheKEs6OeCK6hVJgXZHJ2vbjnC9j119auStQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.1.tgz", + "integrity": "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.33.0", - "@typescript-eslint/types": "8.33.0", - "@typescript-eslint/typescript-estree": "8.33.0", - "@typescript-eslint/visitor-keys": "8.33.0", + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", "debug": "^4.3.4" }, "engines": { @@ -7393,14 +7393,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.0.tgz", - "integrity": "sha512-d1hz0u9l6N+u/gcrk6s6gYdl7/+pp8yHheRTqP6X5hVDKALEaTn8WfGiit7G511yueBEL3OpOEpD+3/MBdoN+A==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.1.tgz", + "integrity": "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.33.0", - "@typescript-eslint/types": "^8.33.0", + "@typescript-eslint/tsconfig-utils": "^8.33.1", + "@typescript-eslint/types": "^8.33.1", "debug": "^4.3.4" }, "engines": { @@ -7409,17 +7409,20 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.0.tgz", - "integrity": "sha512-LMi/oqrzpqxyO72ltP+dBSP6V0xiUb4saY7WLtxSfiNEBI8m321LLVFU9/QDJxjDQG9/tjSqKz/E3380TEqSTw==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", + "integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.33.0", - "@typescript-eslint/visitor-keys": "8.33.0" + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7430,9 +7433,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.0.tgz", - "integrity": "sha512-sTkETlbqhEoiFmGr1gsdq5HyVbSOF0145SYDJ/EQmXHtKViCaGvnyLqWFFHtEXoS0J1yU8Wyou2UGmgW88fEug==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.1.tgz", + "integrity": "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==", "dev": true, "license": "MIT", "engines": { @@ -7447,14 +7450,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.0.tgz", - "integrity": "sha512-lScnHNCBqL1QayuSrWeqAL5GmqNdVUQAAMTaCwdYEdWfIrSrOGzyLGRCHXcCixa5NK6i5l0AfSO2oBSjCjf4XQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.1.tgz", + "integrity": "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.33.0", - "@typescript-eslint/utils": "8.33.0", + "@typescript-eslint/typescript-estree": "8.33.1", + "@typescript-eslint/utils": "8.33.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -7471,9 +7474,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.0.tgz", - "integrity": "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", + "integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", "dev": true, "license": "MIT", "engines": { @@ -7485,16 +7488,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.0.tgz", - "integrity": "sha512-vegY4FQoB6jL97Tu/lWRsAiUUp8qJTqzAmENH2k59SJhw0Th1oszb9Idq/FyyONLuNqT1OADJPXfyUNOR8SzAQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", + "integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.33.0", - "@typescript-eslint/tsconfig-utils": "8.33.0", - "@typescript-eslint/types": "8.33.0", - "@typescript-eslint/visitor-keys": "8.33.0", + "@typescript-eslint/project-service": "8.33.1", + "@typescript-eslint/tsconfig-utils": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/visitor-keys": "8.33.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -7514,16 +7517,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.0.tgz", - "integrity": "sha512-lPFuQaLA9aSNa7D5u2EpRiqdAUhzShwGg/nhpBlc4GR6kcTABttCuyjFs8BcEZ8VWrjCBof/bePhP3Q3fS+Yrw==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.1.tgz", + "integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.33.0", - "@typescript-eslint/types": "8.33.0", - "@typescript-eslint/typescript-estree": "8.33.0" + "@typescript-eslint/scope-manager": "8.33.1", + "@typescript-eslint/types": "8.33.1", + "@typescript-eslint/typescript-estree": "8.33.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7538,13 +7541,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.0.tgz", - "integrity": "sha512-7RW7CMYoskiz5OOGAWjJFxgb7c5UNjTG292gYhWeOAcFmYCtVCSqjqSBj5zMhxbXo2JOW95YYrUWJfU0zrpaGQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", + "integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.33.0", + "@typescript-eslint/types": "8.33.1", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -27054,15 +27057,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.33.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.33.0.tgz", - "integrity": "sha512-5YmNhF24ylCsvdNW2oJwMzTbaeO4bg90KeGtMjUw0AGtHksgEPLRTUil+coHwCfiu4QjVJFnjp94DmU6zV7DhQ==", + "version": "8.33.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.33.1.tgz", + "integrity": "sha512-AgRnV4sKkWOiZ0Kjbnf5ytTJXMUZQ0qhSVdQtDNYLPLnjsATEYhaO94GlRQwi4t4gO8FfjM6NnikHeKjUm8D7A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.33.0", - "@typescript-eslint/parser": "8.33.0", - "@typescript-eslint/utils": "8.33.0" + "@typescript-eslint/eslint-plugin": "8.33.1", + "@typescript-eslint/parser": "8.33.1", + "@typescript-eslint/utils": "8.33.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" diff --git a/web/package.json b/web/package.json index f7d1410d6f..9b5280ea44 100644 --- a/web/package.json +++ b/web/package.json @@ -194,7 +194,7 @@ "storybook-addon-mock": "^5.0.0", "turnstile-types": "^1.2.3", "typescript": "^5.8.3", - "typescript-eslint": "^8.33.0", + "typescript-eslint": "^8.33.1", "vite-plugin-lit-css": "^2.0.0", "vite-tsconfig-paths": "^5.0.1", "wireit": "^0.14.12" From e5cb925f701b87441a72081c5a2c719a54c000c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:28:18 +0200 Subject: [PATCH 19/47] web: bump @fortawesome/fontawesome-free from 6.6.0 to 6.7.2 in /web (#14716) Bumps [@fortawesome/fontawesome-free](https://github.com/FortAwesome/Font-Awesome) from 6.6.0 to 6.7.2. - [Release notes](https://github.com/FortAwesome/Font-Awesome/releases) - [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/6.x/CHANGELOG.md) - [Commits](https://github.com/FortAwesome/Font-Awesome/compare/6.6.0...6.7.2) --- updated-dependencies: - dependency-name: "@fortawesome/fontawesome-free" dependency-version: 6.7.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 9 +++++---- web/package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 761db20f5f..d0e0e7c7aa 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -21,7 +21,7 @@ "@codemirror/theme-one-dark": "^6.1.2", "@floating-ui/dom": "^1.6.11", "@formatjs/intl-listformat": "^7.7.11", - "@fortawesome/fontawesome-free": "^6.6.0", + "@fortawesome/fontawesome-free": "^6.7.2", "@goauthentik/api": "^2025.6.0-1749054550", "@lit/context": "^1.1.2", "@lit/localize": "^0.12.2", @@ -1699,9 +1699,10 @@ } }, "node_modules/@fortawesome/fontawesome-free": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.6.0.tgz", - "integrity": "sha512-60G28ke/sXdtS9KZCpZSHHkCbdsOGEhIUGlwq6yhY74UpTiToIh8np7A8yphhM4BWsvNFtIvLpi4co+h9Mr9Ow==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz", + "integrity": "sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==", + "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)", "engines": { "node": ">=6" } diff --git a/web/package.json b/web/package.json index 9b5280ea44..42d115f0a9 100644 --- a/web/package.json +++ b/web/package.json @@ -92,7 +92,7 @@ "@codemirror/theme-one-dark": "^6.1.2", "@floating-ui/dom": "^1.6.11", "@formatjs/intl-listformat": "^7.7.11", - "@fortawesome/fontawesome-free": "^6.6.0", + "@fortawesome/fontawesome-free": "^6.7.2", "@goauthentik/api": "^2025.6.0-1749054550", "@lit/context": "^1.1.2", "@lit/localize": "^0.12.2", From 633c6ff245f861b4ac5089d51c1a123dabc68d04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:28:44 +0200 Subject: [PATCH 20/47] web: bump mermaid from 11.4.1 to 11.6.0 in /web (#14688) Bumps [mermaid](https://github.com/mermaid-js/mermaid) from 11.4.1 to 11.6.0. - [Release notes](https://github.com/mermaid-js/mermaid/releases) - [Changelog](https://github.com/mermaid-js/mermaid/blob/develop/CHANGELOG.md) - [Commits](https://github.com/mermaid-js/mermaid/compare/mermaid@11.4.1...mermaid@11.6.0) --- updated-dependencies: - dependency-name: mermaid dependency-version: 11.6.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 92 ++++++++++++++++++++++++++++--------------- web/package.json | 2 +- 2 files changed, 62 insertions(+), 32 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index d0e0e7c7aa..7ad4efe65e 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -50,7 +50,7 @@ "hastscript": "^9.0.1", "lit": "^3.2.0", "md-front-matter": "^1.0.4", - "mermaid": "^11.4.1", + "mermaid": "^11.6.0", "rapidoc": "^9.3.8", "react": "^19.1.0", "react-dom": "^19.1.0", @@ -796,6 +796,7 @@ "version": "11.0.3", "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "license": "Apache-2.0", "dependencies": { "@chevrotain/gast": "11.0.3", "@chevrotain/types": "11.0.3", @@ -806,6 +807,7 @@ "version": "11.0.3", "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "license": "Apache-2.0", "dependencies": { "@chevrotain/types": "11.0.3", "lodash-es": "4.17.21" @@ -814,17 +816,20 @@ "node_modules/@chevrotain/regexp-to-ast": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", - "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==" + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==", + "license": "Apache-2.0" }, "node_modules/@chevrotain/types": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", - "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==" + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==", + "license": "Apache-2.0" }, "node_modules/@chevrotain/utils": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", - "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==" + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==", + "license": "Apache-2.0" }, "node_modules/@codemirror/autocomplete": { "version": "6.18.1", @@ -2645,11 +2650,12 @@ } }, "node_modules/@mermaid-js/parser": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.3.0.tgz", - "integrity": "sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.4.0.tgz", + "integrity": "sha512-wla8XOWvQAwuqy+gxiZqY+c7FokraOTHRWMsbB4AgRx9Sy7zKslNyejy7E+a77qHfey5GXw/ik3IXv/NHMJgaA==", + "license": "MIT", "dependencies": { - "langium": "3.0.0" + "langium": "3.3.1" } }, "node_modules/@napi-rs/nice": { @@ -11746,6 +11752,7 @@ "version": "11.0.3", "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "license": "Apache-2.0", "dependencies": { "@chevrotain/cst-dts-gen": "11.0.3", "@chevrotain/gast": "11.0.3", @@ -11759,6 +11766,7 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", + "license": "MIT", "dependencies": { "lodash-es": "^4.17.21" }, @@ -19063,9 +19071,10 @@ "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==" }, "node_modules/langium": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz", - "integrity": "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/langium/-/langium-3.3.1.tgz", + "integrity": "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==", + "license": "MIT", "dependencies": { "chevrotain": "~11.0.3", "chevrotain-allstar": "~0.3.0", @@ -19697,9 +19706,10 @@ } }, "node_modules/marked": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.3.tgz", - "integrity": "sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==", + "version": "15.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", + "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", + "license": "MIT", "bin": { "marked": "bin/marked.js" }, @@ -20152,31 +20162,31 @@ } }, "node_modules/mermaid": { - "version": "11.4.1", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.4.1.tgz", - "integrity": "sha512-Mb01JT/x6CKDWaxigwfZYuYmDZ6xtrNwNlidKZwkSrDaY9n90tdrJTV5Umk+wP1fZscGptmKFXHsXMDEVZ+Q6A==", + "version": "11.6.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.6.0.tgz", + "integrity": "sha512-PE8hGUy1LDlWIHWBP05SFdqUHGmRcCcK4IzpOKPE35eOw+G9zZgcnMpyunJVUEOgb//KBORPjysKndw8bFLuRg==", "license": "MIT", "dependencies": { - "@braintree/sanitize-url": "^7.0.1", - "@iconify/utils": "^2.1.32", - "@mermaid-js/parser": "^0.3.0", + "@braintree/sanitize-url": "^7.0.4", + "@iconify/utils": "^2.1.33", + "@mermaid-js/parser": "^0.4.0", "@types/d3": "^7.4.3", - "cytoscape": "^3.29.2", + "cytoscape": "^3.29.3", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.11", - "dayjs": "^1.11.10", - "dompurify": "^3.2.1", + "dayjs": "^1.11.13", + "dompurify": "^3.2.4", "katex": "^0.16.9", "khroma": "^2.1.0", "lodash-es": "^4.17.21", - "marked": "^13.0.2", + "marked": "^15.0.7", "roughjs": "^4.6.6", - "stylis": "^4.3.1", + "stylis": "^4.3.6", "ts-dedent": "^2.2.0", - "uuid": "^9.0.1" + "uuid": "^11.1.0" } }, "node_modules/mermaid-isomorphic": { @@ -20200,6 +20210,19 @@ } } }, + "node_modules/mermaid/node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -25860,9 +25883,10 @@ } }, "node_modules/stylis": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz", - "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==" + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", + "license": "MIT" }, "node_modules/supports-color": { "version": "5.5.0", @@ -27554,6 +27578,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -28214,6 +28239,7 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "license": "MIT", "engines": { "node": ">=14.0.0" } @@ -28222,6 +28248,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "license": "MIT", "dependencies": { "vscode-languageserver-protocol": "3.17.5" }, @@ -28233,6 +28260,7 @@ "version": "3.17.5", "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "license": "MIT", "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" @@ -28241,7 +28269,8 @@ "node_modules/vscode-languageserver-protocol/node_modules/vscode-languageserver-types": { "version": "3.17.5", "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", - "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT" }, "node_modules/vscode-languageserver-textdocument": { "version": "1.0.12", @@ -28263,7 +28292,8 @@ "node_modules/vscode-uri": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", - "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "license": "MIT" }, "node_modules/w3c-keyname": { "version": "2.2.8", diff --git a/web/package.json b/web/package.json index 42d115f0a9..6d305eaebe 100644 --- a/web/package.json +++ b/web/package.json @@ -121,7 +121,7 @@ "hastscript": "^9.0.1", "lit": "^3.2.0", "md-front-matter": "^1.0.4", - "mermaid": "^11.4.1", + "mermaid": "^11.6.0", "rapidoc": "^9.3.8", "react": "^19.1.0", "react-dom": "^19.1.0", From 52c3ba551dba810ae9069fdf751299b621d37ab3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:30:02 +0200 Subject: [PATCH 21/47] website: bump @types/node from 22.15.29 to 22.15.30 in /website (#14968) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 22.15.29 to 22.15.30. - [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: 22.15.30 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- website/package-lock.json | 8 ++++---- website/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/website/package-lock.json b/website/package-lock.json index 173ddabf26..fe71f4cce7 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -41,7 +41,7 @@ "@goauthentik/tsconfig": "^1.0.4", "@trivago/prettier-plugin-sort-imports": "^5.2.2", "@types/lodash": "^4.17.17", - "@types/node": "^22.15.29", + "@types/node": "^22.15.30", "@types/postman-collection": "^3.5.11", "@types/react": "^18.3.22", "@types/semver": "^7.7.0", @@ -6614,9 +6614,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.15.29", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.29.tgz", - "integrity": "sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==", + "version": "22.15.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.30.tgz", + "integrity": "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" diff --git a/website/package.json b/website/package.json index eb38ff06dc..d1bfabc6cd 100644 --- a/website/package.json +++ b/website/package.json @@ -56,7 +56,7 @@ "@goauthentik/tsconfig": "^1.0.4", "@trivago/prettier-plugin-sort-imports": "^5.2.2", "@types/lodash": "^4.17.17", - "@types/node": "^22.15.29", + "@types/node": "^22.15.30", "@types/postman-collection": "^3.5.11", "@types/react": "^18.3.22", "@types/semver": "^7.7.0", From 9f6173d8b252a29a1a1bed2709db4808f04fdaa1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:30:29 +0200 Subject: [PATCH 22/47] web: bump ts-pattern from 5.4.0 to 5.7.1 in /web (#14686) Bumps [ts-pattern](https://github.com/gvergnaud/ts-pattern) from 5.4.0 to 5.7.1. - [Release notes](https://github.com/gvergnaud/ts-pattern/releases) - [Commits](https://github.com/gvergnaud/ts-pattern/compare/v5.4.0...v5.7.1) --- updated-dependencies: - dependency-name: ts-pattern dependency-version: 5.7.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 9 +++++---- web/package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 7ad4efe65e..47e903b2d2 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -64,7 +64,7 @@ "remark-mdx-frontmatter": "^5.0.0", "style-mod": "^4.1.2", "trusted-types": "^2.0.0", - "ts-pattern": "^5.4.0", + "ts-pattern": "^5.7.1", "unist-util-visit": "^5.0.0", "webcomponent-qr-code": "^1.2.0", "yaml": "^2.8.0" @@ -26373,9 +26373,10 @@ "license": "MIT" }, "node_modules/ts-pattern": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.4.0.tgz", - "integrity": "sha512-hgfOMfjlrARCnYtGD/xEAkFHDXuSyuqjzFSltyQCbN689uNvoQL20TVN2XFcLMjfNuwSsQGU+xtH6MrjIwhwUg==" + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.7.1.tgz", + "integrity": "sha512-EGs8PguQqAAUIcQfK4E9xdXxB6s2GK4sJfT/vcc9V1ELIvC4LH/zXu2t/5fajtv6oiRCxdv7BgtVK3vWgROxag==", + "license": "MIT" }, "node_modules/ts-simple-type": { "version": "2.0.0-next.0", diff --git a/web/package.json b/web/package.json index 6d305eaebe..889b1eb26c 100644 --- a/web/package.json +++ b/web/package.json @@ -135,7 +135,7 @@ "remark-mdx-frontmatter": "^5.0.0", "style-mod": "^4.1.2", "trusted-types": "^2.0.0", - "ts-pattern": "^5.4.0", + "ts-pattern": "^5.7.1", "unist-util-visit": "^5.0.0", "webcomponent-qr-code": "^1.2.0", "yaml": "^2.8.0" From 14f2edc04ba63ce2a0f1f4b34e7f9060ec8a6529 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:30:46 +0200 Subject: [PATCH 23/47] web: bump @types/mocha from 10.0.8 to 10.0.10 in /web (#14684) Bumps [@types/mocha](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mocha) from 10.0.8 to 10.0.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/mocha) --- updated-dependencies: - dependency-name: "@types/mocha" dependency-version: 10.0.10 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 11 ++++++----- web/package.json | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 47e903b2d2..d3f6813fd9 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -93,7 +93,7 @@ "@types/dompurify": "^3.0.5", "@types/grecaptcha": "^3.0.9", "@types/guacamole-common-js": "^1.5.3", - "@types/mocha": "^10.0.8", + "@types/mocha": "^10.0.10", "@types/node": "^22.15.21", "@types/react": "^19.1.5", "@types/react-dom": "^19.1.5", @@ -7086,10 +7086,11 @@ "dev": true }, "node_modules/@types/mocha": { - "version": "10.0.8", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.8.tgz", - "integrity": "sha512-HfMcUmy9hTMJh66VNcmeC9iVErIZJli2bszuXc6julh5YGuRb/W5OnkHjwLNYdFlMis0sY3If5SEAp+PktdJjw==", - "dev": true + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true, + "license": "MIT" }, "node_modules/@types/ms": { "version": "2.1.0", diff --git a/web/package.json b/web/package.json index 889b1eb26c..aad354b4eb 100644 --- a/web/package.json +++ b/web/package.json @@ -164,7 +164,7 @@ "@types/dompurify": "^3.0.5", "@types/grecaptcha": "^3.0.9", "@types/guacamole-common-js": "^1.5.3", - "@types/mocha": "^10.0.8", + "@types/mocha": "^10.0.10", "@types/node": "^22.15.21", "@types/react": "^19.1.5", "@types/react-dom": "^19.1.5", From 6e11554f622d2538a840361b36434e3bcb2de91b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:32:27 +0200 Subject: [PATCH 24/47] core: bump github.com/redis/go-redis/v9 from 9.9.0 to 9.10.0 (#14966) Bumps [github.com/redis/go-redis/v9](https://github.com/redis/go-redis) from 9.9.0 to 9.10.0. - [Release notes](https://github.com/redis/go-redis/releases) - [Changelog](https://github.com/redis/go-redis/blob/master/CHANGELOG.md) - [Commits](https://github.com/redis/go-redis/compare/v9.9.0...v9.10.0) --- updated-dependencies: - dependency-name: github.com/redis/go-redis/v9 dependency-version: 9.10.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f00e9bf14a..ec708801f3 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484 github.com/pires/go-proxyproto v0.8.1 github.com/prometheus/client_golang v1.22.0 - github.com/redis/go-redis/v9 v9.9.0 + github.com/redis/go-redis/v9 v9.10.0 github.com/sethvargo/go-envconfig v1.3.0 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.9.1 diff --git a/go.sum b/go.sum index dd4d6380fe..b3c3c09a66 100644 --- a/go.sum +++ b/go.sum @@ -249,8 +249,8 @@ github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/redis/go-redis/v9 v9.9.0 h1:URbPQ4xVQSQhZ27WMQVmZSo3uT3pL+4IdHVcYq2nVfM= -github.com/redis/go-redis/v9 v9.9.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= +github.com/redis/go-redis/v9 v9.10.0 h1:FxwK3eV8p/CQa0Ch276C7u2d0eNC9kCmAYQ7mCXCzVs= +github.com/redis/go-redis/v9 v9.10.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= From d017af1347b68e83a7529ca7969843fc4b04562f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:32:36 +0200 Subject: [PATCH 25/47] core: bump astral-sh/uv from 0.7.11 to 0.7.12 (#14965) Bumps [astral-sh/uv](https://github.com/astral-sh/uv) from 0.7.11 to 0.7.12. - [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.7.11...0.7.12) --- updated-dependencies: - dependency-name: astral-sh/uv dependency-version: 0.7.12 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 63e07d34c1..429fecb81b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -75,7 +75,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.7.11 AS uv +FROM ghcr.io/astral-sh/uv:0.7.12 AS uv # Stage 5: Base python image FROM ghcr.io/goauthentik/fips-python:3.13.3-slim-bookworm-fips AS python-base From 814f3fc43d0b6f90db29e9277aae393fad5a7470 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:32:51 +0200 Subject: [PATCH 26/47] core: bump axllent/mailpit from v1.25.1 to v1.26.0 in /tests/e2e (#14964) Bumps axllent/mailpit from v1.25.1 to v1.26.0. --- updated-dependencies: - dependency-name: axllent/mailpit dependency-version: v1.26.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- tests/e2e/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/docker-compose.yml b/tests/e2e/docker-compose.yml index 25d0ade7b5..cf998ba6df 100644 --- a/tests/e2e/docker-compose.yml +++ b/tests/e2e/docker-compose.yml @@ -7,7 +7,7 @@ services: network_mode: host restart: always mailpit: - image: docker.io/axllent/mailpit:v1.25.1 + image: docker.io/axllent/mailpit:v1.26.0 ports: - 1025:1025 - 8025:8025 From aaf76bab92f183b17b39898d96dd8e619b595b9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:32:59 +0200 Subject: [PATCH 27/47] core: bump selenium/standalone-chrome from 136.0 to 137.0 in /tests/e2e (#14963) Bumps selenium/standalone-chrome from 136.0 to 137.0. --- updated-dependencies: - dependency-name: selenium/standalone-chrome dependency-version: '137.0' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- tests/e2e/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/docker-compose.yml b/tests/e2e/docker-compose.yml index cf998ba6df..02f65c4276 100644 --- a/tests/e2e/docker-compose.yml +++ b/tests/e2e/docker-compose.yml @@ -1,7 +1,7 @@ services: chrome: platform: linux/x86_64 - image: docker.io/selenium/standalone-chrome:136.0 + image: docker.io/selenium/standalone-chrome:137.0 volumes: - /dev/shm:/dev/shm network_mode: host From a4c4b076147876e76d7e6ec84827e5ec7b78b13c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:39:00 +0200 Subject: [PATCH 28/47] website: bump prettier-plugin-packagejson from 2.5.14 to 2.5.15 in /website (#14829) website: bump prettier-plugin-packagejson in /website Bumps [prettier-plugin-packagejson](https://github.com/matzkoh/prettier-plugin-packagejson) from 2.5.14 to 2.5.15. - [Release notes](https://github.com/matzkoh/prettier-plugin-packagejson/releases) - [Commits](https://github.com/matzkoh/prettier-plugin-packagejson/compare/v2.5.14...v2.5.15) --- updated-dependencies: - dependency-name: prettier-plugin-packagejson dependency-version: 2.5.15 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- website/package-lock.json | 22 +++++++++++----------- website/package.json | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/website/package-lock.json b/website/package-lock.json index fe71f4cce7..47d780d18f 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -52,7 +52,7 @@ "fast-glob": "^3.3.3", "npm-run-all": "^4.1.5", "prettier": "^3.5.3", - "prettier-plugin-packagejson": "^2.5.14", + "prettier-plugin-packagejson": "^2.5.15", "typescript": "^5.8.3", "typescript-eslint": "^8.33.1" }, @@ -4935,9 +4935,9 @@ } }, "node_modules/@pkgr/core": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.4.tgz", - "integrity": "sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.7.tgz", + "integrity": "sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==", "dev": true, "license": "MIT", "engines": { @@ -22290,14 +22290,14 @@ } }, "node_modules/prettier-plugin-packagejson": { - "version": "2.5.14", - "resolved": "https://registry.npmjs.org/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.5.14.tgz", - "integrity": "sha512-h+3tSpr2nVpp+YOK1MDIYtYhHVXr8/0V59UUbJpIJFaqi3w4fvUokJo6eV8W+vELrUXIZzJ+DKm5G7lYzrMcKQ==", + "version": "2.5.15", + "resolved": "https://registry.npmjs.org/prettier-plugin-packagejson/-/prettier-plugin-packagejson-2.5.15.tgz", + "integrity": "sha512-2QSx6y4IT6LTwXtCvXAopENW5IP/aujC8fobEM2pDbs0IGkiVjW/ipPuYAHuXigbNe64aGWF7vIetukuzM3CBw==", "dev": true, "license": "MIT", "dependencies": { "sort-package-json": "3.2.1", - "synckit": "0.11.6" + "synckit": "0.11.8" }, "peerDependencies": { "prettier": ">= 1.16.0" @@ -25837,9 +25837,9 @@ } }, "node_modules/synckit": { - "version": "0.11.6", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.6.tgz", - "integrity": "sha512-2pR2ubZSV64f/vqm9eLPz/KOvR9Dm+Co/5ChLgeHl0yEDRc6h5hXHoxEQH8Y5Ljycozd3p1k5TTSVdzYGkPvLw==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.8.tgz", + "integrity": "sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==", "dev": true, "license": "MIT", "dependencies": { diff --git a/website/package.json b/website/package.json index d1bfabc6cd..6d301cd39a 100644 --- a/website/package.json +++ b/website/package.json @@ -67,7 +67,7 @@ "fast-glob": "^3.3.3", "npm-run-all": "^4.1.5", "prettier": "^3.5.3", - "prettier-plugin-packagejson": "^2.5.14", + "prettier-plugin-packagejson": "^2.5.15", "typescript": "^5.8.3", "typescript-eslint": "^8.33.1" }, From bd5a66a3c7561acb38917d7af86e3446000f5c14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 03:46:41 +0200 Subject: [PATCH 29/47] web: bump @codemirror/lang-python from 6.1.6 to 6.2.1 in /web (#14713) Bumps [@codemirror/lang-python](https://github.com/codemirror/lang-python) from 6.1.6 to 6.2.1. - [Changelog](https://github.com/codemirror/lang-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/codemirror/lang-python/compare/6.1.6...6.2.1) --- updated-dependencies: - dependency-name: "@codemirror/lang-python" dependency-version: 6.2.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package-lock.json | 9 +++++---- web/package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index d3f6813fd9..702e3d9f58 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -15,7 +15,7 @@ "@codemirror/lang-css": "^6.3.1", "@codemirror/lang-html": "^6.4.9", "@codemirror/lang-javascript": "^6.2.4", - "@codemirror/lang-python": "^6.1.6", + "@codemirror/lang-python": "^6.2.1", "@codemirror/lang-xml": "^6.1.0", "@codemirror/legacy-modes": "^6.4.1", "@codemirror/theme-one-dark": "^6.1.2", @@ -904,9 +904,10 @@ } }, "node_modules/@codemirror/lang-python": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.1.6.tgz", - "integrity": "sha512-ai+01WfZhWqM92UqjnvorkxosZ2aq2u28kHvr+N3gu012XqY2CThD67JPMHnGceRfXPDBmn1HnyqowdpF57bNg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.2.1.tgz", + "integrity": "sha512-IRjC8RUBhn9mGR9ywecNhB51yePWCGgvHfY1lWN/Mrp3cKuHr0isDKia+9HnvhiWNnMpbGhWrkhuWOc09exRyw==", + "license": "MIT", "dependencies": { "@codemirror/autocomplete": "^6.3.2", "@codemirror/language": "^6.8.0", diff --git a/web/package.json b/web/package.json index aad354b4eb..83b9da584c 100644 --- a/web/package.json +++ b/web/package.json @@ -86,7 +86,7 @@ "@codemirror/lang-css": "^6.3.1", "@codemirror/lang-html": "^6.4.9", "@codemirror/lang-javascript": "^6.2.4", - "@codemirror/lang-python": "^6.1.6", + "@codemirror/lang-python": "^6.2.1", "@codemirror/lang-xml": "^6.1.0", "@codemirror/legacy-modes": "^6.4.1", "@codemirror/theme-one-dark": "^6.1.2", From 652a32d96809452b5e371ada9253df6ee45b4e72 Mon Sep 17 00:00:00 2001 From: Christian Elsen Date: Sun, 8 Jun 2025 18:49:00 -0700 Subject: [PATCH 30/47] stages/email: Only attach logo to email if used (#14835) * Only attach logo to email if used * Fix MIME logo attachment to adhere to standard * format, fix web Signed-off-by: Jens Langhammer * not tuple Signed-off-by: Jens Langhammer --------- Signed-off-by: Jens Langhammer Co-authored-by: Jens Langhammer --- authentik/stages/email/tasks.py | 8 +++++--- authentik/stages/email/templates/email/base.html | 2 +- authentik/stages/email/utils.py | 3 ++- web/src/components/ak-event-info.ts | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/authentik/stages/email/tasks.py b/authentik/stages/email/tasks.py index 92fc34dd2c..b4b6ba03b5 100644 --- a/authentik/stages/email/tasks.py +++ b/authentik/stages/email/tasks.py @@ -100,9 +100,11 @@ def send_mail( # Because we use the Message-ID as UID for the task, manually assign it message_object.extra_headers["Message-ID"] = message_id - # Add the logo (we can't add it in the previous message since MIMEImage - # can't be converted to json) - message_object.attach(logo_data()) + # Add the logo if it is used in the email body (we can't add it in the + # previous message since MIMEImage can't be converted to json) + body = get_email_body(message_object) + if "cid:logo" in body: + message_object.attach(logo_data()) if ( message_object.to diff --git a/authentik/stages/email/templates/email/base.html b/authentik/stages/email/templates/email/base.html index 08a60107a0..98f9e448cc 100644 --- a/authentik/stages/email/templates/email/base.html +++ b/authentik/stages/email/templates/email/base.html @@ -96,7 +96,7 @@ {% block content %} diff --git a/authentik/stages/email/utils.py b/authentik/stages/email/utils.py index f19d9c1ea6..4ca986045a 100644 --- a/authentik/stages/email/utils.py +++ b/authentik/stages/email/utils.py @@ -19,7 +19,8 @@ def logo_data() -> MIMEImage: path = Path("web/dist/assets/icons/icon_left_brand.png") with open(path, "rb") as _logo_file: logo = MIMEImage(_logo_file.read()) - logo.add_header("Content-ID", "logo.png") + logo.add_header("Content-ID", "") + logo.add_header("Content-Disposition", "inline", filename="logo.png") return logo diff --git a/web/src/components/ak-event-info.ts b/web/src/components/ak-event-info.ts index 23847ba8bc..3a6346e2a2 100644 --- a/web/src/components/ak-event-info.ts +++ b/web/src/components/ak-event-info.ts @@ -374,7 +374,7 @@ ${JSON.stringify(value.new_value, null, 4)}${msg("Email info:")}
${this.getEmailInfo(this.event.context)}
From c60a145f956144c6ba403ffcf060d7d5e90ff4c0 Mon Sep 17 00:00:00 2001 From: "Jens L." Date: Mon, 9 Jun 2025 04:15:33 +0200 Subject: [PATCH 31/47] root: backport 2025.6.1 bump (#14970) release: 2025.6.1 Co-authored-by: Marc 'risson' Schmitt --- .bumpversion.cfg | 6 +++--- authentik/__init__.py | 2 +- blueprints/schema.json | 2 +- docker-compose.yml | 4 ++-- internal/constants/constants.go | 2 +- lifecycle/aws/template.yaml | 2 +- package-lock.json | 4 ++-- package.json | 2 +- pyproject.toml | 2 +- schema.yml | 2 +- uv.lock | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index b8794ba2b5..ee5980b994 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,16 +1,16 @@ [bumpversion] -current_version = 2025.6.0 +current_version = 2025.6.1 tag = True commit = True parse = (?P\d+)\.(?P\d+)\.(?P\d+)(?:-(?P[a-zA-Z-]+)(?P[1-9]\\d*))? -serialize = +serialize = {major}.{minor}.{patch}-{rc_t}{rc_n} {major}.{minor}.{patch} message = release: {new_version} tag_name = version/{new_version} [bumpversion:part:rc_t] -values = +values = rc final optional_value = final diff --git a/authentik/__init__.py b/authentik/__init__.py index 63dffcf666..eef8d90fa3 100644 --- a/authentik/__init__.py +++ b/authentik/__init__.py @@ -2,7 +2,7 @@ from os import environ -__version__ = "2025.6.0" +__version__ = "2025.6.1" ENV_GIT_HASH_KEY = "GIT_BUILD_HASH" diff --git a/blueprints/schema.json b/blueprints/schema.json index 3109aad668..66fa252f6f 100644 --- a/blueprints/schema.json +++ b/blueprints/schema.json @@ -2,7 +2,7 @@ "$schema": "http://json-schema.org/draft-07/schema", "$id": "https://goauthentik.io/blueprints/schema.json", "type": "object", - "title": "authentik 2025.6.0 Blueprint schema", + "title": "authentik 2025.6.1 Blueprint schema", "required": [ "version", "entries" diff --git a/docker-compose.yml b/docker-compose.yml index e8c490f91c..c017db451b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -31,7 +31,7 @@ services: volumes: - redis:/data server: - image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.6.0} + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.6.1} restart: unless-stopped command: server environment: @@ -55,7 +55,7 @@ services: redis: condition: service_healthy worker: - image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.6.0} + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.6.1} restart: unless-stopped command: worker environment: diff --git a/internal/constants/constants.go b/internal/constants/constants.go index c40d718856..a325cc4612 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -33,4 +33,4 @@ func UserAgent() string { return fmt.Sprintf("authentik@%s", FullVersion()) } -const VERSION = "2025.6.0" +const VERSION = "2025.6.1" diff --git a/lifecycle/aws/template.yaml b/lifecycle/aws/template.yaml index 7562729c04..940c93998f 100644 --- a/lifecycle/aws/template.yaml +++ b/lifecycle/aws/template.yaml @@ -26,7 +26,7 @@ Parameters: Description: authentik Docker image AuthentikVersion: Type: String - Default: 2025.6.0 + Default: 2025.6.1 Description: authentik Docker image tag AuthentikServerCPU: Type: Number diff --git a/package-lock.json b/package-lock.json index 83eff6879e..39aeb996a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@goauthentik/authentik", - "version": "2025.6.0", + "version": "2025.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@goauthentik/authentik", - "version": "2025.6.0", + "version": "2025.6.1", "devDependencies": { "@trivago/prettier-plugin-sort-imports": "^5.2.2", "prettier": "^3.3.3", diff --git a/package.json b/package.json index d6e73fcee7..ba8a92bd14 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@goauthentik/authentik", - "version": "2025.6.0", + "version": "2025.6.1", "private": true, "type": "module", "devDependencies": { diff --git a/pyproject.toml b/pyproject.toml index be98f04c83..9c3adb2477 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "authentik" -version = "2025.6.0" +version = "2025.6.1" description = "" authors = [{ name = "authentik Team", email = "hello@goauthentik.io" }] requires-python = "==3.13.*" diff --git a/schema.yml b/schema.yml index e1c4b5fe0c..f807f7af24 100644 --- a/schema.yml +++ b/schema.yml @@ -1,7 +1,7 @@ openapi: 3.0.3 info: title: authentik - version: 2025.6.0 + version: 2025.6.1 description: Making authentication simple. contact: email: hello@goauthentik.io diff --git a/uv.lock b/uv.lock index 80690d5dcc..6063d2f240 100644 --- a/uv.lock +++ b/uv.lock @@ -165,7 +165,7 @@ wheels = [ [[package]] name = "authentik" -version = "2025.6.0" +version = "2025.6.1" source = { editable = "." } dependencies = [ { name = "argon2-cffi" }, From fad6ac76af7ef4c5b02e9a0b8cc42123a308dbbf Mon Sep 17 00:00:00 2001 From: "authentik-automation[bot]" <135050075+authentik-automation[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 02:43:50 +0000 Subject: [PATCH 32/47] web: bump API Client version (#14971) --- web/package-lock.json | 8 ++++---- web/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 702e3d9f58..20bdf1405b 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -22,7 +22,7 @@ "@floating-ui/dom": "^1.6.11", "@formatjs/intl-listformat": "^7.7.11", "@fortawesome/fontawesome-free": "^6.7.2", - "@goauthentik/api": "^2025.6.0-1749054550", + "@goauthentik/api": "^2025.6.1-1749435349", "@lit/context": "^1.1.2", "@lit/localize": "^0.12.2", "@lit/reactive-element": "^2.0.4", @@ -1728,9 +1728,9 @@ } }, "node_modules/@goauthentik/api": { - "version": "2025.6.0-1749054550", - "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2025.6.0-1749054550.tgz", - "integrity": "sha512-4HrejUEsPTcM97VRkl+KhsueBpCrfjLoG+qr43I3Ea71YVzi/U1cefUl6HOxIr5Z2MMv67kieAzbE4MrFzhbgg==" + "version": "2025.6.1-1749435349", + "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2025.6.1-1749435349.tgz", + "integrity": "sha512-wGkzMWOYzLNUhbvQdt/ro/XYIsTshgAX1NEUlPPCofvji8rWgSbDHsDbj+YXWppuscEMrHoEnkxHfhsfaFuqBA==" }, "node_modules/@goauthentik/core": { "resolved": "packages/core", diff --git a/web/package.json b/web/package.json index 83b9da584c..da2c934f50 100644 --- a/web/package.json +++ b/web/package.json @@ -93,7 +93,7 @@ "@floating-ui/dom": "^1.6.11", "@formatjs/intl-listformat": "^7.7.11", "@fortawesome/fontawesome-free": "^6.7.2", - "@goauthentik/api": "^2025.6.0-1749054550", + "@goauthentik/api": "^2025.6.1-1749435349", "@lit/context": "^1.1.2", "@lit/localize": "^0.12.2", "@lit/reactive-element": "^2.0.4", From 6aebf45aea184c4d729c8f0b39cc48c585329cde Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jun 2025 14:52:58 +0200 Subject: [PATCH 33/47] core: bump goauthentik.io/api/v3 from 3.2025060.1 to 3.2025061.1 (#14972) Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2025060.1 to 3.2025061.1. - [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.2025060.1...v3.2025061.1) --- updated-dependencies: - dependency-name: goauthentik.io/api/v3 dependency-version: 3.2025061.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ec708801f3..41ca5e1fcf 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/spf13/cobra v1.9.1 github.com/stretchr/testify v1.10.0 github.com/wwt/guac v1.3.2 - goauthentik.io/api/v3 v3.2025060.1 + goauthentik.io/api/v3 v3.2025061.1 golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab golang.org/x/oauth2 v0.30.0 golang.org/x/sync v0.15.0 diff --git a/go.sum b/go.sum index b3c3c09a66..cca3ad165a 100644 --- a/go.sum +++ b/go.sum @@ -296,8 +296,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -goauthentik.io/api/v3 v3.2025060.1 h1:H/TDuroJlQicuxrWEnLcO3lzQaHuR28xrUb1L2362Vo= -goauthentik.io/api/v3 v3.2025060.1/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw= +goauthentik.io/api/v3 v3.2025061.1 h1:njT00q3YrYnOPbRkG4yfWuA6+EDzi+3p4wKnq7YLAu8= +goauthentik.io/api/v3 v3.2025061.1/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= From 1464852b925fad8dcdc6c28870d2110a306ea2ea Mon Sep 17 00:00:00 2001 From: "Jens L." Date: Mon, 9 Jun 2025 17:13:04 +0200 Subject: [PATCH 34/47] website: fix search across multiple subdomains (#14976) Signed-off-by: Jens Langhammer --- website/docusaurus.config.esm.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/website/docusaurus.config.esm.mjs b/website/docusaurus.config.esm.mjs index 8f6dc1caf1..74a4858bef 100644 --- a/website/docusaurus.config.esm.mjs +++ b/website/docusaurus.config.esm.mjs @@ -86,6 +86,7 @@ const config = createDocusaurusConfig({ appId: "36ROD0O0FV", apiKey: "727db511300ca9aec5425645bbbddfb5", indexName: "goauthentik", + externalUrlRegex: ":\\/\\/goauthentik\\.io", }, }, presets: [ From f4da22aea8cc430a0b87b3d527691486ead5bed0 Mon Sep 17 00:00:00 2001 From: Tana M Berry Date: Mon, 9 Jun 2025 10:14:43 -0500 Subject: [PATCH 35/47] website/docs: added a link in our Upgrade docs to the Outpost upgrade docs, slight reformatting (#14931) * add link to outpost upgrade doc * darn build breaks * kens edits * again --------- Co-authored-by: Tana M Berry --- website/docs/install-config/upgrade.mdx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/website/docs/install-config/upgrade.mdx b/website/docs/install-config/upgrade.mdx index b855b6116a..ba3698c2d5 100644 --- a/website/docs/install-config/upgrade.mdx +++ b/website/docs/install-config/upgrade.mdx @@ -10,13 +10,13 @@ Upgrading to the latest version of authentik, whether a new major release or a p authentik does not support downgrading. Make sure to back up your database in case you need to revert an upgrade. ::: -- Be sure to carefully read the [Release Notes](../releases/) for the specific version to which you plan to upgrade. The release might have special requirements or actions or contain breaking changes. +- **Preview the Release Notes**: Be sure to carefully read the [Release Notes](../releases/) for the specific version to which you plan to upgrade. The release might have special requirements or actions or contain breaking changes. -- Make a backup of your PostgreSQL database before upgrading. You can dump your existing database to get a backup file. For more information about dumping and backing up your database, refer to [Upgrade PostgreSQL on Docker Compose](../troubleshooting/postgres/upgrade_docker.md) or [Upgrade PostgreSQL on Kubernetes](../troubleshooting/postgres/upgrade_kubernetes.md). +- **Database backup**: Make a backup of your PostgreSQL database before upgrading. You can dump your existing database to get a backup file. For more information about dumping and backing up your database, refer to [Upgrade PostgreSQL on Docker Compose](../troubleshooting/postgres/upgrade_docker.md) or [Upgrade PostgreSQL on Kubernetes](../troubleshooting/postgres/upgrade_kubernetes.md). -- You need to upgrade in sequence of the major releases; do not skip directly from an older major version to the most recent version. For example, if you are currently running 2023.10.3, you should first upgrade to the latest 2024.2.x release, then to the latest 2024.4.x release, and finally to the latest 2024.6.x release, in sequence. Always use the latest available patch version (_x_ in this case being the latest patch release) for each major.minor release. +- **Upgrade sequence**: Upgrades need to follow the sequence of major releases; do not skip directly from an older major version to the most recent version. For example, if you are currently running 2023.10.3, you should first upgrade to the latest 2024.2.x release, then to the latest 2024.4.x release, and finally to the latest 2024.6.x release, in sequence. Always use the latest available patch version (_x_ in this case being the latest patch release) for each major.minor release. -- The version of the authentik instance and any outposts must be the same. We recommended that you always upgrade any outposts at the same time you upgrade your authentik instance. +- **Outposts**: The versions of the authentik server and any authentik outposts must be the same. Always [upgrade any outposts](../add-secure-apps/outposts/upgrading.md) at the same time that you upgrade your authentik instance. ## Upgrade authentik @@ -58,6 +58,10 @@ import Tabs from "@theme/Tabs"; +## Upgrade any outposts + +Be sure to also [upgrade any outposts](../add-secure-apps/outposts/upgrading.md) when you upgrade your authentik instance. + ## Verify your upgrade You can view the current version of your authentik instance by logging in to the Admin interface, and then navigating to **Dashboards -> Overview**. From a844fb41d4c9b60c88c3d2663fa1cf579550eb50 Mon Sep 17 00:00:00 2001 From: "Jens L." Date: Mon, 9 Jun 2025 19:04:07 +0200 Subject: [PATCH 36/47] web/elements: fix dual select without sortBy (#14977) Signed-off-by: Jens Langhammer --- web/src/elements/ak-dual-select/ak-dual-select.ts | 4 ++-- web/src/elements/ak-dual-select/types.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/web/src/elements/ak-dual-select/ak-dual-select.ts b/web/src/elements/ak-dual-select/ak-dual-select.ts index 84559f1240..2539620703 100644 --- a/web/src/elements/ak-dual-select/ak-dual-select.ts +++ b/web/src/elements/ak-dual-select/ak-dual-select.ts @@ -32,8 +32,8 @@ import { } from "./types.js"; function localeComparator(a: DualSelectPair, b: DualSelectPair) { - const aSortBy = a[2]; - const bSortBy = b[2]; + const aSortBy = a[2] || a[0]; + const bSortBy = b[2] || a[0]; return aSortBy.localeCompare(bSortBy); } diff --git a/web/src/elements/ak-dual-select/types.ts b/web/src/elements/ak-dual-select/types.ts index d9a410c87f..4ccd374464 100644 --- a/web/src/elements/ak-dual-select/types.ts +++ b/web/src/elements/ak-dual-select/types.ts @@ -34,7 +34,7 @@ export type DualSelectPair = [ /** * A string to sort by. If not provided, the key will be used. */ - sortBy: string, + sortBy?: string, /** * A local mapping of the key to the object. This is used by some specific apps. * From dea2d67cebc19bd943ab76e847582254c13c8709 Mon Sep 17 00:00:00 2001 From: "Jens L." Date: Mon, 9 Jun 2025 20:57:36 +0200 Subject: [PATCH 37/47] internal/outpost: fix incorrect usage of golang SHA API (#14981) Signed-off-by: Jens Langhammer --- internal/outpost/proxyv2/application/application.go | 5 +++-- internal/outpost/radius/handler.go | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/internal/outpost/proxyv2/application/application.go b/internal/outpost/proxyv2/application/application.go index 01b0a44637..49239fbefd 100644 --- a/internal/outpost/proxyv2/application/application.go +++ b/internal/outpost/proxyv2/application/application.go @@ -5,6 +5,7 @@ import ( "crypto/sha256" "crypto/tls" "encoding/gob" + "encoding/hex" "fmt" "html/template" "net/http" @@ -118,8 +119,8 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, server Server, old mux := mux.NewRouter() // Save cookie name, based on hashed client ID - h := sha256.New() - bs := string(h.Sum([]byte(*p.ClientId))) + hs := sha256.Sum256([]byte(*p.ClientId)) + bs := hex.EncodeToString(hs[:]) sessionName := fmt.Sprintf("authentik_proxy_%s", bs[:8]) // When HOST_BROWSER is set, use that as Host header for token requests to make the issuer match diff --git a/internal/outpost/radius/handler.go b/internal/outpost/radius/handler.go index 958e88b707..0b94e86743 100644 --- a/internal/outpost/radius/handler.go +++ b/internal/outpost/radius/handler.go @@ -2,6 +2,7 @@ package radius import ( "crypto/sha512" + "encoding/hex" "time" "github.com/getsentry/sentry-go" @@ -68,7 +69,9 @@ func (rs *RadiusServer) ServeRADIUS(w radius.ResponseWriter, r *radius.Request) } } if pi == nil { - nr.Log().WithField("hashed_secret", string(sha512.New().Sum(r.Secret))).Warning("No provider found") + hs := sha512.Sum512([]byte(r.Secret)) + bs := hex.EncodeToString(hs[:]) + nr.Log().WithField("hashed_secret", bs).Warning("No provider found") _ = w.Write(r.Response(radius.CodeAccessReject)) return } From 856ac052e75a35273facd5c1e56dbe2afdaaef56 Mon Sep 17 00:00:00 2001 From: Dewi Roberts Date: Mon, 9 Jun 2025 21:06:37 +0100 Subject: [PATCH 38/47] website/integrations: replaces all kbd and em tags (#14980) Replaces all kbd and em tags --- .../services/actual-budget/index.mdx | 4 +- .../services/apache-guacamole/index.mdx | 2 +- website/integrations/services/argocd/index.md | 2 +- .../services/aruba-orchestrator/index.md | 6 +-- website/integrations/services/aws/index.mdx | 10 ++-- .../integrations/services/awx-tower/index.md | 6 +-- .../integrations/services/beszel/index.mdx | 18 ++++---- .../integrations/services/budibase/index.md | 12 ++--- .../services/calibre-web/index.md | 8 ++-- .../services/chronograf/index.mdx | 2 +- .../services/cloudflare-access/index.md | 2 +- .../integrations/services/dokuwiki/index.md | 8 ++-- website/integrations/services/drupal/index.md | 12 ++--- .../integrations/services/engomo/index.mdx | 14 +++--- .../services/fortigate-admin/index.md | 22 ++++----- .../services/fortigate-ssl/index.md | 16 +++---- .../services/fortimanager/index.md | 14 +++--- website/integrations/services/frappe/index.md | 6 +-- .../integrations/services/freshrss/index.mdx | 2 +- website/integrations/services/gatus/index.mdx | 2 +- .../services/github-enterprise-cloud/index.md | 6 +-- .../services/github-enterprise-emu/index.md | 6 +-- .../github-enterprise-server/index.md | 4 +- .../services/github-organization/index.md | 6 +-- .../integrations/services/gitlab/index.mdx | 6 +-- .../integrations/services/glitchtip/index.md | 2 +- .../services/globalprotect/index.md | 4 +- .../integrations/services/grafana/index.mdx | 2 +- .../integrations/services/gravitee/index.md | 10 ++-- .../integrations/services/gravity/index.md | 8 ++-- website/integrations/services/harbor/index.md | 8 ++-- .../services/hashicorp-cloud/index.md | 4 +- .../services/hashicorp-vault/index.md | 2 +- .../integrations/services/hedgedoc/index.md | 2 +- website/integrations/services/homarr/index.md | 2 +- .../integrations/services/jenkins/index.md | 2 +- .../integrations/services/karakeep/index.md | 2 +- website/integrations/services/kimai/index.md | 6 +-- .../integrations/services/knocknoc/index.md | 8 ++-- website/integrations/services/komga/index.md | 2 +- .../integrations/services/linkwarden/index.md | 2 +- .../integrations/services/mailcow/index.md | 14 +++--- .../integrations/services/mastodon/index.md | 2 +- .../services/matrix-synapse/index.md | 2 +- website/integrations/services/mautic/index.md | 46 +++++++++---------- .../services/meshcentral/index.md | 2 +- .../integrations/services/miniflux/index.md | 4 +- website/integrations/services/minio/index.md | 2 +- .../integrations/services/mobilizon/index.md | 2 +- website/integrations/services/netbox/index.md | 2 +- .../integrations/services/node-red/index.md | 2 +- .../integrations/services/observium/index.md | 2 +- website/integrations/services/omni/index.md | 6 +-- .../integrations/services/open-webui/index.md | 14 +++--- .../services/openproject/index.md | 4 +- .../services/oracle-cloud/index.md | 2 +- .../integrations/services/outline/index.md | 2 +- .../integrations/services/owncloud/index.md | 10 ++-- .../services/paperless-ngx/index.mdx | 2 +- .../integrations/services/pgadmin/index.md | 2 +- website/integrations/services/plesk/index.md | 10 ++-- .../integrations/services/pocketbase/index.md | 12 ++--- .../integrations/services/portainer/index.md | 2 +- .../integrations/services/proxmox-ve/index.md | 2 +- .../integrations/services/rocketchat/index.md | 2 +- .../integrations/services/roundcube/index.md | 2 +- .../services/rustdesk-pro/index.mdx | 18 ++++---- .../integrations/services/semaphore/index.mdx | 8 ++-- website/integrations/services/slack/index.md | 14 +++--- .../services/synology-dsm/index.md | 2 +- .../integrations/services/tandoor/index.md | 2 +- .../integrations/services/terrakube/index.md | 2 +- .../services/truecommand/index.md | 24 +++++----- .../services/ubuntu-landscape/index.md | 2 +- .../services/uptime-kuma/index.md | 4 +- .../integrations/services/vikunja/index.md | 2 +- .../services/vmware-vcenter/index.md | 2 +- website/integrations/services/wazuh/index.mdx | 2 +- .../integrations/services/weblate/index.md | 14 +++--- website/integrations/services/wekan/index.mdx | 2 +- .../services/whats-up-docker/index.md | 2 +- .../integrations/services/wiki-js/index.md | 2 +- .../integrations/services/wordpress/index.md | 2 +- .../services/writefreely/index.md | 2 +- .../services/xen-orchestra/index.md | 2 +- website/integrations/services/zabbix/index.md | 4 +- website/integrations/services/zammad/index.md | 17 +++---- .../integrations/services/zipline/index.md | 8 ++-- website/integrations/services/zulip/index.md | 4 +- 89 files changed, 278 insertions(+), 277 deletions(-) diff --git a/website/integrations/services/actual-budget/index.mdx b/website/integrations/services/actual-budget/index.mdx index 00005346fc..bc562b0936 100644 --- a/website/integrations/services/actual-budget/index.mdx +++ b/website/integrations/services/actual-budget/index.mdx @@ -37,7 +37,7 @@ To support the integration of Actual Budget with authentik, you need to create a - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://actual.company/openid/callback. + - Set a `Strict` redirect URI to `https://actual.company/openid/callback`. - Select any available signing key. Actual Budget only supports the RS256 algorithm. Be aware of this when choosing a signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -89,7 +89,7 @@ Alternatively, it is possible to configure OpenID Connect via the UI. 5. Scroll up and click **Start using OpenID** under the **Authentication method** section. 6. Fill in the following values: - **OpenID Provider**: authentik - - **OpenID provider URL**: https://authentik.company/application/o/your-application-slug/ + - **OpenID provider URL**: `https://authentik.company/application/o/your-application-slug/` - **Client ID**: Enter the **Client ID** from authentik - **Client Secret**: Enter the **Client Secret** from authentik diff --git a/website/integrations/services/apache-guacamole/index.mdx b/website/integrations/services/apache-guacamole/index.mdx index 63f3428a5f..a4b0dc512d 100644 --- a/website/integrations/services/apache-guacamole/index.mdx +++ b/website/integrations/services/apache-guacamole/index.mdx @@ -37,7 +37,7 @@ To support the integration of Apache Guacamole with authentik, you need to creat - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://guacamole.company/. If you have configured [Apache Tomcat](https://tomcat.apache.org/) to run Apache Guacamole on a subpath, you will need to update this value accordingly. + - Set a `Strict` redirect URI to `https://guacamole.company/`. If you have configured [Apache Tomcat](https://tomcat.apache.org/) to run Apache Guacamole on a subpath, you will need to update this value accordingly. - Select any available signing key. - Note that Apache Guacamole does not support session tokens longer than 300 minutes (5 hours). - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/argocd/index.md b/website/integrations/services/argocd/index.md index 530c540ef9..5b7dd2a796 100644 --- a/website/integrations/services/argocd/index.md +++ b/website/integrations/services/argocd/index.md @@ -34,7 +34,7 @@ To support the integration of ArgoCD with authentik, you need to create an appli - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Add two `Strict` redirect URI and set them to https://argocd.company/api/dex/callback and https://localhost:8085/auth/callback. + - Add two `Strict` redirect URI and set them to `https://argocd.company/api/dex/callback` and `https://localhost:8085/auth/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/aruba-orchestrator/index.md b/website/integrations/services/aruba-orchestrator/index.md index 3e5ee383f8..13afdcde27 100644 --- a/website/integrations/services/aruba-orchestrator/index.md +++ b/website/integrations/services/aruba-orchestrator/index.md @@ -30,9 +30,9 @@ To support the integration of Aruba Orchestrator with authentik, you need to cre 1. Log in to authentik as an administrator and open the authentik Admin interface. 2. Navigate to **Customization** > **Property Mappings** and click **Create**. Create a **SAML Provider Property Mapping** with the following settings: - **Name**: Set an appropriate name - - **SAML Attribute Name**: sp-roles + - **SAML Attribute Name**: `sp-roles` - **Friendly Name**: Leave blank - - **Expression**: (You can modify the authentik Admins group as needed) + - **Expression**: (You can modify the `authentik Admins` group as needed) ```python if ak_is_group_member(request.user, name="authentik Admins"): result = "superAdmin" @@ -47,7 +47,7 @@ To support the integration of Aruba Orchestrator with authentik, you need to cre - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** and **Issuer** to https://arubaorchestrator.company/gms/rest/authentication/saml2/consume. + - Set the **ACS URL** and **Issuer** to `https://arubaorchestrator.company/gms/rest/authentication/saml2/consume`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. - Under **Advanced protocol settings**, add the newly created property mapping under **Property Mappings**. diff --git a/website/integrations/services/aws/index.mdx b/website/integrations/services/aws/index.mdx index 66ad1abd4a..3d4d004ba6 100644 --- a/website/integrations/services/aws/index.mdx +++ b/website/integrations/services/aws/index.mdx @@ -44,7 +44,7 @@ To support the integration of AWS with authentik using the classic IAM method, y - **Role Mapping:** - **Name**: Choose a descriptive name - - **SAML Attribute Name**: https://aws.amazon.com/SAML/Attributes/Role + - **SAML Attribute Name**: `https://aws.amazon.com/SAML/Attributes/Role` - **Friendly Name**: Leave blank - **Expression**: Choose one of these options: @@ -73,9 +73,9 @@ To support the integration of AWS with authentik using the classic IAM method, y - **Session Name Mapping:** - **Name**: Choose a descriptive name - - **SAML Attribute Name**: https://aws.amazon.com/SAML/Attributes/RoleSessionName + - **SAML Attribute Name**: `https://aws.amazon.com/SAML/Attributes/RoleSessionName` - **Friendly Name**: Leave blank - - **Expression**: return user.username + - **Expression**: `return user.username` #### Create an application and provider in authentik @@ -85,8 +85,8 @@ To support the integration of AWS with authentik using the classic IAM method, y - **Application**: provide a descriptive name (e.g. "AWS"), an optional group for the type of application, the policy engine mode, and optional UI settings. The **slug** will be used in URLs and should match the `aws-slug` placeholder defined earlier. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), and configure the following required settings: - - Set the **ACS URL** to https://signin.aws.amazon.com/saml - - Set the **Audience** to urn:amazon:webservices + - Set the **ACS URL** to `https://signin.aws.amazon.com/saml` + - Set the **Audience** to `urn:amazon:webservices` - Under **Advanced protocol settings**, add both property mappings you created in the previous section - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/awx-tower/index.md b/website/integrations/services/awx-tower/index.md index 4952e78d80..cb2bcdecd5 100644 --- a/website/integrations/services/awx-tower/index.md +++ b/website/integrations/services/awx-tower/index.md @@ -37,9 +37,9 @@ To support the integration of AWX Tower with authentik, you need to create an ap - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://awx.company/sso/complete/saml/. - - Set the **Audience** to awx. - - Set the **Issuer** to https://awx.company/sso/metadata/saml/. + - Set the **ACS URL** to `https://awx.company/sso/complete/saml/`. + - Set the **Audience** to `awx`. + - Set the **Issuer** to `https://awx.company/sso/metadata/saml/`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/beszel/index.mdx b/website/integrations/services/beszel/index.mdx index c107fb4953..b32919b073 100644 --- a/website/integrations/services/beszel/index.mdx +++ b/website/integrations/services/beszel/index.mdx @@ -36,7 +36,7 @@ The steps to configure authentik include creating an application and provider pa - **Choose a Provider type**: OAuth2/OpenID - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and any required configurations. - Note the **Client ID**, **Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://beszel.company/api/oauth2-redirect. + - Set a `Strict` redirect URI to `https://beszel.company/api/oauth2-redirect`. - Select any available signing key. - **Configure Bindings** _(optional):_ you can create a [binding](https://docs.goauthentik.io/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user’s \***\*My applications** \*_page_.\* @@ -48,9 +48,9 @@ Beszel uses PocketBase as its server backend, and when you install Beszel you au ## Beszel configuration -1. Sign in to Beszel and access the superusers dashboard by navigating to https://beszel.company/\_/#/settings. +1. Sign in to Beszel and access the superusers dashboard by navigating to `https://beszel.company/\_/#/settings`. 2. Toggle off **Hide collection create and edit controls**," then click the **Save changes** button. -3. Open the **users** collection by clicking the **Collections** icon on the sidebar or head to https://beszel.company/\_/#/collections?collection=pb_users_auth. +3. Open the **users** collection by clicking the **Collections** icon on the sidebar or head to `https://beszel.company/\_/#/collections?collection=pb_users_auth`. 4. Click the gear icon next to the collection's name, then select the **Options** tab in the popup on the right. 5. Enable the **OAuth2** authentication method by clicking the **OAuth2** tab and toggling **Enable**. 6. Click **+ Add provider**, then select **OpenID Connect**. @@ -58,15 +58,15 @@ Beszel uses PocketBase as its server backend, and when you install Beszel you au - Set **Client ID** to the Client ID copied from authentik. - Set **Client secret** to the Client Secret copied from authentik. - Set **Display name** to `authentik`. - - Set **Auth URL** to https://authentik.company/application/o/authorize/. - - Set **Token URL** to https://authentik.company/application/o/token/. - - Make sure **Fetch user info from** is set to `User info URL`, then set **User info URL** to https://authentik.company/application/o/userinfo/ + - Set **Auth URL** to `https://authentik.company/application/o/authorize/`. + - Set **Token URL** to `https://authentik.company/application/o/token/`. + - Make sure **Fetch user info from** is set to `User info URL`, then set **User info URL** to `https://authentik.company/application/o/userinfo/` ## Test the login -- Open your web browser and go to: https://beszel.company. +- Open your web browser and go to: `https://beszel.company`. - Click **authentik** to log in. -- You should be redirected to authentik (following the login flow you configured). After logging in, authentik will redirect you back to https://beszel.company. +- You should be redirected to authentik (following the login flow you configured). After logging in, authentik will redirect you back to `https://beszel.company`. - If you successfully return to the Beszel WebGUI, the login is working correctly. ## User Creation @@ -75,7 +75,7 @@ Beszel uses PocketBase as its server backend, and when you install Beszel you au - Users are not created automatically when logging in with authentik. The owner must manually create each user in Beszel. - To create users, go to the System Settings where you configured OpenID Connect. - - The URL for user creation is: https://beszel.company>/\_/#/collections?collection=pb_users_auth. + - The URL for user creation is: `https://beszel.company>/\_/#/collections?collection=pb_users_auth`. - Click **+ New record** and enter the user's **email** (must match the authentik email address). 2. Automatically Creating Users: diff --git a/website/integrations/services/budibase/index.md b/website/integrations/services/budibase/index.md index ecd733a74c..dc659ce45c 100644 --- a/website/integrations/services/budibase/index.md +++ b/website/integrations/services/budibase/index.md @@ -34,7 +34,7 @@ To support the integration of Budibase with authentik, you need to create an app - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://budibase.company/api/global/auth/oidc/callback. + - Set a `Strict` redirect URI to `https://budibase.company/api/global/auth/oidc/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -44,11 +44,11 @@ To support the integration of Budibase with authentik, you need to create an app From the main page of your Budibase installation, add the following values under the **Auth** section of the builder: -- **Config URL**: https://authentik.company/application/o/your-application-slug/.well-known/openid-configuration -- **Client ID**: Client ID from authentik -- **Client Secret**: Client Secret from authentik -- **Callback URL**: https://budibase.company/api/global/auth/oidc/callback/ -- **Name**: authentik +- **Config URL**: `https://authentik.company/application/o/your-application-slug/.well-known/openid-configuration` +- **Client ID**: `Client ID from authentik` +- **Client Secret**: `Client Secret from authentik` +- **Callback URL**: `https://budibase.company/api/global/auth/oidc/callback/` +- **Name**: `authentik` ## Configuration verification diff --git a/website/integrations/services/calibre-web/index.md b/website/integrations/services/calibre-web/index.md index ac2224c0be..5c0b17dee5 100644 --- a/website/integrations/services/calibre-web/index.md +++ b/website/integrations/services/calibre-web/index.md @@ -69,17 +69,17 @@ Add the user that require access to the newly created group. 1. Navigate to **Admin** > **Edit Basic Configuration** and click on **Feature Configuration** and set the following options: - Login Type: `Use LDAP Authentication` -- LDAP Server: `authentik.company` +- LDAP Server: `authentik.company` - LDAP Server Port: `389` - LDAP Encryption: `None` - LDAP Authentication: `Simple` -- LDAP Administrator Username: `cn=,ou=users,dc=goauthentik,dc=io` (e.g. `cn=akadmin,ou=users,dc=goauthentik,dc=io`) -- LDAP Administrator Password: `` +- LDAP Administrator Username: `cn=,ou=users,dc=goauthentik,dc=io` (e.g. `cn=akadmin,ou=users,dc=goauthentik,dc=io`) +- LDAP Administrator Password: `` - LDAP Distinguished Name (DN): `dc=ldap,dc=goauthentik,dc=io` - LDAP User Object Filter: `(&(objectclass=user)(cn=%s))` - LDAP Server is OpenLDAP?: `true` - LDAP Group Object Filter: `(&(objectclass=group)(cn=%s))` -- LDAP Group Name: `` (e.g. `Calibre-Web`) +- LDAP Group Name: `` (e.g. `Calibre-Web`) - LDAP Group Members Field: `member` - LDAP Member User Filter Detection: `Autodetect` diff --git a/website/integrations/services/chronograf/index.mdx b/website/integrations/services/chronograf/index.mdx index 7ca172ee6d..23ba31eb64 100644 --- a/website/integrations/services/chronograf/index.mdx +++ b/website/integrations/services/chronograf/index.mdx @@ -35,7 +35,7 @@ To support the integration of Chronograf with authentik, you need to create an a - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://chronograf.company/oauth/authentik/callback/. + - Set a `Strict` redirect URI to `https://chronograf.company/oauth/authentik/callback/`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/cloudflare-access/index.md b/website/integrations/services/cloudflare-access/index.md index 57a9f2e6c0..222dcdb6ae 100644 --- a/website/integrations/services/cloudflare-access/index.md +++ b/website/integrations/services/cloudflare-access/index.md @@ -36,7 +36,7 @@ To support the integration of Cloudflare Access with authentik, you need to crea - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://company.cloudflareaccess.com/cdn-cgi/access/callback. + - Set a `Strict` redirect URI to `https://company.cloudflareaccess.com/cdn-cgi/access/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/dokuwiki/index.md b/website/integrations/services/dokuwiki/index.md index 85ded1fc56..bb5204eff7 100644 --- a/website/integrations/services/dokuwiki/index.md +++ b/website/integrations/services/dokuwiki/index.md @@ -34,7 +34,7 @@ To support the integration of DocuWiki with authentik, you need to create an app - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID** and **Client Secret** values because they will be required later. - - Set a `Strict` redirect URI to https://docuwiki.company/doku.php. + - Set a `Strict` redirect URI to `https://docuwiki.company/doku.php`. - Select any available signing key. - Under **Advanced Protocol Settings**, add the following OAuth mapping under **Scopes**: `authentik default OAuth Mapping: OpenID 'offline_access'` - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -60,9 +60,9 @@ For **oauthgeneric**: - Set `plugin»oauthgeneric»key` to the Client ID from authentik - Set `plugin»oauthgeneric»secret` to the Client Secret from authentik -- Set `plugin»oauthgeneric»authurl` to https://authentik.company/application/o/authorize/ -- Set `plugin»oauthgeneric»tokenurl` to https://authentik.company/application/o/token/ -- Set `plugin»oauthgeneric»userurl` to https://authentik.company/application/o/userinfo/ +- Set `plugin»oauthgeneric»authurl` to `https://authentik.company/application/o/authorize/` +- Set `plugin»oauthgeneric»tokenurl` to `https://authentik.company/application/o/token/` +- Set `plugin»oauthgeneric»userurl` to `https://authentik.company/application/o/userinfo/` - Set `plugin»oauthgeneric»authmethod` to `Bearer Header` - Set `plugin»oauthgeneric»scopes` to `email, openid, profile, offline_access` - Select `plugin»oauthgeneric»needs-state` diff --git a/website/integrations/services/drupal/index.md b/website/integrations/services/drupal/index.md index 48cd57c3b5..d2ba8ac6b0 100644 --- a/website/integrations/services/drupal/index.md +++ b/website/integrations/services/drupal/index.md @@ -38,7 +38,7 @@ To support the integration of Drupal with authentik, you need to create an appli - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. The **slug** will be used in URLs and should match the `drupal-slug` placeholder defined earlier. - **Choose a Provider type**: select **OAuth2/OpenID Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), and configure the following required settings: - - Add the following **Redirect URI**: https://drupal.company/openid-connect/generic + - Add the following **Redirect URI**: `https://drupal.company/openid-connect/generic` - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. 3. Click **Submit** to save the new application and provider. @@ -46,14 +46,14 @@ To support the integration of Drupal with authentik, you need to create an appli ## Drupal configuration -1. From the Admin Toolbar or admin page at https://drupal.company/admin, navigate to **Configuration** > **Web Services** > **OpenID Connect** (or directly at https://drupal.company/admin/config/services/openid-connect) +1. From the Admin Toolbar or admin page at `https://drupal.company/admin`, navigate to **Configuration** > **Web Services** > **OpenID Connect** (or directly at `https://drupal.company/admin/config/services/openid-connect`) 2. Configure the following settings: - Set the **Client ID** and **Client Secret** to the values noted from authentik - Configure the endpoints: - - **Authorization endpoint**: https://authentik.company/application/o/authorize/ - - **Token endpoint**: https://authentik.company/application/o/token/ - - **UserInfo endpoint**: https://authentik.company/application/o/userinfo/ -3. Under **Admin** > **Configuration** > **People** > **Account Settings** (or https://drupal.company/admin/config/people/accounts): + - **Authorization endpoint**: `https://authentik.company/application/o/authorize/` + - **Token endpoint**: `https://authentik.company/application/o/token/` + - **UserInfo endpoint**: `https://authentik.company/application/o/userinfo/` +3. Under **Admin** > **Configuration** > **People** > **Account Settings** (or `https://drupal.company/admin/config/people/accounts`): - If new user registration is disabled, check **Override registration settings** to enable new account creation - Note: Without this setting, new users will receive a message that their account is blocked pending administrator approval 4. Enable the OpenID button on the user login form diff --git a/website/integrations/services/engomo/index.mdx b/website/integrations/services/engomo/index.mdx index 82524895ae..6d5ac05888 100644 --- a/website/integrations/services/engomo/index.mdx +++ b/website/integrations/services/engomo/index.mdx @@ -46,7 +46,7 @@ To support the integration of Engomo with authentik, you need to create an appli - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID** and **slug** values because they will be required later. - Set the **Client type** to `Public`. - - Add two `Strict` redirect URIs and set them to https://engomo.company/auth and com.engomo.engomo://callback/. + - Add two `Strict` redirect URIs and set them to `https://engomo.company/auth` and `com.engomo.engomo://callback/`. - Select any available signing key. - Under **Advanced Protocol Settings**, add the scope you just created to the list of available scopes. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -55,7 +55,7 @@ To support the integration of Engomo with authentik, you need to create an appli ## engomo configuration -Navigate to https://engomo.company/composer and log in with your admin credentials. +Navigate to `https://engomo.company/composer` and log in with your admin credentials. 1. Select **Server**. 2. Select **Authentication**. @@ -64,14 +64,14 @@ Navigate to https://engomo.company/composer and log in with 5. Type: **OpenID Connect** 6. Click **Create**. 7. Configure the following values using information from the authentik provider: - - Set **Issuer** to https://authentik.company/application/o/engomo. + - Set **Issuer** to `https://authentik.company/application/o/engomo`. - Set **Client ID** to the Client ID copied from authentik. - Set **Client secret** to the Client Secret copied from authentik. ## engomo user creation engomo doesn't create users automatically when signing in. So you have to do it manually right now. -Navigate to https://engomo.company/composer and log in with your admin credentials. +Navigate to `https://engomo.company/composer` and log in with your admin credentials. - Select **Users & Devices**. - Click the plus button in the Users section. @@ -80,10 +80,10 @@ Navigate to https://engomo.company/composer and log in with ## Test the login -- Open a browser of your choice and open the URL https://engomo.company. +- Open a browser of your choice and open the URL `https://engomo.company`. - Enter the created user's email address and click the small arrow icon to log in. -- You should be redirected to authentik (with the login flows you created) and then authentik should redirect you back to https://engomo.company/composer URL. -- If you are redirected back to the https://engomo.company/composer URL you did everything correct. +- You should be redirected to authentik (with the login flows you created) and then authentik should redirect you back to `https://engomo.company/composer` URL. +- If you are redirected back to the `https://engomo.company/composer` URL you did everything correct. :::note The created user will only have access to the app or composer page if they have been granted the necessary permissions. diff --git a/website/integrations/services/fortigate-admin/index.md b/website/integrations/services/fortigate-admin/index.md index 3733ac32a7..28491fabda 100644 --- a/website/integrations/services/fortigate-admin/index.md +++ b/website/integrations/services/fortigate-admin/index.md @@ -31,9 +31,9 @@ To support the integration of FortiGate with authentik, you need to create an ap 2. Navigate to **Customization** > **Property Mappings** and click **Create**. Create a **SAML Provider Property Mapping** with the following settings: - **Name**: Choose a descriptive name -- **SAML Attribute Name**: username +- **SAML Attribute Name**: `username` - **Friendly Name**: Leave blank -- **Expression**: return request.user.email +- **Expression**: `return request.user.email` ### Create an application and provider in authentik @@ -43,9 +43,9 @@ To support the integration of FortiGate with authentik, you need to create an ap - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://fgt.company/saml/?acs. - - Set the **Issuer** to https://authentik.company. - - Set the **Audience** to https://fgt.company/metadata. + - Set the **ACS URL** to `https://fgt.company/saml/?acs`. + - Set the **Issuer** to `https://authentik.company`. + - Set the **Audience** to `https://fgt.company/metadata`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, add the **Property Mapping** you created in the previous section, then select an available **Signing Certificate**. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -54,13 +54,13 @@ To support the integration of FortiGate with authentik, you need to create an ap ## FortiGate Configuration -To integrate Fortigate with authentik, nagiate to https://fortigate.company/ng/system/certificate and import the certificate you configured in the previous section. +To integrate Fortigate with authentik, nagiate to `https://fortigate.company/ng/system/certificate` and import the certificate you configured in the previous section. -Once that is done, navigate to https://fortigate.company/fabric-connector/edit/security-fabric-connection and select **Single Sign-On** to configure SAML authentication. You should see, under **Mode**, a toggle named **Service Provider (SP)**, toggle it to enable this authentication method. +Once that is done, navigate to `https://fortigate.company/fabric-connector/edit/security-fabric-connection` and select **Single Sign-On** to configure SAML authentication. You should see, under **Mode**, a toggle named **Service Provider (SP)**, toggle it to enable this authentication method. Then, set the following values in the Fortigate administrative UI: -- **SP Address**: fortigate.company +- **SP Address**: `fortigate.company` - **Default login page**: `Normal` or `Single Sign-On`, depending on your needs. `Normal` allows local and SAML authentication while the latter only allows SAML authentication. - **Default admin profile**: Set this to an available profile. @@ -68,9 +68,9 @@ Under **IdP Details**, set the following values: - **SP entity ID**: `https` - **IdP Type**: `Custom` -- **IdP entity ID**: https://authentik.company -- **IdP Login URL**: https://authentik.company/application/saml/slug-from-authentik/sso/binding/redirect/ -- **IdP Logout URL**: https://authentik.company/application/saml/slug-from-authentik/slo/binding/redirect/ +- **IdP entity ID**: `https://authentik.company` +- **IdP Login URL**: `https://authentik.company/application/saml/slug-from-authentik/sso/binding/redirect/` +- **IdP Logout URL**: `https://authentik.company/application/saml/slug-from-authentik/slo/binding/redirect/` FortiGate creates a new user by default if one does not exist, so you will need to set the Default Admin Profile to the permissions you want any new users to have. (I have created a `no_permissions` profile to assign by default.) diff --git a/website/integrations/services/fortigate-ssl/index.md b/website/integrations/services/fortigate-ssl/index.md index 75e75e4c6d..818829103a 100644 --- a/website/integrations/services/fortigate-ssl/index.md +++ b/website/integrations/services/fortigate-ssl/index.md @@ -49,14 +49,14 @@ To support the integration of FortiGate SSLVPN with authentik, you need to creat - **Choose a Provider type**: select **SAML Provider from metadata** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), and configure the following required settings: - Upload the metadata file from FortiGate (you will get this in the FortiGate configuration steps) - - Set the **ACS URL** to https://fortigate.company/remote/saml/login - - Set the **Audience** to http://fortigate.company/remote/saml/metadata/ + - Set the **ACS URL** to `https://fortigate.company/remote/saml/login` + - Set the **Audience** to `http://fortigate.company/remote/saml/metadata/` - Select your signing certificate - Under **Advanced Protocol Settings**: - - Set **Assertion valid not before** to minutes=5 - - Set **Assertion valid not on or after** to minutes=5 - - Set **Digest algorithm** to sha256 - - Set **Signature algorithm** to sha256 + - Set **Assertion valid not before** to `minutes=5` + - Set **Assertion valid not on or after** to `minutes=5` + - Set **Digest algorithm** to `sha256` + - Set **Signature algorithm** to `sha256` - **Configure Bindings**: create a binding to the user group you created earlier to manage access to the SSLVPN. 3. Click **Submit** to save the new application and provider. @@ -110,7 +110,7 @@ Remember to map the user group to a portal in the 'SSL-VPN Settings' page and ad ### Download SAML metadata -1. Navigate to your FortiGate web interface at https://fortigate.company +1. Navigate to your FortiGate web interface at `https://fortigate.company` 2. Go to **User & Authentication** > **SAML** > **Single Sign-On Server** 3. Click on the "authentik-sso" server you created 4. Click **Download** to get the SAML metadata file @@ -120,7 +120,7 @@ Remember to map the user group to a portal in the 'SSL-VPN Settings' page and ad To verify the integration: -1. Navigate to your FortiGate SSLVPN portal at https://fortigate.company +1. Navigate to your FortiGate SSLVPN portal at `https://fortigate.company` 2. You should be redirected to authentik to authenticate 3. After successful authentication, you should be redirected back to the FortiGate SSLVPN portal 4. Verify that you can establish a VPN connection diff --git a/website/integrations/services/fortimanager/index.md b/website/integrations/services/fortimanager/index.md index 5985df33d8..b8e1d50ad0 100644 --- a/website/integrations/services/fortimanager/index.md +++ b/website/integrations/services/fortimanager/index.md @@ -33,8 +33,8 @@ To support the integration of FortiManager with authentik, you need to create an - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://fortimanager.company/saml/?acs. - - Set the **Issuer** to https://authentik.company/application/saml/application-slug/sso/binding/redirect/. + - Set the **ACS URL** to `https://fortimanager.company/saml/?acs`. + - Set the **Issuer** to `https://authentik.company/application/saml/application-slug/sso/binding/redirect/`. - Set the **Service Provider Binding** to `Post`. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -42,15 +42,15 @@ To support the integration of FortiManager with authentik, you need to create an ## FortiManager Configuration -1. Navigate to https://fortimanager.company/p/app/#!/sys/sso_settings and select **SAML SSO Settings** to configure SAML. +1. Navigate to `https://fortimanager.company/p/app/#!/sys/sso_settings` and select **SAML SSO Settings** to configure SAML. 2. Under **Single Sign-On Mode**, choose **Service Provider (SP)** to enable SAML authentication. -3. Set the **SP Address** field to the FortiManager FQDN, fortimanager.company. This provides the URLs needed for configuration in authentik. +3. Set the **SP Address** field to the FortiManager FQDN, `fortimanager.company`. This provides the URLs needed for configuration in authentik. 4. Choose the **Default Login Page** as either **Normal** or **Single Sign-On**. Selecting **Normal** allows both local and SAML authentication, while **Single Sign-On** restricts login to SAML only. 5. By default, FortiManager creates a new user if one does not exist. Set the **Default Admin Profile** to assign the desired permissions to new users. A `no_permissions` profile is created by default for this purpose. 6. Set the **IdP Type** field to **Custom**. -7. For the **IdP Entity ID** field, enter: https://authentik.company/application/saml/application-slug/sso/binding/redirect/ -8. Set the **IdP Login URL** to: https://authentik.company/application/saml/application-slug/sso/binding/redirect/ -9. Set the **IdP Logout URL** to: https://authentik.company/ +7. For the **IdP Entity ID** field, enter: `https://authentik.company/application/saml/application-slug/sso/binding/redirect/` +8. Set the **IdP Login URL** to: `https://authentik.company/application/saml/application-slug/sso/binding/redirect/` +9. Set the **IdP Logout URL** to: `https://authentik.company/` 10. In the **IdP Certificate** field, import your authentik certificate (either self-signed or valid). ## Configuration verification diff --git a/website/integrations/services/frappe/index.md b/website/integrations/services/frappe/index.md index 3cd046da1d..428cdcbf27 100644 --- a/website/integrations/services/frappe/index.md +++ b/website/integrations/services/frappe/index.md @@ -39,7 +39,7 @@ To support the integration of Frappe with authentik, you need to create an appli - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**, **Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://frappe.company/api/method/frappe.integrations.oauth2_logins.custom/provider. + - Set a `Strict` redirect URI to `https://frappe.company/api/method/frappe.integrations.oauth2_logins.custom/provider`. - Select any available signing key. - Under **Advanced Protocol Settings**, set **Subject mode** to be `Based on the Users's username`. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -72,11 +72,11 @@ To support the integration of Frappe with authentik, you need to create an appli - **Identity Details** - - **Base URL**: https://authentik.company/ + - **Base URL**: `https://authentik.company/` - **Client URLs**: - **Authorize URL**: `/application/o/authorize/` - **Access Token URL**: `/application/o/token/` - - **Redirect URL**: https://frappe.company/api/method/frappe.integrations.oauth2_logins.custom/provider + - **Redirect URL**: `https://frappe.company/api/method/frappe.integrations.oauth2_logins.custom/provider` - **API Endpoint**: `/application/o/userinfo/` ![](./frappe3.png) diff --git a/website/integrations/services/freshrss/index.mdx b/website/integrations/services/freshrss/index.mdx index 8f99af3590..ae034adfe4 100644 --- a/website/integrations/services/freshrss/index.mdx +++ b/website/integrations/services/freshrss/index.mdx @@ -34,7 +34,7 @@ To support the integration of FreshRss with authentik, you need to create an app - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Add two `Strict` redirect URI and set them to https://freshrss.company/i/oidc/ and https://freshrss.company:443/i/oidc/. If FreshRSS is exposed on a port other than `443`, update the second redirect URI accordingly. + - Add two `Strict` redirect URI and set them to `https://freshrss.company/i/oidc/` and `https://freshrss.company:443/i/oidc/`. If FreshRSS is exposed on a port other than `443`, update the second redirect URI accordingly. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/gatus/index.mdx b/website/integrations/services/gatus/index.mdx index 3873f32b70..96751a732e 100644 --- a/website/integrations/services/gatus/index.mdx +++ b/website/integrations/services/gatus/index.mdx @@ -34,7 +34,7 @@ To support the integration of Gatus with authentik, you need to create an applic - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://gatus.company/authorization-code/callback. + - Set a `Strict` redirect URI to `https://gatus.company/authorization-code/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/github-enterprise-cloud/index.md b/website/integrations/services/github-enterprise-cloud/index.md index 5216343b1d..6caab23ce7 100644 --- a/website/integrations/services/github-enterprise-cloud/index.md +++ b/website/integrations/services/github-enterprise-cloud/index.md @@ -37,9 +37,9 @@ To support the integration of GitHub Enterprise Cloud with authentik, you need t - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://github.com/enterprises/foo/saml/consume. - - Set the **Audience** to https://github.com/enterprises/foo. - - Set the **Issuer** to https://github.com/enterprises/foo. + - Set the **ACS URL** to `https://github.com/enterprises/foo/saml/consume`. + - Set the **Audience** to `https://github.com/enterprises/foo`. + - Set the **Issuer** to `https://github.com/enterprises/foo`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. It is advised to download this certificate as it will be required later. It can be found under **System** > **Certificates** in the Admin Interface. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/github-enterprise-emu/index.md b/website/integrations/services/github-enterprise-emu/index.md index 1ab3114051..b75d10b1c0 100644 --- a/website/integrations/services/github-enterprise-emu/index.md +++ b/website/integrations/services/github-enterprise-emu/index.md @@ -49,9 +49,9 @@ GitHub will create usenames for your EMU users based on the SAML `NameID` proper - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://github.com/enterprises/foo/saml/consume. - - Set the **Audience** to https://github.com/enterprises/foo. - - Set the **Issuer** to https://github.com/enterprises/foo. + - Set the **ACS URL** to `https://github.com/enterprises/foo/saml/consume`. + - Set the **Audience** to `https://github.com/enterprises/foo`. + - Set the **Issuer** to `https://github.com/enterprises/foo`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. It is advised to download this certificate as it will be required later. It can be found under **System** > **Certificates** in the Admin Interface. - Under **NameID Property Mapping**, set **NameID Property Mapping** to be based on the `Email` field. diff --git a/website/integrations/services/github-enterprise-server/index.md b/website/integrations/services/github-enterprise-server/index.md index df6997e038..0630b82748 100644 --- a/website/integrations/services/github-enterprise-server/index.md +++ b/website/integrations/services/github-enterprise-server/index.md @@ -39,8 +39,8 @@ In order to use GitHub Enterprise Server, SCIM must also be set up. - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://github.company/saml/consume. - - Set the **Audience** and **Issuer** to https://github.company. + - Set the **ACS URL** to `https://github.company/saml/consume`. + - Set the **Audience** and **Issuer** to `https://github.company`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. It is advised to download this certificate as it will be required later. It can be found under **System** > **Certificates** in the Admin Interface. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/github-organization/index.md b/website/integrations/services/github-organization/index.md index 05127f0ec5..7f08f1967f 100644 --- a/website/integrations/services/github-organization/index.md +++ b/website/integrations/services/github-organization/index.md @@ -33,9 +33,9 @@ To support the integration of AWX Tower with authentik, you need to create an ap - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://github.com/orgs/foo/saml/consume. - - Set the **Audience** to https://github.com/orgs/foo. - - Set the **Issuer** to https://github.com/orgs/foo. + - Set the **ACS URL** to `https://github.com/orgs/foo/saml/consume`. + - Set the **Audience** to `https://github.com/orgs/foo`. + - Set the **Issuer** to `https://github.com/orgs/foo`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. It is advised to download this certificate as it will be required later. It can be found under **System** > **Certificates** in the Admin Interface. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/gitlab/index.mdx b/website/integrations/services/gitlab/index.mdx index 61bff8689f..b933c96777 100644 --- a/website/integrations/services/gitlab/index.mdx +++ b/website/integrations/services/gitlab/index.mdx @@ -52,8 +52,8 @@ To support the integration of GitLab with authentik, you need to create an appli - **Application**: Provide a descriptive name, an optional group, and UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: Select **SAML Provider**. - **Configure the Provider**: - - Set the **ACS URL** to https://gitlab.company/users/auth/saml/callback. - - Set the **Audience** and **Issuer** to https://gitlab.company. + - Set the **ACS URL** to `https://gitlab.company/users/auth/saml/callback`. + - Set the **Audience** and **Issuer** to `https://gitlab.company`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. 3. Click **Submit** to save the new application and provider. @@ -111,7 +111,7 @@ To support the integration of GitLab with authentik, you need to create an appli - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://gitlab.company/users/auth/openid_connect/callback. + - Set a `Strict` redirect URI to `https://gitlab.company/users/auth/openid_connect/callback`. - Select any available signing key. - Under **Advanced protocol settings**, set the **Subject mode** to `Based on the User's Email`. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/glitchtip/index.md b/website/integrations/services/glitchtip/index.md index 4316346eb2..063184372c 100644 --- a/website/integrations/services/glitchtip/index.md +++ b/website/integrations/services/glitchtip/index.md @@ -34,7 +34,7 @@ To support the integration of Glitchtip with authentik, you need to create an ap - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://glitchtip.company/accounts/oidc/authentik/login/callback/. + - Set a `Strict` redirect URI to `https://glitchtip.company/accounts/oidc/authentik/login/callback/`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/globalprotect/index.md b/website/integrations/services/globalprotect/index.md index 72659bf354..732b3d934f 100644 --- a/website/integrations/services/globalprotect/index.md +++ b/website/integrations/services/globalprotect/index.md @@ -38,8 +38,8 @@ To support the integration of GlobalProtect with authentik, you need to create a - **Application**: Provide a descriptive name, an optional group, and UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: Select **SAML Provider**. - **Configure the Provider**: - - Set the **ACS URL** to https://gp.company:443/SAML20/SP/ACS. (Note the absence of the trailing slash and the inclusion of the web interface port) - - Set the **Issuer** to https://authentik.company/application/saml/application-slug/sso/binding/redirect/. + - Set the **ACS URL** to `https://gp.company:443/SAML20/SP/ACS`. (Note the absence of the trailing slash and the inclusion of the web interface port) + - Set the **Issuer** to `https://authentik.company/application/saml/application-slug/sso/binding/redirect/`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. 3. Click **Submit** to save the new application and provider. diff --git a/website/integrations/services/grafana/index.mdx b/website/integrations/services/grafana/index.mdx index 5478055592..e4867ee47b 100644 --- a/website/integrations/services/grafana/index.mdx +++ b/website/integrations/services/grafana/index.mdx @@ -34,7 +34,7 @@ To support the integration of Grafana with authentik, you need to create an appl - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://grafana.company/login/generic_oauth. + - Set a `Strict` redirect URI to `https://grafana.company/login/generic_oauth`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/gravitee/index.md b/website/integrations/services/gravitee/index.md index 124c7e7ced..fb1ac0ed2a 100644 --- a/website/integrations/services/gravitee/index.md +++ b/website/integrations/services/gravitee/index.md @@ -36,7 +36,7 @@ To support the integration of Gravitee with authentik, you need to create an app - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Add two `Strict` redirect URI and set them to https://gravitee.company/user/login and https://gravitee.company/console/. Ensure a trailing slash is present at the end of the second redirect URI. + - Add two `Strict` redirect URI and set them to `https://gravitee.company/user/login` and `https://gravitee.company/console/`. Ensure a trailing slash is present at the end of the second redirect URI. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -53,8 +53,8 @@ Only settings that have been modified from default have been listed. - **Allow portal authentication to use this identity provider**: enable this - **Client ID**: Enter the Client ID from authentik that you noted in step 1 - **Client Secret**: Enter the Client Secret from authentik that you noted in step 1 -- **Token Endpoint**: https://authentik.company/application/o/token/ -- **Authorize Endpoint**: https://authentik.company/application/o/authorize/ -- **Userinfo Endpoint**: https://authentik.company/application/o/userinfo/ -- **Userinfo Logout Endpoint**: https://authentik.company/application/o/application-slug/end-session/ +- **Token Endpoint**: `https://authentik.company/application/o/token/` +- **Authorize Endpoint**: `https://authentik.company/application/o/authorize/` +- **Userinfo Endpoint**: `https://authentik.company/application/o/userinfo/` +- **Userinfo Logout Endpoint**: `https://authentik.company/application/o/application-slug/end-session/` - **Scopes**: `email openid profile` diff --git a/website/integrations/services/gravity/index.md b/website/integrations/services/gravity/index.md index ae6a00a09b..4c32fef73c 100644 --- a/website/integrations/services/gravity/index.md +++ b/website/integrations/services/gravity/index.md @@ -22,7 +22,7 @@ This documentation lists only the settings that you need to change from their de ::: :::note -Gravity automatically triggers SSO authentication when configured. To prevent this behavior, log in using the following URL: https://gravity.company/ui/?local. +Gravity automatically triggers SSO authentication when configured. To prevent this behavior, log in using the following URL: `https://gravity.company/ui/?local`. ::: ## authentik configuration @@ -38,7 +38,7 @@ To support the integration of Gravity with authentik, you need to create an appl - **Choose a Provider type**: Select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: Provide a name (or accept the auto-provided name), choose the authorization flow for this provider, and configure the following required settings: - Note the **Client ID**, **Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://gravity.company/auth/oidc/callback. + - Set a `Strict` redirect URI to `https://gravity.company/auth/oidc/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: Create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -49,10 +49,10 @@ To support the integration of Gravity with authentik, you need to create an appl 1. From the **Gravity administrative interface**, navigate to **Cluster** > **Roles** and click **API**. 2. Under the **OIDC** sub-section, configure the following values: -- **Issuer**: https://authentik.company/application/o/application-slug/ +- **Issuer**: `https://authentik.company/application/o/application-slug/` - **Client ID**: Your Client ID from authentik - **Client Secret**: Your Client Secret from authentik -- **Redirect URL**: https://gravity.company/auth/oidc/callback +- **Redirect URL**: `https://gravity.company/auth/oidc/callback` 3. Click **Update** to save and apply your configuration. diff --git a/website/integrations/services/harbor/index.md b/website/integrations/services/harbor/index.md index d90f47f807..82e923539c 100644 --- a/website/integrations/services/harbor/index.md +++ b/website/integrations/services/harbor/index.md @@ -36,7 +36,7 @@ To support the integration of Harbor with authentik, you need to create an appli - **Protocol Settings**: - **Redirect URI**: - - Strict: https://harbor.company/c/oidc/callback/. + - Strict: `https://harbor.company/c/oidc/callback/`. - **Signing Key**: select any available signing key. - **Advanced Protocol Settings**: - **Scopes**: add `authentik default OAuth Mapping: OpenID 'offline_access'` to **Selected Scopes**. @@ -54,9 +54,9 @@ To support the integration of authentik with Harbor, you need to configure OIDC 3. In the **Auth Mode** dropdown, select **OIDC** and provide the following required configurations. - **OIDC Provider Name**: `authentik` - - **OIDC Endpoint**: https://authentik.company/application/o/harbor - - **OIDC Client ID**: client ID from authentik - - **OIDC Client Secret**: client secret from authentik + - **OIDC Endpoint**: `https://authentik.company/application/o/harbor` + - **OIDC Client ID**: client ID from authentik + - **OIDC Client Secret**: client secret from authentik - **OIDC Scope**: `openid,profile,email,offline_access` - **Username Claim**: `preferred_username` diff --git a/website/integrations/services/hashicorp-cloud/index.md b/website/integrations/services/hashicorp-cloud/index.md index bf2dc0fa85..496f2a0650 100644 --- a/website/integrations/services/hashicorp-cloud/index.md +++ b/website/integrations/services/hashicorp-cloud/index.md @@ -37,8 +37,8 @@ To support the integration of HashiCorp Cloud with authentik, you need to create - **Application**: Provide a descriptive name, an optional group, and UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: Select **SAML Provider**. - **Configure the Provider**: - - Set the **ACS URL** to the value of SSO Sign-On URL in the **HashiCorp Cloud preparation** section. - - Set the **Issuer** and **Audience** to the value of Entity ID in the **HashiCorp Cloud preparation** section. + - Set the **ACS URL** to the value of `SSO Sign-On URL` in the **HashiCorp Cloud preparation** section. + - Set the **Issuer** and **Audience** to the value of `Entity ID` in the **HashiCorp Cloud preparation** section. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. 3. Click **Submit** to save the new application and provider. diff --git a/website/integrations/services/hashicorp-vault/index.md b/website/integrations/services/hashicorp-vault/index.md index e40c85545c..b3329ba9fd 100644 --- a/website/integrations/services/hashicorp-vault/index.md +++ b/website/integrations/services/hashicorp-vault/index.md @@ -38,7 +38,7 @@ To support the integration of Hashicorp Vault with authentik, you need to create - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Add three `Strict` redirect URIs and set them to https://vault.company/ui/vault/auth/oidc/oidc/callback, https://vault.company/oidc/callback, and http://localhost:8250/oidc/callback. + - Add three `Strict` redirect URIs and set them to `https://vault.company/ui/vault/auth/oidc/oidc/callback`, `https://vault.company/oidc/callback`, and `http://localhost:8250/oidc/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/hedgedoc/index.md b/website/integrations/services/hedgedoc/index.md index 639c3a85a7..65cbab83ad 100644 --- a/website/integrations/services/hedgedoc/index.md +++ b/website/integrations/services/hedgedoc/index.md @@ -34,7 +34,7 @@ To support the integration of HedgeDoc with authentik, you need to create an app - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://hedgedoc.company/auth/oauth2/callback. + - Set a `Strict` redirect URI to `https://hedgedoc.company/auth/oauth2/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/homarr/index.md b/website/integrations/services/homarr/index.md index 20dfdf67d0..78c016bd7b 100644 --- a/website/integrations/services/homarr/index.md +++ b/website/integrations/services/homarr/index.md @@ -34,7 +34,7 @@ To support the integration of Homarr with authentik, you need to create an appli - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Create two `strict` redirect URIs and set to https://homarr.company/api/auth/callback/oidc and http://localhost:50575/api/auth/callback/oidc. + - Create two `strict` redirect URIs and set to `https://homarr.company/api/auth/callback/oidc` and ` http://localhost:50575/api/auth/callback/oidc`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/jenkins/index.md b/website/integrations/services/jenkins/index.md index 7164004c76..d68faf44cc 100644 --- a/website/integrations/services/jenkins/index.md +++ b/website/integrations/services/jenkins/index.md @@ -34,7 +34,7 @@ To support the integration of Jenkins with authentik, you need to create an appl - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://jenkins.company/securityRealm/finishLogin. + - Set a `Strict` redirect URI to `https://jenkins.company/securityRealm/finishLogin`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/karakeep/index.md b/website/integrations/services/karakeep/index.md index dfec6b3122..8b3493433b 100644 --- a/website/integrations/services/karakeep/index.md +++ b/website/integrations/services/karakeep/index.md @@ -34,7 +34,7 @@ To support the integration of Karakeep with authentik, you need to create an app - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://karakeep.company/api/auth/callback/custom. + - Set a `Strict` redirect URI to `https://karakeep.company/api/auth/callback/custom`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/kimai/index.md b/website/integrations/services/kimai/index.md index 8ec58037b2..12de340e7d 100644 --- a/website/integrations/services/kimai/index.md +++ b/website/integrations/services/kimai/index.md @@ -34,9 +34,9 @@ To support the integration of Kimai with authentik, you need to create an applic - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://kimai.company/auth/saml/acs. - - Set the **Audience** to https://kimai.companyauth/saml. - - Set the **Issuer** to https://authentik.company. + - Set the **ACS URL** to `https://kimai.company/auth/saml/acs`. + - Set the **Audience** to `https://kimai.companyauth/saml`. + - Set the **Issuer** to `https://authentik.company`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/knocknoc/index.md b/website/integrations/services/knocknoc/index.md index 23fcf1f9d7..a1d38898c1 100644 --- a/website/integrations/services/knocknoc/index.md +++ b/website/integrations/services/knocknoc/index.md @@ -79,10 +79,10 @@ This example will set session duration at 540 minutes. Change the value to match - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. **Protocol Settings**: - - **ACS URL**: https://knocknoc.company/api/saml/acs - - **Issuer**: https://authentik.company + - **ACS URL**: `https://knocknoc.company/api/saml/acs` + - **Issuer**: `https://authentik.company` - **Service Provider Binding**: `Post` - - **Audience**: https://kocknoc.company/api/saml/metadata + - **Audience**: `https://kocknoc.company/api/saml/metadata` - Under **Advanced protocol settings**, add the three **Property Mappings** you created in the previous section, then set the **NameID Property Mapping** to `Authentik default SAML Mapping: Username`. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -99,7 +99,7 @@ This example will set session duration at 540 minutes. Change the value to match 2. Set the following configuration: - **Metadata URL**: **SAML Metadata URL** copied from the authentik provider. - - **Public URL**: https://knocknoc.company + - **Public URL**: `https://knocknoc.company` - **Key file**: select a key file. - **Cert file**: select a certificate file. diff --git a/website/integrations/services/komga/index.md b/website/integrations/services/komga/index.md index a5cb4b9e70..ed1c30079d 100644 --- a/website/integrations/services/komga/index.md +++ b/website/integrations/services/komga/index.md @@ -34,7 +34,7 @@ To support the integration of Komga with authentik, you need to create an applic - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://komga.company/login/oauth2/code/authentik. + - Set a `Strict` redirect URI to `https://komga.company/login/oauth2/code/authentik`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/linkwarden/index.md b/website/integrations/services/linkwarden/index.md index 10ecc8a628..a10262c805 100644 --- a/website/integrations/services/linkwarden/index.md +++ b/website/integrations/services/linkwarden/index.md @@ -34,7 +34,7 @@ To support the integration of Linkwarden with authentik, you need to create an a - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://linkwarden.company/api/v1/auth/callback/authentik. + - Set a `Strict` redirect URI to `https://linkwarden.company/api/v1/auth/callback/authentik`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/mailcow/index.md b/website/integrations/services/mailcow/index.md index 1831feebc6..a90914fa19 100644 --- a/website/integrations/services/mailcow/index.md +++ b/website/integrations/services/mailcow/index.md @@ -38,7 +38,7 @@ To support the integration of mailcow with authentik, you need to create an appl - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID** and **Client Secret** values because they will be required later. - - Set a `Strict` redirect URI to https://mailcow.company. + - Set a `Strict` redirect URI to `https://mailcow.company`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -49,14 +49,14 @@ To support the integration of mailcow with authentik, you need to create an appl To configure mailcow with authentik, log in as an administrator and navigate to **System** > **Configuration**. Then, go to **Access** > **Identity Provider** and enter the following information in the form: -- **Identity Provider**: Generic-OIDC -- **Authorization endpoint**: https://authentik.company/application/o/authorize/ -- **Token endpoint**: https://authentik.company/application/o/token/ -- **User info endpoint**: https://authentik.company/application/o/userinfo/ +- **Identity Provider**: `Generic-OIDC` +- **Authorization endpoint**: `https://authentik.company/application/o/authorize/` +- **Token endpoint**: `https://authentik.company/application/o/token/` +- **User info endpoint**: `https://authentik.company/application/o/userinfo/` - **Client ID**: The `Client ID` from the authentik provider - **Client Secret**: The `Client secret` from the authentik provider -- **Redirect Url**: https://mailcow.company -- **Client Scopes**: openid profile email +- **Redirect Url**: `https://mailcow.company` +- **Client Scopes**: `openid profile email` ## Configuration verification diff --git a/website/integrations/services/mastodon/index.md b/website/integrations/services/mastodon/index.md index c7d1acf433..150a6feb88 100644 --- a/website/integrations/services/mastodon/index.md +++ b/website/integrations/services/mastodon/index.md @@ -34,7 +34,7 @@ To support the integration of Mastodon with authentik, you need to create an app - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://mastodon.company/auth/auth/openid_connect/callback. + - Set a `Strict` redirect URI to `https://mastodon.company/auth/auth/openid_connect/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/matrix-synapse/index.md b/website/integrations/services/matrix-synapse/index.md index a0d4c50e7b..269aa28e4c 100644 --- a/website/integrations/services/matrix-synapse/index.md +++ b/website/integrations/services/matrix-synapse/index.md @@ -34,7 +34,7 @@ To support the integration of Matrix Synapse with authentik, you need to create - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://matrix.company/\_synapse/client/oidc/callback. + - Set a `Strict` redirect URI to `https://matrix.company/\_synapse/client/oidc/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/mautic/index.md b/website/integrations/services/mautic/index.md index daebcc075e..def12835af 100644 --- a/website/integrations/services/mautic/index.md +++ b/website/integrations/services/mautic/index.md @@ -69,15 +69,15 @@ Because Mautic requires a first name and last name attribute, create two [SAML p - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. - **Choose a Provider**: select **SAML Provider** as the provider type. - **Configure the Provider**: - - Set the **Name** to mautic-provider - - Set the **ACS URL** to https://mautic.company/s/saml/login_check - - Set the **Issuer** to mautic.company + - Set the **Name** to `mautic-provider` + - Set the **ACS URL** to `https://mautic.company/s/saml/login_check` + - Set the **Issuer** to `mautic.company` - Set the **Service Provider Binding** to `Post` - Under **Advanced protocol settings** set the **Signing Certificate** to `authentik Self-signed Certificate` and check **Sign assertions** and **Sign responses** - Under **Advanced protocol settings** add the newly created property mappings `SAML-FirstName-from-Name` and `SAML-LastName-from-Name` under **Property Mappings**. **Property Mappings**. 3. Click **Submit** to save the new application and provider. -4. Go to **Applications** > **Providers** and click on mautic-provider. - - Under **Metadata** click on **Download** to save the file as mautic-provider\_authentik_meta.xml. +4. Go to **Applications** > **Providers** and click on `mautic-provider`. + - Under **Metadata** click on **Download** to save the file as `mautic-provider\_authentik_meta.xml`. ## Mautic configuration @@ -92,8 +92,8 @@ When running behind an SSL-terminating reverse proxy (e.g. traefik): In **Config In **Configuration > User/Authentication Settings**, set the following values: -- **Entity ID for the IDP**: https://mautic.company -- **Identity provider metadata file**: The mautic-provider\_authentik_meta.xml file +- **Entity ID for the IDP**: `https://mautic.company` +- **Identity provider metadata file**: The `mautic-provider\_authentik_meta.xml` file - **Default role for created users**: Choose one to enable creating users. - **Email**: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` (as per provider > preview in authentik) - **Username**: `http://schemas.goauthentik.io/2021/02/saml/username` (as per provider > preview in authentik) @@ -145,16 +145,16 @@ Therefore, follow these steps (where the placeholder `Mautic Self-signed Certifi To avoid changing certificates in authentik, go to the authentik Admin interface and generate a new one: 1. Go to **System > Certificates** and click on **Generate**. Use the following values: - - **Common Name**: Mautic Self-signed Certificate + - **Common Name**: `Mautic Self-signed Certificate` - **Private key Algorithm**: `RSA` -2. Click the caret (**>**) next to the newly generated certificate, then select **Download certificate** to get the Mautic Self-signed Certificate\_certificate.pem file and **Download Private key** to get the Mautic Self-signed Certificate\_private_key.pem file. -3. Make sure that the Mautic Self-signed Certificate\_private_key.pem is in PKCS#1 format. - To verify, use `grep` to check for `RSA` in the header and footer of the file: - ```sh - grep "RSA PRIVATE KEY" "Mautic Self-signed Certificate_private_key.pem" - ``` - If the command returns the correct match (e.g., `-----BEGIN RSA PRIVATE KEY-----` and `-----BEGIN RSA PRIVATE KEY-----`), the key is in PKCS#1 format, and you can skip steps 4 to 6. -4. If the key is not in PKCS#1 format, add RSA after `BEGIN` and `END` in Mautic Self-signed Certificate\_private_key.pem as shown below and save the file as `private_key_new.pem`: +2. Click the caret (**>**) next to the newly generated certificate, then select **Download certificate** to get the `Mautic Self-signed Certificate\_certificate.pem` file and **Download Private key** to get the `Mautic Self-signed Certificate\_private_key.pem` file. +3. Make sure that the `Mautic Self-signed Certificate\_private_key.pem` is in PKCS#1 format. + To verify, use `grep`to check for`RSA` in the header and footer of the file: + `sh +grep "RSA PRIVATE KEY" "Mautic Self-signed Certificate_private_key.pem" +` + If the command returns the correct match (e.g., `-----BEGIN RSA PRIVATE KEY-----` and `-----BEGIN RSA PRIVATE KEY-----`), the key is in PKCS#1 format, and you can skip steps 4 to 6. +4. If the key is not in PKCS#1 format, add RSA after `BEGIN` and `END` in `Mautic Self-signed Certificate\_private_key.pem` as shown below and save the file as `private_key_new.pem`: ```diff - -----BEGIN PRIVATE KEY----- + -----BEGIN RSA PRIVATE KEY----- @@ -175,7 +175,7 @@ To avoid changing certificates in authentik, go to the authentik Admin interface - **Organization Name**: `authentik` - **Organizational Unit Name**: `Self-signed` - - **Common Name**: Mautic Self-signed Certificate + - **Common Name**: `Mautic Self-signed Certificate` 6. Next, generate the certificate with the (now) PKCS#1-compliant key and the previously generated signing request using the following command: @@ -185,16 +185,16 @@ To avoid changing certificates in authentik, go to the authentik Admin interface 7. In authentik, navigate to **System > Certificates** and click on **Edit** the update previously generated certificate. Click on the description below the text inputs to activate the inputs. - - **Certificate**: Enter the contents of `certificate_new.pem` or, if steps 4 to 6 were skipped, Mautic Self-signed Certificate\_certificate.pem - - **Private Key**: Enter the contents of `private_key_new.pem` or, if steps 4 to 6 were skipped, Mautic Self-signed Certificate\_private_key.pem + - **Certificate**: Enter the contents of `certificate_new.pem` or, if steps 4 to 6 were skipped, `Mautic Self-signed Certificate\_certificate.pem` + - **Private Key**: Enter the contents of `private_key_new.pem` or, if steps 4 to 6 were skipped, `Mautic Self-signed Certificate\_private_key.pem` - Click on **Update** -8. Navigate to **Applications > Providers** and **Edit** mautic-provider (which was created in [Create an application and provider in authentik](#create-an-application-and-provider-in-authentik)). - In **Advanced protocol settings**, change **Signing Certificate** to Mautic Self-signed Certificate -9. Save the provider, view it, and download the metadata file to mautic-provider\_authentik_meta.xml +8. Navigate to **Applications > Providers** and **Edit** `mautic-provider` (which was created in [Create an application and provider in authentik](#create-an-application-and-provider-in-authentik)). + In **Advanced protocol settings**, change **Signing Certificate** to `Mautic Self-signed Certificate` +9. Save the provider, view it, and download the metadata file to `mautic-provider\_authentik_meta.xml` 10. In Mautic, navigate to **Configuration > User/Authentication Settings** and set the following values: - **X.509 certificate**: The `certificate_new.crt` file - **Private key**: The `private_key_new.pem` file -- **Identity provider metadata file**: The new mautic-provider\_authentik_meta.xml file +- **Identity provider metadata file**: The new `mautic-provider\_authentik_meta.xml` file 11. Click on **Save**. diff --git a/website/integrations/services/meshcentral/index.md b/website/integrations/services/meshcentral/index.md index 2c66252975..bfa36d5f26 100644 --- a/website/integrations/services/meshcentral/index.md +++ b/website/integrations/services/meshcentral/index.md @@ -34,7 +34,7 @@ To support the integration of MeshCentral with authentik, you need to create an - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://meshcentral.company/auth-oidc-callback. + - Set a `Strict` redirect URI to `https://meshcentral.company/auth-oidc-callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/miniflux/index.md b/website/integrations/services/miniflux/index.md index 9fd29b7ce7..dd2baf8b53 100644 --- a/website/integrations/services/miniflux/index.md +++ b/website/integrations/services/miniflux/index.md @@ -37,7 +37,7 @@ To support the integration of Miniflux with authentik, you need to create an app - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - **Redirect URI**: - - Strict: https://miniflux.company/oauth2/oidc/callback + - Strict: `https://miniflux.company/oauth2/oidc/callback` - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -52,7 +52,7 @@ OAUTH2_PROVIDER=oidc OAUTH2_CLIENT_ID= OAUTH2_CLIENT_SECRET= OAUTH2_REDIRECT_URL=https://miniflux.company/oauth2/oidc/callback -OAUTH2_OIDC_DISCOVERY_ENDPOINT=https://authentik.company/application/o// +OAUTH2_OIDC_DISCOVERY_ENDPOINT=https://authentik.company/application/o// OAUTH2_USER_CREATION=1 ``` diff --git a/website/integrations/services/minio/index.md b/website/integrations/services/minio/index.md index 35cb768ffc..d2777dd1a9 100644 --- a/website/integrations/services/minio/index.md +++ b/website/integrations/services/minio/index.md @@ -71,7 +71,7 @@ You can assign multiple policies to a user by returning a list, and returning `N - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://minio.company/oauth_callback. + - Set a `Strict` redirect URI to `https://minio.company/oauth_callback`. - Select any available signing key. - Under **Advanced protocol settings**, add the **Scope** you just created to the list of selected scopes. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/mobilizon/index.md b/website/integrations/services/mobilizon/index.md index c86e403e22..d58a642b36 100644 --- a/website/integrations/services/mobilizon/index.md +++ b/website/integrations/services/mobilizon/index.md @@ -34,7 +34,7 @@ To support the integration of Mobilizon with authentik, you need to create an ap - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://mobilizon.company/auth/keycloak/callback. + - Set a `Strict` redirect URI to `https://mobilizon.company/auth/keycloak/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/netbox/index.md b/website/integrations/services/netbox/index.md index af8a051977..5d7410f888 100644 --- a/website/integrations/services/netbox/index.md +++ b/website/integrations/services/netbox/index.md @@ -34,7 +34,7 @@ To support the integration of NetBox with authentik, you need to create an appli - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://netbox.company/oauth/complete/oidc/. + - Set a `Strict` redirect URI to `https://netbox.company/oauth/complete/oidc/`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/node-red/index.md b/website/integrations/services/node-red/index.md index 5d3e944175..5c5c0f5899 100644 --- a/website/integrations/services/node-red/index.md +++ b/website/integrations/services/node-red/index.md @@ -40,7 +40,7 @@ To support the integration of Node-RED with authentik, you need to create an app - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://nodered.company/auth/strategy/callback/. + - Set a `Strict` redirect URI to `https://nodered.company/auth/strategy/callback/`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/observium/index.md b/website/integrations/services/observium/index.md index 1cc2efef51..beea6e2f6b 100644 --- a/website/integrations/services/observium/index.md +++ b/website/integrations/services/observium/index.md @@ -51,7 +51,7 @@ To support the integration of Observium with authentik, you need to create an ap - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://observium.company/secure/redirect_uri. Note that the Redirect URI can be anything, as long as it does not point to existing content. + - Set a `Strict` redirect URI to `https://observium.company/secure/redirect_uri`. Note that the Redirect URI can be anything, as long as it does not point to existing content. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/omni/index.md b/website/integrations/services/omni/index.md index a3df14a3f9..2483770272 100644 --- a/website/integrations/services/omni/index.md +++ b/website/integrations/services/omni/index.md @@ -45,9 +45,9 @@ To support the integration of Omni with authentik, you need to create a property - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - **ACS URL**: https://omni.company/saml/acs + - **ACS URL**: `https://omni.company/saml/acs` - **Service Provider Binding**: `Post` - - **Audience**: https://omni.company/saml/metadata + - **Audience**: `https://omni.company/saml/metadata` - **Signing Certificate**: select a signing certificate, either the `authentik Self-signed Certificate` or generate a certificate via **System** > **Certificate** - **Sign assertions**: `true` - **Sign responses**: `true` @@ -64,7 +64,7 @@ Add the following environment variables to your Omni configuration. Make sure to ```shell auth-saml-enabled=true -auth-saml-url=https://authentik.company/application/saml//metadata/ +auth-saml-url=https://authentik.company/application/saml//metadata/ ``` ## Configuration verification diff --git a/website/integrations/services/open-webui/index.md b/website/integrations/services/open-webui/index.md index 5efd555a43..37f0bd8bad 100644 --- a/website/integrations/services/open-webui/index.md +++ b/website/integrations/services/open-webui/index.md @@ -34,7 +34,7 @@ To support the integration of Open WebUI with authentik, you need to create an a - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://openwebui.company/oauth/oidc/callback. + - Set a `Strict` redirect URI to `https://openwebui.company/oauth/oidc/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -49,21 +49,21 @@ Enter the following details from the authentik provider: - Set **OAUTH_CLIENT_ID** to the Client ID copied from authentik. - Set **OAUTH_CLIENT_SECRET** to the Client Secret copied from authentik. - Set **OAUTH_PROVIDER_NAME** to `authentik`. -- Set **OPENID_PROVIDER_URL** to https://authentik.company/application/o/your-slug-here/.well-known/openid-configuration. -- Set **OPENID_REDIRECT_URI** to https://openwebui.company/oauth/oidc/callback. +- Set **OPENID_PROVIDER_URL** to `https://authentik.company/application/o/your-slug-here/.well-known/openid-configuration`. +- Set **OPENID_REDIRECT_URI** to `https://openwebui.company/oauth/oidc/callback`. - If you wish for new users to be created on Open Web UI, set **ENABLE_OAUTH_SIGNUP** to 'true'. ## Configuration verification -- Open your web browser and go to https://openwebui.company. +- Open your web browser and go to `https://openwebui.company`. - Make sure you are logged off any previous session. - Click **Continue with authentik** to log in. -- After logging in, authentik will redirect you back to https://openwebui.company. +- After logging in, authentik will redirect you back to `https://openwebui.company`. - If you successfully return to the Open WebUI, the login is working correctly. :::note Users are automatically created, but an administrator must update their role to at least **User** via the WebGUI. -To do so, log in as an administrator and access the **Admin Panel** (URL: https://openwebui.company/admin/users). +To do so, log in as an administrator and access the **Admin Panel** (URL: `https://openwebui.company`/admin/users). Click on the user whose role should be increased from **Pending** to at least **User**. -More details on how to administer Open WebUI can be found here https://docs.openwebui.com/. +More details on how to administer Open WebUI can be found here `https://docs.openwebui.com/`. ::: diff --git a/website/integrations/services/openproject/index.md b/website/integrations/services/openproject/index.md index 7b44ca1f54..5989b2c620 100644 --- a/website/integrations/services/openproject/index.md +++ b/website/integrations/services/openproject/index.md @@ -62,7 +62,7 @@ OpenProject requires a first and last name for each user. By default authentik o - **Protocol settings**: - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - **Redirect URI**: - - Strict: https://openproject.company/auth/oidc-authentik/callback + - Strict: `https://openproject.company/auth/oidc-authentik/callback` - **Signing key**: select any available signing key. - **Advanced protocol settings**: - **Scopes**: @@ -80,7 +80,7 @@ To support the integration of authentik with OpenProject, you need to configure 2. Navigate to **Authentication** > **OpenID providers**. 3. Provide a display name (e.g. `Authentik`) and click **Save**. 4. Click on **I have a discover endpoint URL** and enter: - https://authentik.company/application/o/openproject/.well-known/openid-configuration + `https://authentik.company/application/o/openproject/.well-known/openid-configuration` 5. Under **Advanced configuration** > **Metadata** the values should be automatically populated based on your discovery endpoint URL. If not, these values can be copied from the **Overview** page of the OpenProject provider in authentik. 6. Under **Advanced configuration** > **Client details** enter your authentik client ID and client secret. 7. Under **Optional configuration** > **Attribute mapping** enter the following required configurations: diff --git a/website/integrations/services/oracle-cloud/index.md b/website/integrations/services/oracle-cloud/index.md index 46fd8d1549..70a4814419 100644 --- a/website/integrations/services/oracle-cloud/index.md +++ b/website/integrations/services/oracle-cloud/index.md @@ -34,7 +34,7 @@ To support the integration of Oracle Cloud with authentik, you need to create an - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://tenant.identity.oraclecloud.com/oauth2/v1/authorize. + - Set a `Strict` redirect URI to `https://tenant.identity.oraclecloud.com/oauth2/v1/authorize`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/outline/index.md b/website/integrations/services/outline/index.md index 6f48a6be03..de6034f1fd 100644 --- a/website/integrations/services/outline/index.md +++ b/website/integrations/services/outline/index.md @@ -35,7 +35,7 @@ To support the integration of Outline with authentik, you need to create an appl - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://outline.company/auth/oidc.callback. + - Set a `Strict` redirect URI to `https://outline.company/auth/oidc.callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/owncloud/index.md b/website/integrations/services/owncloud/index.md index ef5bfd1f72..a215a5f212 100644 --- a/website/integrations/services/owncloud/index.md +++ b/website/integrations/services/owncloud/index.md @@ -46,7 +46,7 @@ The configuration for each application is nearly identical, except for the **Cli - **Client Secret**: Use the value generated by authentik. - **Redirect URIs**: - - Strict: https://owncloud.company/apps/openidconnect/redirect + - Strict: `https://owncloud.company/apps/openidconnect/redirect` **Desktop Application** @@ -55,8 +55,8 @@ The configuration for each application is nearly identical, except for the **Cli - **Client Secret**: Use the predefined value found in the [ownCloud admin manual](https://doc.owncloud.com/server/latest/admin_manual/configuration/user/oidc/oidc.html#client-secret). - **Redirect URIs**: - - Regex: http://localhost:\d+ - - Regex: http://127.0.0.1:\d+ + - Regex: `http://localhost:\d+` + - Regex: `http://127.0.0.1:\d+` **Android Application** @@ -65,7 +65,7 @@ The configuration for each application is nearly identical, except for the **Cli - **Client Secret**: Use the predefined value found in the [ownCloud admin manual](https://doc.owncloud.com/server/latest/admin_manual/configuration/user/oidc/oidc.html#client-secret). - **Redirect URI**: - - Strict: oc://android.owncloud.com + - Strict: `oc://android.owncloud.com` **iOS Application** @@ -74,7 +74,7 @@ The configuration for each application is nearly identical, except for the **Cli - **Client Secret**: Use the predefined value found in the [ownCloud admin manual](https://doc.owncloud.com/server/latest/admin_manual/configuration/user/oidc/oidc.html#client-secret). - **Redirect URI**: - - Strict: oc://ios.owncloud.com + - Strict: `oc://ios.owncloud.com` - **Advanced protocol settings:** - **Scopes**: Select the following scopes for each of the four application/provider pairs: `email`, `offline_access`, `openid`, `profile`. diff --git a/website/integrations/services/paperless-ngx/index.mdx b/website/integrations/services/paperless-ngx/index.mdx index b05577e1a1..3d29f1738d 100644 --- a/website/integrations/services/paperless-ngx/index.mdx +++ b/website/integrations/services/paperless-ngx/index.mdx @@ -34,7 +34,7 @@ To support the integration of Paperless-ngx with authentik, you need to create a - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://paperless.company/accounts/oidc/authentik/login/callback/. + - Set a `Strict` redirect URI to `https://paperless.company/accounts/oidc/authentik/login/callback/`. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. - **Advanced protocol settings**: - **Selected Scopes**: Add the following diff --git a/website/integrations/services/pgadmin/index.md b/website/integrations/services/pgadmin/index.md index 2637142dea..b621c629c5 100644 --- a/website/integrations/services/pgadmin/index.md +++ b/website/integrations/services/pgadmin/index.md @@ -38,7 +38,7 @@ To support the integration of pgAdmin with authentik, you need to create an appl - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://pgadmin.company/oauth2/authorize. + - Set a `Strict` redirect URI to `https://pgadmin.company/oauth2/authorize`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/plesk/index.md b/website/integrations/services/plesk/index.md index 70d85de4d8..6d61b30d99 100644 --- a/website/integrations/services/plesk/index.md +++ b/website/integrations/services/plesk/index.md @@ -38,7 +38,7 @@ To support the integration of Plesk with authentik, you need to create an applic - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://plesk.company/modules/oauth/public/login.php. + - Set a `Strict` redirect URI to `https://plesk.company/modules/oauth/public/login.php`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -63,10 +63,10 @@ To support the integration of Plesk with authentik, you need to create an applic - **Client ID**: Enter the Client ID from your authentik provider - **Client Secret**: Enter the Client Secret from your authentik provider - - **Callback Host**: Enter your Plesk FQDN (example: https://plesk.company) - - **Authorize URL**: https://authentik.company/application/o/authorize/ - - **Token URL**: https://authentik.company/application/o/token/ - - **Userinfo URL**: https://authentik.company/application/o/userinfo/ + - **Callback Host**: Enter your Plesk FQDN (example: `https://plesk.company`) + - **Authorize URL**: `https://authentik.company/application/o/authorize/` + - **Token URL**: `https://authentik.company/application/o/token/` + - **Userinfo URL**: `https://authentik.company/application/o/userinfo/` - **Scopes**: `openid,profile,email` - **Login Button Text**: Set your preferred text (example: "Log in with authentik") diff --git a/website/integrations/services/pocketbase/index.md b/website/integrations/services/pocketbase/index.md index 3220335659..3e41789eb4 100644 --- a/website/integrations/services/pocketbase/index.md +++ b/website/integrations/services/pocketbase/index.md @@ -41,7 +41,7 @@ To support the integration of Pocketbase with authentik, you need to create an a - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://pocketbase.company/api/oauth2-redirect. + - Set a `Strict` redirect URI to `https://pocketbase.company/api/oauth2-redirect`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -49,9 +49,9 @@ To support the integration of Pocketbase with authentik, you need to create an a ## PocketBase configuration -1. Sign in to PocketBase and access the superusers dashboard by navigating to https://pocketbase.company/\_/#/settings. +1. Sign in to PocketBase and access the superusers dashboard by navigating to `https://pocketbase.company/\_/#/settings`. 2. Toggle off **Hide collection create and edit controls**," then click the **Save changes** button. -3. Open the **users** collection by clicking the **Collections** icon on the sidebar or head to https://pocketbase.company/\_/#/collections?collection=pb_users_auth. +3. Open the **users** collection by clicking the **Collections** icon on the sidebar or head to `https://pocketbase.company/\_/#/collections?collection=pb_users_auth`. 4. Click the gear icon next to the collection's name, then select the **Options** tab in the popup on the right. 5. Enable the **OAuth2** authentication method by clicking the **OAuth2** tab and toggling **Enable**. 6. Click **+ Add provider**, then select **OpenID Connect**. @@ -59,6 +59,6 @@ To support the integration of Pocketbase with authentik, you need to create an a - Set **Client ID** to the Client ID copied from authentik. - Set **Client secret** to the Client Secret copied from authentik. - Set **Display name** to `authentik`. - - Set **Auth URL** to https://authentik.company/application/o/authorize/. - - Set **Token URL** to https://authentik.company/application/o/token/. - - Make sure **Fetch user info from** is set to `User info URL`, then set **User info URL** to https://authentik.company/application/o/userinfo/ + - Set **Auth URL** to `https://authentik.company/application/o/authorize/`. + - Set **Token URL** to `https://authentik.company/application/o/token/`. + - Make sure **Fetch user info from** is set to `User info URL`, then set **User info URL** to `https://authentik.company/application/o/userinfo/` diff --git a/website/integrations/services/portainer/index.md b/website/integrations/services/portainer/index.md index e309f94fe9..4f5e13b872 100644 --- a/website/integrations/services/portainer/index.md +++ b/website/integrations/services/portainer/index.md @@ -38,7 +38,7 @@ To support the integration of Portainer with authentik, you need to create an ap - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://portainer.company/. + - Set a `Strict` redirect URI to `https://portainer.company/`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/proxmox-ve/index.md b/website/integrations/services/proxmox-ve/index.md index 024f8fba6d..d40f110c8b 100644 --- a/website/integrations/services/proxmox-ve/index.md +++ b/website/integrations/services/proxmox-ve/index.md @@ -38,7 +38,7 @@ To support the integration of Proxmox with authentik, you need to create an appl - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://proxmox.company:8006. + - Set a `Strict` redirect URI to `https://proxmox.company:8006`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/rocketchat/index.md b/website/integrations/services/rocketchat/index.md index e9385e261e..473cefdf86 100644 --- a/website/integrations/services/rocketchat/index.md +++ b/website/integrations/services/rocketchat/index.md @@ -38,7 +38,7 @@ To support the integration of Rocket.chat with authentik, you need to create an - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://rocket.company/\_oauth/authentik. + - Set a `Strict` redirect URI to `https://rocket.company/\_oauth/authentik`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/roundcube/index.md b/website/integrations/services/roundcube/index.md index 797c0bdd52..ed6ad15e43 100644 --- a/website/integrations/services/roundcube/index.md +++ b/website/integrations/services/roundcube/index.md @@ -56,7 +56,7 @@ To support the integration of Roundcube with authentik, you need to create an ap - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://roundcube.company/index.php?\_task=settings&\_action=plugin.oauth_redirect. + - Set a `Strict` redirect URI to `https://roundcube.company/index.php?\_task=settings&\_action=plugin.oauth_redirect`. - Select any available signing key. - Under **Advanced protocol settings**, add the scope you just created to the list of selected scopes. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/rustdesk-pro/index.mdx b/website/integrations/services/rustdesk-pro/index.mdx index 9b96454e07..768b8933eb 100644 --- a/website/integrations/services/rustdesk-pro/index.mdx +++ b/website/integrations/services/rustdesk-pro/index.mdx @@ -38,7 +38,7 @@ To support the integration of Rustdesk Server Pro with authentik, you need to cr - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://rustdesk.company/api/oidc/callback. + - Set a `Strict` redirect URI to `https://rustdesk.company/api/oidc/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -54,11 +54,11 @@ To support the integration of Rustdesk Server Pro with authentik, you need to cr - Set **Name** to `authentik` - Set **Client ID** to the Client ID copied from authentik. - Set **Client secret** to the Client Secret copied from authentik. - - Set **Issuer** to https://authentik.company/application/o/slug/ - - Set **Authorization Endpoint** to https://authentik.company/application/o/authorize/ - - Set **Token Endpoint** to https://authentik.company/application/o/token/ - - Set **Userinfo Endpoint** to https://authentik.company/application/o/userinfo/ - - Set **JWKS Endpoint** to https://authentik.company/application/o/slug/jwks/ + - Set **Issuer** to `https://authentik.company/application/o/slug/` + - Set **Authorization Endpoint** to `https://authentik.company/application/o/authorize/` + - Set **Token Endpoint** to `https://authentik.company/application/o/token/` + - Set **Userinfo Endpoint** to `https://authentik.company/application/o/userinfo/` + - Set **JWKS Endpoint** to `https://authentik.company/application/o/slug/jwks/` :::info Users are created automatically on login. Permissions must be assigned by an administrator after user creation. @@ -66,7 +66,7 @@ Users are created automatically on login. Permissions must be assigned by an adm ## Test the Login -- Open a browser and navigate to https://rustdesk.company. +- Open a browser and navigate to `https://rustdesk.company`. - Click **Continue with authentik**. -- You should be redirected to authentik (with the login flows you configured). After logging in, authentik will redirect you back to https://rustdesk.company. -- If you are redirected back to https://rustdesk.company and can read the username in the top right corner, the setup was successful. +- You should be redirected to authentik (with the login flows you configured). After logging in, authentik will redirect you back to `https://rustdesk.company`. +- If you are redirected back to `https://rustdesk.company` and can read the username in the top right corner, the setup was successful. diff --git a/website/integrations/services/semaphore/index.mdx b/website/integrations/services/semaphore/index.mdx index aee1d9f989..e01a8befdc 100644 --- a/website/integrations/services/semaphore/index.mdx +++ b/website/integrations/services/semaphore/index.mdx @@ -36,7 +36,7 @@ To support the integration of Semaphore with authentik, you need to create an ap - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://semaphore.company/api/auth/oidc/authentik/redirect. + - Set a `Strict` redirect URI to `https://semaphore.company/api/auth/oidc/authentik/redirect`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -84,10 +84,10 @@ More information on this can be found in the Semaphore documentation https://doc ## Test the login -- Open a browser of your choice and open the URL https://semaphore.company. +- Open a browser of your choice and open the URL `https://semaphore.company`. - Click on the SSO-Login button. -- You should be redirected to authentik (with the login flows you created) and then authentik should redirect you back to https://semaphore.company URL. -- If you are redirected back to the https://semaphore.company URL you did everything correct. +- You should be redirected to authentik (with the login flows you created) and then authentik should redirect you back to `https://semaphore.company` URL. +- If you are redirected back to the `https://semaphore.company` URL you did everything correct. :::info Users are created upon logging in with authentik. They will not have the rights to create anything initially. These permissions must be assigned later by the local admin created during the first login to the Semaphore UI. diff --git a/website/integrations/services/slack/index.md b/website/integrations/services/slack/index.md index 5eeb8944e8..16c0f02b67 100644 --- a/website/integrations/services/slack/index.md +++ b/website/integrations/services/slack/index.md @@ -12,7 +12,7 @@ support_level: authentik The following placeholders are used in this guide: -- company.slack.com is the FQDN of your Slack workspace. +- `company.slack.com` is the FQDN of your Slack workspace. - `authentik.company` is the FQDN of the authentik installation. :::note @@ -31,14 +31,14 @@ To support the integration of Slack with authentik, you need to create an applic 2. Navigate to **Customization** > **Property Mappings** and click **Create**. Create two **SAML Provider Property Mapping**s with the following settings: - **Name Mapping:** - **Name**: Choose a descriptive name - - **SAML Attribute Name**: User.Email + - **SAML Attribute Name**: `User.Email` - **Friendly Name**: Leave blank - - **Expression**: return request.user.email + - **Expression**: `return request.user.email` - **Email Mapping:** - **Name**: Choose a descriptive name - - **SAML Attribute Name**: User.Username + - **SAML Attribute Name**: `User.Username` - **Friendly Name**: Leave blank - - **Expression**: return request.user.username + - **Expression**: `return request.user.username` ### Create an application and provider in authentik @@ -48,8 +48,8 @@ To support the integration of Slack with authentik, you need to create an applic - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://company.slack.com/sso/saml. - - Set the **Issuer** to https://slack.com. + - Set the **ACS URL** to `https://company.slack.com/sso/saml`. + - Set the **Issuer** to `https://slack.com`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, add the two **Property Mappings** you created in the previous section, then select a **Signing Certificate**. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/synology-dsm/index.md b/website/integrations/services/synology-dsm/index.md index b3bbe29090..d54b2e0657 100644 --- a/website/integrations/services/synology-dsm/index.md +++ b/website/integrations/services/synology-dsm/index.md @@ -38,7 +38,7 @@ To support the integration of Synology DSM with authentik, you need to create an - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://synology.company. + - Set a `Strict` redirect URI to `https://synology.company`. - Select any available signing key. - Under **Advanced Protocol Settings**, set the **subject mode** to be based on the user's email. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/tandoor/index.md b/website/integrations/services/tandoor/index.md index 0ae54bc863..5cd4cfbfd6 100644 --- a/website/integrations/services/tandoor/index.md +++ b/website/integrations/services/tandoor/index.md @@ -34,7 +34,7 @@ To support the integration of Tandoor with authentik, you need to create an appl - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://tandoor.company/accounts/oidc/authentik/login/callback/. + - Set a `Strict` redirect URI to `https://tandoor.company/accounts/oidc/authentik/login/callback/`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/terrakube/index.md b/website/integrations/services/terrakube/index.md index 54fbea8621..a1437c6b8b 100644 --- a/website/integrations/services/terrakube/index.md +++ b/website/integrations/services/terrakube/index.md @@ -34,7 +34,7 @@ To support the integration of Terrakube with authentik, you need to create an ap - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://terrakube-dex.company/dex/callback. + - Set a `Strict` redirect URI to `https://terrakube-dex.company/dex/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/truecommand/index.md b/website/integrations/services/truecommand/index.md index b0f24dcedc..4983ede264 100644 --- a/website/integrations/services/truecommand/index.md +++ b/website/integrations/services/truecommand/index.md @@ -35,29 +35,29 @@ To support the integration of TrueCommand with authentik, you need to create an 2. Navigate to **Customization** > **Property Mappings** and click **Create**. Create create three or five **SAML Provider Property Mapping**s, depending on your setup, with the following settings: - **Username Mapping:** - **Name**: Choose a descriptive name - - **SAML Attribute Name**: unique_name + - **SAML Attribute Name**: `unique_name` - **Friendly Name**: Leave blank - - **Expression**: return request.user.username + - **Expression**: `return request.user.username` - **Email Mapping:** - **Name**: Choose a descriptive name - - **SAML Attribute Name**: email + - **SAML Attribute Name**: `email` - **Friendly Name**: Leave blank - - **Expression**: return request.user.email + - **Expression**: `return request.user.email` - **Name Mapping:** - **Name**: Choose a descriptive name - - **SAML Attribute Name**: given_name or display_name + - **SAML Attribute Name**: `given_name` or display_name - **Friendly Name**: Leave blank - - **Expression**: return request.user.name + - **Expression**: `return request.user.name` - **Title Mapping:** - **Name**: Choose a descriptive name - - **SAML Attribute Name**: title + - **SAML Attribute Name**: `title` - **Friendly Name**: Leave blank - - **Expression**: return [custom_attribute] + - **Expression**: `return [custom_attribute]` - **Telephone Number Mapping:** - **Name**: Choose a descriptive name - - **SAML Attribute Name**: telephone_number + - **SAML Attribute Name**: `telephone_number` - **Friendly Name**: Leave blank - - **Expression**: return [custom_attribute] + - **Expression**: `return [custom_attribute]` ### Create an application and provider in authentik @@ -67,8 +67,8 @@ To support the integration of TrueCommand with authentik, you need to create an - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://truecommand.company/saml/acs. - - Set the **Issuer** to truecommand-saml. + - Set the **ACS URL** to `https://truecommand.company/saml/acs`. + - Set the **Issuer** to `truecommand-saml`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, add the three or five **Property Mappings** you created in the previous section, then set the **NameID Property Mapping** to be based on the user's email. Finally, select an available signing certificate. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/ubuntu-landscape/index.md b/website/integrations/services/ubuntu-landscape/index.md index a81f6c9bb6..8d17c63e0c 100644 --- a/website/integrations/services/ubuntu-landscape/index.md +++ b/website/integrations/services/ubuntu-landscape/index.md @@ -40,7 +40,7 @@ To support the integration of Landscape with authentik, you need to create an ap - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://landscape.company/login/handle-openid. + - Set a `Strict` redirect URI to `https://landscape.company/login/handle-openid`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/uptime-kuma/index.md b/website/integrations/services/uptime-kuma/index.md index 86f73a6edb..6e5c10b0f6 100644 --- a/website/integrations/services/uptime-kuma/index.md +++ b/website/integrations/services/uptime-kuma/index.md @@ -36,8 +36,8 @@ To support the integration of Uptime Kuma with authentik, you need to create an - **Choose a Provider type**: select **Proxy Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **External host** to https://uptime-kuma.company. - - Set the **Internal host** to http://uptime-kuma:3001 where uptime-kuma:3001 is the hostname and port of your Uptime Kuma container. + - Set the **External host** to `https://uptime-kuma.company`. + - Set the **Internal host** to `http://uptime-kuma:3001` where `uptime-kuma:3001` is the hostname and port of your Uptime Kuma container. - Under **Advanced protocol settings**, set **Unauthenticated Paths** to the following to allow unauthenticated access to the public status page: ``` diff --git a/website/integrations/services/vikunja/index.md b/website/integrations/services/vikunja/index.md index dbff2b68b0..068f677b11 100644 --- a/website/integrations/services/vikunja/index.md +++ b/website/integrations/services/vikunja/index.md @@ -39,7 +39,7 @@ To support the integration of Vikunja with authentik, you need to create an appl - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://vik.company/auth/openid/authentiklogin. + - Set a `Strict` redirect URI to `https://vik.company/auth/openid/authentiklogin`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/vmware-vcenter/index.md b/website/integrations/services/vmware-vcenter/index.md index 76132aea3d..8ff52b7ba3 100644 --- a/website/integrations/services/vmware-vcenter/index.md +++ b/website/integrations/services/vmware-vcenter/index.md @@ -36,7 +36,7 @@ To support the integration of vCenter with authentik, you need to create an appl - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://vcenter.company/ui/login/oauth2/authcode. + - Set a `Strict` redirect URI to `https://vcenter.company/ui/login/oauth2/authcode`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/wazuh/index.mdx b/website/integrations/services/wazuh/index.mdx index 4d32940d67..68a26869e6 100644 --- a/website/integrations/services/wazuh/index.mdx +++ b/website/integrations/services/wazuh/index.mdx @@ -59,7 +59,7 @@ To support the integration of Wazuh with authentik, you need to create a group, - **Application**: provide a descriptive name (e.g., `Wazuh`), an optional group for the type of application, the policy engine mode, and optional UI settings. - **Choose a Provider type**: Select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - **ACS URL**: https://wazuh-dashboard.company/\_opendistro/\_security/saml/acs + - **ACS URL**: `https://wazuh-dashboard.company/\_opendistro/\_security/saml/acs` - **Issuer**: `wazuh-saml` - **Service Provider Binding**: `Post` - Under **Advanced protocol settings**: diff --git a/website/integrations/services/weblate/index.md b/website/integrations/services/weblate/index.md index 4baa39b2b2..a0e1da3de1 100644 --- a/website/integrations/services/weblate/index.md +++ b/website/integrations/services/weblate/index.md @@ -32,7 +32,7 @@ To support the integration of Weblate with authentik, you need to create an appl 2. Navigate to **Customization** > **Property Mappings** and click **Create**. Create four **SAML Provider Property Mapping**s with the following settings: - **Full Name Mapping:** - **Name**: Choose a descriptive name - - **SAML Attribute Name**: urn:oid:2.5.4.3 + - **SAML Attribute Name**: `urn:oid:2.5.4.3` - **Friendly Name**: Leave blank - **Expression**: ```python @@ -40,7 +40,7 @@ To support the integration of Weblate with authentik, you need to create an appl ``` - **OID_USERID Mapping:** - **Name**: Choose a descriptive name - - **SAML Attribute Name**: urn:oid:0.9.2342.19200300.100.1.1 + - **SAML Attribute Name**: `urn:oid:0.9.2342.19200300.100.1.1` - **Friendly Name**: Leave blank - **Expression**: ```python @@ -48,7 +48,7 @@ To support the integration of Weblate with authentik, you need to create an appl ``` - **Username Mapping:** - **Name**: Choose a descriptive name - - **SAML Attribute Name**: username + - **SAML Attribute Name**: `username` - **Friendly Name**: Leave blank - **Expression**: ```python @@ -56,7 +56,7 @@ To support the integration of Weblate with authentik, you need to create an appl ``` - **Email Mapping:** - **Name**: Choose a descriptive name - - **SAML Attribute Name**: email + - **SAML Attribute Name**: `email` - **Friendly Name**: Leave blank - **Expression**: ```python @@ -71,9 +71,9 @@ To support the integration of Weblate with authentik, you need to create an appl - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://weblate.company/accounts/complete/saml/. - - Set the **Audience** to https://weblate.company/accounts/metadata/saml/. - - Set the **Issuer** to https://authentik.company/application/saml/application-slug/sso/binding/redirect/. + - Set the **ACS URL** to `https://weblate.company/accounts/complete/saml/`. + - Set the **Audience** to `https://weblate.company/accounts/metadata/saml/`. + - Set the **Issuer** to `https://authentik.company/application/saml/application-slug/sso/binding/redirect/`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. Then, under **Property mappings**, add the ones you just created. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/wekan/index.mdx b/website/integrations/services/wekan/index.mdx index 217f56b7b5..2d5e3de342 100644 --- a/website/integrations/services/wekan/index.mdx +++ b/website/integrations/services/wekan/index.mdx @@ -34,7 +34,7 @@ To support the integration of Wekan with authentik, you need to create an applic - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://wekan.company/\_oauth/oidc. + - Set a `Strict` redirect URI to `https://wekan.company/\_oauth/oidc`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/whats-up-docker/index.md b/website/integrations/services/whats-up-docker/index.md index cd988863ef..55e325aa45 100644 --- a/website/integrations/services/whats-up-docker/index.md +++ b/website/integrations/services/whats-up-docker/index.md @@ -34,7 +34,7 @@ To support the integration of What's Up Docker with authentik, you need to creat - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://wud.company/auth/oidc/authentik/cb. + - Set a `Strict` redirect URI to `https://wud.company/auth/oidc/authentik/cb`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/wiki-js/index.md b/website/integrations/services/wiki-js/index.md index 2aac3bada1..72bfef1e33 100644 --- a/website/integrations/services/wiki-js/index.md +++ b/website/integrations/services/wiki-js/index.md @@ -44,7 +44,7 @@ To support the integration of Wiki.js with authentik, you need to create an appl - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://wiki.company/login/id-from-wiki/callback. + - Set a `Strict` redirect URI to `https://wiki.company/login/id-from-wiki/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/wordpress/index.md b/website/integrations/services/wordpress/index.md index 0b46114d1b..3d91281545 100644 --- a/website/integrations/services/wordpress/index.md +++ b/website/integrations/services/wordpress/index.md @@ -38,7 +38,7 @@ To support the integration of WordPress with authentik, you need to create an ap - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://wp.company/wp-admin/admin-ajax.php\?action=openid-connect-authorize. + - Set a `Strict` redirect URI to `https://wp.company/wp-admin/admin-ajax.php\?action=openid-connect-authorize`. - Select any available signing key. - Under **Advanced Protocol Settings**, add `offline_access` to the list of available scopes. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/writefreely/index.md b/website/integrations/services/writefreely/index.md index 54725dfbbb..8616c839d0 100644 --- a/website/integrations/services/writefreely/index.md +++ b/website/integrations/services/writefreely/index.md @@ -38,7 +38,7 @@ To support the integration of Writefreely with authentik, you need to create an - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://writefreely.company/oauth/callback/generic. + - Set a `Strict` redirect URI to `https://writefreely.company/oauth/callback/generic`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/xen-orchestra/index.md b/website/integrations/services/xen-orchestra/index.md index 3548061b55..757a24bfcb 100644 --- a/website/integrations/services/xen-orchestra/index.md +++ b/website/integrations/services/xen-orchestra/index.md @@ -39,7 +39,7 @@ To support the integration of Xen Orchestra with authentik, you need to create a - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://xenorchestra.company/signin/oidc/callback. + - Set a `Strict` redirect URI to `https://xenorchestra.company/signin/oidc/callback`. - Select any available signing key. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/zabbix/index.md b/website/integrations/services/zabbix/index.md index 4e2053c3fc..c87baf1fa6 100644 --- a/website/integrations/services/zabbix/index.md +++ b/website/integrations/services/zabbix/index.md @@ -35,8 +35,8 @@ To support the integration of Zabbix with authentik, you need to create an appli - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://zabbix.company/zabbix/index_sso.php?acs. - - Set the **Issuer** to zabbix. + - Set the **ACS URL** to `https://zabbix.company/zabbix/index_sso.php?acs`. + - Set the **Issuer** to `zabbix`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. diff --git a/website/integrations/services/zammad/index.md b/website/integrations/services/zammad/index.md index 26d6edc0f2..8ae724415c 100644 --- a/website/integrations/services/zammad/index.md +++ b/website/integrations/services/zammad/index.md @@ -32,14 +32,14 @@ To support the integration of Zammad with authentik, you need to create an appli 2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. Take note of the **slug** as it will be required later. -- **Choose a Provider type**: select **SAML Provider** as the provider type. +- **Choose a Provider type**: selec`AML Provider\*\* as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://zammad.company/auth/saml/callback. - - Set the **Issuer** to https://zammad.company/auth/saml/metadata. - - Set the **Audience** to https://zammad.company/auth/saml/metadata. - - Set the **Service Provider Binding** to `Post`. + - Set the **ACS URL** `bd>https://zammad.company/auth/saml/callback`. + - Set the **Issuer** to `https://zammad.company/auth/saml/metadata`. + - Set the **Audience** to `https://zammad.company/auth/saml/metadata`. + - Set the **Service Provider Bi`** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. -- **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. +- **Configure Bindings** _`onal)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. 3. Click **Submit** to save the new application and provider. @@ -49,9 +49,10 @@ To support the integration of Zammad with authentik, you need to create an appli 2. Navigate to **Applications** > **Providers** and click on the name of the provider that you created in the previous section (e.g. `Provider for zammad`). 3. Under **Related objects** > **Download signing certificate **, click on **Download**. This downloaded file is your certificate file and it will be required in the next section. -## Zammad configuration +## Zammad configuration` -To configure the Zammad SAML options go to **Settings** (the gear icon) and select **Security** > **Third-party Applications**. Next, activate the **Authentication via SAML** toggle and change the following fields: +` +To configure the Zammad SAML o`s go to **Settings** (the gear icon) and select **Security** > **Third-party Applications**. Next, activate the **Authentication via SAML** toggle and change the following fields: - **Display name**: authentik - **IDP SSO target URL**: `https://authentik.company/application/saml//sso/binding/post/` diff --git a/website/integrations/services/zipline/index.md b/website/integrations/services/zipline/index.md index 8835bdacec..8c1374d1b6 100644 --- a/website/integrations/services/zipline/index.md +++ b/website/integrations/services/zipline/index.md @@ -38,7 +38,7 @@ To support the integration of Zipline with authentik, you need to create an appl - **Choose a Provider type**: Select **OAuth2/OpenID Connect** as the provider type. - **Configure the Provider**: Provide a name (or accept the auto-provided name), choose the authorization flow for this provider, and configure the following required settings: - Note the **Client ID** and **Client Secret** values because they will be required later. - - Set a `Strict` redirect URI to https://zipline.company/api/auth/oauth/oidc. + - Set a `Strict` redirect URI to `https://zipline.company/api/auth/oauth/oidc`. - Select any available signing key. - **Configure Bindings** _(optional)_: Create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -52,9 +52,9 @@ To support the integration of Zipline with authentik, you need to create an appl - **OIDC Client ID**: Your Client ID from authentik - **OIDC Client Secret**: Your Client Secret from authentik -- **OIDC Authorize URL**: https://authentik.company/application/o/authorize/ -- **OIDC Token URL**: https://authentik.company/application/o/token/ -- **OIDC Userinfo URL**: https://authentik.company/application/o/userinfo/ +- **OIDC Authorize URL**: `https://authentik.company/application/o/authorize/` +- **OIDC Token URL**: `https://authentik.company/application/o/token/` +- **OIDC Userinfo URL**: `https://authentik.company/application/o/userinfo/` 3. Then, click **Save**. diff --git a/website/integrations/services/zulip/index.md b/website/integrations/services/zulip/index.md index 7b7a9c3b79..e951cda029 100644 --- a/website/integrations/services/zulip/index.md +++ b/website/integrations/services/zulip/index.md @@ -33,8 +33,8 @@ To support the integration of Zulip with authentik, you need to create an applic - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Set the **ACS URL** to https://zulip.company/complete/saml/. - - Set the **Issuer** to https://zulip.company. + - Set the **ACS URL** to `https://zulip.company/complete/saml/`. + - Set the **Issuer** to `https://zulip.company`. - Set the **Service Provider Binding** to `Post`. - Under **Advanced protocol settings**, select an available signing certificate. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. From 734db4dee650e6cbc8c0a5a2a3c3843f162e1559 Mon Sep 17 00:00:00 2001 From: "Jens L." Date: Tue, 10 Jun 2025 02:36:09 +0200 Subject: [PATCH 39/47] events: rework metrics endpoint (#14934) * rework event volume Signed-off-by: Jens Langhammer * migrate more Signed-off-by: Jens Langhammer * migrate more Signed-off-by: Jens Langhammer * migrate more Signed-off-by: Jens Langhammer * the rest of the owl Signed-off-by: Jens Langhammer * client-side data padding Signed-off-by: Jens Langhammer * I love deleting code Signed-off-by: Jens Langhammer * fix Signed-off-by: Jens Langhammer * fix clamping Signed-off-by: Jens Langhammer * chunk it Signed-off-by: Jens Langhammer * fix Signed-off-by: Jens Langhammer * fix tests Signed-off-by: Jens Langhammer * add event-to-color map Signed-off-by: Jens Langhammer * sync colours Signed-off-by: Jens Langhammer * switch colours Signed-off-by: Jens Langhammer * heatmap? Signed-off-by: Jens Langhammer * Revert "heatmap?" This reverts commit c1f549a18b61ef28753bc36cf7ffa4ed3d15b87d. * Revert "Revert "heatmap?"" This reverts commit 6d6175b96bda21ac6ca9030463eff4fbc1692f98. * Revert "Revert "Revert "heatmap?""" This reverts commit 3717903f1275a0efc5a6952c18d6103e2849daf8. * format Signed-off-by: Jens Langhammer --------- Signed-off-by: Jens Langhammer --- authentik/admin/api/metrics.py | 79 ----- authentik/admin/tests/test_api.py | 5 - authentik/admin/urls.py | 6 - authentik/core/api/applications.py | 19 -- authentik/core/api/users.py | 60 ---- authentik/core/tests/test_users_api.py | 16 - authentik/events/api/events.py | 79 ++--- authentik/events/models.py | 63 ---- authentik/rbac/tests/test_decorators.py | 45 +-- pyproject.toml | 1 + schema.yml | 288 ++++++------------ .../admin/admin-overview/DashboardUserPage.ts | 8 +- .../charts/AdminLoginAuthorizeChart.ts | 95 +++--- .../admin-overview/charts/AdminModelPerDay.ts | 61 ++-- .../charts/OutpostStatusChart.ts | 9 +- .../admin-overview/charts/SyncStatusChart.ts | 15 +- .../applications/ApplicationAuthorizeChart.ts | 58 ++-- .../admin/applications/ApplicationViewPage.ts | 2 +- web/src/admin/events/EventVolumeChart.ts | 41 +-- web/src/admin/users/UserChart.ts | 100 +++--- web/src/admin/users/UserViewPage.ts | 2 +- web/src/elements/charts/Chart.ts | 32 +- web/src/elements/charts/EventChart.ts | 120 ++++++++ 23 files changed, 461 insertions(+), 743 deletions(-) delete mode 100644 authentik/admin/api/metrics.py create mode 100644 web/src/elements/charts/EventChart.ts diff --git a/authentik/admin/api/metrics.py b/authentik/admin/api/metrics.py deleted file mode 100644 index 6929767ecf..0000000000 --- a/authentik/admin/api/metrics.py +++ /dev/null @@ -1,79 +0,0 @@ -"""authentik administration metrics""" - -from datetime import timedelta - -from django.db.models.functions import ExtractHour -from drf_spectacular.utils import extend_schema, extend_schema_field -from guardian.shortcuts import get_objects_for_user -from rest_framework.fields import IntegerField, SerializerMethodField -from rest_framework.permissions import IsAuthenticated -from rest_framework.request import Request -from rest_framework.response import Response -from rest_framework.views import APIView - -from authentik.core.api.utils import PassiveSerializer -from authentik.events.models import EventAction - - -class CoordinateSerializer(PassiveSerializer): - """Coordinates for diagrams""" - - x_cord = IntegerField(read_only=True) - y_cord = IntegerField(read_only=True) - - -class LoginMetricsSerializer(PassiveSerializer): - """Login Metrics per 1h""" - - logins = SerializerMethodField() - logins_failed = SerializerMethodField() - authorizations = SerializerMethodField() - - @extend_schema_field(CoordinateSerializer(many=True)) - def get_logins(self, _): - """Get successful logins per 8 hours for the last 7 days""" - user = self.context["user"] - return ( - get_objects_for_user(user, "authentik_events.view_event").filter( - action=EventAction.LOGIN - ) - # 3 data points per day, so 8 hour spans - .get_events_per(timedelta(days=7), ExtractHour, 7 * 3) - ) - - @extend_schema_field(CoordinateSerializer(many=True)) - def get_logins_failed(self, _): - """Get failed logins per 8 hours for the last 7 days""" - user = self.context["user"] - return ( - get_objects_for_user(user, "authentik_events.view_event").filter( - action=EventAction.LOGIN_FAILED - ) - # 3 data points per day, so 8 hour spans - .get_events_per(timedelta(days=7), ExtractHour, 7 * 3) - ) - - @extend_schema_field(CoordinateSerializer(many=True)) - def get_authorizations(self, _): - """Get successful authorizations per 8 hours for the last 7 days""" - user = self.context["user"] - return ( - get_objects_for_user(user, "authentik_events.view_event").filter( - action=EventAction.AUTHORIZE_APPLICATION - ) - # 3 data points per day, so 8 hour spans - .get_events_per(timedelta(days=7), ExtractHour, 7 * 3) - ) - - -class AdministrationMetricsViewSet(APIView): - """Login Metrics per 1h""" - - permission_classes = [IsAuthenticated] - - @extend_schema(responses={200: LoginMetricsSerializer(many=False)}) - def get(self, request: Request) -> Response: - """Login Metrics per 1h""" - serializer = LoginMetricsSerializer(True) - serializer.context["user"] = request.user - return Response(serializer.data) diff --git a/authentik/admin/tests/test_api.py b/authentik/admin/tests/test_api.py index ed6656470a..1268812e7d 100644 --- a/authentik/admin/tests/test_api.py +++ b/authentik/admin/tests/test_api.py @@ -36,11 +36,6 @@ class TestAdminAPI(TestCase): body = loads(response.content) self.assertEqual(len(body), 0) - def test_metrics(self): - """Test metrics API""" - response = self.client.get(reverse("authentik_api:admin_metrics")) - self.assertEqual(response.status_code, 200) - def test_apps(self): """Test apps API""" response = self.client.get(reverse("authentik_api:apps-list")) diff --git a/authentik/admin/urls.py b/authentik/admin/urls.py index 51bdd4eca5..0dd6fc02f2 100644 --- a/authentik/admin/urls.py +++ b/authentik/admin/urls.py @@ -3,7 +3,6 @@ from django.urls import path from authentik.admin.api.meta import AppsViewSet, ModelViewSet -from authentik.admin.api.metrics import AdministrationMetricsViewSet from authentik.admin.api.system import SystemView from authentik.admin.api.version import VersionView from authentik.admin.api.version_history import VersionHistoryViewSet @@ -12,11 +11,6 @@ from authentik.admin.api.workers import WorkerView api_urlpatterns = [ ("admin/apps", AppsViewSet, "apps"), ("admin/models", ModelViewSet, "models"), - path( - "admin/metrics/", - AdministrationMetricsViewSet.as_view(), - name="admin_metrics", - ), path("admin/version/", VersionView.as_view(), name="admin_version"), ("admin/version/history", VersionHistoryViewSet, "version_history"), path("admin/workers/", WorkerView.as_view(), name="admin_workers"), diff --git a/authentik/core/api/applications.py b/authentik/core/api/applications.py index c96680d373..269b82d2db 100644 --- a/authentik/core/api/applications.py +++ b/authentik/core/api/applications.py @@ -2,11 +2,9 @@ from collections.abc import Iterator from copy import copy -from datetime import timedelta from django.core.cache import cache from django.db.models import QuerySet -from django.db.models.functions import ExtractHour from django.shortcuts import get_object_or_404 from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema @@ -20,7 +18,6 @@ from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet from structlog.stdlib import get_logger -from authentik.admin.api.metrics import CoordinateSerializer from authentik.api.pagination import Pagination from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT from authentik.core.api.providers import ProviderSerializer @@ -28,7 +25,6 @@ from authentik.core.api.used_by import UsedByMixin from authentik.core.api.utils import ModelSerializer from authentik.core.models import Application, User from authentik.events.logs import LogEventSerializer, capture_logs -from authentik.events.models import EventAction from authentik.lib.utils.file import ( FilePathSerializer, FileUploadSerializer, @@ -321,18 +317,3 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet): """Set application icon (as URL)""" app: Application = self.get_object() return set_file_url(request, app, "meta_icon") - - @permission_required("authentik_core.view_application", ["authentik_events.view_event"]) - @extend_schema(responses={200: CoordinateSerializer(many=True)}) - @action(detail=True, pagination_class=None, filter_backends=[]) - def metrics(self, request: Request, slug: str): - """Metrics for application logins""" - app = self.get_object() - return Response( - get_objects_for_user(request.user, "authentik_events.view_event").filter( - action=EventAction.AUTHORIZE_APPLICATION, - context__authorized_application__pk=app.pk.hex, - ) - # 3 data points per day, so 8 hour spans - .get_events_per(timedelta(days=7), ExtractHour, 7 * 3) - ) diff --git a/authentik/core/api/users.py b/authentik/core/api/users.py index 2e95a1396e..7a560959e0 100644 --- a/authentik/core/api/users.py +++ b/authentik/core/api/users.py @@ -6,7 +6,6 @@ from typing import Any from django.contrib.auth import update_session_auth_hash from django.contrib.auth.models import Permission -from django.db.models.functions import ExtractHour from django.db.transaction import atomic from django.db.utils import IntegrityError from django.urls import reverse_lazy @@ -52,7 +51,6 @@ from rest_framework.validators import UniqueValidator from rest_framework.viewsets import ModelViewSet from structlog.stdlib import get_logger -from authentik.admin.api.metrics import CoordinateSerializer from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT from authentik.brands.models import Brand from authentik.core.api.used_by import UsedByMixin @@ -317,53 +315,6 @@ class SessionUserSerializer(PassiveSerializer): original = UserSelfSerializer(required=False) -class UserMetricsSerializer(PassiveSerializer): - """User Metrics""" - - logins = SerializerMethodField() - logins_failed = SerializerMethodField() - authorizations = SerializerMethodField() - - @extend_schema_field(CoordinateSerializer(many=True)) - def get_logins(self, _): - """Get successful logins per 8 hours for the last 7 days""" - user = self.context["user"] - request = self.context["request"] - return ( - get_objects_for_user(request.user, "authentik_events.view_event").filter( - action=EventAction.LOGIN, user__pk=user.pk - ) - # 3 data points per day, so 8 hour spans - .get_events_per(timedelta(days=7), ExtractHour, 7 * 3) - ) - - @extend_schema_field(CoordinateSerializer(many=True)) - def get_logins_failed(self, _): - """Get failed logins per 8 hours for the last 7 days""" - user = self.context["user"] - request = self.context["request"] - return ( - get_objects_for_user(request.user, "authentik_events.view_event").filter( - action=EventAction.LOGIN_FAILED, context__username=user.username - ) - # 3 data points per day, so 8 hour spans - .get_events_per(timedelta(days=7), ExtractHour, 7 * 3) - ) - - @extend_schema_field(CoordinateSerializer(many=True)) - def get_authorizations(self, _): - """Get failed logins per 8 hours for the last 7 days""" - user = self.context["user"] - request = self.context["request"] - return ( - get_objects_for_user(request.user, "authentik_events.view_event").filter( - action=EventAction.AUTHORIZE_APPLICATION, user__pk=user.pk - ) - # 3 data points per day, so 8 hour spans - .get_events_per(timedelta(days=7), ExtractHour, 7 * 3) - ) - - class UsersFilter(FilterSet): """Filter for users""" @@ -607,17 +558,6 @@ class UserViewSet(UsedByMixin, ModelViewSet): update_session_auth_hash(self.request, user) return Response(status=204) - @permission_required("authentik_core.view_user", ["authentik_events.view_event"]) - @extend_schema(responses={200: UserMetricsSerializer(many=False)}) - @action(detail=True, pagination_class=None, filter_backends=[]) - def metrics(self, request: Request, pk: int) -> Response: - """User metrics per 1h""" - user: User = self.get_object() - serializer = UserMetricsSerializer(instance={}) - serializer.context["user"] = user - serializer.context["request"] = request - return Response(serializer.data) - @permission_required("authentik_core.reset_user_password") @extend_schema( responses={ diff --git a/authentik/core/tests/test_users_api.py b/authentik/core/tests/test_users_api.py index ff5a28bec4..b35ce2d70f 100644 --- a/authentik/core/tests/test_users_api.py +++ b/authentik/core/tests/test_users_api.py @@ -81,22 +81,6 @@ class TestUsersAPI(APITestCase): response = self.client.get(reverse("authentik_api:user-list"), {"include_groups": "true"}) self.assertEqual(response.status_code, 200) - def test_metrics(self): - """Test user's metrics""" - self.client.force_login(self.admin) - response = self.client.get( - reverse("authentik_api:user-metrics", kwargs={"pk": self.user.pk}) - ) - self.assertEqual(response.status_code, 200) - - def test_metrics_denied(self): - """Test user's metrics (non-superuser)""" - self.client.force_login(self.user) - response = self.client.get( - reverse("authentik_api:user-metrics", kwargs={"pk": self.user.pk}) - ) - self.assertEqual(response.status_code, 403) - def test_recovery_no_flow(self): """Test user recovery link (no recovery flow set)""" self.client.force_login(self.admin) diff --git a/authentik/events/api/events.py b/authentik/events/api/events.py index 609161152f..73f3f2593d 100644 --- a/authentik/events/api/events.py +++ b/authentik/events/api/events.py @@ -1,28 +1,36 @@ """Events API Views""" from datetime import timedelta -from json import loads import django_filters -from django.db.models.aggregates import Count +from django.db.models import Count, ExpressionWrapper, F, QuerySet +from django.db.models import DateTimeField as DjangoDateTimeField from django.db.models.fields.json import KeyTextTransform, KeyTransform -from django.db.models.functions import ExtractDay, ExtractHour +from django.db.models.functions import TruncHour from django.db.models.query_utils import Q +from django.utils.timezone import now from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import OpenApiParameter, extend_schema from guardian.shortcuts import get_objects_for_user from rest_framework.decorators import action -from rest_framework.fields import DictField, IntegerField +from rest_framework.fields import ChoiceField, DateTimeField, DictField, IntegerField from rest_framework.request import Request from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet -from authentik.admin.api.metrics import CoordinateSerializer from authentik.core.api.object_types import TypeCreateSerializer from authentik.core.api.utils import ModelSerializer, PassiveSerializer from authentik.events.models import Event, EventAction +class EventVolumeSerializer(PassiveSerializer): + """Count of events of action created on day""" + + action = ChoiceField(choices=EventAction.choices) + time = DateTimeField() + count = IntegerField() + + class EventSerializer(ModelSerializer): """Event Serializer""" @@ -53,7 +61,7 @@ class EventsFilter(django_filters.FilterSet): """Filter for events""" username = django_filters.CharFilter( - field_name="user", lookup_expr="username", label="Username" + field_name="user", label="Username", method="filter_username" ) context_model_pk = django_filters.CharFilter( field_name="context", @@ -78,12 +86,19 @@ class EventsFilter(django_filters.FilterSet): field_name="action", lookup_expr="icontains", ) + actions = django_filters.MultipleChoiceFilter( + field_name="action", + choices=EventAction.choices, + ) brand_name = django_filters.CharFilter( field_name="brand", lookup_expr="name", label="Brand name", ) + def filter_username(self, queryset, name, value): + return queryset.filter(Q(user__username=value) | Q(context__username=value)) + def filter_context_model_pk(self, queryset, name, value): """Because we store the PK as UUID.hex, we need to remove the dashes that a client may send. We can't use a @@ -156,45 +171,37 @@ class EventViewSet(ModelViewSet): return Response(EventTopPerUserSerializer(instance=events, many=True).data) @extend_schema( - responses={200: CoordinateSerializer(many=True)}, - ) - @action(detail=False, methods=["GET"], pagination_class=None) - def volume(self, request: Request) -> Response: - """Get event volume for specified filters and timeframe""" - queryset = self.filter_queryset(self.get_queryset()) - return Response(queryset.get_events_per(timedelta(days=7), ExtractHour, 7 * 3)) - - @extend_schema( - responses={200: CoordinateSerializer(many=True)}, - filters=[], + responses={200: EventVolumeSerializer(many=True)}, parameters=[ OpenApiParameter( - "action", - type=OpenApiTypes.STR, - location=OpenApiParameter.QUERY, - required=False, - ), - OpenApiParameter( - "query", - type=OpenApiTypes.STR, + "history_days", + type=OpenApiTypes.NUMBER, location=OpenApiParameter.QUERY, required=False, + default=7, ), ], ) @action(detail=False, methods=["GET"], pagination_class=None) - def per_month(self, request: Request): - """Get the count of events per month""" - filtered_action = request.query_params.get("action", EventAction.LOGIN) - try: - query = loads(request.query_params.get("query", "{}")) - except ValueError: - return Response(status=400) + def volume(self, request: Request) -> Response: + """Get event volume for specified filters and timeframe""" + queryset: QuerySet[Event] = self.filter_queryset(self.get_queryset()) + delta = timedelta(days=7) + time_delta = request.query_params.get("history_days", 7) + if time_delta: + delta = timedelta(days=min(int(time_delta), 60)) return Response( - get_objects_for_user(request.user, "authentik_events.view_event") - .filter(action=filtered_action) - .filter(**query) - .get_events_per(timedelta(weeks=4), ExtractDay, 30) + queryset.filter(created__gte=now() - delta) + .annotate(hour=TruncHour("created")) + .annotate( + time=ExpressionWrapper( + F("hour") - (F("hour__hour") % 6) * timedelta(hours=1), + output_field=DjangoDateTimeField(), + ) + ) + .values("time", "action") + .annotate(count=Count("pk")) + .order_by("time", "action") ) @extend_schema(responses={200: TypeCreateSerializer(many=True)}) diff --git a/authentik/events/models.py b/authentik/events/models.py index 6ade3c107d..83d87da916 100644 --- a/authentik/events/models.py +++ b/authentik/events/models.py @@ -1,7 +1,5 @@ """authentik events models""" -import time -from collections import Counter from datetime import timedelta from difflib import get_close_matches from functools import lru_cache @@ -11,11 +9,6 @@ from uuid import uuid4 from django.apps import apps from django.db import connection, models -from django.db.models import Count, ExpressionWrapper, F -from django.db.models.fields import DurationField -from django.db.models.functions import Extract -from django.db.models.manager import Manager -from django.db.models.query import QuerySet from django.http import HttpRequest from django.http.request import QueryDict from django.utils.timezone import now @@ -124,60 +117,6 @@ class EventAction(models.TextChoices): CUSTOM_PREFIX = "custom_" -class EventQuerySet(QuerySet): - """Custom events query set with helper functions""" - - def get_events_per( - self, - time_since: timedelta, - extract: Extract, - data_points: int, - ) -> list[dict[str, int]]: - """Get event count by hour in the last day, fill with zeros""" - _now = now() - max_since = timedelta(days=60) - # Allow maximum of 60 days to limit load - if time_since.total_seconds() > max_since.total_seconds(): - time_since = max_since - date_from = _now - time_since - result = ( - self.filter(created__gte=date_from) - .annotate(age=ExpressionWrapper(_now - F("created"), output_field=DurationField())) - .annotate(age_interval=extract("age")) - .values("age_interval") - .annotate(count=Count("pk")) - .order_by("age_interval") - ) - data = Counter({int(d["age_interval"]): d["count"] for d in result}) - results = [] - interval_delta = time_since / data_points - for interval in range(1, -data_points, -1): - results.append( - { - "x_cord": time.mktime((_now + (interval_delta * interval)).timetuple()) * 1000, - "y_cord": data[interval * -1], - } - ) - return results - - -class EventManager(Manager): - """Custom helper methods for Events""" - - def get_queryset(self) -> QuerySet: - """use custom queryset""" - return EventQuerySet(self.model, using=self._db) - - def get_events_per( - self, - time_since: timedelta, - extract: Extract, - data_points: int, - ) -> list[dict[str, int]]: - """Wrap method from queryset""" - return self.get_queryset().get_events_per(time_since, extract, data_points) - - class Event(SerializerModel, ExpiringModel): """An individual Audit/Metrics/Notification/Error Event""" @@ -193,8 +132,6 @@ class Event(SerializerModel, ExpiringModel): # Shadow the expires attribute from ExpiringModel to override the default duration expires = models.DateTimeField(default=default_event_duration) - objects = EventManager() - @staticmethod def _get_app_from_request(request: HttpRequest) -> str: if not isinstance(request, HttpRequest): diff --git a/authentik/rbac/tests/test_decorators.py b/authentik/rbac/tests/test_decorators.py index 974ce97652..dae9377418 100644 --- a/authentik/rbac/tests/test_decorators.py +++ b/authentik/rbac/tests/test_decorators.py @@ -1,12 +1,29 @@ """test decorators api""" -from django.urls import reverse from guardian.shortcuts import assign_perm +from rest_framework.decorators import action +from rest_framework.request import Request +from rest_framework.response import Response from rest_framework.test import APITestCase +from rest_framework.viewsets import ModelViewSet from authentik.core.models import Application from authentik.core.tests.utils import create_test_user from authentik.lib.generators import generate_id +from authentik.lib.tests.utils import get_request +from authentik.rbac.decorators import permission_required + + +class MVS(ModelViewSet): + + queryset = Application.objects.all() + lookup_field = "slug" + + @permission_required("authentik_core.view_application", ["authentik_events.view_event"]) + @action(detail=True, pagination_class=None, filter_backends=[]) + def test(self, request: Request, slug: str): + self.get_object() + return Response(status=200) class TestAPIDecorators(APITestCase): @@ -18,41 +35,33 @@ class TestAPIDecorators(APITestCase): def test_obj_perm_denied(self): """Test object perm denied""" - self.client.force_login(self.user) + request = get_request("", user=self.user) app = Application.objects.create(name=generate_id(), slug=generate_id()) - response = self.client.get( - reverse("authentik_api:application-metrics", kwargs={"slug": app.slug}) - ) + response = MVS.as_view({"get": "test"})(request, slug=app.slug) self.assertEqual(response.status_code, 403) def test_obj_perm_global(self): """Test object perm successful (global)""" assign_perm("authentik_core.view_application", self.user) assign_perm("authentik_events.view_event", self.user) - self.client.force_login(self.user) app = Application.objects.create(name=generate_id(), slug=generate_id()) - response = self.client.get( - reverse("authentik_api:application-metrics", kwargs={"slug": app.slug}) - ) - self.assertEqual(response.status_code, 200) + request = get_request("", user=self.user) + response = MVS.as_view({"get": "test"})(request, slug=app.slug) + self.assertEqual(response.status_code, 200, response.data) def test_obj_perm_scoped(self): """Test object perm successful (scoped)""" assign_perm("authentik_events.view_event", self.user) app = Application.objects.create(name=generate_id(), slug=generate_id()) assign_perm("authentik_core.view_application", self.user, app) - self.client.force_login(self.user) - response = self.client.get( - reverse("authentik_api:application-metrics", kwargs={"slug": app.slug}) - ) + request = get_request("", user=self.user) + response = MVS.as_view({"get": "test"})(request, slug=app.slug) self.assertEqual(response.status_code, 200) def test_other_perm_denied(self): """Test other perm denied""" - self.client.force_login(self.user) app = Application.objects.create(name=generate_id(), slug=generate_id()) assign_perm("authentik_core.view_application", self.user, app) - response = self.client.get( - reverse("authentik_api:application-metrics", kwargs={"slug": app.slug}) - ) + request = get_request("", user=self.user) + response = MVS.as_view({"get": "test"})(request, slug=app.slug) self.assertEqual(response.status_code, 403) diff --git a/pyproject.toml b/pyproject.toml index 9c3adb2477..62c2cbb00c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -140,6 +140,7 @@ skip = [ "**/storybook-static", "**/web/src/locales", "**/web/xliff", + "**/web/out", "./web/storybook-static", "./web/custom-elements.json", "./website/build", diff --git a/schema.yml b/schema.yml index f807f7af24..ae415b8f15 100644 --- a/schema.yml +++ b/schema.yml @@ -38,33 +38,6 @@ paths: schema: $ref: '#/components/schemas/GenericError' description: '' - /admin/metrics/: - get: - operationId: admin_metrics_retrieve - description: Login Metrics per 1h - tags: - - admin - security: - - authentik: [] - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/LoginMetrics' - description: '' - '400': - content: - application/json: - schema: - $ref: '#/components/schemas/ValidationError' - description: '' - '403': - content: - application/json: - schema: - $ref: '#/components/schemas/GenericError' - description: '' /admin/models/: get: operationId: admin_models_list @@ -4136,42 +4109,6 @@ paths: schema: $ref: '#/components/schemas/GenericError' description: '' - /core/applications/{slug}/metrics/: - get: - operationId: core_applications_metrics_list - description: Metrics for application logins - parameters: - - in: path - name: slug - schema: - type: string - description: Internal application name, used in URLs. - required: true - tags: - - core - security: - - authentik: [] - responses: - '200': - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Coordinate' - description: '' - '400': - content: - application/json: - schema: - $ref: '#/components/schemas/ValidationError' - description: '' - '403': - content: - application/json: - schema: - $ref: '#/components/schemas/GenericError' - description: '' /core/applications/{slug}/set_icon/: post: operationId: core_applications_set_icon_create @@ -6071,40 +6008,6 @@ paths: schema: $ref: '#/components/schemas/GenericError' description: '' - /core/users/{id}/metrics/: - get: - operationId: core_users_metrics_retrieve - description: User metrics per 1h - parameters: - - in: path - name: id - schema: - type: integer - description: A unique integer value identifying this User. - required: true - tags: - - core - security: - - authentik: [] - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/UserMetrics' - description: '' - '400': - content: - application/json: - schema: - $ref: '#/components/schemas/ValidationError' - description: '' - '403': - content: - application/json: - schema: - $ref: '#/components/schemas/GenericError' - description: '' /core/users/{id}/recovery/: post: operationId: core_users_recovery_create @@ -7112,6 +7015,42 @@ paths: name: action schema: type: string + - in: query + name: actions + schema: + type: array + items: + type: string + enum: + - authorize_application + - configuration_error + - custom_ + - email_sent + - flow_execution + - impersonation_ended + - impersonation_started + - invitation_used + - login + - login_failed + - logout + - model_created + - model_deleted + - model_updated + - password_set + - policy_exception + - policy_execution + - property_mapping_exception + - secret_rotate + - secret_view + - source_linked + - suspicious_request + - system_exception + - system_task_exception + - system_task_execution + - update_available + - user_write + explode: true + style: form - in: query name: brand_name schema: @@ -7398,44 +7337,6 @@ paths: schema: $ref: '#/components/schemas/GenericError' description: '' - /events/events/per_month/: - get: - operationId: events_events_per_month_list - description: Get the count of events per month - parameters: - - in: query - name: action - schema: - type: string - - in: query - name: query - schema: - type: string - tags: - - events - security: - - authentik: [] - responses: - '200': - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Coordinate' - description: '' - '400': - content: - application/json: - schema: - $ref: '#/components/schemas/ValidationError' - description: '' - '403': - content: - application/json: - schema: - $ref: '#/components/schemas/GenericError' - description: '' /events/events/top_per_user/: get: operationId: events_events_top_per_user_list @@ -7483,6 +7384,42 @@ paths: name: action schema: type: string + - in: query + name: actions + schema: + type: array + items: + type: string + enum: + - authorize_application + - configuration_error + - custom_ + - email_sent + - flow_execution + - impersonation_ended + - impersonation_started + - invitation_used + - login + - login_failed + - logout + - model_created + - model_deleted + - model_updated + - password_set + - policy_exception + - policy_execution + - property_mapping_exception + - secret_rotate + - secret_view + - source_linked + - suspicious_request + - system_exception + - system_task_exception + - system_task_execution + - update_available + - user_write + explode: true + style: form - in: query name: brand_name schema: @@ -7512,6 +7449,11 @@ paths: schema: type: string description: Context Model Primary Key + - in: query + name: history_days + schema: + type: number + default: 7 - name: ordering required: false in: query @@ -7540,7 +7482,7 @@ paths: schema: type: array items: - $ref: '#/components/schemas/Coordinate' + $ref: '#/components/schemas/EventVolume' description: '' '400': content: @@ -43596,19 +43538,6 @@ components: - sidebar_left - sidebar_right type: string - Coordinate: - type: object - description: Coordinates for diagrams - properties: - x_cord: - type: integer - readOnly: true - y_cord: - type: integer - readOnly: true - required: - - x_cord - - y_cord CountryCodeEnum: enum: - AF @@ -44986,6 +44915,21 @@ components: - application - counted_events - unique_users + EventVolume: + type: object + description: Count of events of action created on day + properties: + action: + $ref: '#/components/schemas/EventActions' + time: + type: string + format: date-time + count: + type: integer + required: + - action + - count + - time EventsRequestedEnum: enum: - https://schemas.openid.net/secevent/caep/event-type/session-revoked @@ -48297,29 +48241,6 @@ components: xak-flow-redirect: '#/components/schemas/RedirectChallenge' ak-source-oauth-apple: '#/components/schemas/AppleLoginChallenge' ak-source-plex: '#/components/schemas/PlexAuthenticationChallenge' - LoginMetrics: - type: object - description: Login Metrics per 1h - properties: - logins: - type: array - items: - $ref: '#/components/schemas/Coordinate' - readOnly: true - logins_failed: - type: array - items: - $ref: '#/components/schemas/Coordinate' - readOnly: true - authorizations: - type: array - items: - $ref: '#/components/schemas/Coordinate' - readOnly: true - required: - - authorizations - - logins - - logins_failed LoginSource: type: object description: Serializer for Login buttons of sources @@ -60729,29 +60650,6 @@ components: - username_link - username_deny type: string - UserMetrics: - type: object - description: User Metrics - properties: - logins: - type: array - items: - $ref: '#/components/schemas/Coordinate' - readOnly: true - logins_failed: - type: array - items: - $ref: '#/components/schemas/Coordinate' - readOnly: true - authorizations: - type: array - items: - $ref: '#/components/schemas/Coordinate' - readOnly: true - required: - - authorizations - - logins - - logins_failed UserOAuthSourceConnection: type: object description: User source connection diff --git a/web/src/admin/admin-overview/DashboardUserPage.ts b/web/src/admin/admin-overview/DashboardUserPage.ts index eb1b168bd0..0d8a765628 100644 --- a/web/src/admin/admin-overview/DashboardUserPage.ts +++ b/web/src/admin/admin-overview/DashboardUserPage.ts @@ -13,7 +13,7 @@ import PFList from "@patternfly/patternfly/components/List/list.css"; import PFPage from "@patternfly/patternfly/components/Page/page.css"; import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css"; -import { EventActions } from "@goauthentik/api"; +import { EventActions, EventsEventsVolumeListRequest } from "@goauthentik/api"; @customElement("ak-admin-dashboard-users") export class DashboardUserPage extends AKElement { @@ -46,9 +46,9 @@ export class DashboardUserPage extends AKElement { diff --git a/web/src/admin/admin-overview/charts/AdminLoginAuthorizeChart.ts b/web/src/admin/admin-overview/charts/AdminLoginAuthorizeChart.ts index 59345a1e7c..fdca98eb63 100644 --- a/web/src/admin/admin-overview/charts/AdminLoginAuthorizeChart.ts +++ b/web/src/admin/admin-overview/charts/AdminLoginAuthorizeChart.ts @@ -1,68 +1,51 @@ +import { EventChart } from "#elements/charts/EventChart"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; -import { AKChart, RGBAColor } from "@goauthentik/elements/charts/Chart"; -import { ChartData } from "chart.js"; +import { ChartData, ChartDataset } from "chart.js"; import { msg } from "@lit/localize"; import { customElement } from "lit/decorators.js"; -import { AdminApi, LoginMetrics } from "@goauthentik/api"; +import { EventActions, EventVolume, EventsApi } from "@goauthentik/api"; @customElement("ak-charts-admin-login-authorization") -export class AdminLoginAuthorizeChart extends AKChart { - async apiRequest(): Promise { - return new AdminApi(DEFAULT_CONFIG).adminMetricsRetrieve(); +export class AdminLoginAuthorizeChart extends EventChart { + async apiRequest(): Promise { + return new EventsApi(DEFAULT_CONFIG).eventsEventsVolumeList({ + actions: [ + EventActions.AuthorizeApplication, + EventActions.Login, + EventActions.LoginFailed, + ], + }); } - getChartData(data: LoginMetrics): ChartData { - return { - datasets: [ - { - label: msg("Authorizations"), - backgroundColor: new RGBAColor(43, 154, 243, 0.5).toString(), - borderColor: new RGBAColor(43, 154, 243, 1).toString(), - spanGaps: true, - fill: "origin", - cubicInterpolationMode: "monotone", - tension: 0.4, - data: data.authorizations.map((cord) => { - return { - x: cord.xCord, - y: cord.yCord, - }; - }), - }, - { - label: msg("Failed Logins"), - backgroundColor: new RGBAColor(201, 24, 11, 0.5).toString(), - borderColor: new RGBAColor(201, 24, 11, 1).toString(), - spanGaps: true, - fill: "origin", - cubicInterpolationMode: "monotone", - tension: 0.4, - data: data.loginsFailed.map((cord) => { - return { - x: cord.xCord, - y: cord.yCord, - }; - }), - }, - { - label: msg("Successful Logins"), - backgroundColor: new RGBAColor(62, 134, 53, 0.5).toString(), - borderColor: new RGBAColor(62, 134, 53, 1).toString(), - spanGaps: true, - fill: "origin", - cubicInterpolationMode: "monotone", - tension: 0.4, - data: data.logins.map((cord) => { - return { - x: cord.xCord, - y: cord.yCord, - }; - }), - }, - ], - }; + getChartData(data: EventVolume[]): ChartData { + const optsMap = new Map>(); + optsMap.set(EventActions.AuthorizeApplication, { + label: msg("Authorizations"), + spanGaps: true, + fill: "origin", + cubicInterpolationMode: "monotone", + tension: 0.4, + }); + optsMap.set(EventActions.Login, { + label: msg("Successful Logins"), + spanGaps: true, + fill: "origin", + cubicInterpolationMode: "monotone", + tension: 0.4, + }); + optsMap.set(EventActions.LoginFailed, { + label: msg("Failed Logins"), + spanGaps: true, + fill: "origin", + cubicInterpolationMode: "monotone", + tension: 0.4, + }); + return this.eventVolume(data, { + optsMap: optsMap, + padToDays: 7, + }); } } diff --git a/web/src/admin/admin-overview/charts/AdminModelPerDay.ts b/web/src/admin/admin-overview/charts/AdminModelPerDay.ts index 5227616d4b..f728a415f2 100644 --- a/web/src/admin/admin-overview/charts/AdminModelPerDay.ts +++ b/web/src/admin/admin-overview/charts/AdminModelPerDay.ts @@ -1,14 +1,19 @@ +import { EventChart } from "#elements/charts/EventChart"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; -import { AKChart } from "@goauthentik/elements/charts/Chart"; -import { ChartData, Tick } from "chart.js"; +import { ChartData } from "chart.js"; -import { msg, str } from "@lit/localize"; +import { msg } from "@lit/localize"; import { customElement, property } from "lit/decorators.js"; -import { Coordinate, EventActions, EventsApi } from "@goauthentik/api"; +import { + EventActions, + EventVolume, + EventsApi, + EventsEventsVolumeListRequest, +} from "@goauthentik/api"; @customElement("ak-charts-admin-model-per-day") -export class AdminModelPerDay extends AKChart { +export class AdminModelPerDay extends EventChart { @property() action: EventActions = EventActions.ModelCreated; @@ -16,39 +21,29 @@ export class AdminModelPerDay extends AKChart { label?: string; @property({ attribute: false }) - query?: { [key: string]: unknown } | undefined; + query?: EventsEventsVolumeListRequest; - async apiRequest(): Promise { - return new EventsApi(DEFAULT_CONFIG).eventsEventsPerMonthList({ + async apiRequest(): Promise { + return new EventsApi(DEFAULT_CONFIG).eventsEventsVolumeList({ action: this.action, - query: JSON.stringify(this.query || {}), + historyDays: 30, + ...this.query, }); } - timeTickCallback(tickValue: string | number, index: number, ticks: Tick[]): string { - const valueStamp = ticks[index]; - const delta = Date.now() - valueStamp.value; - const ago = Math.round(delta / 1000 / 3600 / 24); - return msg(str`${ago} days ago`); - } - - getChartData(data: Coordinate[]): ChartData { - return { - datasets: [ - { - label: this.label || msg("Objects created"), - backgroundColor: "rgba(189, 229, 184, .5)", - spanGaps: true, - data: - data.map((cord) => { - return { - x: cord.xCord || 0, - y: cord.yCord || 0, - }; - }) || [], - }, - ], - }; + getChartData(data: EventVolume[]): ChartData { + return this.eventVolume(data, { + optsMap: new Map([ + [ + this.action, + { + label: this.label || msg("Objects created"), + spanGaps: true, + }, + ], + ]), + padToDays: 30, + }); } } diff --git a/web/src/admin/admin-overview/charts/OutpostStatusChart.ts b/web/src/admin/admin-overview/charts/OutpostStatusChart.ts index f62535bc84..1bee838288 100644 --- a/web/src/admin/admin-overview/charts/OutpostStatusChart.ts +++ b/web/src/admin/admin-overview/charts/OutpostStatusChart.ts @@ -1,3 +1,4 @@ +import { actionToColor } from "#elements/charts/EventChart"; import { SummarizedSyncStatus } from "@goauthentik/admin/admin-overview/charts/SyncStatusChart"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { AKChart } from "@goauthentik/elements/charts/Chart"; @@ -7,7 +8,7 @@ import { ChartData, ChartOptions } from "chart.js"; import { msg } from "@lit/localize"; import { customElement } from "lit/decorators.js"; -import { OutpostsApi } from "@goauthentik/api"; +import { EventActions, OutpostsApi } from "@goauthentik/api"; @customElement("ak-admin-status-chart-outpost") export class OutpostStatusChart extends AKChart { @@ -65,7 +66,11 @@ export class OutpostStatusChart extends AKChart { labels: [msg("Healthy outposts"), msg("Outdated outposts"), msg("Unhealthy outposts")], datasets: data.map((d) => { return { - backgroundColor: ["#3e8635", "#C9190B", "#2b9af3"], + backgroundColor: [ + actionToColor(EventActions.Login), + actionToColor(EventActions.SuspiciousRequest), + actionToColor(EventActions.AuthorizeApplication), + ], spanGaps: true, data: [d.healthy, d.failed, d.unsynced], label: d.label, diff --git a/web/src/admin/admin-overview/charts/SyncStatusChart.ts b/web/src/admin/admin-overview/charts/SyncStatusChart.ts index 7855823133..e864546fd1 100644 --- a/web/src/admin/admin-overview/charts/SyncStatusChart.ts +++ b/web/src/admin/admin-overview/charts/SyncStatusChart.ts @@ -1,3 +1,4 @@ +import { actionToColor } from "#elements/charts/EventChart"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { AKChart } from "@goauthentik/elements/charts/Chart"; import "@goauthentik/elements/forms/ConfirmationForm"; @@ -7,7 +8,13 @@ import { ChartData, ChartOptions } from "chart.js"; import { msg } from "@lit/localize"; import { customElement } from "lit/decorators.js"; -import { ProvidersApi, SourcesApi, SyncStatus, SystemTaskStatusEnum } from "@goauthentik/api"; +import { + EventActions, + ProvidersApi, + SourcesApi, + SyncStatus, + SystemTaskStatusEnum, +} from "@goauthentik/api"; export interface SummarizedSyncStatus { healthy: number; @@ -136,7 +143,11 @@ export class SyncStatusChart extends AKChart { labels: [msg("Healthy"), msg("Failed"), msg("Unsynced / N/A")], datasets: data.map((d) => { return { - backgroundColor: ["#3e8635", "#C9190B", "#2b9af3"], + backgroundColor: [ + actionToColor(EventActions.Login), + actionToColor(EventActions.SuspiciousRequest), + actionToColor(EventActions.AuthorizeApplication), + ], spanGaps: true, data: [d.healthy, d.failed, d.unsynced], label: d.label, diff --git a/web/src/admin/applications/ApplicationAuthorizeChart.ts b/web/src/admin/applications/ApplicationAuthorizeChart.ts index 0d1b8ac7b2..37de1b0e3f 100644 --- a/web/src/admin/applications/ApplicationAuthorizeChart.ts +++ b/web/src/admin/applications/ApplicationAuthorizeChart.ts @@ -1,47 +1,37 @@ +import { EventChart } from "#elements/charts/EventChart"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; -import { AKChart } from "@goauthentik/elements/charts/Chart"; -import { ChartData, Tick } from "chart.js"; +import { ChartData } from "chart.js"; -import { msg, str } from "@lit/localize"; +import { msg } from "@lit/localize"; import { customElement, property } from "lit/decorators.js"; -import { Coordinate, CoreApi } from "@goauthentik/api"; +import { EventActions, EventVolume, EventsApi } from "@goauthentik/api"; @customElement("ak-charts-application-authorize") -export class ApplicationAuthorizeChart extends AKChart { - @property() - applicationSlug!: string; +export class ApplicationAuthorizeChart extends EventChart { + @property({ attribute: "application-id" }) + applicationId!: string; - async apiRequest(): Promise { - return new CoreApi(DEFAULT_CONFIG).coreApplicationsMetricsList({ - slug: this.applicationSlug, + async apiRequest(): Promise { + return new EventsApi(DEFAULT_CONFIG).eventsEventsVolumeList({ + action: EventActions.AuthorizeApplication, + contextAuthorizedApp: this.applicationId.replaceAll("-", ""), }); } - timeTickCallback(tickValue: string | number, index: number, ticks: Tick[]): string { - const valueStamp = ticks[index]; - const delta = Date.now() - valueStamp.value; - const ago = Math.round(delta / 1000 / 3600 / 24); - return msg(str`${ago} days ago`); - } - - getChartData(data: Coordinate[]): ChartData { - return { - datasets: [ - { - label: msg("Authorizations"), - backgroundColor: "rgba(189, 229, 184, .5)", - spanGaps: true, - data: - data.map((cord) => { - return { - x: cord.xCord || 0, - y: cord.yCord || 0, - }; - }) || [], - }, - ], - }; + getChartData(data: EventVolume[]): ChartData { + return this.eventVolume(data, { + optsMap: new Map([ + [ + EventActions.AuthorizeApplication, + { + label: msg("Authorizations"), + spanGaps: true, + }, + ], + ]), + padToDays: 7, + }); } } diff --git a/web/src/admin/applications/ApplicationViewPage.ts b/web/src/admin/applications/ApplicationViewPage.ts index 7c23925316..39c7a19e69 100644 --- a/web/src/admin/applications/ApplicationViewPage.ts +++ b/web/src/admin/applications/ApplicationViewPage.ts @@ -282,7 +282,7 @@ export class ApplicationViewPage extends AKElement {
${this.application && html` `}
diff --git a/web/src/admin/events/EventVolumeChart.ts b/web/src/admin/events/EventVolumeChart.ts index 3ff3c49fd5..fa38d0e6e8 100644 --- a/web/src/admin/events/EventVolumeChart.ts +++ b/web/src/admin/events/EventVolumeChart.ts @@ -1,21 +1,21 @@ +import { EventChart } from "#elements/charts/EventChart"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; -import { AKChart } from "@goauthentik/elements/charts/Chart"; import { ChartData } from "chart.js"; -import { msg } from "@lit/localize"; import { CSSResult, TemplateResult, css, html } from "lit"; import { customElement, property } from "lit/decorators.js"; import PFCard from "@patternfly/patternfly/components/Card/card.css"; -import { Coordinate, EventsApi, EventsEventsListRequest } from "@goauthentik/api"; +import { EventVolume, EventsApi, EventsEventsListRequest } from "@goauthentik/api"; @customElement("ak-events-volume-chart") -export class EventVolumeChart extends AKChart { +export class EventVolumeChart extends EventChart { _query?: EventsEventsListRequest; @property({ attribute: false }) set query(value: EventsEventsListRequest | undefined) { + if (JSON.stringify(this._query) === JSON.stringify(value)) return; this._query = value; this.refreshHandler(); } @@ -24,39 +24,28 @@ export class EventVolumeChart extends AKChart { return super.styles.concat( PFCard, css` - .pf-c-card__body { - height: 12rem; + .pf-c-card { + height: 20rem; } `, ); } - apiRequest(): Promise { - return new EventsApi(DEFAULT_CONFIG).eventsEventsVolumeList(this._query); + apiRequest(): Promise { + return new EventsApi(DEFAULT_CONFIG).eventsEventsVolumeList({ + historyDays: 7, + ...this._query, + }); } - getChartData(data: Coordinate[]): ChartData { - return { - datasets: [ - { - label: msg("Events"), - backgroundColor: "rgba(189, 229, 184, .5)", - spanGaps: true, - data: - data.map((cord) => { - return { - x: cord.xCord || 0, - y: cord.yCord || 0, - }; - }) || [], - }, - ], - }; + getChartData(data: EventVolume[]): ChartData { + return this.eventVolume(data, { + padToDays: 7, + }); } render(): TemplateResult { return html`
-
${msg("Event volume")}
${super.render()}
`; } diff --git a/web/src/admin/users/UserChart.ts b/web/src/admin/users/UserChart.ts index fb7c7fedf6..a5b8144486 100644 --- a/web/src/admin/users/UserChart.ts +++ b/web/src/admin/users/UserChart.ts @@ -1,71 +1,55 @@ +import { EventChart } from "#elements/charts/EventChart"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; -import { AKChart } from "@goauthentik/elements/charts/Chart"; -import { ChartData, Tick } from "chart.js"; +import { ChartData } from "chart.js"; -import { msg, str } from "@lit/localize"; +import { msg } from "@lit/localize"; import { customElement, property } from "lit/decorators.js"; -import { CoreApi, UserMetrics } from "@goauthentik/api"; +import { EventActions, EventVolume, EventsApi } from "@goauthentik/api"; @customElement("ak-charts-user") -export class UserChart extends AKChart { - @property({ type: Number }) - userId?: number; +export class UserChart extends EventChart { + @property() + username?: string; - async apiRequest(): Promise { - return new CoreApi(DEFAULT_CONFIG).coreUsersMetricsRetrieve({ - id: this.userId || 0, + async apiRequest(): Promise { + return new EventsApi(DEFAULT_CONFIG).eventsEventsVolumeList({ + actions: [ + EventActions.Login, + EventActions.LoginFailed, + EventActions.AuthorizeApplication, + ], + username: this.username, }); } - timeTickCallback(tickValue: string | number, index: number, ticks: Tick[]): string { - const valueStamp = ticks[index]; - const delta = Date.now() - valueStamp.value; - const ago = Math.round(delta / 1000 / 3600 / 24); - return msg(str`${ago} days ago`); - } - - getChartData(data: UserMetrics): ChartData { - return { - datasets: [ - { - label: msg("Failed Logins"), - backgroundColor: "rgba(201, 25, 11, .5)", - spanGaps: true, - data: - data.loginsFailed?.map((cord) => { - return { - x: cord.xCord || 0, - y: cord.yCord || 0, - }; - }) || [], - }, - { - label: msg("Successful Logins"), - backgroundColor: "rgba(189, 229, 184, .5)", - spanGaps: true, - data: - data.logins?.map((cord) => { - return { - x: cord.xCord || 0, - y: cord.yCord || 0, - }; - }) || [], - }, - { - label: msg("Application authorizations"), - backgroundColor: "rgba(43, 154, 243, .5)", - spanGaps: true, - data: - data.authorizations?.map((cord) => { - return { - x: cord.xCord || 0, - y: cord.yCord || 0, - }; - }) || [], - }, - ], - }; + getChartData(data: EventVolume[]): ChartData { + return this.eventVolume(data, { + optsMap: new Map([ + [ + EventActions.LoginFailed, + { + label: msg("Failed Logins"), + spanGaps: true, + }, + ], + [ + EventActions.Login, + { + label: msg("Successful Logins"), + spanGaps: true, + }, + ], + [ + EventActions.AuthorizeApplication, + { + label: msg("Application authorizations"), + spanGaps: true, + }, + ], + ]), + padToDays: 7, + }); } } diff --git a/web/src/admin/users/UserViewPage.ts b/web/src/admin/users/UserViewPage.ts index 4360c34afd..85c7391273 100644 --- a/web/src/admin/users/UserViewPage.ts +++ b/web/src/admin/users/UserViewPage.ts @@ -389,7 +389,7 @@ export class UserViewPage extends WithCapabilitiesConfig(AKElement) { ${msg("Actions over the last week (per 8 hours)")}
- +
> (i * 8)) & 255; - rgb[i] = value; - } - return new RGBAColor(rgb[0], rgb[1], rgb[2]); -} - export abstract class AKChart extends AKElement { abstract apiRequest(): Promise; abstract getChartData(data: T): ChartData; @@ -184,7 +158,7 @@ export abstract class AKChart extends AKElement { responsive: true, scales: { x: { - type: "time", + type: "timeseries", display: true, ticks: { callback: (tickValue: string | number, index: number, ticks: Tick[]) => { diff --git a/web/src/elements/charts/EventChart.ts b/web/src/elements/charts/EventChart.ts new file mode 100644 index 0000000000..cfc5c43879 --- /dev/null +++ b/web/src/elements/charts/EventChart.ts @@ -0,0 +1,120 @@ +import { actionToLabel } from "#common/labels"; +import { AKChart } from "#elements/charts/Chart"; +import { ChartData, ChartDataset } from "chart.js"; + +import { EventActions, EventVolume } from "@goauthentik/api"; + +export function actionToColor(action: EventActions): string { + switch (action) { + case EventActions.AuthorizeApplication: + return "#0060c0"; + case EventActions.ConfigurationError: + return "#23511e"; + case EventActions.EmailSent: + return "#009596"; + case EventActions.FlowExecution: + return "#f4c145"; + case EventActions.ImpersonationEnded: + return "#a2d9d9"; + case EventActions.ImpersonationStarted: + return "#a2d9d9"; + case EventActions.InvitationUsed: + return "#8bc1f7"; + case EventActions.Login: + return "#4cb140"; + case EventActions.LoginFailed: + return "#ec7a08"; + case EventActions.Logout: + return "#f9e0a2"; + case EventActions.ModelCreated: + return "#8f4700"; + case EventActions.ModelDeleted: + return "#002f5d"; + case EventActions.ModelUpdated: + return "#bde2b9"; + case EventActions.PasswordSet: + return "#003737"; + case EventActions.PolicyException: + return "#c58c00"; + case EventActions.PolicyExecution: + return "#f4b678"; + case EventActions.PropertyMappingException: + return "#519de9"; + case EventActions.SecretRotate: + return "#38812f"; + case EventActions.SecretView: + return "#73c5c5"; + case EventActions.SourceLinked: + return "#f6d173"; + case EventActions.SuspiciousRequest: + return "#c46100"; + case EventActions.SystemException: + return "#004b95"; + case EventActions.SystemTaskException: + return "#7cc674"; + case EventActions.SystemTaskExecution: + return "#005f60"; + case EventActions.UpdateAvailable: + return "#f0ab00"; + case EventActions.UserWrite: + return "#ef9234"; + } + return ""; +} + +export abstract class EventChart extends AKChart { + eventVolume( + data: EventVolume[], + options?: { + optsMap?: Map>; + padToDays?: number; + }, + ): ChartData { + const datasets: ChartData = { + datasets: [], + }; + if (!options) { + options = {}; + } + if (!options.optsMap) { + options.optsMap = new Map>(); + } + const actions = new Set(data.map((v) => v.action)); + actions.forEach((action) => { + const actionData: { x: number; y: number }[] = []; + data.filter((v) => v.action === action).forEach((v) => { + actionData.push({ + x: v.time.getTime(), + y: v.count, + }); + }); + // Check if we need to pad the data to reach a certain time window + const earliestDate = data + .filter((v) => v.action === action) + .map((v) => v.time) + .sort((a, b) => b.getTime() - a.getTime()) + .reverse(); + if (earliestDate.length > 0 && options.padToDays) { + const earliestPadded = new Date( + new Date().getTime() - options.padToDays * (1000 * 3600 * 24), + ); + const daysDelta = Math.round( + (earliestDate[0].getTime() - earliestPadded.getTime()) / (1000 * 3600 * 24), + ); + if (daysDelta > 0) { + actionData.push({ + x: earliestPadded.getTime(), + y: 0, + }); + } + } + datasets.datasets.push({ + data: actionData, + label: actionToLabel(action), + backgroundColor: actionToColor(action), + ...options.optsMap?.get(action), + }); + }); + return datasets; + } +} From 48696e3d7d912227c9728e301458bf69c168c210 Mon Sep 17 00:00:00 2001 From: "authentik-automation[bot]" <135050075+authentik-automation[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 02:36:27 +0200 Subject: [PATCH 40/47] core, web: update translations (#14984) 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> --- locale/fr/LC_MESSAGES/django.mo | Bin 91856 -> 93815 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/locale/fr/LC_MESSAGES/django.mo b/locale/fr/LC_MESSAGES/django.mo index 724e8d51464bdd60084182c468e7033459b392a9..c1f5bce2334903b132aa341f10e8ce2983fcf8e1 100644 GIT binary patch delta 19256 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 Date: Tue, 10 Jun 2025 02:39:20 +0200 Subject: [PATCH 41/47] web: bump API Client version (#14985) 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> --- web/package-lock.json | 8 ++++---- web/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 20bdf1405b..6ec30f9d41 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -22,7 +22,7 @@ "@floating-ui/dom": "^1.6.11", "@formatjs/intl-listformat": "^7.7.11", "@fortawesome/fontawesome-free": "^6.7.2", - "@goauthentik/api": "^2025.6.1-1749435349", + "@goauthentik/api": "^2025.6.1-1749515784", "@lit/context": "^1.1.2", "@lit/localize": "^0.12.2", "@lit/reactive-element": "^2.0.4", @@ -1728,9 +1728,9 @@ } }, "node_modules/@goauthentik/api": { - "version": "2025.6.1-1749435349", - "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2025.6.1-1749435349.tgz", - "integrity": "sha512-wGkzMWOYzLNUhbvQdt/ro/XYIsTshgAX1NEUlPPCofvji8rWgSbDHsDbj+YXWppuscEMrHoEnkxHfhsfaFuqBA==" + "version": "2025.6.1-1749515784", + "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2025.6.1-1749515784.tgz", + "integrity": "sha512-0yN4vJ2/grtNz6OVNMW34gd6TylBeyTSoH1Zlr7e2yeAbg+oZB8WmpLLCZGqvOguYGN6vYEYrPQF1k3RJohmlQ==" }, "node_modules/@goauthentik/core": { "resolved": "packages/core", diff --git a/web/package.json b/web/package.json index da2c934f50..48dd80a96a 100644 --- a/web/package.json +++ b/web/package.json @@ -93,7 +93,7 @@ "@floating-ui/dom": "^1.6.11", "@formatjs/intl-listformat": "^7.7.11", "@fortawesome/fontawesome-free": "^6.7.2", - "@goauthentik/api": "^2025.6.1-1749435349", + "@goauthentik/api": "^2025.6.1-1749515784", "@lit/context": "^1.1.2", "@lit/localize": "^0.12.2", "@lit/reactive-element": "^2.0.4", From f145580dae39fdbc3e2f65d1e7b45541755e44ef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 11:25:33 +0200 Subject: [PATCH 42/47] core: bump goauthentik/fips-python from 3.13.3-slim-bookworm-fips to 3.13.4-slim-bookworm-fips (#14990) core: bump goauthentik/fips-python Bumps goauthentik/fips-python from 3.13.3-slim-bookworm-fips to 3.13.4-slim-bookworm-fips. --- updated-dependencies: - dependency-name: goauthentik/fips-python dependency-version: 3.13.4-slim-bookworm-fips dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 429fecb81b..dfebd9e4c1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -77,7 +77,7 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \ # Stage 4: Download uv FROM ghcr.io/astral-sh/uv:0.7.12 AS uv # Stage 5: Base python image -FROM ghcr.io/goauthentik/fips-python:3.13.3-slim-bookworm-fips AS python-base +FROM ghcr.io/goauthentik/fips-python:3.13.4-slim-bookworm-fips AS python-base ENV VENV_PATH="/ak-root/.venv" \ PATH="/lifecycle:/ak-root/.venv/bin:$PATH" \ From 8bfc9ab7c975436f16f025521b7c15e01e382252 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Jun 2025 11:25:52 +0200 Subject: [PATCH 43/47] core: bump cryptography from 45.0.3 to 45.0.4 (#14989) Bumps [cryptography](https://github.com/pyca/cryptography) from 45.0.3 to 45.0.4. - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/45.0.3...45.0.4) --- updated-dependencies: - dependency-name: cryptography dependency-version: 45.0.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- uv.lock | 57 ++++++++++++++++++++++++++------------------------ 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 62c2cbb00c..d7f67a12c6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ dependencies = [ "celery==5.5.3", "channels==4.2.2", "channels-redis==4.2.1", - "cryptography==45.0.3", + "cryptography==45.0.4", "dacite==1.9.2", "deepmerge==2.0", "defusedxml==0.7.1", diff --git a/uv.lock b/uv.lock index 6063d2f240..002312c510 100644 --- a/uv.lock +++ b/uv.lock @@ -270,7 +270,7 @@ requires-dist = [ { name = "celery", specifier = "==5.5.3" }, { name = "channels", specifier = "==4.2.2" }, { name = "channels-redis", specifier = "==4.2.1" }, - { name = "cryptography", specifier = "==45.0.3" }, + { name = "cryptography", specifier = "==45.0.4" }, { name = "dacite", specifier = "==1.9.2" }, { name = "deepmerge", specifier = "==2.0" }, { name = "defusedxml", specifier = "==0.7.1" }, @@ -870,37 +870,37 @@ wheels = [ [[package]] name = "cryptography" -version = "45.0.3" +version = "45.0.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/13/1f/9fa001e74a1993a9cadd2333bb889e50c66327b8594ac538ab8a04f915b7/cryptography-45.0.3.tar.gz", hash = "sha256:ec21313dd335c51d7877baf2972569f40a4291b76a0ce51391523ae358d05899", size = 744738, upload-time = "2025-05-25T14:17:24.777Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/c8/a2a376a8711c1e11708b9c9972e0c3223f5fc682552c82d8db844393d6ce/cryptography-45.0.4.tar.gz", hash = "sha256:7405ade85c83c37682c8fe65554759800a4a8c54b2d96e0f8ad114d31b808d57", size = 744890, upload-time = "2025-06-10T00:03:51.297Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/82/b2/2345dc595998caa6f68adf84e8f8b50d18e9fc4638d32b22ea8daedd4b7a/cryptography-45.0.3-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:7573d9eebaeceeb55285205dbbb8753ac1e962af3d9640791d12b36864065e71", size = 7056239, upload-time = "2025-05-25T14:16:12.22Z" }, - { url = "https://files.pythonhosted.org/packages/71/3d/ac361649a0bfffc105e2298b720d8b862330a767dab27c06adc2ddbef96a/cryptography-45.0.3-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d377dde61c5d67eb4311eace661c3efda46c62113ff56bf05e2d679e02aebb5b", size = 4205541, upload-time = "2025-05-25T14:16:14.333Z" }, - { url = "https://files.pythonhosted.org/packages/70/3e/c02a043750494d5c445f769e9c9f67e550d65060e0bfce52d91c1362693d/cryptography-45.0.3-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fae1e637f527750811588e4582988932c222f8251f7b7ea93739acb624e1487f", size = 4433275, upload-time = "2025-05-25T14:16:16.421Z" }, - { url = "https://files.pythonhosted.org/packages/40/7a/9af0bfd48784e80eef3eb6fd6fde96fe706b4fc156751ce1b2b965dada70/cryptography-45.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ca932e11218bcc9ef812aa497cdf669484870ecbcf2d99b765d6c27a86000942", size = 4209173, upload-time = "2025-05-25T14:16:18.163Z" }, - { url = "https://files.pythonhosted.org/packages/31/5f/d6f8753c8708912df52e67969e80ef70b8e8897306cd9eb8b98201f8c184/cryptography-45.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af3f92b1dc25621f5fad065288a44ac790c5798e986a34d393ab27d2b27fcff9", size = 3898150, upload-time = "2025-05-25T14:16:20.34Z" }, - { url = "https://files.pythonhosted.org/packages/8b/50/f256ab79c671fb066e47336706dc398c3b1e125f952e07d54ce82cf4011a/cryptography-45.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2f8f8f0b73b885ddd7f3d8c2b2234a7d3ba49002b0223f58cfde1bedd9563c56", size = 4466473, upload-time = "2025-05-25T14:16:22.605Z" }, - { url = "https://files.pythonhosted.org/packages/62/e7/312428336bb2df0848d0768ab5a062e11a32d18139447a76dfc19ada8eed/cryptography-45.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9cc80ce69032ffa528b5e16d217fa4d8d4bb7d6ba8659c1b4d74a1b0f4235fca", size = 4211890, upload-time = "2025-05-25T14:16:24.738Z" }, - { url = "https://files.pythonhosted.org/packages/e7/53/8a130e22c1e432b3c14896ec5eb7ac01fb53c6737e1d705df7e0efb647c6/cryptography-45.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c824c9281cb628015bfc3c59335163d4ca0540d49de4582d6c2637312907e4b1", size = 4466300, upload-time = "2025-05-25T14:16:26.768Z" }, - { url = "https://files.pythonhosted.org/packages/ba/75/6bb6579688ef805fd16a053005fce93944cdade465fc92ef32bbc5c40681/cryptography-45.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:5833bb4355cb377ebd880457663a972cd044e7f49585aee39245c0d592904578", size = 4332483, upload-time = "2025-05-25T14:16:28.316Z" }, - { url = "https://files.pythonhosted.org/packages/2f/11/2538f4e1ce05c6c4f81f43c1ef2bd6de7ae5e24ee284460ff6c77e42ca77/cryptography-45.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9bb5bf55dcb69f7067d80354d0a348368da907345a2c448b0babc4215ccd3497", size = 4573714, upload-time = "2025-05-25T14:16:30.474Z" }, - { url = "https://files.pythonhosted.org/packages/f5/bb/e86e9cf07f73a98d84a4084e8fd420b0e82330a901d9cac8149f994c3417/cryptography-45.0.3-cp311-abi3-win32.whl", hash = "sha256:3ad69eeb92a9de9421e1f6685e85a10fbcfb75c833b42cc9bc2ba9fb00da4710", size = 2934752, upload-time = "2025-05-25T14:16:32.204Z" }, - { url = "https://files.pythonhosted.org/packages/c7/75/063bc9ddc3d1c73e959054f1fc091b79572e716ef74d6caaa56e945b4af9/cryptography-45.0.3-cp311-abi3-win_amd64.whl", hash = "sha256:97787952246a77d77934d41b62fb1b6f3581d83f71b44796a4158d93b8f5c490", size = 3412465, upload-time = "2025-05-25T14:16:33.888Z" }, - { url = "https://files.pythonhosted.org/packages/71/9b/04ead6015229a9396890d7654ee35ef630860fb42dc9ff9ec27f72157952/cryptography-45.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:c92519d242703b675ccefd0f0562eb45e74d438e001f8ab52d628e885751fb06", size = 7031892, upload-time = "2025-05-25T14:16:36.214Z" }, - { url = "https://files.pythonhosted.org/packages/46/c7/c7d05d0e133a09fc677b8a87953815c522697bdf025e5cac13ba419e7240/cryptography-45.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5edcb90da1843df85292ef3a313513766a78fbbb83f584a5a58fb001a5a9d57", size = 4196181, upload-time = "2025-05-25T14:16:37.934Z" }, - { url = "https://files.pythonhosted.org/packages/08/7a/6ad3aa796b18a683657cef930a986fac0045417e2dc428fd336cfc45ba52/cryptography-45.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38deed72285c7ed699864f964a3f4cf11ab3fb38e8d39cfcd96710cd2b5bb716", size = 4423370, upload-time = "2025-05-25T14:16:39.502Z" }, - { url = "https://files.pythonhosted.org/packages/4f/58/ec1461bfcb393525f597ac6a10a63938d18775b7803324072974b41a926b/cryptography-45.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5555365a50efe1f486eed6ac7062c33b97ccef409f5970a0b6f205a7cfab59c8", size = 4197839, upload-time = "2025-05-25T14:16:41.322Z" }, - { url = "https://files.pythonhosted.org/packages/d4/3d/5185b117c32ad4f40846f579369a80e710d6146c2baa8ce09d01612750db/cryptography-45.0.3-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9e4253ed8f5948a3589b3caee7ad9a5bf218ffd16869c516535325fece163dcc", size = 3886324, upload-time = "2025-05-25T14:16:43.041Z" }, - { url = "https://files.pythonhosted.org/packages/67/85/caba91a57d291a2ad46e74016d1f83ac294f08128b26e2a81e9b4f2d2555/cryptography-45.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cfd84777b4b6684955ce86156cfb5e08d75e80dc2585e10d69e47f014f0a5342", size = 4450447, upload-time = "2025-05-25T14:16:44.759Z" }, - { url = "https://files.pythonhosted.org/packages/ae/d1/164e3c9d559133a38279215c712b8ba38e77735d3412f37711b9f8f6f7e0/cryptography-45.0.3-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:a2b56de3417fd5f48773ad8e91abaa700b678dc7fe1e0c757e1ae340779acf7b", size = 4200576, upload-time = "2025-05-25T14:16:46.438Z" }, - { url = "https://files.pythonhosted.org/packages/71/7a/e002d5ce624ed46dfc32abe1deff32190f3ac47ede911789ee936f5a4255/cryptography-45.0.3-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:57a6500d459e8035e813bd8b51b671977fb149a8c95ed814989da682314d0782", size = 4450308, upload-time = "2025-05-25T14:16:48.228Z" }, - { url = "https://files.pythonhosted.org/packages/87/ad/3fbff9c28cf09b0a71e98af57d74f3662dea4a174b12acc493de00ea3f28/cryptography-45.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f22af3c78abfbc7cbcdf2c55d23c3e022e1a462ee2481011d518c7fb9c9f3d65", size = 4325125, upload-time = "2025-05-25T14:16:49.844Z" }, - { url = "https://files.pythonhosted.org/packages/f5/b4/51417d0cc01802304c1984d76e9592f15e4801abd44ef7ba657060520bf0/cryptography-45.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:232954730c362638544758a8160c4ee1b832dc011d2c41a306ad8f7cccc5bb0b", size = 4560038, upload-time = "2025-05-25T14:16:51.398Z" }, - { url = "https://files.pythonhosted.org/packages/80/38/d572f6482d45789a7202fb87d052deb7a7b136bf17473ebff33536727a2c/cryptography-45.0.3-cp37-abi3-win32.whl", hash = "sha256:cb6ab89421bc90e0422aca911c69044c2912fc3debb19bb3c1bfe28ee3dff6ab", size = 2924070, upload-time = "2025-05-25T14:16:53.472Z" }, - { url = "https://files.pythonhosted.org/packages/91/5a/61f39c0ff4443651cc64e626fa97ad3099249152039952be8f344d6b0c86/cryptography-45.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:d54ae41e6bd70ea23707843021c778f151ca258081586f0cfa31d936ae43d1b2", size = 3395005, upload-time = "2025-05-25T14:16:55.134Z" }, + { url = "https://files.pythonhosted.org/packages/cc/1c/92637793de053832523b410dbe016d3f5c11b41d0cf6eef8787aabb51d41/cryptography-45.0.4-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:425a9a6ac2823ee6e46a76a21a4e8342d8fa5c01e08b823c1f19a8b74f096069", size = 7055712, upload-time = "2025-06-10T00:02:38.826Z" }, + { url = "https://files.pythonhosted.org/packages/ba/14/93b69f2af9ba832ad6618a03f8a034a5851dc9a3314336a3d71c252467e1/cryptography-45.0.4-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:680806cf63baa0039b920f4976f5f31b10e772de42f16310a6839d9f21a26b0d", size = 4205335, upload-time = "2025-06-10T00:02:41.64Z" }, + { url = "https://files.pythonhosted.org/packages/67/30/fae1000228634bf0b647fca80403db5ca9e3933b91dd060570689f0bd0f7/cryptography-45.0.4-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4ca0f52170e821bc8da6fc0cc565b7bb8ff8d90d36b5e9fdd68e8a86bdf72036", size = 4431487, upload-time = "2025-06-10T00:02:43.696Z" }, + { url = "https://files.pythonhosted.org/packages/6d/5a/7dffcf8cdf0cb3c2430de7404b327e3db64735747d641fc492539978caeb/cryptography-45.0.4-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f3fe7a5ae34d5a414957cc7f457e2b92076e72938423ac64d215722f6cf49a9e", size = 4208922, upload-time = "2025-06-10T00:02:45.334Z" }, + { url = "https://files.pythonhosted.org/packages/c6/f3/528729726eb6c3060fa3637253430547fbaaea95ab0535ea41baa4a6fbd8/cryptography-45.0.4-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:25eb4d4d3e54595dc8adebc6bbd5623588991d86591a78c2548ffb64797341e2", size = 3900433, upload-time = "2025-06-10T00:02:47.359Z" }, + { url = "https://files.pythonhosted.org/packages/d9/4a/67ba2e40f619e04d83c32f7e1d484c1538c0800a17c56a22ff07d092ccc1/cryptography-45.0.4-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ce1678a2ccbe696cf3af15a75bb72ee008d7ff183c9228592ede9db467e64f1b", size = 4464163, upload-time = "2025-06-10T00:02:49.412Z" }, + { url = "https://files.pythonhosted.org/packages/7e/9a/b4d5aa83661483ac372464809c4b49b5022dbfe36b12fe9e323ca8512420/cryptography-45.0.4-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:49fe9155ab32721b9122975e168a6760d8ce4cffe423bcd7ca269ba41b5dfac1", size = 4208687, upload-time = "2025-06-10T00:02:50.976Z" }, + { url = "https://files.pythonhosted.org/packages/db/b7/a84bdcd19d9c02ec5807f2ec2d1456fd8451592c5ee353816c09250e3561/cryptography-45.0.4-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2882338b2a6e0bd337052e8b9007ced85c637da19ef9ecaf437744495c8c2999", size = 4463623, upload-time = "2025-06-10T00:02:52.542Z" }, + { url = "https://files.pythonhosted.org/packages/d8/84/69707d502d4d905021cac3fb59a316344e9f078b1da7fb43ecde5e10840a/cryptography-45.0.4-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:23b9c3ea30c3ed4db59e7b9619272e94891f8a3a5591d0b656a7582631ccf750", size = 4332447, upload-time = "2025-06-10T00:02:54.63Z" }, + { url = "https://files.pythonhosted.org/packages/f3/ee/d4f2ab688e057e90ded24384e34838086a9b09963389a5ba6854b5876598/cryptography-45.0.4-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b0a97c927497e3bc36b33987abb99bf17a9a175a19af38a892dc4bbb844d7ee2", size = 4572830, upload-time = "2025-06-10T00:02:56.689Z" }, + { url = "https://files.pythonhosted.org/packages/70/d4/994773a261d7ff98034f72c0e8251fe2755eac45e2265db4c866c1c6829c/cryptography-45.0.4-cp311-abi3-win32.whl", hash = "sha256:e00a6c10a5c53979d6242f123c0a97cff9f3abed7f064fc412c36dc521b5f257", size = 2932769, upload-time = "2025-06-10T00:02:58.467Z" }, + { url = "https://files.pythonhosted.org/packages/5a/42/c80bd0b67e9b769b364963b5252b17778a397cefdd36fa9aa4a5f34c599a/cryptography-45.0.4-cp311-abi3-win_amd64.whl", hash = "sha256:817ee05c6c9f7a69a16200f0c90ab26d23a87701e2a284bd15156783e46dbcc8", size = 3410441, upload-time = "2025-06-10T00:03:00.14Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0b/2488c89f3a30bc821c9d96eeacfcab6ff3accc08a9601ba03339c0fd05e5/cryptography-45.0.4-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:964bcc28d867e0f5491a564b7debb3ffdd8717928d315d12e0d7defa9e43b723", size = 7031836, upload-time = "2025-06-10T00:03:01.726Z" }, + { url = "https://files.pythonhosted.org/packages/fe/51/8c584ed426093aac257462ae62d26ad61ef1cbf5b58d8b67e6e13c39960e/cryptography-45.0.4-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6a5bf57554e80f75a7db3d4b1dacaa2764611ae166ab42ea9a72bcdb5d577637", size = 4195746, upload-time = "2025-06-10T00:03:03.94Z" }, + { url = "https://files.pythonhosted.org/packages/5c/7d/4b0ca4d7af95a704eef2f8f80a8199ed236aaf185d55385ae1d1610c03c2/cryptography-45.0.4-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:46cf7088bf91bdc9b26f9c55636492c1cce3e7aaf8041bbf0243f5e5325cfb2d", size = 4424456, upload-time = "2025-06-10T00:03:05.589Z" }, + { url = "https://files.pythonhosted.org/packages/1d/45/5fabacbc6e76ff056f84d9f60eeac18819badf0cefc1b6612ee03d4ab678/cryptography-45.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:7bedbe4cc930fa4b100fc845ea1ea5788fcd7ae9562e669989c11618ae8d76ee", size = 4198495, upload-time = "2025-06-10T00:03:09.172Z" }, + { url = "https://files.pythonhosted.org/packages/55/b7/ffc9945b290eb0a5d4dab9b7636706e3b5b92f14ee5d9d4449409d010d54/cryptography-45.0.4-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:eaa3e28ea2235b33220b949c5a0d6cf79baa80eab2eb5607ca8ab7525331b9ff", size = 3885540, upload-time = "2025-06-10T00:03:10.835Z" }, + { url = "https://files.pythonhosted.org/packages/7f/e3/57b010282346980475e77d414080acdcb3dab9a0be63071efc2041a2c6bd/cryptography-45.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:7ef2dde4fa9408475038fc9aadfc1fb2676b174e68356359632e980c661ec8f6", size = 4452052, upload-time = "2025-06-10T00:03:12.448Z" }, + { url = "https://files.pythonhosted.org/packages/37/e6/ddc4ac2558bf2ef517a358df26f45bc774a99bf4653e7ee34b5e749c03e3/cryptography-45.0.4-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:6a3511ae33f09094185d111160fd192c67aa0a2a8d19b54d36e4c78f651dc5ad", size = 4198024, upload-time = "2025-06-10T00:03:13.976Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c0/85fa358ddb063ec588aed4a6ea1df57dc3e3bc1712d87c8fa162d02a65fc/cryptography-45.0.4-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:06509dc70dd71fa56eaa138336244e2fbaf2ac164fc9b5e66828fccfd2b680d6", size = 4451442, upload-time = "2025-06-10T00:03:16.248Z" }, + { url = "https://files.pythonhosted.org/packages/33/67/362d6ec1492596e73da24e669a7fbbaeb1c428d6bf49a29f7a12acffd5dc/cryptography-45.0.4-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:5f31e6b0a5a253f6aa49be67279be4a7e5a4ef259a9f33c69f7d1b1191939872", size = 4325038, upload-time = "2025-06-10T00:03:18.4Z" }, + { url = "https://files.pythonhosted.org/packages/53/75/82a14bf047a96a1b13ebb47fb9811c4f73096cfa2e2b17c86879687f9027/cryptography-45.0.4-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:944e9ccf67a9594137f942d5b52c8d238b1b4e46c7a0c2891b7ae6e01e7c80a4", size = 4560964, upload-time = "2025-06-10T00:03:20.06Z" }, + { url = "https://files.pythonhosted.org/packages/cd/37/1a3cba4c5a468ebf9b95523a5ef5651244693dc712001e276682c278fc00/cryptography-45.0.4-cp37-abi3-win32.whl", hash = "sha256:c22fe01e53dc65edd1945a2e6f0015e887f84ced233acecb64b4daadb32f5c97", size = 2924557, upload-time = "2025-06-10T00:03:22.563Z" }, + { url = "https://files.pythonhosted.org/packages/2a/4b/3256759723b7e66380397d958ca07c59cfc3fb5c794fb5516758afd05d41/cryptography-45.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:627ba1bc94f6adf0b0a2e35d87020285ead22d9f648c7e75bb64f367375f3b22", size = 3395508, upload-time = "2025-06-10T00:03:24.586Z" }, ] [[package]] @@ -1396,6 +1396,9 @@ dependencies = [ { name = "uritemplate" }, ] sdist = { url = "https://files.pythonhosted.org/packages/35/99/237cd2510aecca9fabb54007e58553274cc43cb3c18512ee1ea574d11b87/google_api_python_client-2.171.0.tar.gz", hash = "sha256:057a5c08d28463c6b9eb89746355de5f14b7ed27a65c11fdbf1d06c66bb66b23", size = 13028937, upload-time = "2025-06-03T18:57:38.732Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/db/c397e3eb3ea18f423855479d0a5852bdc9c3f644e3d4194931fa664a70b4/google_api_python_client-2.171.0-py3-none-any.whl", hash = "sha256:c9c9b76f561e9d9ac14e54a9e2c0842876201d5b96e69e48f967373f0784cbe9", size = 13547393, upload-time = "2025-06-10T02:14:38.225Z" }, +] [[package]] name = "google-auth" From 88fa7e37dc69c208c13fcf361e8b633ef1c0d646 Mon Sep 17 00:00:00 2001 From: "Jens L." Date: Tue, 10 Jun 2025 12:11:21 +0200 Subject: [PATCH 44/47] outposts: Refactor session end signal and add LDAP support (#14539) * outpost: promote session end signal to non-provider specific Signed-off-by: Jens Langhammer * implement server-side logout in ldap Signed-off-by: Jens Langhammer * fix previous import Signed-off-by: Jens Langhammer * use better retry logic Signed-off-by: Jens Langhammer * log Signed-off-by: Jens Langhammer * make more generic if we switch from ws to something else Signed-off-by: Jens Langhammer * make it possible to e2e test WS Signed-off-by: Jens Langhammer * fix ldap session id Signed-off-by: Jens Langhammer * ok I actually need to go to bed this took me an hour to fix Signed-off-by: Jens Langhammer * format; add ldap test Signed-off-by: Jens Langhammer * fix leftover state Signed-off-by: Jens Langhammer * remove thread Signed-off-by: Jens Langhammer * use ws base for radius Signed-off-by: Jens Langhammer * separate test utils Signed-off-by: Jens Langhammer * rename Signed-off-by: Jens Langhammer * fix missing super calls Signed-off-by: Jens Langhammer * websocket tests with browser :tada: Signed-off-by: Jens Langhammer * add proxy test for sign out Signed-off-by: Jens Langhammer * fix install_id issue with channels tests Signed-off-by: Jens Langhammer * fix proxy basic auth test Signed-off-by: Jens Langhammer * big code dedupe Signed-off-by: Jens Langhammer * allow passing go build args Signed-off-by: Jens Langhammer * improve waiting for outpost Signed-off-by: Jens Langhammer * rewrite ldap tests Signed-off-by: Jens Langhammer * ok actually fix the tests Signed-off-by: Jens Langhammer * undo a couple things that need more time to cook Signed-off-by: Jens Langhammer * remove unused lockfile-lint dependency since we use a shell script and SFE does not have a lockfile Signed-off-by: Jens Langhammer * fix session id for ldap Signed-off-by: Jens Langhammer * fix missing createTimestamp and modifyTimestamp ldap attributes closes #10474 Signed-off-by: Jens Langhammer --------- Signed-off-by: Jens Langhammer --- .dockerignore | 1 + authentik/outposts/consumer.py | 11 ++ authentik/outposts/signals.py | 25 +++- authentik/outposts/tasks.py | 23 ++++ authentik/providers/proxy/signals.py | 23 ---- authentik/providers/proxy/tasks.py | 26 ---- go.mod | 1 + go.sum | 2 + internal/outpost/ak/api.go | 64 +++++----- .../outpost/ak/{api_ws.go => api_event.go} | 114 +++++++++--------- internal/outpost/ak/api_event_msg.go | 37 ++++++ .../ak/{api_ws_test.go => api_event_test.go} | 6 +- internal/outpost/ak/api_ws_msg.go | 19 --- internal/outpost/ak/test.go | 9 +- internal/outpost/flow/executor.go | 2 +- internal/outpost/flow/session.go | 19 +++ internal/outpost/ldap/bind.go | 9 +- internal/outpost/ldap/bind/direct/bind.go | 5 +- internal/outpost/ldap/close.go | 20 +++ internal/outpost/ldap/flags/flags.go | 22 +++- internal/outpost/ldap/ldap.go | 46 +++++-- internal/outpost/ldap/search/direct/schema.go | 38 +++--- internal/outpost/proxyv2/proxyv2.go | 2 +- internal/outpost/proxyv2/ws.go | 51 +++----- internal/outpost/rac/rac.go | 21 ++-- 25 files changed, 347 insertions(+), 249 deletions(-) delete mode 100644 authentik/providers/proxy/signals.py delete mode 100644 authentik/providers/proxy/tasks.py rename internal/outpost/ak/{api_ws.go => api_event.go} (67%) create mode 100644 internal/outpost/ak/api_event_msg.go rename internal/outpost/ak/{api_ws_test.go => api_event_test.go} (88%) delete mode 100644 internal/outpost/ak/api_ws_msg.go create mode 100644 internal/outpost/flow/session.go create mode 100644 internal/outpost/ldap/close.go diff --git a/.dockerignore b/.dockerignore index bfdb9d241b..29cbbac9d1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -11,3 +11,4 @@ blueprints/local !gen-ts-api/node_modules !gen-ts-api/dist/** !gen-go-api/ +.venv diff --git a/authentik/outposts/consumer.py b/authentik/outposts/consumer.py index 80b64999d5..58b53e24db 100644 --- a/authentik/outposts/consumer.py +++ b/authentik/outposts/consumer.py @@ -37,6 +37,9 @@ class WebsocketMessageInstruction(IntEnum): # Provider specific message PROVIDER_SPECIFIC = 3 + # Session ended + SESSION_END = 4 + @dataclass(slots=True) class WebsocketMessage: @@ -145,6 +148,14 @@ class OutpostConsumer(JsonWebsocketConsumer): asdict(WebsocketMessage(instruction=WebsocketMessageInstruction.TRIGGER_UPDATE)) ) + def event_session_end(self, event): + """Event handler which is called when a session is ended""" + self.send_json( + asdict( + WebsocketMessage(instruction=WebsocketMessageInstruction.SESSION_END, args=event) + ) + ) + def event_provider_specific(self, event): """Event handler which can be called by provider-specific implementations to send specific messages to the outpost""" diff --git a/authentik/outposts/signals.py b/authentik/outposts/signals.py index 73d05a4b9a..08c3ae668e 100644 --- a/authentik/outposts/signals.py +++ b/authentik/outposts/signals.py @@ -1,17 +1,24 @@ """authentik outpost signals""" +from django.contrib.auth.signals import user_logged_out from django.core.cache import cache from django.db.models import Model from django.db.models.signals import m2m_changed, post_save, pre_delete, pre_save from django.dispatch import receiver +from django.http import HttpRequest from structlog.stdlib import get_logger from authentik.brands.models import Brand -from authentik.core.models import Provider +from authentik.core.models import AuthenticatedSession, Provider, User from authentik.crypto.models import CertificateKeyPair from authentik.lib.utils.reflection import class_to_path from authentik.outposts.models import Outpost, OutpostServiceConnection -from authentik.outposts.tasks import CACHE_KEY_OUTPOST_DOWN, outpost_controller, outpost_post_save +from authentik.outposts.tasks import ( + CACHE_KEY_OUTPOST_DOWN, + outpost_controller, + outpost_post_save, + outpost_session_end, +) LOGGER = get_logger() UPDATE_TRIGGERING_MODELS = ( @@ -73,3 +80,17 @@ def pre_delete_cleanup(sender, instance: Outpost, **_): instance.user.delete() cache.set(CACHE_KEY_OUTPOST_DOWN % instance.pk.hex, instance) outpost_controller.delay(instance.pk.hex, action="down", from_cache=True) + + +@receiver(user_logged_out) +def logout_revoke_direct(sender: type[User], request: HttpRequest, **_): + """Catch logout by direct logout and forward to providers""" + if not request.session or not request.session.session_key: + return + outpost_session_end.delay(request.session.session_key) + + +@receiver(pre_delete, sender=AuthenticatedSession) +def logout_revoke(sender: type[AuthenticatedSession], instance: AuthenticatedSession, **_): + """Catch logout by expiring sessions being deleted""" + outpost_session_end.delay(instance.session.session_key) diff --git a/authentik/outposts/tasks.py b/authentik/outposts/tasks.py index e09dcf769f..fe716ff455 100644 --- a/authentik/outposts/tasks.py +++ b/authentik/outposts/tasks.py @@ -1,5 +1,6 @@ """outpost tasks""" +from hashlib import sha256 from os import R_OK, access from pathlib import Path from socket import gethostname @@ -49,6 +50,11 @@ LOGGER = get_logger() CACHE_KEY_OUTPOST_DOWN = "goauthentik.io/outposts/teardown/%s" +def hash_session_key(session_key: str) -> str: + """Hash the session key for sending session end signals""" + return sha256(session_key.encode("ascii")).hexdigest() + + def controller_for_outpost(outpost: Outpost) -> type[BaseController] | None: """Get a controller for the outpost, when a service connection is defined""" if not outpost.service_connection: @@ -289,3 +295,20 @@ def outpost_connection_discovery(self: SystemTask): url=unix_socket_path, ) self.set_status(TaskStatus.SUCCESSFUL, *messages) + + +@CELERY_APP.task() +def outpost_session_end(session_id: str): + """Update outpost instances connected to a single outpost""" + layer = get_channel_layer() + hashed_session_id = hash_session_key(session_id) + for outpost in Outpost.objects.all(): + LOGGER.info("Sending session end signal to outpost", outpost=outpost) + group = OUTPOST_GROUP % {"outpost_pk": str(outpost.pk)} + async_to_sync(layer.group_send)( + group, + { + "type": "event.session.end", + "session_id": hashed_session_id, + }, + ) diff --git a/authentik/providers/proxy/signals.py b/authentik/providers/proxy/signals.py deleted file mode 100644 index 48b9f9794d..0000000000 --- a/authentik/providers/proxy/signals.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Proxy provider signals""" - -from django.contrib.auth.signals import user_logged_out -from django.db.models.signals import pre_delete -from django.dispatch import receiver -from django.http import HttpRequest - -from authentik.core.models import AuthenticatedSession, User -from authentik.providers.proxy.tasks import proxy_on_logout - - -@receiver(user_logged_out) -def logout_proxy_revoke_direct(sender: type[User], request: HttpRequest, **_): - """Catch logout by direct logout and forward to proxy providers""" - if not request.session or not request.session.session_key: - return - proxy_on_logout.delay(request.session.session_key) - - -@receiver(pre_delete, sender=AuthenticatedSession) -def logout_proxy_revoke(sender: type[AuthenticatedSession], instance: AuthenticatedSession, **_): - """Catch logout by expiring sessions being deleted""" - proxy_on_logout.delay(instance.session.session_key) diff --git a/authentik/providers/proxy/tasks.py b/authentik/providers/proxy/tasks.py deleted file mode 100644 index 7051619b5e..0000000000 --- a/authentik/providers/proxy/tasks.py +++ /dev/null @@ -1,26 +0,0 @@ -"""proxy provider tasks""" - -from asgiref.sync import async_to_sync -from channels.layers import get_channel_layer - -from authentik.outposts.consumer import OUTPOST_GROUP -from authentik.outposts.models import Outpost, OutpostType -from authentik.providers.oauth2.id_token import hash_session_key -from authentik.root.celery import CELERY_APP - - -@CELERY_APP.task() -def proxy_on_logout(session_id: str): - """Update outpost instances connected to a single outpost""" - layer = get_channel_layer() - hashed_session_id = hash_session_key(session_id) - for outpost in Outpost.objects.filter(type=OutpostType.PROXY): - group = OUTPOST_GROUP % {"outpost_pk": str(outpost.pk)} - async_to_sync(layer.group_send)( - group, - { - "type": "event.provider.specific", - "sub_type": "logout", - "session_id": hashed_session_id, - }, - ) diff --git a/go.mod b/go.mod index 41ca5e1fcf..283328a580 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.24.0 require ( beryju.io/ldap v0.1.0 + github.com/avast/retry-go/v4 v4.6.1 github.com/coreos/go-oidc/v3 v3.14.1 github.com/getsentry/sentry-go v0.33.0 github.com/go-http-utils/etag v0.0.0-20161124023236-513ea8f21eb1 diff --git a/go.sum b/go.sum index cca3ad165a..7b2ebb4d04 100644 --- a/go.sum +++ b/go.sum @@ -41,6 +41,8 @@ github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7V github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/avast/retry-go/v4 v4.6.1 h1:VkOLRubHdisGrHnTu89g08aQEWEgRU7LVEop3GbIcMk= +github.com/avast/retry-go/v4 v4.6.1/go.mod h1:V6oF8njAwxJ5gRo1Q7Cxab24xs5NCWZBeaHHBklR8mA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= diff --git a/internal/outpost/ak/api.go b/internal/outpost/ak/api.go index e68bb1e114..85d202032c 100644 --- a/internal/outpost/ak/api.go +++ b/internal/outpost/ak/api.go @@ -13,6 +13,7 @@ import ( "syscall" "time" + "github.com/avast/retry-go/v4" "github.com/getsentry/sentry-go" "github.com/google/uuid" "github.com/gorilla/websocket" @@ -25,8 +26,6 @@ import ( "goauthentik.io/internal/utils/web" ) -type WSHandler func(ctx context.Context, args map[string]interface{}) - const ConfigLogLevel = "log_level" // APIController main controller which connects to the authentik api via http and ws @@ -43,12 +42,11 @@ type APIController struct { reloadOffset time.Duration - wsConn *websocket.Conn - lastWsReconnect time.Time - wsIsReconnecting bool - wsBackoffMultiplier int - wsHandlers []WSHandler - refreshHandlers []func() + eventConn *websocket.Conn + lastWsReconnect time.Time + wsIsReconnecting bool + eventHandlers []EventHandler + refreshHandlers []func() instanceUUID uuid.UUID } @@ -83,20 +81,19 @@ func NewAPIController(akURL url.URL, token string) *APIController { // Because we don't know the outpost UUID, we simply do a list and pick the first // The service account this token belongs to should only have access to a single outpost - var outposts *api.PaginatedOutpostList - var err error - for { - outposts, _, err = apiClient.OutpostsApi.OutpostsInstancesList(context.Background()).Execute() - - if err == nil { - break - } - - log.WithError(err).Error("Failed to fetch outpost configuration, retrying in 3 seconds") - time.Sleep(time.Second * 3) - } + outposts, _ := retry.DoWithData[*api.PaginatedOutpostList]( + func() (*api.PaginatedOutpostList, error) { + outposts, _, err := apiClient.OutpostsApi.OutpostsInstancesList(context.Background()).Execute() + return outposts, err + }, + retry.Attempts(0), + retry.Delay(time.Second*3), + retry.OnRetry(func(attempt uint, err error) { + log.WithError(err).Error("Failed to fetch outpost configuration, retrying in 3 seconds") + }), + ) if len(outposts.Results) < 1 { - panic("No outposts found with given token, ensure the given token corresponds to an authenitk Outpost") + log.Panic("No outposts found with given token, ensure the given token corresponds to an authenitk Outpost") } outpost := outposts.Results[0] @@ -119,17 +116,16 @@ func NewAPIController(akURL url.URL, token string) *APIController { token: token, logger: log, - reloadOffset: time.Duration(rand.Intn(10)) * time.Second, - instanceUUID: uuid.New(), - Outpost: outpost, - wsHandlers: []WSHandler{}, - wsBackoffMultiplier: 1, - refreshHandlers: make([]func(), 0), + reloadOffset: time.Duration(rand.Intn(10)) * time.Second, + instanceUUID: uuid.New(), + Outpost: outpost, + eventHandlers: []EventHandler{}, + refreshHandlers: make([]func(), 0), } ac.logger.WithField("offset", ac.reloadOffset.String()).Debug("HA Reload offset") - err = ac.initWS(akURL, outpost.Pk) + err = ac.initEvent(akURL, outpost.Pk) if err != nil { - go ac.reconnectWS() + go ac.recentEvents() } ac.configureRefreshSignal() return ac @@ -200,7 +196,7 @@ func (a *APIController) OnRefresh() error { return err } -func (a *APIController) getWebsocketPingArgs() map[string]interface{} { +func (a *APIController) getEventPingArgs() map[string]interface{} { args := map[string]interface{}{ "version": constants.VERSION, "buildHash": constants.BUILD(""), @@ -226,12 +222,12 @@ func (a *APIController) StartBackgroundTasks() error { "build": constants.BUILD(""), }).Set(1) go func() { - a.logger.Debug("Starting WS Handler...") - a.startWSHandler() + a.logger.Debug("Starting Event Handler...") + a.startEventHandler() }() go func() { - a.logger.Debug("Starting WS Health notifier...") - a.startWSHealth() + a.logger.Debug("Starting Event health notifier...") + a.startEventHealth() }() go func() { a.logger.Debug("Starting Interval updater...") diff --git a/internal/outpost/ak/api_ws.go b/internal/outpost/ak/api_event.go similarity index 67% rename from internal/outpost/ak/api_ws.go rename to internal/outpost/ak/api_event.go index a45738f6c1..ba05c74614 100644 --- a/internal/outpost/ak/api_ws.go +++ b/internal/outpost/ak/api_event.go @@ -11,6 +11,7 @@ import ( "strings" "time" + "github.com/avast/retry-go/v4" "github.com/gorilla/websocket" "github.com/prometheus/client_golang/prometheus" "goauthentik.io/internal/config" @@ -30,7 +31,7 @@ func (ac *APIController) getWebsocketURL(akURL url.URL, outpostUUID string, quer return wsUrl } -func (ac *APIController) initWS(akURL url.URL, outpostUUID string) error { +func (ac *APIController) initEvent(akURL url.URL, outpostUUID string) error { query := akURL.Query() query.Set("instance_uuid", ac.instanceUUID.String()) @@ -57,19 +58,19 @@ func (ac *APIController) initWS(akURL url.URL, outpostUUID string) error { return err } - ac.wsConn = ws + ac.eventConn = ws // Send hello message with our version - msg := websocketMessage{ - Instruction: WebsocketInstructionHello, - Args: ac.getWebsocketPingArgs(), + msg := Event{ + Instruction: EventKindHello, + Args: ac.getEventPingArgs(), } err = ws.WriteJSON(msg) if err != nil { - ac.logger.WithField("logger", "authentik.outpost.ak-ws").WithError(err).Warning("Failed to hello to authentik") + ac.logger.WithField("logger", "authentik.outpost.events").WithError(err).Warning("Failed to hello to authentik") return err } ac.lastWsReconnect = time.Now() - ac.logger.WithField("logger", "authentik.outpost.ak-ws").WithField("outpost", outpostUUID).Info("Successfully connected websocket") + ac.logger.WithField("logger", "authentik.outpost.events").WithField("outpost", outpostUUID).Info("Successfully connected websocket") return nil } @@ -77,19 +78,19 @@ func (ac *APIController) initWS(akURL url.URL, outpostUUID string) error { func (ac *APIController) Shutdown() { // Cleanly close the connection by sending a close message and then // waiting (with timeout) for the server to close the connection. - err := ac.wsConn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) + err := ac.eventConn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) if err != nil { ac.logger.WithError(err).Warning("failed to write close message") return } - err = ac.wsConn.Close() + err = ac.eventConn.Close() if err != nil { ac.logger.WithError(err).Warning("failed to close websocket") } ac.logger.Info("finished shutdown") } -func (ac *APIController) reconnectWS() { +func (ac *APIController) recentEvents() { if ac.wsIsReconnecting { return } @@ -100,46 +101,47 @@ func (ac *APIController) reconnectWS() { Path: strings.ReplaceAll(ac.Client.GetConfig().Servers[0].URL, "api/v3", ""), } attempt := 1 - for { - q := u.Query() - q.Set("attempt", strconv.Itoa(attempt)) - u.RawQuery = q.Encode() - err := ac.initWS(u, ac.Outpost.Pk) - attempt += 1 - if err != nil { - ac.logger.Infof("waiting %d seconds to reconnect", ac.wsBackoffMultiplier) - time.Sleep(time.Duration(ac.wsBackoffMultiplier) * time.Second) - ac.wsBackoffMultiplier = ac.wsBackoffMultiplier * 2 - // Limit to 300 seconds (5m) - if ac.wsBackoffMultiplier >= 300 { - ac.wsBackoffMultiplier = 300 + _ = retry.Do( + func() error { + q := u.Query() + q.Set("attempt", strconv.Itoa(attempt)) + u.RawQuery = q.Encode() + err := ac.initEvent(u, ac.Outpost.Pk) + attempt += 1 + if err != nil { + return err } - } else { ac.wsIsReconnecting = false - ac.wsBackoffMultiplier = 1 - return - } - } + return nil + }, + retry.Delay(1*time.Second), + retry.MaxDelay(5*time.Minute), + retry.DelayType(retry.BackOffDelay), + retry.Attempts(0), + retry.OnRetry(func(attempt uint, err error) { + ac.logger.Infof("waiting %d seconds to reconnect", attempt) + }), + ) } -func (ac *APIController) startWSHandler() { - logger := ac.logger.WithField("loop", "ws-handler") +func (ac *APIController) startEventHandler() { + logger := ac.logger.WithField("loop", "event-handler") for { - var wsMsg websocketMessage - if ac.wsConn == nil { - go ac.reconnectWS() + var wsMsg Event + if ac.eventConn == nil { + go ac.recentEvents() time.Sleep(time.Second * 5) continue } - err := ac.wsConn.ReadJSON(&wsMsg) + err := ac.eventConn.ReadJSON(&wsMsg) if err != nil { ConnectionStatus.With(prometheus.Labels{ "outpost_name": ac.Outpost.Name, "outpost_type": ac.Server.Type(), "uuid": ac.instanceUUID.String(), }).Set(0) - logger.WithError(err).Warning("ws read error") - go ac.reconnectWS() + logger.WithError(err).Warning("event read error") + go ac.recentEvents() time.Sleep(time.Second * 5) continue } @@ -149,7 +151,8 @@ func (ac *APIController) startWSHandler() { "uuid": ac.instanceUUID.String(), }).Set(1) switch wsMsg.Instruction { - case WebsocketInstructionTriggerUpdate: + case EventKindAck: + case EventKindTriggerUpdate: time.Sleep(ac.reloadOffset) logger.Debug("Got update trigger...") err := ac.OnRefresh() @@ -164,30 +167,33 @@ func (ac *APIController) startWSHandler() { "build": constants.BUILD(""), }).SetToCurrentTime() } - case WebsocketInstructionProviderSpecific: - for _, h := range ac.wsHandlers { - h(context.Background(), wsMsg.Args) + default: + for _, h := range ac.eventHandlers { + err := h(context.Background(), wsMsg) + if err != nil { + ac.logger.WithError(err).Warning("failed to run event handler") + } } } } } -func (ac *APIController) startWSHealth() { +func (ac *APIController) startEventHealth() { ticker := time.NewTicker(time.Second * 10) for ; true; <-ticker.C { - if ac.wsConn == nil { - go ac.reconnectWS() + if ac.eventConn == nil { + go ac.recentEvents() time.Sleep(time.Second * 5) continue } - err := ac.SendWSHello(map[string]interface{}{}) + err := ac.SendEventHello(map[string]interface{}{}) if err != nil { - ac.logger.WithField("loop", "ws-health").WithError(err).Warning("ws write error") - go ac.reconnectWS() + ac.logger.WithField("loop", "event-health").WithError(err).Warning("event write error") + go ac.recentEvents() time.Sleep(time.Second * 5) continue } else { - ac.logger.WithField("loop", "ws-health").Trace("hello'd") + ac.logger.WithField("loop", "event-health").Trace("hello'd") ConnectionStatus.With(prometheus.Labels{ "outpost_name": ac.Outpost.Name, "outpost_type": ac.Server.Type(), @@ -230,19 +236,19 @@ func (ac *APIController) startIntervalUpdater() { } } -func (a *APIController) AddWSHandler(handler WSHandler) { - a.wsHandlers = append(a.wsHandlers, handler) +func (a *APIController) AddEventHandler(handler EventHandler) { + a.eventHandlers = append(a.eventHandlers, handler) } -func (a *APIController) SendWSHello(args map[string]interface{}) error { - allArgs := a.getWebsocketPingArgs() +func (a *APIController) SendEventHello(args map[string]interface{}) error { + allArgs := a.getEventPingArgs() for key, value := range args { allArgs[key] = value } - aliveMsg := websocketMessage{ - Instruction: WebsocketInstructionHello, + aliveMsg := Event{ + Instruction: EventKindHello, Args: allArgs, } - err := a.wsConn.WriteJSON(aliveMsg) + err := a.eventConn.WriteJSON(aliveMsg) return err } diff --git a/internal/outpost/ak/api_event_msg.go b/internal/outpost/ak/api_event_msg.go new file mode 100644 index 0000000000..6f6d7449fb --- /dev/null +++ b/internal/outpost/ak/api_event_msg.go @@ -0,0 +1,37 @@ +package ak + +import ( + "context" + + "github.com/mitchellh/mapstructure" +) + +type EventKind int + +const ( + // Code used to acknowledge a previous message + EventKindAck EventKind = 0 + // Code used to send a healthcheck keepalive + EventKindHello EventKind = 1 + // Code received to trigger a config update + EventKindTriggerUpdate EventKind = 2 + // Code received to trigger some provider specific function + EventKindProviderSpecific EventKind = 3 + // Code received to identify the end of a session + EventKindSessionEnd EventKind = 4 +) + +type EventHandler func(ctx context.Context, msg Event) error + +type Event struct { + Instruction EventKind `json:"instruction"` + Args interface{} `json:"args"` +} + +func (wm Event) ArgsAs(out interface{}) error { + return mapstructure.Decode(wm.Args, out) +} + +type EventArgsSessionEnd struct { + SessionID string `mapstructure:"session_id"` +} diff --git a/internal/outpost/ak/api_ws_test.go b/internal/outpost/ak/api_event_test.go similarity index 88% rename from internal/outpost/ak/api_ws_test.go rename to internal/outpost/ak/api_event_test.go index f52c353758..6d9b93e2d4 100644 --- a/internal/outpost/ak/api_ws_test.go +++ b/internal/outpost/ak/api_event_test.go @@ -15,7 +15,7 @@ func URLMustParse(u string) *url.URL { return ur } -func TestWebsocketURL(t *testing.T) { +func TestEventWebsocketURL(t *testing.T) { u := URLMustParse("http://localhost:9000?foo=bar") uuid := "23470845-7263-4fe3-bd79-ec1d7bf77d77" ac := &APIController{} @@ -23,7 +23,7 @@ func TestWebsocketURL(t *testing.T) { assert.Equal(t, "ws://localhost:9000/ws/outpost/23470845-7263-4fe3-bd79-ec1d7bf77d77/?foo=bar", nu.String()) } -func TestWebsocketURL_Query(t *testing.T) { +func TestEventWebsocketURL_Query(t *testing.T) { u := URLMustParse("http://localhost:9000?foo=bar") uuid := "23470845-7263-4fe3-bd79-ec1d7bf77d77" ac := &APIController{} @@ -33,7 +33,7 @@ func TestWebsocketURL_Query(t *testing.T) { assert.Equal(t, "ws://localhost:9000/ws/outpost/23470845-7263-4fe3-bd79-ec1d7bf77d77/?bar=baz&foo=bar", nu.String()) } -func TestWebsocketURL_Subpath(t *testing.T) { +func TestEventWebsocketURL_Subpath(t *testing.T) { u := URLMustParse("http://localhost:9000/foo/bar/") uuid := "23470845-7263-4fe3-bd79-ec1d7bf77d77" ac := &APIController{} diff --git a/internal/outpost/ak/api_ws_msg.go b/internal/outpost/ak/api_ws_msg.go deleted file mode 100644 index cedecb93d5..0000000000 --- a/internal/outpost/ak/api_ws_msg.go +++ /dev/null @@ -1,19 +0,0 @@ -package ak - -type websocketInstruction int - -const ( - // WebsocketInstructionAck Code used to acknowledge a previous message - WebsocketInstructionAck websocketInstruction = 0 - // WebsocketInstructionHello Code used to send a healthcheck keepalive - WebsocketInstructionHello websocketInstruction = 1 - // WebsocketInstructionTriggerUpdate Code received to trigger a config update - WebsocketInstructionTriggerUpdate websocketInstruction = 2 - // WebsocketInstructionProviderSpecific Code received to trigger some provider specific function - WebsocketInstructionProviderSpecific websocketInstruction = 3 -) - -type websocketMessage struct { - Instruction websocketInstruction `json:"instruction"` - Args map[string]interface{} `json:"args"` -} diff --git a/internal/outpost/ak/test.go b/internal/outpost/ak/test.go index 82a92351ee..d0a8691748 100644 --- a/internal/outpost/ak/test.go +++ b/internal/outpost/ak/test.go @@ -55,11 +55,10 @@ func MockAK(outpost api.Outpost, globalConfig api.Config) *APIController { token: token, logger: log, - reloadOffset: time.Duration(rand.Intn(10)) * time.Second, - instanceUUID: uuid.New(), - Outpost: outpost, - wsBackoffMultiplier: 1, - refreshHandlers: make([]func(), 0), + reloadOffset: time.Duration(rand.Intn(10)) * time.Second, + instanceUUID: uuid.New(), + Outpost: outpost, + refreshHandlers: make([]func(), 0), } ac.logger.WithField("offset", ac.reloadOffset.String()).Debug("HA Reload offset") return ac diff --git a/internal/outpost/flow/executor.go b/internal/outpost/flow/executor.go index 465715472e..7bfd3cc54b 100644 --- a/internal/outpost/flow/executor.go +++ b/internal/outpost/flow/executor.go @@ -127,7 +127,7 @@ func (fe *FlowExecutor) getAnswer(stage StageComponent) string { return "" } -func (fe *FlowExecutor) GetSession() *http.Cookie { +func (fe *FlowExecutor) SessionCookie() *http.Cookie { return fe.session } diff --git a/internal/outpost/flow/session.go b/internal/outpost/flow/session.go new file mode 100644 index 0000000000..b4e458b8f7 --- /dev/null +++ b/internal/outpost/flow/session.go @@ -0,0 +1,19 @@ +package flow + +import "github.com/golang-jwt/jwt/v5" + +type SessionCookieClaims struct { + jwt.Claims + + SessionID string `json:"sid"` + Authenticated bool `json:"authenticated"` +} + +func (fe *FlowExecutor) Session() *jwt.Token { + sc := fe.SessionCookie() + if sc == nil { + return nil + } + t, _, _ := jwt.NewParser().ParseUnverified(sc.Value, &SessionCookieClaims{}) + return t +} diff --git a/internal/outpost/ldap/bind.go b/internal/outpost/ldap/bind.go index 050dea646f..ae79f69f83 100644 --- a/internal/outpost/ldap/bind.go +++ b/internal/outpost/ldap/bind.go @@ -38,7 +38,14 @@ func (ls *LDAPServer) Bind(bindDN string, bindPW string, conn net.Conn) (ldap.LD username, err := instance.binder.GetUsername(bindDN) if err == nil { selectedApp = instance.GetAppSlug() - return instance.binder.Bind(username, req) + c, err := instance.binder.Bind(username, req) + if c == ldap.LDAPResultSuccess { + f := instance.GetFlags(req.BindDN) + ls.connectionsSync.Lock() + ls.connections[f.SessionID()] = conn + ls.connectionsSync.Unlock() + } + return c, err } else { req.Log().WithError(err).Debug("Username not for instance") } diff --git a/internal/outpost/ldap/bind/direct/bind.go b/internal/outpost/ldap/bind/direct/bind.go index 36697fbe0f..cc72577716 100644 --- a/internal/outpost/ldap/bind/direct/bind.go +++ b/internal/outpost/ldap/bind/direct/bind.go @@ -27,8 +27,9 @@ func (db *DirectBinder) Bind(username string, req *bind.Request) (ldap.LDAPResul passed, err := fe.Execute() flags := flags.UserFlags{ - Session: fe.GetSession(), - UserPk: flags.InvalidUserPK, + Session: fe.SessionCookie(), + SessionJWT: fe.Session(), + UserPk: flags.InvalidUserPK, } // only set flags if we don't have flags for this DN yet // as flags are only checked during the bind, we can remember whether a certain DN diff --git a/internal/outpost/ldap/close.go b/internal/outpost/ldap/close.go new file mode 100644 index 0000000000..d050e07639 --- /dev/null +++ b/internal/outpost/ldap/close.go @@ -0,0 +1,20 @@ +package ldap + +import "net" + +func (ls *LDAPServer) Close(dn string, conn net.Conn) error { + ls.connectionsSync.Lock() + defer ls.connectionsSync.Unlock() + key := "" + for k, c := range ls.connections { + if c == conn { + key = k + break + } + } + if key == "" { + return nil + } + delete(ls.connections, key) + return nil +} diff --git a/internal/outpost/ldap/flags/flags.go b/internal/outpost/ldap/flags/flags.go index 60538de2c0..bf7faf473e 100644 --- a/internal/outpost/ldap/flags/flags.go +++ b/internal/outpost/ldap/flags/flags.go @@ -1,16 +1,30 @@ package flags import ( + "crypto/sha256" + "encoding/hex" "net/http" + "github.com/golang-jwt/jwt/v5" "goauthentik.io/api/v3" + "goauthentik.io/internal/outpost/flow" ) const InvalidUserPK = -1 type UserFlags struct { - UserInfo *api.User - UserPk int32 - CanSearch bool - Session *http.Cookie + UserInfo *api.User + UserPk int32 + CanSearch bool + Session *http.Cookie + SessionJWT *jwt.Token +} + +func (uf UserFlags) SessionID() string { + if uf.SessionJWT == nil { + return "" + } + h := sha256.New() + h.Write([]byte(uf.SessionJWT.Claims.(*flow.SessionCookieClaims).SessionID)) + return hex.EncodeToString(h.Sum(nil)) } diff --git a/internal/outpost/ldap/ldap.go b/internal/outpost/ldap/ldap.go index 57d91e4ed4..5bbdc0d167 100644 --- a/internal/outpost/ldap/ldap.go +++ b/internal/outpost/ldap/ldap.go @@ -18,21 +18,26 @@ import ( ) type LDAPServer struct { - s *ldap.Server - log *log.Entry - ac *ak.APIController - cs *ak.CryptoStore - defaultCert *tls.Certificate - providers []*ProviderInstance + s *ldap.Server + log *log.Entry + ac *ak.APIController + cs *ak.CryptoStore + defaultCert *tls.Certificate + providers []*ProviderInstance + connections map[string]net.Conn + connectionsSync sync.Mutex } func NewServer(ac *ak.APIController) ak.Outpost { ls := &LDAPServer{ - log: log.WithField("logger", "authentik.outpost.ldap"), - ac: ac, - cs: ak.NewCryptoStore(ac.Client.CryptoApi), - providers: []*ProviderInstance{}, + log: log.WithField("logger", "authentik.outpost.ldap"), + ac: ac, + cs: ak.NewCryptoStore(ac.Client.CryptoApi), + providers: []*ProviderInstance{}, + connections: map[string]net.Conn{}, + connectionsSync: sync.Mutex{}, } + ac.AddEventHandler(ls.handleWSSessionEnd) s := ldap.NewServer() s.EnforceLDAP = true @@ -50,6 +55,7 @@ func NewServer(ac *ak.APIController) ak.Outpost { s.BindFunc("", ls) s.UnbindFunc("", ls) s.SearchFunc("", ls) + s.CloseFunc("", ls) return ls } @@ -117,3 +123,23 @@ func (ls *LDAPServer) TimerFlowCacheExpiry(ctx context.Context) { p.binder.TimerFlowCacheExpiry(ctx) } } + +func (ls *LDAPServer) handleWSSessionEnd(ctx context.Context, msg ak.Event) error { + if msg.Instruction != ak.EventKindSessionEnd { + return nil + } + mmsg := ak.EventArgsSessionEnd{} + err := msg.ArgsAs(&mmsg) + if err != nil { + return err + } + ls.connectionsSync.Lock() + defer ls.connectionsSync.Unlock() + ls.log.Info("Disconnecting session due to session end event") + conn, ok := ls.connections[mmsg.SessionID] + if !ok { + return nil + } + delete(ls.connections, mmsg.SessionID) + return conn.Close() +} diff --git a/internal/outpost/ldap/search/direct/schema.go b/internal/outpost/ldap/search/direct/schema.go index 6fe88ead72..94fb225be2 100644 --- a/internal/outpost/ldap/search/direct/schema.go +++ b/internal/outpost/ldap/search/direct/schema.go @@ -44,38 +44,40 @@ func (ds *DirectSearcher) SearchSubschema(req *search.Request) (ldap.ServerSearc { Name: "attributeTypes", Values: []string{ - "( 2.5.4.0 NAME 'objectClass' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' NO-USER-MODIFICATION )", - "( 2.5.4.4 NAME 'sn' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", - "( 2.5.4.3 NAME 'cn' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", - "( 2.5.4.6 NAME 'c' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", - "( 2.5.4.7 NAME 'l' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", - "( 2.5.4.10 NAME 'o' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", - "( 2.5.4.11 NAME 'ou' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", - "( 2.5.4.12 NAME 'title' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", - "( 2.5.4.13 NAME 'description' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", - "( 2.5.4.20 NAME 'telephoneNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", - "( 2.5.4.31 NAME 'member' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", - "( 2.5.4.42 NAME 'givenName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", - "( 2.5.21.2 NAME 'dITContentRules' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", - "( 2.5.21.5 NAME 'attributeTypes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", - "( 2.5.21.6 NAME 'objectClasses' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", "( 0.9.2342.19200300.100.1.1 NAME 'uid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", "( 0.9.2342.19200300.100.1.3 NAME 'mail' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", "( 0.9.2342.19200300.100.1.41 NAME 'mobile' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", - "( 1.2.840.113556.1.2.13 NAME 'displayName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", - "( 1.2.840.113556.1.2.146 NAME 'company' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", "( 1.2.840.113556.1.2.102 NAME 'memberOf' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' NO-USER-MODIFICATION )", + "( 1.2.840.113556.1.2.13 NAME 'displayName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", "( 1.2.840.113556.1.2.131 NAME 'co' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", "( 1.2.840.113556.1.2.141 NAME 'department' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.2.146 NAME 'company' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", "( 1.2.840.113556.1.4.1 NAME 'name' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE NO-USER-MODIFICATION )", - "( 1.2.840.113556.1.4.44 NAME 'homeDirectory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", "( 1.2.840.113556.1.4.221 NAME 'sAMAccountName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", "( 1.2.840.113556.1.4.261 NAME 'division' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 1.2.840.113556.1.4.44 NAME 'homeDirectory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", "( 1.2.840.113556.1.4.750 NAME 'groupType' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", "( 1.2.840.113556.1.4.782 NAME 'objectCategory' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' SINGLE-VALUE )", "( 1.3.6.1.1.1.1.0 NAME 'uidNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", "( 1.3.6.1.1.1.1.1 NAME 'gidNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.27' SINGLE-VALUE )", "( 1.3.6.1.1.1.1.12 NAME 'memberUid' SYNTAX '1.3.6.1.4.1.1466.115.121.1.26' )", + "( 2.5.18.1 NAME 'createTimestamp' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION )", + "( 2.5.18.2 NAME 'modifyTimestamp' SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE NO-USER-MODIFICATION )", + "( 2.5.21.2 NAME 'dITContentRules' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", + "( 2.5.21.5 NAME 'attributeTypes' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", + "( 2.5.21.6 NAME 'objectClasses' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' NO-USER-MODIFICATION )", + "( 2.5.4.0 NAME 'objectClass' SYNTAX '1.3.6.1.4.1.1466.115.121.1.38' NO-USER-MODIFICATION )", + "( 2.5.4.10 NAME 'o' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.5.4.11 NAME 'ou' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.5.4.12 NAME 'title' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.13 NAME 'description' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' )", + "( 2.5.4.20 NAME 'telephoneNumber' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.3 NAME 'cn' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.31 NAME 'member' SYNTAX '1.3.6.1.4.1.1466.115.121.1.12' )", + "( 2.5.4.4 NAME 'sn' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.42 NAME 'givenName' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.6 NAME 'c' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", + "( 2.5.4.7 NAME 'l' SYNTAX '1.3.6.1.4.1.1466.115.121.1.15' SINGLE-VALUE )", // Custom attributes // Temporarily use 1.3.6.1.4.1.26027.1.1 as a base diff --git a/internal/outpost/proxyv2/proxyv2.go b/internal/outpost/proxyv2/proxyv2.go index 690c6135f9..65c74469b9 100644 --- a/internal/outpost/proxyv2/proxyv2.go +++ b/internal/outpost/proxyv2/proxyv2.go @@ -66,7 +66,7 @@ func NewProxyServer(ac *ak.APIController) ak.Outpost { globalMux.PathPrefix("/outpost.goauthentik.io/static").HandlerFunc(s.HandleStatic) globalMux.Path("/outpost.goauthentik.io/ping").HandlerFunc(sentryutils.SentryNoSample(s.HandlePing)) rootMux.PathPrefix("/").HandlerFunc(s.Handle) - ac.AddWSHandler(s.handleWSMessage) + ac.AddEventHandler(s.handleWSMessage) return s } diff --git a/internal/outpost/proxyv2/ws.go b/internal/outpost/proxyv2/ws.go index 4632a67cbe..c08c354ed9 100644 --- a/internal/outpost/proxyv2/ws.go +++ b/internal/outpost/proxyv2/ws.go @@ -3,48 +3,27 @@ package proxyv2 import ( "context" - "github.com/mitchellh/mapstructure" + "goauthentik.io/internal/outpost/ak" "goauthentik.io/internal/outpost/proxyv2/application" ) -type WSProviderSubType string - -const ( - WSProviderSubTypeLogout WSProviderSubType = "logout" -) - -type WSProviderMsg struct { - SubType WSProviderSubType `mapstructure:"sub_type"` - SessionID string `mapstructure:"session_id"` -} - -func ParseWSProvider(args map[string]interface{}) (*WSProviderMsg, error) { - msg := &WSProviderMsg{} - err := mapstructure.Decode(args, &msg) - if err != nil { - return nil, err +func (ps *ProxyServer) handleWSMessage(ctx context.Context, msg ak.Event) error { + if msg.Instruction != ak.EventKindSessionEnd { + return nil } - return msg, nil -} - -func (ps *ProxyServer) handleWSMessage(ctx context.Context, args map[string]interface{}) { - msg, err := ParseWSProvider(args) + mmsg := ak.EventArgsSessionEnd{} + err := msg.ArgsAs(&mmsg) if err != nil { - ps.log.WithError(err).Warning("invalid provider-specific ws message") - return + return err } - switch msg.SubType { - case WSProviderSubTypeLogout: - for _, p := range ps.apps { - ps.log.WithField("provider", p.Host).Debug("Logging out") - err := p.Logout(ctx, func(c application.Claims) bool { - return c.Sid == msg.SessionID - }) - if err != nil { - ps.log.WithField("provider", p.Host).WithError(err).Warning("failed to logout") - } + for _, p := range ps.apps { + ps.log.WithField("provider", p.Host).Debug("Logging out") + err := p.Logout(ctx, func(c application.Claims) bool { + return c.Sid == mmsg.SessionID + }) + if err != nil { + ps.log.WithField("provider", p.Host).WithError(err).Warning("failed to logout") } - default: - ps.log.WithField("sub_type", msg.SubType).Warning("invalid sub_type") } + return nil } diff --git a/internal/outpost/rac/rac.go b/internal/outpost/rac/rac.go index 028ded0959..ab50d3a7fb 100644 --- a/internal/outpost/rac/rac.go +++ b/internal/outpost/rac/rac.go @@ -6,7 +6,6 @@ import ( "strconv" "sync" - "github.com/mitchellh/mapstructure" log "github.com/sirupsen/logrus" "github.com/wwt/guac" @@ -30,7 +29,7 @@ func NewServer(ac *ak.APIController) ak.Outpost { connm: sync.RWMutex{}, conns: map[string]connection.Connection{}, } - ac.AddWSHandler(rs.wsHandler) + ac.AddEventHandler(rs.wsHandler) return rs } @@ -52,12 +51,14 @@ func parseIntOrZero(input string) int { return x } -func (rs *RACServer) wsHandler(ctx context.Context, args map[string]interface{}) { +func (rs *RACServer) wsHandler(ctx context.Context, msg ak.Event) error { + if msg.Instruction != ak.EventKindProviderSpecific { + return nil + } wsm := WSMessage{} - err := mapstructure.Decode(args, &wsm) + err := msg.ArgsAs(&wsm) if err != nil { - rs.log.WithError(err).Warning("invalid ws message") - return + return err } config := guac.NewGuacamoleConfiguration() config.Protocol = wsm.Protocol @@ -71,23 +72,23 @@ func (rs *RACServer) wsHandler(ctx context.Context, args map[string]interface{}) } cc, err := connection.NewConnection(rs.ac, wsm.DestChannelID, config) if err != nil { - rs.log.WithError(err).Warning("failed to setup connection") - return + return err } cc.OnError = func(err error) { rs.connm.Lock() delete(rs.conns, wsm.ConnID) - _ = rs.ac.SendWSHello(map[string]interface{}{ + _ = rs.ac.SendEventHello(map[string]interface{}{ "active_connections": len(rs.conns), }) rs.connm.Unlock() } rs.connm.Lock() rs.conns[wsm.ConnID] = *cc - _ = rs.ac.SendWSHello(map[string]interface{}{ + _ = rs.ac.SendEventHello(map[string]interface{}{ "active_connections": len(rs.conns), }) rs.connm.Unlock() + return nil } func (rs *RACServer) Start() error { From c65b3e8ae579c63423da53d091933521c14ae093 Mon Sep 17 00:00:00 2001 From: Dewi Roberts Date: Tue, 10 Jun 2025 12:09:43 +0100 Subject: [PATCH 45/47] website/integrations: add nextcloud ldap config and update doc to new styling (#14866) * Initial changes * Added LDAP config * WIP * WIP * Updated document to new style and added LDAP config * Make website * WIP * Fixed formatting on SAML section * Typo * Update website/integrations/services/nextcloud/index.mdx Co-authored-by: Dominic R Signed-off-by: Dewi Roberts * Update website/integrations/services/nextcloud/index.mdx Co-authored-by: Dominic R Signed-off-by: Dewi Roberts * Update website/integrations/services/nextcloud/index.mdx Co-authored-by: Dominic R Signed-off-by: Dewi Roberts * Update website/integrations/services/nextcloud/index.mdx Co-authored-by: Dominic R Signed-off-by: Dewi Roberts * Applied suggestions from Dominic * Applied more suggestions * Typo * Applied suggestions --------- Signed-off-by: Dewi Roberts Co-authored-by: Dominic R --- .../integrations/services/nextcloud/index.mdx | 473 +++++++++++------- 1 file changed, 294 insertions(+), 179 deletions(-) diff --git a/website/integrations/services/nextcloud/index.mdx b/website/integrations/services/nextcloud/index.mdx index b713fb6385..fe259e57a4 100644 --- a/website/integrations/services/nextcloud/index.mdx +++ b/website/integrations/services/nextcloud/index.mdx @@ -8,10 +8,10 @@ support_level: community > Nextcloud is a suite of client-server software for creating and using file hosting services. Nextcloud is free and open-source, which means that anyone is allowed to install and operate it on their own private server devices. > -> -- https://en.wikipedia.org/wiki/Nextcloud +> -- https://nextcloud.com/ :::warning -If you require [Server Side Encryption](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html), you must use LDAP. OpenID and SAML will cause **irrevocable data loss**. Nextcloud Server-Side Encryption requires access to the user's cleartext password, which Nextcloud only has access to when using LDAP as the user enters their password directly into Nextcloud. +If you require [server side encryption](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html), you must use LDAP. OpenID and SAML will cause **irrevocable data loss**. Nextcloud server side encryption requires access to the user's cleartext password, which Nextcloud has access to only when using LDAP because the user enters their password directly into Nextcloud. ::: :::caution @@ -19,16 +19,12 @@ This setup only works when Nextcloud is running with HTTPS enabled. See [here](h ::: :::info -In case something goes wrong with the configuration, you can use the URL `http://nextcloud.company/login?direct=1` to log in using the built-in authentication. -::: - -:::note -This documentation lists only the settings that you need to change from their default values. Be aware that any changes other than those explicitly mentioned in this guide could cause issues accessing your application. +If there’s an issue with the configuration, you can log in using the built-in authentication by visiting http://nextcloud.company/login?direct=1. ::: ## Configuration methods -It is possible to configure Nextcloud to use either OpenID Connect or SAML for authentication. Below are the steps to configure both methods. +It is possible to configure Nextcloud to use OIDC, SAML, or LDAP for authentication. Below are the steps to configure each method. import TabItem from "@theme/TabItem"; import Tabs from "@theme/Tabs"; @@ -36,8 +32,9 @@ import Tabs from "@theme/Tabs"; @@ -49,6 +46,14 @@ The following placeholders are used in this guide: - `nextcloud.company` is the FQDN of the Nextcloud installation. - `authentik.company` is the FQDN of the authentik installation. +:::note +This documentation lists only the settings that you need to change from their default values. Be aware that any changes other than those explicitly mentioned in this guide could cause issues accessing your application. +::: + +:::warning +If you require [server side encryption](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html), you must use LDAP. OpenID and SAML will cause **irrevocable data loss**. +::: + Let's start by considering which user attributes need to be available in Nextcloud: - name @@ -63,135 +68,265 @@ authentik already provides some default _scopes_ with _claims_, such as: - `profile` scope: includes `name`, `given_name`, `preferred_username`, `nickname`, `groups` - `openid` scope: a default required by the OpenID spec (contains no claims) -### Custom Profile Scope +## Create property mapping _(optional)_ -If you do not need storage quota, group information, or to manage already existing users in Nextcloud, [skip to the next step](#provider-and-application). +If you do not need storage quota, group information, or to manage already existing users in Nextcloud, skip to the [next section](#create-an-application-and-provider-in-authentik). -If you want to control user storage and designate Nextcloud administrators, create a custom `profile` scope. Go to _Customization_ > _Property mappings_ and create a _Scope mapping_ with: +If you want to control user storage and designate Nextcloud administrators, you will need to create a property mapping. -- **Name:** Nextcloud Profile -- **Scope name:** profile -- **Expression:** +1. Log in to authentik as an administrator and open the authentik Admin interface. +2. Navigate to **Customization** > **Property mappings** and click **Create**. - ```python - # Extract all groups the user is a member of - groups = [group.name for group in user.ak_groups.all()] + - **Select type**: select **Scope mapping**. + - **Create Scope Mapping**: - # Nextcloud admins must be members of a group called "admin". - # This is static and cannot be changed. - # Append "admin" to the user's groups if they are an admin in authentik. - if user.is_superuser and "admin" not in groups: - groups.append("admin") + - **Name**: `Nextcloud Profile` + - **Scope name**: `profile` + - **Expression**: - return { - "name": request.user.name, - "groups": groups, - # Set a quota by using the "nextcloud_quota" property in the user's attributes - "quota": user.group_attributes().get("nextcloud_quota", None), - # To connect an existing Nextcloud user, set "nextcloud_user_id" to the Nextcloud username. - "user_id": user.attributes.get("nextcloud_user_id", str(user.uuid)), - } - ``` + ```python + # Extract all groups the user is a member of + groups = [group.name for group in user.ak_groups.all()] + + # In Nextcloud, administrators must be members of a fixed group called "admin". + + # If a user is an admin in authentik, ensure that "admin" is appended to their group list. + if user.is_superuser and "admin" not in groups: + groups.append("admin") + + return { + "name": request.user.name, + "groups": groups, + # Set a quota by using the "nextcloud_quota" property in the user's attributes + "quota": user.group_attributes().get("nextcloud_quota", None), + # To connect an existing Nextcloud user, set "nextcloud_user_id" to the Nextcloud username. + "user_id": user.attributes.get("nextcloud_user_id", str(user.uuid)), + } + ``` + +3. Click **Finish**. :::note To set a quota, define the `nextcloud_quota` attribute for individual users or groups. For example, setting it to `1 GB` will restrict the user to 1GB of storage. If not set, storage is unlimited. ::: :::note -To connect to an existing Nextcloud user, set the `nextcloud_user_id` attribute to match the Nextcloud username (found under the user's _Display name_ in Nextcloud). +To connect to an existing Nextcloud user, set the `nextcloud_user_id` attribute to match the Nextcloud username (found under the user's `Display name` in Nextcloud). ::: -### Provider and Application +## Create an application and provider in authentik -1. **Create a provider:** - In the authentik Admin Interface, navigate to **Applications > Providers**. Create an **OAuth2/OpenID Provider** with the following settings: +1. Log in to authentik as an administrator and open the authentik Admin interface. +2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) - - **Name:** Nextcloud - - **Client type:** Confidential - - **Redirect URIs/Origins (RegEx):** - `https://nextcloud.company/apps/user_oidc/code` - - **Signing key:** Any valid certificate + - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. + - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. + - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. + - Note the **Client ID** and **slug** values because they will be required later. + - Set a `Strict` redirect URI to `https://nextcloud.company/apps/user_oidc/code`. + - Select any available signing key. + - Under **Advanced Protocol Settings**: + - _(optional)_ If you created the `Nextcloud Profile` scope mapping, add it to **Selected Scopes**. + - **Subject Mode**: `Based on the User's UUID` + - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. -2. **Configure advanced settings:** - Under advanced settings, set: - - - **Scopes:** - - `authentik default Oauth Mapping email` - - `Nextcloud Profile` (or `authentik default Oauth Mapping profile` if you skipped the custom profile scope) - - **Subject mode:** Based on the User's UUID - - :::danger - Mapping the subject mode to authentik usernames is **not recommended** due to their mutable nature. If you choose to map to usernames, [disable username changing](../../../docs/sys-mgmt/settings#allow-users-to-change-username) in authentik and set it to `Based on the User's username`. - ::: - - - **Include claims in ID token:** Enabled - - **Note:** Save your `client ID` and `secret ID` for later. +3. Click **Submit** to save the new application and provider. :::note -An issue with the Nextcloud OIDC app limited the secret ID size to 64 characters. This has been fixed as of December 2023—ensure you update the [OpenID Connect user backend](https://apps.nextcloud.com/apps/user_oidc) to the latest version. +Depending on your Nextcloud configuration, you may need to use `https://nextcloud.company/index.php/` instead of `https://nextcloud.company/`. ::: -:::note -Depending on your Nextcloud configuration, you might need to use `https://nextcloud.company/index.php/` instead of `https://nextcloud.company/`. -::: +## Nextcloud configuration -3. **Link the provider to an application:** - In **Applications > Applications**, create an application and select the provider you just created. Note the _application slug_ for later use. +1. In Nextcloud, ensure that the **OpenID Connect user backend** app is installed. +2. Log in to Nextcloud as an administrator and navigate to **Settings** > **OpenID Connect**. +3. Click the **+** button and enter the following settings: -### Nextcloud configuration + - **Identifier**: `authentik` + - **Client ID**: Client ID from authentik + - **Client secret**: Client secret from authentik + - **Discovery endpoint**: `https://authentik.company/application/o//.well-known/openid-configuration` + - **Scope**: `email profile openid` + - Under **Attribute mappings**: -1. **Install the app:** - In Nextcloud, ensure the **OpenID Connect user backend** app is installed. Then navigate to **Settings > OpenID Connect**. - -2. **Add a provider:** - Click the **+** button and enter the following: - - - **Identifier:** Authentik - - **Client ID:** (from the provider) - - **Client secret:** (from the provider) - - **Discovery endpoint:** - ``` - https://authentik.company/application/o//.well-known/openid-configuration - ``` - - **Scope:** `email profile` (omit `openid` if preferred) - - **Attribute mappings:** - - - **User ID mapping:** `sub` (or `user_id` for existing users) - - **Display name mapping:** `name` - - **Email mapping:** `email` - - **Quota mapping:** `quota` (leave blank if the custom profile scope was skipped) - - **Groups mapping:** `groups` (leave blank if the custom profile scope was skipped) + - **User ID mapping**: `sub` (or `user_id` for existing users) + - **Display name mapping**: `name` + - **Email mapping**: `email` + - **Quota mapping**: `quota` (leave blank if the `Nextcloud Profile` property mapping was skipped) + - **Groups mapping**: `groups` (leave blank if the `Nextcloud Profile` property mapping was skipped) :::tip Enable **Use group provisioning** to allow writing to this field. ::: - - **Use unique user ID:** - If deselected, Nextcloud uses the mapped user ID in the Federated Cloud ID. - :::tip - To avoid a hashed Federated Cloud ID, deselect **Use unique user ID** and use `user_id` for the User ID mapping. - ::: + - **Use unique user ID**: If this option is disabled, Nextcloud will use the mapped user ID as the Federated Cloud ID. - :::danger - If you are using a custom profile scope and want administrators to be able to log in, ensure that **Use unique user ID** is deselected. Otherwise, this setting will remove Administrator users from the internal admin group and replace them with a hashed group ID named "admin", which lacks actual admin access rights. - ::: + :::tip + To avoid a hashed Federated Cloud ID, deselect **Use unique user ID** and use `user_id` for the User ID mapping. + ::: -3. **Log in:** - Once configured, single sign-on (SSO) login via authentik becomes available. + :::danger + If you're using the `Nextcloud Profile` property mapping and want administrators to retain their ability to log in, make sure that **Use unique user ID** is disabled. If this setting is enabled, it will remove administrator users from the internal admin group and replace them with a hashed group ID named "admin," which does not have real administrative privileges. + ::: -#### Making OIDC the default login method +## Making OIDC the default login method -Automatically redirect users to authentik when they access Nextcloud by running: +Automatically redirect users to authentik when they access Nextcloud by running the following command on your Nextcloud docker host: -```bash -sudo -u www-data php var/www/nextcloud/occ config:app:set --value=0 user_oidc allow_multiple_user_backends -``` + ```bash + sudo docker exec --user www-data -it nextcloud-aio-nextcloud php occ config:app:set --value=0 user_oidc allow_multiple_user_backends + ``` + +## Configuration verification + +To confirm that authentik is correctly configured with Nextcloud, log out and then log back in by clicking **OpenID Connect**. You'll then be redirected to authentik to log in, and once authentication is successful, you'll reach the Nextcloud dashboard. -### SAML Auth +## Preparation + +The following placeholders are used in this guide: + + - `nextcloud.company` is the FQDN of the Nextcloud installation. + - `authentik.company` is the FQDN of the authentik installation. + +:::note +This documentation lists only the settings that you need to change from their default values. Be aware that any changes other than those explicitly mentioned in this guide could cause issues accessing your application. +::: + +:::warning +If you require [server side encryption](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html), you must use LDAP. OpenID and SAML will cause **irrevocable data loss**. +::: + +## Create an application and provider in authentik + +1. Log in to authentik as an administrator and open the authentik Admin interface. +2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) + + - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. + - Note the application slug because it will be required later. + - **Choose a Provider type**: select **SAML Provider** as the provider type. + - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. + - Set the **ACS URL** to `https://nextcloud.company/apps/user_saml/saml/acs`. + - Set the **Issuer** to `https://authentik.company`. + - Set the **Audience** to `https://nextcloud.company/apps/user_saml/saml/metadata`. + - Set the **Service Provider Binding** to `Post`. + - Under **Advanced protocol settings**, set an available signing certificate. + - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. + +3. Click **Submit** to save the new application and provider. + +:::note +Depending on your Nextcloud configuration, you might need to use `https://nextcloud.company/index.php/` instead of `https://nextcloud.company/`. +::: + +## Download the signing certificate + +1. Log in to authentik as an administrator and open the authentik Admin interface. +2. Navigate to **Applications** > **Providers** and click on the name of the newly created Nextcloud provider. +3. Under **Download signing certificate** click **Download**. The contents of this certificate will be required in the next section. + +## Configure group quotas _(optional)_ + +To configure group quotas you will need to create groups in authentik for each quota, and a property mapping. + +### Create group/s in authentik _(optional)_ + +1. Log in to authentik as an administrator and open the authentik Admin interface. +2. Navigate to **Directory** > **Groups** and click **Create**. +3. Set a name for the group (e.g. `nextlcloud-15GB`), assign a custom attribute (e.g., `nextcloud_quota`), and click **Create**. +4. Click the name of the newly created group and navigate to the **Users** tab. +5. Click **Add existing user**, select the users that require this storage quota and click **Add**. + +### Create property mapping in authentik _(optional)_ + +1. Log in to authentik as an administrator and open the authentik Admin interface. +2. Navigate to **Customization** > **Property mappings** and click **Create**. + + - **Select type**: select **SAML Provider Property Mapping** as the property mapping type. + - **Create SAML Provider Property Mapping**: + + - **Name**: Provide a name for the property mapping. + - **SAML Attribute Name**: `nextcloud_quota` + - **Expression**: + + ```python + return user.group_attributes().get("nextcloud_quota", "1 GB") + ``` + + :::note + Where `"1 GB"` is the default if a quota is not set. + ::: + +3. Click **Finish** to save the property mapping. + +### Configure quota attribute in Nextcloud _(optional)_ + +1. Log in to Nextcloud as an administrator. +2. Navigate to **Settings** > **SSO & SAML Authentication**. +3. Set **Attribute to map the quota to** to `nextcloud_quota`. + +## Configure admin group _(optional)_ + +To grant Nextcloud admin access to authentik users you will need to create a property mapping. + +### Create property mapping in authentik _(optional)_ + +1. Log in to authentik as an administrator and open the authentik Admin interface. +2. Navigate to **Customization** > **Property mappings** and click **Create**. + + - **Select type**: select **SAML Provider Property Mapping** as the property mapping type. + - **Create SAML Provider Property Mapping**: + + - **Name**: Provide a name for the property mapping. + - **SAML Attribute Name**: `http://schemas.xmlsoap.org/claims/Group` + - **Expression**: + + ```python + for group in request.user.all_groups(): + yield group.name + if ak_is_group_member(request.user, name=""): + yield "admin" + ``` + +### Configure group attribute in Nextcloud _(optional)_ + +1. Log in to Nextcloud as an administrator. +2. Navigate to **Settings** > **SSO & SAML Authentication**. +3. Set the groups mapping to `http://schemas.xmlsoap.org/claims/Group`. + +## Nextcloud configuration + +1. In Nextcloud, ensure that the **SSO & SAML Authentication** app is installed. +2. Log in to Nextcloud as an administrator, navigate to **Settings** > **SSO & SAML Authentication**, and configure the following settings: + + - **Attribute to map the UID to**: `http://schemas.goauthentik.io/2021/02/saml/uid` + + :::danger + Using the UID attribute as username is **not recommended** because of its mutable nature. If you map to the username instead, [disable username changing](https://docs.goauthentik.io/docs/sys-mgmt/settings#allow-users-to-change-username) and set the UID attribute to `http://schemas.goauthentik.io/2021/02/saml/username`. + ::: + + - **Optional display name**: `authentik` + - **Identifier of the IdP entity**: `https://authentik.company` + - **URL target for authentication requests**: `https://authentik.company/application/saml//sso/binding/redirect/` + - **URL for SLO requests**: `https://authentik.company/application/saml//slo/binding/redirect/` + - **Public X.509 certificate of the IdP**: Paste the contents of your certificate file. + - **Set attribute mappings**: + - **Display name**: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name` + - **Email**: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` + - **User groups**: `http://schemas.xmlsoap.org/claims/Group` + +:::note +If Nextcloud is behind a reverse proxy, force HTTPS by adding `'overwriteprotocol' => 'https'` to the Nextcloud `config/config.php` file. See [this guide](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/reverse_proxy_configuration.html#overwrite-parameters) for more details. +::: + +## Configuration verification + +To confirm that authentik is properly configured with Nextcloud, log out and log back in using the **SSO and SAML log in** option. You will be redirected to authentik to log in; if successful you will then be redirected to the Nextcloud dashboard. + + + ## Preparation @@ -201,107 +336,87 @@ The following placeholders are used in this guide: - `authentik.company` is the FQDN of the authentik installation. :::note -This documentation lists only the settings you need to change from their default values. Other changes might cause issues accessing your application. +This documentation lists only the settings that you need to change from their default values. Be aware that any changes other than those explicitly mentioned in this guide could cause issues accessing your application. ::: -1. **Create an application in authentik:** - Note the chosen slug as it will be used later. +## Create an application and provider in authentik -2. **Create a SAML provider:** - In authentik, navigate to **Applications > Providers** and create a **SAML provider** with the following settings: +1. Log in to authentik as an administrator and open the authentik Admin interface. +2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) - - **ACS URL:** - `https://nextcloud.company/apps/user_saml/saml/acs` - - **Issuer:** - `https://authentik.company` - - **Service Provider Binding:** - Post - - **Audience:** - `https://nextcloud.company/apps/user_saml/saml/metadata` - - **Signing certificate:** Select any valid certificate. - - **Property mappings:** Select all managed mappings. + - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. + - **Choose a Provider type**: select **LDAP** as the provider type. + - **Configure the Provider**: provide a name (or accept the auto-provided name) and the bind flow to use for this provider + - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. -:::note -Depending on your Nextcloud configuration, you might need to use `https://nextcloud.company/index.php/` instead of `https://nextcloud.company/`. -::: +3. Click **Submit** to save the new application and provider. -#### Nextcloud configuration +## Create an LDAP outpost -1. **Install the app:** - In Nextcloud, ensure the **SSO & SAML Authentication** app is installed. Then navigate to **Settings > SSO & SAML Authentication**. +1. Log in to authentik as an admin, and open the authentik Admin interface. +2. Navigate to **Applications** > **Outposts** and click **Create**. -2. **Configure the following settings:** + - **Name**: provide a suitable name for the outpost. + - **Type**: `LDAP` + - Under applications, add the newly created Nextcloud application to **Selected Applications**. - - **Attribute to map the UID to:** - `http://schemas.goauthentik.io/2021/02/saml/uid` +3. Click **Create**. - :::danger - Using the UID attribute as username is **not recommended** because of its mutable nature. If you map to the username instead, [disable username changing](https://docs.goauthentik.io/docs/sys-mgmt/settings#allow-users-to-change-username) and set the UID attribute to `http://schemas.goauthentik.io/2021/02/saml/username`. - ::: +## Nextcloud configuration - - **Optional display name:** `authentik` - - **Identifier of the IdP entity:** - `https://authentik.company` - - **URL target for authentication requests:** - `https://authentik.company/application/saml//sso/binding/redirect/` - - **URL for SLO requests:** - `https://authentik.company/application/saml//slo/binding/redirect/` - - **Public X.509 certificate of the IdP:** - Paste the PEM from your selected certificate. +1. In Nextcloud, ensure that the **LDAP user and group backend** app is installed. +2. Log in to Nextcloud as an administrator. +3. Navigate to **Settings** > **LDAP user and group backend** and configure the following settings: -3. **Set attribute mapping:** - Configure the following mappings: + - On the **Server** tab: - - **Display name:** - `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name` - - **Email:** - `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` - - **User groups:** - `http://schemas.xmlsoap.org/claims/Group` + - Click the **+** icon and enter the following settings: + - **Host**: enter the hostname/IP address of the authentik LDAP outpost preceded by `ldap://` or `ldaps://`. If using LDAPS you will also need to specify the certificate that is being used. + - **Port**: `389` or `636` for secure LDAP. + - Under **Credentials**, enter the **Bind DN** of the authentik LDAP provider and the associated user password. + - Under **Base DN**, enter the **Search base** of the authentik LDAP provider. -:::note -If Nextcloud is behind a reverse proxy, force HTTPS by adding `'overwriteprotocol' => 'https'` to the Nextcloud `config/config.php` file. See [this guide](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/reverse_proxy_configuration.html#overwrite-parameters) for more details. -::: + - On the **Users** tab: -#### Group quotas + - Set **Only these object classes** to `Users`. -1. **Set up groups:** - Create a group for each storage quota level and assign a custom attribute (e.g., `nextcloud_quota`) with values like `15 GB`. + - On the **LDAP/AD integration** tab: -2. **Create a custom SAML property mapping:** - Name the mapping **SAML Nextcloud Quota** with: + - Uncheck **LDAP/AD Username**. + - Set **Other Attributes** to `cn`. + - Click **Expert** in the top right corner and enter these settings: + - **Internal Username Attribute**: `uid` + - **UUID Attribute for Users**: `uid` + - **UUID Attribute for Groups**: `gidNumber` + - Click **Advanced** in the top right corner and enter these settings: + - Under **Connection Settings**: + - **Configuration Active**: checked + - Under **Directory Settings**: + - **User Display Name Field**: `name` + - **Base User Tree**: enter the **Search base** of the authentik LDAP provider. + - **Group Display Name Field**: `cn` + - **Base Group Tree**: enter the **Search base** of the authentik LDAP provider. + - **Group-Member Association**: `gidNumber` + - Under **Special Attributes**: + - **Email Field**: `mailPrimaryAddress` - - **SAML Attribute Name:** `nextcloud_quota` - - **Expression:** + - On the **Groups** tab: - ```python - return user.group_attributes().get("nextcloud_quota", "1 GB") - ``` + - Set **Only these object classes** to `groups`. + - Select the authentik groups that require Nextcloud access. - (Here, `"1 GB"` is the default if no quota is set.) + :::note + If Nextcloud is behind a reverse proxy, force HTTPS by adding `'overwriteprotocol' => 'https'` to the Nextcloud `config/config.php` file. See [the Nextcloud admin manual](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/reverse_proxy_configuration.html#overwrite-parameters) for more details. + ::: -3. **Configure Nextcloud:** - In Nextcloud under **Settings > SSO & SAML Authentication**, set the **Attribute to map the quota to** as `nextcloud_quota`. +## Configuration verification -#### Admin group - -To grant admin access to authentik users: - -1. **Create a custom SAML property mapping for admins:** - Configure a mapping with: - - - **SAML Attribute Name:** `http://schemas.xmlsoap.org/claims/Group` - - **Expression:** - - ```python - for group in request.user.all_groups(): - yield group.name - if ak_is_group_member(request.user, name=""): - yield "admin" - ``` - -2. **Update the Nextcloud provider:** - Replace the default Groups mapping with this custom mapping. +To confirm that authentik is properly configured with Nextcloud, log out and log back in using LDAP credentials. If successful you will then be redirected to the Nextcloud dashboard. + +## Resources + +- [Nextcloud docs - User authentication with LDAP](https://docs.nextcloud.com/server/latest/admin_manual/configuration_user/user_auth_ldap.html) +- [Nextcloud OIDC App - User Documentation](https://github.com/H2CK/oidc/wiki/User-Documentation) From 74b5380f32d54aeaa089d1556e74b55e2b113793 Mon Sep 17 00:00:00 2001 From: Dewi Roberts Date: Tue, 10 Jun 2025 12:43:43 +0100 Subject: [PATCH 46/47] website/integrations: add 1password (#14815) * Add doc and update sidebar * Begin document * WIP * Typo * Added automated user privisioning steps * Added note about redirect URIs * Update website/integrations/services/1password/index.mdx Co-authored-by: Dominic R Signed-off-by: Dewi Roberts * Update website/integrations/services/1password/index.mdx Co-authored-by: Dominic R Signed-off-by: Dewi Roberts * Update website/integrations/services/1password/index.mdx Co-authored-by: Dominic R Signed-off-by: Dewi Roberts * Update website/integrations/services/1password/index.mdx Co-authored-by: Dominic R Signed-off-by: Dewi Roberts * Update website/integrations/services/1password/index.mdx Co-authored-by: Dominic R Signed-off-by: Dewi Roberts * Updated based on recommendations from Dominic * Update website/integrations/services/1password/index.mdx Co-authored-by: Tana M Berry Signed-off-by: Dewi Roberts * Update website/integrations/services/1password/index.mdx Co-authored-by: Tana M Berry Signed-off-by: Dewi Roberts * Update website/integrations/services/1password/index.mdx Co-authored-by: Tana M Berry Signed-off-by: Dewi Roberts --------- Signed-off-by: Dewi Roberts Co-authored-by: Dominic R Co-authored-by: Tana M Berry --- .../integrations/services/1password/index.mdx | 115 ++++++++++++++++++ website/sidebars/integrations.mjs | 1 + 2 files changed, 116 insertions(+) create mode 100644 website/integrations/services/1password/index.mdx diff --git a/website/integrations/services/1password/index.mdx b/website/integrations/services/1password/index.mdx new file mode 100644 index 0000000000..9a5e4b66d0 --- /dev/null +++ b/website/integrations/services/1password/index.mdx @@ -0,0 +1,115 @@ +--- +title: Integrate with 1Password +sidebar_label: 1Password +support_level: community +--- + +## What is 1Password + +> 1Password is a password management tool that simplifies the process of creating, storing, and sharing passwords. It allows you to create strong, unique passwords, securely store them in a vault, and automatically fill them in when needed. +> +> -- https://1password.com/ + +## Preparation + +The following placeholders are used in this guide: + +- `authentik.company` is the FQDN of the authentik installation. +- `scim-bridge.company` is the FQDN of the 1Password SCIM Bridge _(optional)_. + +:::note +This documentation lists only the settings that you need to change from their default values. Be aware that any changes other than those explicitly mentioned in this guide could cause issues accessing your application. +::: + +## authentik configuration + +To support the integration of 1Password with authentik, you need to create an application/provider pair in authentik. + +### Create an application and provider in authentik + +1. Log in to authentik as an administrator, and open the authentik Admin interface. +2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) + + - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. + - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. + - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. + - Set **Client type** to `Public`. + - Note the **Client ID** and **slug** values because they will be required later. + - Set two `Strict` redirect URIs to `https://<1password_company_domain>.1password.com/sso/oidc/redirect/` and `onepassword://sso/oidc/redirect`. + - Select any available signing key. + - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. + +3. Click **Submit** to save the new application and provider. + +## 1Password configuration + +1. Log in to the [1Password dashboard](https://start.1password.com/) as an administrator. +2. In the sidebar, click **Policies**. +3. Under **Configure Identity Provider**, click **Manage**. +4. Set the following values: + - **Client ID**: Client ID from authentik. + - **Well-known URL**: `https://temp.temp` +5. Take note of the **Redirect URIs** that are shown because they will be required in the next section. +6. Keep the page open because you will need to return to it after reconfiguring authentik. + +## Reconfigure authentik provider + +1. Log in to authentik as an administrator, and open the authentik Admin interface. +2. Navigate to **Applications** > **Providers** and click the **Edit** icon of the newly created 1Password provider. + - Set redirect URIs matching the values taken from 1Password. +3. Click **Update**. + +## Finalize 1Password configuration + +1. Return to the 1Password SSO configuration page. +2. Click **Test connection** to validate the configuration. +3. After the test completes successfully, click **Save**. + +## Configuration verification + +To verify that authentik is properly integrated with 1Password, first sign out of your account. Then, navigate to the [1Password login page](https://my.1password.com/signin), enter an email that's provisioned for SSO in 1Password, and click **Sign in with authentik**. You will then be redirected to authentik for authentication before being sent back to the 1Password dashboard. + +## Automated user provisioning _(optional)_ + +You can optionally configure automated user provisioning from authentik to 1Password. This allows you to create users and groups, manage access, and suspend users in 1Password with authentik. + +To support automated user provisioning, you need to create a group, and a SCIM provider in authentik. This SCIM provider is then connected to the **1Password SCIM Bridge**, which will need to be deployed. For more information, see the [Automate provisioning in 1Password Business using SCIM Documentation](https://support.1password.com/scim/). + +### Setup automated user provisioning in authentik + +#### Create a user group + +1. Log in to authentik as an administrator, and open the authentik Admin interface. +2. Navigate to **Directory** > **Groups** and click **Create**. +3. Set a name for the group (e.g. `1Password Users`), and click **Create**. +4. Click the name of the newly created group and navigate to the **Users** tab. +5. Click **Add existing user**, select the users that need 1Password access, and click **Add**. + +#### Create a SCIM provider + +1. Log in to authentik as an admin, and open the authentik Admin interface. +2. Navigate to **Applications** > **Providers** and click **Create** + + - **Choose a Provider type**: select **SCIM** as the provider type. + - **Configure the Provider**: provide a name (e.g. `1password-scim`), and the following required configurations. + - Set the **URL** to `scim-bridge.company`. + - Set the **Token** to the token taken from your 1Password SCIM Bridge deployment. + - Under **User filtering**: + - Set **Group** to the previously created group (e.g. `1Password Users`). + +3. Click **Finish** to save the new provider. + +### Setup automated user provisioning in 1Password + +1. Log in to the [1Password dashboard](https://start.1password.com/) as an administrator. +2. Click on **Integrations** in the sidebar and **Automated User Provisioning**. +3. Enable **Provisioning users & groups**. + +For more information see the [Automate provisioning in 1Password Business using SCIM Documentation](https://support.1password.com/scim/), [1Password SCIM Bridge deployment methods Documentation](https://github.com/1Password/scim-examples), and the [1Password Connect Microsoft Entra ID to 1Password SCIM Bridge Documentation](https://support.1password.com/scim-entra-id/#next-steps) that can be used as an example. + +## Resources + +- [Configure Unlock 1Password with SSO using OpenID Connect Documentation](https://support.1password.com/sso-configure-generic/) +- [Automate provisioning in 1Password Business using SCIM Documentation](https://support.1password.com/scim/) +- [1Password SCIM Bridge deployment methods Documentation](https://github.com/1Password/scim-examples) +- [1Password Connect Microsoft Entra ID to 1Password SCIM Bridge Documentation](https://support.1password.com/scim-entra-id/#next-steps) diff --git a/website/sidebars/integrations.mjs b/website/sidebars/integrations.mjs index 2fc99b3fa5..e057ebc04b 100644 --- a/website/sidebars/integrations.mjs +++ b/website/sidebars/integrations.mjs @@ -132,6 +132,7 @@ const items = [ type: "category", label: "Miscellaneous", items: [ + "services/1password/index", "services/actual-budget/index", "services/adventurelog/index", "services/calibre-web/index", From 6d4c9a3446e96a16622d4d14b044201c53f276f0 Mon Sep 17 00:00:00 2001 From: Dewi Roberts Date: Tue, 10 Jun 2025 12:48:49 +0100 Subject: [PATCH 47/47] website/integrations: fix typos, update language and styling (#14978) * Typo and improved language * Changes "admin" to "administrator" and updates indentation * Updates miniflux to newer styling * Combines two notes at beginning of jellyfin doc into one * Replaces all "your application slug" with "application_slug" and replaces tags that are no longer in use * Replaces tags that are no longer in use * Updates immich indentation, application_slug and removes tags * Updated bookstack indentation, tags and application slug * Removes kbd and em tags, and updates the application slug * Gix metadata header in bookstack doc * Lint fix miniflux * ArgoCD indentation --------- Signed-off-by: Dewi Roberts --- .../services/actual-budget/index.mdx | 20 ++++++------ .../services/adventurelog/index.mdx | 2 +- website/integrations/services/argocd/index.md | 16 +++++----- .../integrations/services/atlassian/index.mdx | 6 ++-- website/integrations/services/aws/index.mdx | 8 ++--- .../integrations/services/bookstack/index.mdx | 31 ++++++++++--------- .../integrations/services/budibase/index.md | 16 +++++----- .../services/chronograf/index.mdx | 2 +- .../integrations/services/espocrm/index.md | 10 +++--- .../integrations/services/firezone/index.md | 4 +-- .../services/fortigate-ssl/index.md | 2 +- .../integrations/services/freshrss/index.mdx | 2 +- website/integrations/services/gatus/index.mdx | 2 +- .../github-enterprise-server/index.md | 6 ++-- .../services/globalprotect/index.md | 4 +-- .../services/hashicorp-cloud/index.md | 2 +- website/integrations/services/immich/index.md | 16 +++++----- .../integrations/services/jellyfin/index.md | 12 +++---- .../integrations/services/miniflux/index.md | 30 +++++++----------- .../integrations/services/pgadmin/index.md | 16 +++++----- .../integrations/services/semaphore/index.mdx | 16 +++++----- 21 files changed, 108 insertions(+), 115 deletions(-) diff --git a/website/integrations/services/actual-budget/index.mdx b/website/integrations/services/actual-budget/index.mdx index bc562b0936..3f56b71dd8 100644 --- a/website/integrations/services/actual-budget/index.mdx +++ b/website/integrations/services/actual-budget/index.mdx @@ -33,13 +33,13 @@ To support the integration of Actual Budget with authentik, you need to create a 1. Log in to authentik as an administrator and open the authentik Admin interface. 2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) -- **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. -- **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. -- **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to `https://actual.company/openid/callback`. - - Select any available signing key. Actual Budget only supports the RS256 algorithm. Be aware of this when choosing a signing key. -- **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. + - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. + - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. + - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. + - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. + - Set a `Strict` redirect URI to `https://actual.company/openid/callback`. + - Select any available signing key. Actual Budget only supports the RS256 algorithm. Be aware of this when choosing a signing key. + - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. 3. Click **Submit** to save the new application and provider. @@ -56,7 +56,7 @@ To support the integration of Actual Budget with authentik, you need to create a You can configure OpenID Connect with Actual Budget by adding the following variables to your `.env` file. ```yaml showLineNumbers - ACTUAL_OPENID_DISCOVERY_URL=https://authentik.company/application/o// + ACTUAL_OPENID_DISCOVERY_URL=https://authentik.company/application/o// ACTUAL_OPENID_CLIENT_ID=Your Client ID from authentik ACTUAL_OPENID_CLIENT_SECRET=Your Client Secret from authentik ACTUAL_OPENID_SERVER_HOSTNAME=https://actual.company @@ -69,7 +69,7 @@ You can configure Actual Budget to authenticate users with OpenID Connect by mod ```json showLineNumbers title="/data/config.json" "openId": { - "issuer": "https://authentik.company/application/o//", + "issuer": "https://authentik.company/application/o//", "client_id": "", "client_secret": "", "server_hostname": "https://actual.company", @@ -89,7 +89,7 @@ Alternatively, it is possible to configure OpenID Connect via the UI. 5. Scroll up and click **Start using OpenID** under the **Authentication method** section. 6. Fill in the following values: - **OpenID Provider**: authentik - - **OpenID provider URL**: `https://authentik.company/application/o/your-application-slug/` + - **OpenID provider URL**: `https://authentik.company/application/o//` - **Client ID**: Enter the **Client ID** from authentik - **Client Secret**: Enter the **Client Secret** from authentik diff --git a/website/integrations/services/adventurelog/index.mdx b/website/integrations/services/adventurelog/index.mdx index 7284c19a99..b3cdf5344b 100644 --- a/website/integrations/services/adventurelog/index.mdx +++ b/website/integrations/services/adventurelog/index.mdx @@ -56,7 +56,7 @@ To support the integration of AdventureLog with authentik, you need to create an - **Secret Key**: Enter the Client Secret from authentik - **Key**: Leave this line blank - Under **Settings**: - - **server_url**: https://authentik.company/application/o/your-application-slug/ + - **server_url**: `https://authentik.company/application/o//` - **Sites**: move over the sites you want to enable authentik on, usually `example.com` and `www.example.com` unless you renamed your sites. ### Linking to Existing Account diff --git a/website/integrations/services/argocd/index.md b/website/integrations/services/argocd/index.md index 5b7dd2a796..73fdb1ff02 100644 --- a/website/integrations/services/argocd/index.md +++ b/website/integrations/services/argocd/index.md @@ -30,19 +30,19 @@ To support the integration of ArgoCD with authentik, you need to create an appli 1. Log in to authentik as an administrator and open the authentik Admin interface. 2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) -- **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. -- **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. -- **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Add two `Strict` redirect URI and set them to `https://argocd.company/api/dex/callback` and `https://localhost:8085/auth/callback`. - - Select any available signing key. -- **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. + - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. + - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. + - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. + - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. + - Add two `Strict` redirect URI and set them to `https://argocd.company/api/dex/callback` and `https://localhost:8085/auth/callback`. + - Select any available signing key. + - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. 3. Click **Submit** to save the new application and provider. ### Create the users and administrator groups -Using the authentik Admin interface, navigate to **Directory** -> **Groups** and click **Create** to create two required groups: `ArgoCD Admins` for administrator users and `ArgoCD Viewers` for read-only users. +Using the authentik Admin interface, navigate to **Directory** > **Groups** and click **Create** to create two required groups: `ArgoCD Admins` for administrator users and `ArgoCD Viewers` for read-only users. After creating the groups, select a group, navigate to the **Users** tab, and manage its members by using the **Add existing user** and **Create user** buttons as needed. diff --git a/website/integrations/services/atlassian/index.mdx b/website/integrations/services/atlassian/index.mdx index f17e853422..0dfc5f4748 100644 --- a/website/integrations/services/atlassian/index.mdx +++ b/website/integrations/services/atlassian/index.mdx @@ -79,9 +79,9 @@ To support the integration of Atlassian Cloud with authentik, you need to create 1. Log in to authentik as an administrator and open the authentik Admin interface. 2. Navigate to **Applications** > **Providers** and click the **Edit** icon of the newly created Atlassian Cloud provider. -3. Under **Protocol settgins**, set the following required configurations: - - **ACS URL**: set the acs url to the copied **Service provider assertion consumer service URL** (e.g. https://auth.atlassian.com/login/callback?connection=saml-example). - - **Audience**: set the audience to the copied **Service provider entity URL** (e.g. https://auth.atlassian.com/saml/example). +3. Under **Protocol settings**, set the following required configurations: + - **ACS URL**: set to the **Service provider assertion consumer service URL** from Atlassian Cloud (e.g. https://auth.atlassian.com/login/callback?connection=saml-example). + - **Audience**: set to the **Service provider entity URL** from Atlassian Cloud (e.g. https://auth.atlassian.com/saml/example). 4. Click **Update** ## Enabling SSO in Atlassian Cloud diff --git a/website/integrations/services/aws/index.mdx b/website/integrations/services/aws/index.mdx index 3d4d004ba6..bd44e3084f 100644 --- a/website/integrations/services/aws/index.mdx +++ b/website/integrations/services/aws/index.mdx @@ -30,7 +30,7 @@ import Tabs from "@theme/Tabs"; ### Prerequisites - An AWS account with permissions to create IAM roles and identity providers -- An authentik instance with admin access +- An authentik instance with administrator access ### authentik configuration @@ -111,7 +111,7 @@ To support the integration of AWS with authentik using the classic IAM method, y ### Prerequisites - An AWS account with IAM Identity Center enabled -- An authentik instance with admin access +- An authentik instance with administrator access - A certificate for signing SAML assertions (you can use authentik's default or provide your own) ### authentik configuration @@ -152,8 +152,8 @@ To support the integration of AWS with authentik using IAM Identity Center, you ### Prerequisites - Completed either Classic IAM or IAM Identity Center setup -- AWS Identity Center enabled with admin access -- authentik instance with admin access +- AWS Identity Center enabled with administrator access +- authentik instance with administrator access ### authentik configuration diff --git a/website/integrations/services/bookstack/index.mdx b/website/integrations/services/bookstack/index.mdx index 49b1f4adc4..0c2f9d4ac2 100644 --- a/website/integrations/services/bookstack/index.mdx +++ b/website/integrations/services/bookstack/index.mdx @@ -45,13 +45,13 @@ To support the integration of BookStack with authentik, you need to create an ap 1. Log in to authentik as an administrator and open the authentik Admin interface. 2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) -- **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. -- **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. -- **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Note the **Client ID**, **Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to https://bookstack.company/oidc/callback/. - - Select any available signing key. -- **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. + - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. + - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. + - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. + - Note the **Client ID**, **Client Secret**, and **slug** values because they will be required later. + - Set a `Strict` redirect URI to `https://bookstack.company/oidc/callback/`. + - Select any available signing key. + - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. 3. Click **Submit** to save the new application and provider. @@ -66,7 +66,7 @@ Once that's done, the next step is to update your `.env` file to include the fol OIDC_DISPLAY_NAME_CLAIMS=name # Claim(s) for the user's display name. Can have multiple attributes listed, separated with a '|' in which case those values will be joined with a space. OIDC_CLIENT_ID= OIDC_CLIENT_SECRET= - OIDC_ISSUER=https://authentik.company/application/o/ + OIDC_ISSUER=https://authentik.company/application/o/ OIDC_ISSUER_DISCOVER=true OIDC_END_SESSION_ENDPOINT=true ``` @@ -88,10 +88,10 @@ To support the integration of BookStack with authentik, you need to create an ap - **Choose a Provider type**: select **SAML Provider** as the provider type. - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**, **Client Secret**, and **slug** values because they will be required later. - - Set the **ACS URL** to https://bookstack.company/saml2/acs. - - Set the **Issuer** to https://authentik.company. + - Set the **ACS URL** to `https://bookstack.company/saml2/acs`. + - Set the **Issuer** to `https://authentik.company`. - Set the **Service Provider Binding** to `Post`. - - Set the **Audience** to https://bookstack.company/saml2/metadata. + - Set the **Audience** to `https://bookstack.company/saml2/metadata`. - Under **Advanced protocol settings**, set **Signing Certificate** to use any available certificate. - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. @@ -99,8 +99,11 @@ To support the integration of BookStack with authentik, you need to create an ap ### Obtain the SAML metadata URL -1. In the authentik Admin Interface, nagiate to **Applications** > **Providers** and click on the provider tied to the application/provider pair created in the previous step. -2. Under the **Related objects** section, click **Copy download URL**. Take note of this value as you will need it later. +### Get metadata URL + +1. Log in to authentik as an administrator and open the authentik Admin interface. +2. Navigate to **Applications** > **Providers** and click on the name of the provider that you created in the previous section (e.g. `Provider for bookstack`). +3. Under **Related objects** > **Metadata**, click on **Copy download URL**. This is your authentik metadata URL and it will be required in the next section. ## Bookstack configuration @@ -115,7 +118,7 @@ Once that's done, the next step is to update your `.env` file to include the fol SAML2_USER_TO_GROUPS=true SAML2_GROUP_ATTRIBUTE=http://schemas.xmlsoap.org/claims/Group SAML2_DISPLAY_NAME_ATTRIBUTES=http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname - SAML2_IDP_ENTITYID=https://authentik.company/api/v3/providers/saml//metadata/?download + SAML2_IDP_ENTITYID= SAML2_AUTOLOAD_METADATA=true ``` diff --git a/website/integrations/services/budibase/index.md b/website/integrations/services/budibase/index.md index dc659ce45c..f6dfa0c925 100644 --- a/website/integrations/services/budibase/index.md +++ b/website/integrations/services/budibase/index.md @@ -30,13 +30,13 @@ To support the integration of Budibase with authentik, you need to create an app 1. Log in to authentik as an administrator and open the authentik Admin interface. 2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) -- **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. -- **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. -- **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to `https://budibase.company/api/global/auth/oidc/callback`. - - Select any available signing key. -- **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. + - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. + - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. + - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. + - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. + - Set a `Strict` redirect URI to `https://budibase.company/api/global/auth/oidc/callback`. + - Select any available signing key. + - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. 3. Click **Submit** to save the new application and provider. @@ -44,7 +44,7 @@ To support the integration of Budibase with authentik, you need to create an app From the main page of your Budibase installation, add the following values under the **Auth** section of the builder: -- **Config URL**: `https://authentik.company/application/o/your-application-slug/.well-known/openid-configuration` +- **Config URL**: `https://authentik.company/application/o//.well-known/openid-configuration` - **Client ID**: `Client ID from authentik` - **Client Secret**: `Client Secret from authentik` - **Callback URL**: `https://budibase.company/api/global/auth/oidc/callback/` diff --git a/website/integrations/services/chronograf/index.mdx b/website/integrations/services/chronograf/index.mdx index 23ba31eb64..a153df5b51 100644 --- a/website/integrations/services/chronograf/index.mdx +++ b/website/integrations/services/chronograf/index.mdx @@ -52,7 +52,7 @@ Refer to the [Chronograf configuration options documentation](https://docs.influ ```yaml showLineNumbers PUBLIC_URL=https://chronograf.company TOKEN_SECRET=Your random secret - JWKS_URL=https://authentik.company/application/o//jwks/ + JWKS_URL=https://authentik.company/application/o//jwks/ GENERIC_NAME=authentik GENERIC_CLIENT_ID= GENERIC_CLIENT_SECRET= diff --git a/website/integrations/services/espocrm/index.md b/website/integrations/services/espocrm/index.md index 0c8dc31ff7..e9c4dd8848 100644 --- a/website/integrations/services/espocrm/index.md +++ b/website/integrations/services/espocrm/index.md @@ -53,13 +53,13 @@ Configure the following fields: - **Client ID**: The Client ID from authentik - **Client Secret**: The Client Secret from authentik -- **Authorization Redirect URI**: https://espocrm.company/oauth-callback.php +- **Authorization Redirect URI**: `https://espocrm.company/oauth-callback.php` - **Fallback Login**: Toggle this option if you wish to have the option to use EspoCRM's integrated login as a fallback. - **Allow OIDC login for admin users**: Toggle this option if you wish to allow administrator users to log in with OIDC. -- **Authorization Endpoint**: https://authentik.company/application/o/authorize -- **Token Endpoint**: https://authentik.company/application/o/token -- **JSON Web Key Set Endpoint**: https://authentik.company/application/o/your-application-slug/jwks -- **Logout URL**: https://authentik.company/application/o/your-application-slug/end_session +- **Authorization Endpoint**: `https://authentik.company/application/o/authorize` +- **Token Endpoint**: `https://authentik.company/application/o/token` +- **JSON Web Key Set Endpoint**: `https://authentik.company/application/o//jwks` +- **Logout URL**: `https://authentik.company/application/o//end_session` ## Configuration verification diff --git a/website/integrations/services/firezone/index.md b/website/integrations/services/firezone/index.md index e48fa62cbc..2050644f34 100644 --- a/website/integrations/services/firezone/index.md +++ b/website/integrations/services/firezone/index.md @@ -56,8 +56,8 @@ Set the following values in the Firezone UI: - **Response type**: Keep the default value: `code` - **Client ID**: Use the Client ID from authentik - **Client Secret**: Use the Client Secret from authentik -- **Discovery Document URI**: https://authentik.company/application/o/your-application-slug/.well-known/openid-configuration -- **Redirect URI**: https://firezone.company/auth/oidc/authentik/callback/ +- **Discovery Document URI**: `https://authentik.company/application/o//.well-known/openid-configuration` +- **Redirect URI**: `https://firezone.company/auth/oidc/authentik/callback/` - **Auth-create Users**: Turn this on ## Configuration verification diff --git a/website/integrations/services/fortigate-ssl/index.md b/website/integrations/services/fortigate-ssl/index.md index 818829103a..d9530ba6ac 100644 --- a/website/integrations/services/fortigate-ssl/index.md +++ b/website/integrations/services/fortigate-ssl/index.md @@ -34,7 +34,7 @@ To support the integration of FortiGate SSLVPN with authentik, you need to creat ### Create a user group -1. Log in to authentik as an admin and navigate to the admin Interface. +1. Log in to authentik as an administrator and navigate to the admin Interface. 2. Navigate to **Directory** > **Groups** and click **Create**. 3. Set a descriptive name for the group (e.g. "FortiGate SSLVPN Users"). 4. Add the users who should have access to the SSLVPN. diff --git a/website/integrations/services/freshrss/index.mdx b/website/integrations/services/freshrss/index.mdx index ae034adfe4..d80bdd16ce 100644 --- a/website/integrations/services/freshrss/index.mdx +++ b/website/integrations/services/freshrss/index.mdx @@ -54,7 +54,7 @@ To enable OIDC login with FreshRSS, update your `.env` file to include the follo ```yaml showLineNumbers OIDC_ENABLED=1 - OIDC_PROVIDER_METADATA_URL=https://authentik.company/application/o//.well-known/openid-configuration + OIDC_PROVIDER_METADATA_URL=https://authentik.company/application/o//.well-known/openid-configuration OIDC_CLIENT_ID= OIDC_CLIENT_SECRET= OIDC_X_FORWARDED_HEADERS=X-Forwarded-Port X-Forwarded-Proto X-Forwarded-Host diff --git a/website/integrations/services/gatus/index.mdx b/website/integrations/services/gatus/index.mdx index 96751a732e..99cef355fe 100644 --- a/website/integrations/services/gatus/index.mdx +++ b/website/integrations/services/gatus/index.mdx @@ -56,7 +56,7 @@ Gatus automatically updates its configuration approximately every 30 seconds. If ```yaml showLineNumbers title="config.yaml" security: oidc: - issuer-url: https://authentik.company/application/o// + issuer-url: https://authentik.company/application/o// client-id: $\{OIDC_CLIENT_ID} client-secret: $\{OIDC_CLIENT_SECRET} redirect-url: https://gatus.company/authorization-code/callback diff --git a/website/integrations/services/github-enterprise-server/index.md b/website/integrations/services/github-enterprise-server/index.md index 0630b82748..695157ef6f 100644 --- a/website/integrations/services/github-enterprise-server/index.md +++ b/website/integrations/services/github-enterprise-server/index.md @@ -55,7 +55,7 @@ After creating the groups, select a group, navigate to the **Users** tab, and ma ## SAML Configuration -If you are planning to use SCIM, (available from GHES 3.14.0) you should create a first admin user on your instance and go to your personal access tokens at `https://github.company/settings/tokens/new`, click _Generate new token_ and click _Generate new token (classic)_. Your token should have a descriptive name and ideally, no expiration date. For permission scopes, you need to select _admin:enterprise_. Click _Generate token_ and store the resulting token in a safe location. +If you are planning to use SCIM, (available from GHES 3.14.0) you should create a first administrator user on your instance and go to your personal access tokens at `https://github.company/settings/tokens/new`, click _Generate new token_ and click _Generate new token (classic)_. Your token should have a descriptive name and ideally, no expiration date. For permission scopes, you need to select _admin:enterprise_. Click _Generate token_ and store the resulting token in a safe location. To enable SAML, navigate to your appliance maintenance settings. These are found at `https://github.company:8443`. Here, sign in with an administrator user and go to the Authentication section. @@ -66,7 +66,7 @@ On this page: - For _Issuer_, use the _Audience_ you set in authentik. - Verify that the _Signature method_ and _Digest method_ match your SAML provider settings in authentik. - For _Validation certificate_, upload the signing certificate you downloaded after creating the provider. -- If you plan to enable SCIM, select _Allow creation of accounts with built-in authentication_ and _Disable administrator demotion/promotion_ options. These are selected so you can use your admin user as an emergency non-SSO account, as well as create machine users, and to ensure users are not promoted outside your IdP. +- If you plan to enable SCIM, select _Allow creation of accounts with built-in authentication_ and _Disable administrator demotion/promotion_ options. These are selected so you can use your administrator user as an emergency non-SSO account, as well as create machine users, and to ensure users are not promoted outside your IdP. - In the _User attributes_ section, enter `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` in the _Username_ field to ensure the emails become normalized into usernames in GitHub. - Press Save settings on the left-hand side and wait for the changes to apply. @@ -78,7 +78,7 @@ Once the appliance has saved the settings and reloaded the services, you should This section only applies if you have taken the steps prior to prepare the instance for SCIM enablement. -After enabling SAML, log into your initial admin account again. Click the user portrait in tee top right, click _Enterprise settings_, click _Settigs_ in the left-hand sidebar, click _Authentication security_. On this page you have to check _Enable SCIM configuration_ and press _Save_. After which you should get a message reading _SCIM Enabled_. +After enabling SAML, log into your initial administrator account again. Click the user portrait in tee top right, click _Enterprise settings_, click _Settigs_ in the left-hand sidebar, click _Authentication security_. On this page you have to check _Enable SCIM configuration_ and press _Save_. After which you should get a message reading _SCIM Enabled_. Before we create a SCIM provider, we have to create a new Property Mapping. In authentik, go to _Customization_, then _Property Mappings_. Here, click _Create_, select _SCIM Provider Mapping_. Name the mapping something memorable and paste the following code in the _Expression_ field: diff --git a/website/integrations/services/globalprotect/index.md b/website/integrations/services/globalprotect/index.md index 732b3d934f..805eccb088 100644 --- a/website/integrations/services/globalprotect/index.md +++ b/website/integrations/services/globalprotect/index.md @@ -33,7 +33,7 @@ To support the integration of GlobalProtect with authentik, you need to create a ### Create an Application and Provider in authentik -1. Log in to authentik as an admin and open the authentik Admin interface. +1. Log in to authentik as an administrator and open the authentik Admin interface. 2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) - **Application**: Provide a descriptive name, an optional group, and UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: Select **SAML Provider**. @@ -46,7 +46,7 @@ To support the integration of GlobalProtect with authentik, you need to create a ### Download the metadata -1. Log in to authentik as an admin and open the authentik Admin interface. +1. Log in to authentik as an administrator and open the authentik Admin interface. 2. Navigate to **Applications** > **Providers** > **_Provider Name_** and download the SAML metadata. ## GlobalProtect configuration diff --git a/website/integrations/services/hashicorp-cloud/index.md b/website/integrations/services/hashicorp-cloud/index.md index 496f2a0650..b65afaeba0 100644 --- a/website/integrations/services/hashicorp-cloud/index.md +++ b/website/integrations/services/hashicorp-cloud/index.md @@ -32,7 +32,7 @@ To support the integration of HashiCorp Cloud with authentik, you need to create ### Create an Application and Provider in authentik -1. Log in to authentik as an admin and open the authentik Admin interface. +1. Log in to authentik as an administrator and open the authentik Admin interface. 2. Navigate to **Applications** > **Applications** and click **Create with Provider**. - **Application**: Provide a descriptive name, an optional group, and UI settings. Take note of the **slug** as it will be required later. - **Choose a Provider type**: Select **SAML Provider**. diff --git a/website/integrations/services/immich/index.md b/website/integrations/services/immich/index.md index 33c75206ed..86e8c52bd4 100644 --- a/website/integrations/services/immich/index.md +++ b/website/integrations/services/immich/index.md @@ -30,13 +30,13 @@ To support the integration of Immich with authentik, you need to create an appli 1. Log in to authentik as an administrator and open the authentik Admin interface. 2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) -- **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. -- **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. -- **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Add three `Strict` redirect URIs and set them to app.immich:///oauth-callback, https://immich.company/auth/login, and https://immich.company/user-settings. - - Select any available signing key. -- **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. + - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. + - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. + - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. + - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. + - Add three `Strict` redirect URIs and set them to `app.immich:///oauth-callback`, `https://immich.company/auth/login`, and `https://immich.company/user-settings`. + - Select any available signing key. + - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. 3. Click **Submit** to save the new application and provider. @@ -46,7 +46,7 @@ Immich documentation can be found here: https://immich.app/docs/administration/o 1. In Immich, navigate to **Administration** > **Settings** > **OAuth Authentication** 2. Configure Immich as follows: - - **Issuer URL**: https://authentik.company/application/o/application-slug/ + - **Issuer URL**: `https://authentik.company/application/o//` - **Client ID**: Enter your Client ID from authentik - **Client Secret**: Enter your Client Secret from authentik - **Scope**: `openid email profile` diff --git a/website/integrations/services/jellyfin/index.md b/website/integrations/services/jellyfin/index.md index 83fe545603..43640acfe6 100644 --- a/website/integrations/services/jellyfin/index.md +++ b/website/integrations/services/jellyfin/index.md @@ -11,11 +11,7 @@ support_level: community > -- https://jellyfin.org :::note -Jellyfin does not have any native external authentication support as of the writing of this page. -::: - -:::note -Currently, there are two plugins for Jellyfin that provide external authentication, an OIDC plugin and an LDAP plugin. +Jellyfin does not have any native external authentication support as of the writing of this page. Currently, there are two plugins for Jellyfin that provide external authentication, an OIDC plugin and an LDAP plugin. ::: :::caution @@ -47,7 +43,7 @@ No additional authentik configuration needs to be configured. Follow the LDAP ou 1. If you don't have one already, create an LDAP bind user before starting these steps. - Ideally, this user doesn't have any permissions other than the ability to view other users. However, some functions do require an account with permissions. - This user must be part of the group that is specified in the "Search group" in the LDAP outpost. -2. Navigate to your Jellyfin installation and log in with the admin account or currently configured local admin. +2. Navigate to your Jellyfin installation and log in with the administrator account or currently configured local admin. 3. Open the **Administrator dashboard** and go to the **Plugins** section. 4. Click **Catalog** at the top of the page, and locate the "LDAP Authentication Plugin" 5. Install the plugin. You may need to restart Jellyfin to finish installation. @@ -122,7 +118,7 @@ Set the launch URL to `https://jellyfin.company/sso/OID/start/authentik` ### Jellyfin Configuration -1. Log in to Jellyfin with an admin account and navigate to the **Admin Dashboard** by selecting your profile icon in the top right, then clicking **Dashboard**. +1. Log in to Jellyfin with an administrator account and navigate to the **Admin Dashboard** by selecting your profile icon in the top right, then clicking **Dashboard**. 2. Go to **Dashboard > Plugins > Repositories**. 3. Click the **+** in the top left to add a new repository. Use the following URL and name it "SSO-Auth": @@ -146,7 +142,7 @@ https://raw.githubusercontent.com/9p4/jellyfin-plugin-sso/manifest-release/manif 9. If you want to use the role claim then also fill out these: - Roles: roles to look for when authorizing access (should be done through authentik instead) - - Admin Roles: roles to look for when giving admin privilege + - Admin Roles: roles to look for when giving administrator privilege - Role Claim: `groups` 10. Hit **Save** at the bottom. diff --git a/website/integrations/services/miniflux/index.md b/website/integrations/services/miniflux/index.md index dd2baf8b53..acb79303c0 100644 --- a/website/integrations/services/miniflux/index.md +++ b/website/integrations/services/miniflux/index.md @@ -30,16 +30,10 @@ To support the integration of Miniflux with authentik, you need to create an app 1. Log in to authentik as an administrator and open the authentik Admin interface. 2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) -- **Application**: provide a descriptive name (e.g., `Miniflux`), an optional group for the type of application, the policy engine mode, and optional UI settings. - -- **Choose a Provider type**: Select OAuth2/OpenID Provider as the provider type. - -- **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - - **Redirect URI**: - - Strict: `https://miniflux.company/oauth2/oidc/callback` - -- **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. + - **Application**: provide a descriptive name (e.g., `Miniflux`), an optional group for the type of application, the policy engine mode, and optional UI settings. + - **Choose a Provider type**: Select OAuth2/OpenID Provider as the provider type. + - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - Note the **Client ID**, **Client Secret**, and **slug** values because they will be required later. - Set a `Strict` redirect URI to `https://miniflux.company/oauth2/oidc/callback` - Select any available signing key. + - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. 3. Click **Submit** to save the new application and provider. @@ -47,14 +41,14 @@ To support the integration of Miniflux with authentik, you need to create an app Add the following environment variables to your Miniflux configuration. Make sure to fill in the client ID, client secret, and OpenID Connect well-known URL from your authentik instance. -```sh -OAUTH2_PROVIDER=oidc -OAUTH2_CLIENT_ID= -OAUTH2_CLIENT_SECRET= -OAUTH2_REDIRECT_URL=https://miniflux.company/oauth2/oidc/callback -OAUTH2_OIDC_DISCOVERY_ENDPOINT=https://authentik.company/application/o// -OAUTH2_USER_CREATION=1 -``` + ```sh + OAUTH2_PROVIDER=oidc + OAUTH2_CLIENT_ID= + OAUTH2_CLIENT_SECRET= + OAUTH2_REDIRECT_URL=https://miniflux.company/oauth2/oidc/callback + OAUTH2_OIDC_DISCOVERY_ENDPOINT=https://authentik.company/application/o// + OAUTH2_USER_CREATION=1 + ``` :::note The trailing `.well-known/openid-configuration` is not required for `OAUTH2_OIDC_DISCOVERY_ENDPOINT` diff --git a/website/integrations/services/pgadmin/index.md b/website/integrations/services/pgadmin/index.md index b621c629c5..8bcd41fbcf 100644 --- a/website/integrations/services/pgadmin/index.md +++ b/website/integrations/services/pgadmin/index.md @@ -34,13 +34,13 @@ To support the integration of pgAdmin with authentik, you need to create an appl 1. Log in to authentik as an administrator and open the authentik Admin interface. 2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) -- **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. -- **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. -- **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to `https://pgadmin.company/oauth2/authorize`. - - Select any available signing key. -- **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. + - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. + - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. + - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. + - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. + - Set a `Strict` redirect URI to `https://pgadmin.company/oauth2/authorize`. + - Select any available signing key. + - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. 3. Click **Submit** to save the new application and provider. @@ -101,7 +101,7 @@ PGADMIN_CONFIG_OAUTH2_CONFIG="[{'OAUTH2_NAME':'authentik','OAUTH2_DISPLAY_NAME': AUTHENTICATION_SOURCES = ['oauth2'] ``` - Ensure that you promote at least one user to an admin before disabling the internal authentication. + Ensure that you promote at least one user to an administrator before disabling the internal authentication. - To **disable automatic user creation**, set: ```python diff --git a/website/integrations/services/semaphore/index.mdx b/website/integrations/services/semaphore/index.mdx index e01a8befdc..f7c734365d 100644 --- a/website/integrations/services/semaphore/index.mdx +++ b/website/integrations/services/semaphore/index.mdx @@ -32,13 +32,13 @@ To support the integration of Semaphore with authentik, you need to create an ap 1. Log in to authentik as an administrator and open the authentik Admin interface. 2. Navigate to **Applications** > **Applications** and click **Create with Provider** to create an application and provider pair. (Alternatively you can first create a provider separately, then create the application and connect it with the provider.) -- **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. -- **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. -- **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. - - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. - - Set a `Strict` redirect URI to `https://semaphore.company/api/auth/oidc/authentik/redirect`. - - Select any available signing key. -- **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. + - **Application**: provide a descriptive name, an optional group for the type of application, the policy engine mode, and optional UI settings. + - **Choose a Provider type**: select **OAuth2/OpenID Connect** as the provider type. + - **Configure the Provider**: provide a name (or accept the auto-provided name), the authorization flow to use for this provider, and the following required configurations. + - Note the **Client ID**,**Client Secret**, and **slug** values because they will be required later. + - Set a `Strict` redirect URI to `https://semaphore.company/api/auth/oidc/authentik/redirect`. + - Select any available signing key. + - **Configure Bindings** _(optional)_: you can create a [binding](/docs/add-secure-apps/flows-stages/bindings/) (policy, group, or user) to manage the listing and access to applications on a user's **My applications** page. 3. Click **Submit** to save the new application and provider. @@ -90,5 +90,5 @@ More information on this can be found in the Semaphore documentation https://doc - If you are redirected back to the `https://semaphore.company` URL you did everything correct. :::info -Users are created upon logging in with authentik. They will not have the rights to create anything initially. These permissions must be assigned later by the local admin created during the first login to the Semaphore UI. +Users are created upon logging in with authentik. They will not have the rights to create anything initially. These permissions must be assigned later by the local administrator created during the first login to the Semaphore UI. :::
- +