Merge remote-tracking branch 'origin/master' into feat-settings-ui
# Conflicts: # go.mod # web/package.json # web/pnpm-lock.yamlfeat-otp-verification
commit
e6ef74fd8e
|
@ -68,7 +68,7 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- ${PWD}/data/nginx-proxy-manager/data:/data
|
- ${PWD}/data/nginx-proxy-manager/data:/data
|
||||||
- ${PWD}/data/nginx-proxy-manager/letsencrypt:/etc/letsencrypt
|
- ${PWD}/data/nginx-proxy-manager/letsencrypt:/etc/letsencrypt
|
||||||
- ${PWD}/data/nginx/snippets:/config/nginx/snippets:ro
|
- ${PWD}/data/nginx/snippets:/snippets:ro
|
||||||
environment:
|
environment:
|
||||||
TZ: 'Australia/Melbourne'
|
TZ: 'Australia/Melbourne'
|
||||||
authelia:
|
authelia:
|
||||||
|
|
|
@ -42,22 +42,67 @@ bootstrapping *Authelia*.
|
||||||
|
|
||||||
### SWAG Caveat
|
### SWAG Caveat
|
||||||
|
|
||||||
One current caveat of the [SWAG] implementation is that it serves Authelia as a subpath for each domain. We
|
One current caveat of the [SWAG] implementation is that it serves Authelia as a subpath for each domain by default. We
|
||||||
*__strongly recommend__* instead of using the out of the box method and guide for [SWAG] that you follow the
|
*__strongly recommend__* instead of using the defaults that you configure Authelia as a subdomain if possible.
|
||||||
[NGINX](nginx.md) guide (which *can be used* with [SWAG]) and run Authelia as it's own subdomain.
|
|
||||||
|
|
||||||
This is partly because Webauthn requires that the domain is an exact match when registering and authenticating and it is
|
There are two potential ways to achieve this:
|
||||||
|
|
||||||
|
1. Adjust the default `authelia-server.conf` as per the included directions.
|
||||||
|
2. Use the supplementary configuration snippets provided officially by Authelia.
|
||||||
|
|
||||||
|
This is partly because WebAuthn requires that the domain is an exact match when registering and authenticating and it is
|
||||||
possible that due to web standards this will never change.
|
possible that due to web standards this will never change.
|
||||||
|
|
||||||
In addition this represents a bad user experience in some instances such as:
|
In addition this represents a bad user experience in some instances such as:
|
||||||
|
|
||||||
- Users sometimes visit the `https://app.example.com/authelia` URL which doesn't automatically redirect the user to
|
- Users sometimes visit the `https://app.example.com/authelia` URL which doesn't automatically redirect the user to
|
||||||
`https://app.example.com` (if they visit `https://app.example.com` then they'll be redirected to authenticate then
|
`https://app.example.com` (if they visit `https://app.example.com` then they'll be redirected to authenticate then
|
||||||
redirected back to their original URL).
|
redirected back to their original URL).
|
||||||
- Administrators may wish to setup OpenID Connect 1.0 in which case it also doesn't represent a good user experience.
|
- Administrators may wish to setup [OpenID Connect 1.0](../../configuration/identity-providers/open-id-connect.md) in
|
||||||
|
which case it also doesn't represent a good user experience as the `issuer` will be
|
||||||
|
`https://app.example.com/authelia` for example
|
||||||
|
- Using the [SWAG] default configurations are more difficult to support as our specific familiarity is with our own
|
||||||
|
example snippets
|
||||||
|
|
||||||
Taking these factors into consideration we're adapting our [SWAG] guide to use what we consider best for the users and
|
#### Option 1: Adjusting the Default Configuration
|
||||||
most easily supported. Users who wish to use the [SWAG] guide are free to do so but may not receive the same support.
|
|
||||||
|
Open the generated `authelia-server.conf`. Adjust the following sections. There are two snippets, one before and one
|
||||||
|
after. The only lines that change are the `set $authelia_backend` lines, and this configuration assumes you're
|
||||||
|
serving Authelia at `auth.example.com`.
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
## Set $authelia_backend to route requests to the current domain by default
|
||||||
|
set $authelia_backend $http_host;
|
||||||
|
## In order for Webauthn to work with multiple domains authelia must operate on a separate subdomain
|
||||||
|
## To use authelia on a separate subdomain:
|
||||||
|
## * comment the $authelia_backend line above
|
||||||
|
## * rename /config/nginx/proxy-confs/authelia.conf.sample to /config/nginx/proxy-confs/authelia.conf
|
||||||
|
## * make sure that your dns has a cname set for authelia
|
||||||
|
## * uncomment the $authelia_backend line below and change example.com to your domain
|
||||||
|
## * restart the swag container
|
||||||
|
#set $authelia_backend authelia.example.com;
|
||||||
|
|
||||||
|
return 302 https://$authelia_backend/authelia/?rd=$target_url;
|
||||||
|
```
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
## Set $authelia_backend to route requests to the current domain by default
|
||||||
|
# set $authelia_backend $http_host;
|
||||||
|
## In order for Webauthn to work with multiple domains authelia must operate on a separate subdomain
|
||||||
|
## To use authelia on a separate subdomain:
|
||||||
|
## * comment the $authelia_backend line above
|
||||||
|
## * rename /config/nginx/proxy-confs/authelia.conf.sample to /config/nginx/proxy-confs/authelia.conf
|
||||||
|
## * make sure that your dns has a cname set for authelia
|
||||||
|
## * uncomment the $authelia_backend line below and change example.com to your domain
|
||||||
|
## * restart the swag container
|
||||||
|
set $authelia_backend auth.example.com;
|
||||||
|
|
||||||
|
return 302 https://$authelia_backend/authelia/?rd=$target_url;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Option 2: Using the Authelia Supplementary Configuration Snippets
|
||||||
|
|
||||||
|
See standard [NGINX](nginx.md) guide (which *can be used* with [SWAG]) and run Authelia as it's own subdomain.
|
||||||
|
|
||||||
## Trusted Proxies
|
## Trusted Proxies
|
||||||
|
|
||||||
|
@ -102,6 +147,8 @@ services:
|
||||||
- '443:443'
|
- '443:443'
|
||||||
volumes:
|
volumes:
|
||||||
- ${PWD}/data/swag:/config
|
- ${PWD}/data/swag:/config
|
||||||
|
#- ${PWD}/data/nginx/snippets:/snippets:ro
|
||||||
|
## Uncomment the above line if you want to use the Authelia configuration snippets.
|
||||||
environment:
|
environment:
|
||||||
PUID: '1000'
|
PUID: '1000'
|
||||||
PGID: '1000'
|
PGID: '1000'
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -13,7 +13,7 @@ require (
|
||||||
github.com/go-asn1-ber/asn1-ber v1.5.4
|
github.com/go-asn1-ber/asn1-ber v1.5.4
|
||||||
github.com/go-crypt/crypt v0.2.6
|
github.com/go-crypt/crypt v0.2.6
|
||||||
github.com/go-ldap/ldap/v3 v3.4.4
|
github.com/go-ldap/ldap/v3 v3.4.4
|
||||||
github.com/go-rod/rod v0.112.5
|
github.com/go-rod/rod v0.112.6
|
||||||
github.com/go-sql-driver/mysql v1.7.0
|
github.com/go-sql-driver/mysql v1.7.0
|
||||||
github.com/go-webauthn/webauthn v0.8.2
|
github.com/go-webauthn/webauthn v0.8.2
|
||||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||||
|
@ -33,7 +33,7 @@ require (
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
|
||||||
github.com/ory/fosite v0.44.0
|
github.com/ory/fosite v0.44.0
|
||||||
github.com/ory/herodot v0.9.13
|
github.com/ory/herodot v0.9.13
|
||||||
github.com/ory/x v0.0.537
|
github.com/ory/x v0.0.541
|
||||||
github.com/otiai10/copy v1.9.0
|
github.com/otiai10/copy v1.9.0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pquerna/otp v1.4.0
|
github.com/pquerna/otp v1.4.0
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -160,8 +160,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
|
||||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||||
github.com/go-rod/rod v0.112.5 h1:2mH97UK8We4D2MfX388WqPjG1lDbxx8lLi5MzfvnEo0=
|
github.com/go-rod/rod v0.112.6 h1:zMirUmhsBeshMWyf285BD0UGtGq54HfThLDGSjcP3lU=
|
||||||
github.com/go-rod/rod v0.112.5/go.mod h1:ElViL9ABbcshNQw93+11FrYRH92RRhMKleuILo6+5V0=
|
github.com/go-rod/rod v0.112.6/go.mod h1:ElViL9ABbcshNQw93+11FrYRH92RRhMKleuILo6+5V0=
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
|
||||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
|
@ -387,8 +387,8 @@ github.com/ory/go-convenience v0.1.0/go.mod h1:uEY/a60PL5c12nYz4V5cHY03IBmwIAEm8
|
||||||
github.com/ory/herodot v0.9.13 h1:cN/Z4eOkErl/9W7hDIDLb79IO/bfsH+8yscBjRpB4IU=
|
github.com/ory/herodot v0.9.13 h1:cN/Z4eOkErl/9W7hDIDLb79IO/bfsH+8yscBjRpB4IU=
|
||||||
github.com/ory/herodot v0.9.13/go.mod h1:IWDs9kSvFQqw/cQ8zi5ksyYvITiUU4dI7glUrhZcJYo=
|
github.com/ory/herodot v0.9.13/go.mod h1:IWDs9kSvFQqw/cQ8zi5ksyYvITiUU4dI7glUrhZcJYo=
|
||||||
github.com/ory/viper v1.7.5/go.mod h1:ypOuyJmEUb3oENywQZRgeAMwqgOyDqwboO1tj3DjTaM=
|
github.com/ory/viper v1.7.5/go.mod h1:ypOuyJmEUb3oENywQZRgeAMwqgOyDqwboO1tj3DjTaM=
|
||||||
github.com/ory/x v0.0.537 h1:FB8Tioza6pihvy/RsVNzX08Qg3/VpIhI9vBnEQ4iFmQ=
|
github.com/ory/x v0.0.541 h1:rp8AD7X5/WiZIJws5kBwFgXoSeunxNMD54QV58+pcew=
|
||||||
github.com/ory/x v0.0.537/go.mod h1:CQopDsCC9t0tQsddE9UlyRFVEFd2xjKBVcw4nLMMMS0=
|
github.com/ory/x v0.0.541/go.mod h1:ktXUvx51Ok1gMGr3ysvktanqr+eiB4FXglt4nF4w2Uo=
|
||||||
github.com/otiai10/copy v1.9.0 h1:7KFNiCgZ91Ru4qW4CWPf/7jqtxLagGRmIxWldPP9VY4=
|
github.com/otiai10/copy v1.9.0 h1:7KFNiCgZ91Ru4qW4CWPf/7jqtxLagGRmIxWldPP9VY4=
|
||||||
github.com/otiai10/copy v1.9.0/go.mod h1:hsfX19wcn0UWIHUQ3/4fHuehhk2UyArQ9dVFAn3FczI=
|
github.com/otiai10/copy v1.9.0/go.mod h1:hsfX19wcn0UWIHUQ3/4fHuehhk2UyArQ9dVFAn3FczI=
|
||||||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
||||||
|
|
|
@ -777,3 +777,12 @@ Layouts:
|
||||||
const (
|
const (
|
||||||
fmtLogServerListening = "Listening for %s connections on '%s' path '%s'"
|
fmtLogServerListening = "Listening for %s connections on '%s' path '%s'"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
logFieldService = "service"
|
||||||
|
logFieldFile = "file"
|
||||||
|
logFieldOP = "op"
|
||||||
|
|
||||||
|
serviceTypeServer = "server"
|
||||||
|
serviceTypeWatcher = "watcher"
|
||||||
|
)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/fsnotify/fsnotify"
|
"github.com/fsnotify/fsnotify"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
@ -23,11 +24,12 @@ import (
|
||||||
// NewServerService creates a new ServerService with the appropriate logger etc.
|
// NewServerService creates a new ServerService with the appropriate logger etc.
|
||||||
func NewServerService(name string, server *fasthttp.Server, listener net.Listener, paths []string, isTLS bool, log *logrus.Logger) (service *ServerService) {
|
func NewServerService(name string, server *fasthttp.Server, listener net.Listener, paths []string, isTLS bool, log *logrus.Logger) (service *ServerService) {
|
||||||
return &ServerService{
|
return &ServerService{
|
||||||
|
name: name,
|
||||||
server: server,
|
server: server,
|
||||||
listener: listener,
|
listener: listener,
|
||||||
paths: paths,
|
paths: paths,
|
||||||
isTLS: isTLS,
|
isTLS: isTLS,
|
||||||
log: log.WithFields(map[string]any{"service": "server", "server": name}),
|
log: log.WithFields(map[string]any{logFieldService: serviceTypeServer, serviceTypeServer: name}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,10 +55,11 @@ func NewFileWatcherService(name, path string, reload ProviderReload, log *logrus
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
entry := log.WithFields(map[string]any{"service": "watcher", "watcher": name})
|
entry := log.WithFields(map[string]any{logFieldService: serviceTypeWatcher, serviceTypeWatcher: name})
|
||||||
|
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
service = &FileWatcherService{
|
service = &FileWatcherService{
|
||||||
|
name: name,
|
||||||
watcher: watcher,
|
watcher: watcher,
|
||||||
reload: reload,
|
reload: reload,
|
||||||
log: entry,
|
log: entry,
|
||||||
|
@ -64,6 +67,7 @@ func NewFileWatcherService(name, path string, reload ProviderReload, log *logrus
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
service = &FileWatcherService{
|
service = &FileWatcherService{
|
||||||
|
name: name,
|
||||||
watcher: watcher,
|
watcher: watcher,
|
||||||
reload: reload,
|
reload: reload,
|
||||||
log: entry,
|
log: entry,
|
||||||
|
@ -86,12 +90,25 @@ type ProviderReload interface {
|
||||||
|
|
||||||
// Service represents the required methods to support handling a service.
|
// Service represents the required methods to support handling a service.
|
||||||
type Service interface {
|
type Service interface {
|
||||||
|
// ServiceType returns the type name for the Service.
|
||||||
|
ServiceType() string
|
||||||
|
|
||||||
|
// ServiceName returns the individual name for the Service.
|
||||||
|
ServiceName() string
|
||||||
|
|
||||||
|
// Run performs the running operations for the Service.
|
||||||
Run() (err error)
|
Run() (err error)
|
||||||
|
|
||||||
|
// Shutdown perform the shutdown cleanup and termination operations for the Service.
|
||||||
Shutdown()
|
Shutdown()
|
||||||
|
|
||||||
|
// Log returns the logger configured for the service.
|
||||||
|
Log() *logrus.Entry
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerService is a Service which runs a webserver.
|
// ServerService is a Service which runs a webserver.
|
||||||
type ServerService struct {
|
type ServerService struct {
|
||||||
|
name string
|
||||||
server *fasthttp.Server
|
server *fasthttp.Server
|
||||||
paths []string
|
paths []string
|
||||||
isTLS bool
|
isTLS bool
|
||||||
|
@ -99,6 +116,16 @@ type ServerService struct {
|
||||||
log *logrus.Entry
|
log *logrus.Entry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServiceType returns the service type for this service, which is always 'server'.
|
||||||
|
func (service *ServerService) ServiceType() string {
|
||||||
|
return serviceTypeServer
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceName returns the individual name for this service.
|
||||||
|
func (service *ServerService) ServiceName() string {
|
||||||
|
return service.name
|
||||||
|
}
|
||||||
|
|
||||||
// Run the ServerService.
|
// Run the ServerService.
|
||||||
func (service *ServerService) Run() (err error) {
|
func (service *ServerService) Run() (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -120,13 +147,24 @@ func (service *ServerService) Run() (err error) {
|
||||||
|
|
||||||
// Shutdown the ServerService.
|
// Shutdown the ServerService.
|
||||||
func (service *ServerService) Shutdown() {
|
func (service *ServerService) Shutdown() {
|
||||||
if err := service.server.Shutdown(); err != nil {
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||||
|
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if err := service.server.ShutdownWithContext(ctx); err != nil {
|
||||||
service.log.WithError(err).Error("Error occurred during shutdown")
|
service.log.WithError(err).Error("Error occurred during shutdown")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log returns the *logrus.Entry of the ServerService.
|
||||||
|
func (service *ServerService) Log() *logrus.Entry {
|
||||||
|
return service.log
|
||||||
|
}
|
||||||
|
|
||||||
// FileWatcherService is a Service that watches files for changes.
|
// FileWatcherService is a Service that watches files for changes.
|
||||||
type FileWatcherService struct {
|
type FileWatcherService struct {
|
||||||
|
name string
|
||||||
|
|
||||||
watcher *fsnotify.Watcher
|
watcher *fsnotify.Watcher
|
||||||
reload ProviderReload
|
reload ProviderReload
|
||||||
|
|
||||||
|
@ -135,6 +173,16 @@ type FileWatcherService struct {
|
||||||
directory string
|
directory string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServiceType returns the service type for this service, which is always 'watcher'.
|
||||||
|
func (service *FileWatcherService) ServiceType() string {
|
||||||
|
return serviceTypeWatcher
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceName returns the individual name for this service.
|
||||||
|
func (service *FileWatcherService) ServiceName() string {
|
||||||
|
return service.name
|
||||||
|
}
|
||||||
|
|
||||||
// Run the FileWatcherService.
|
// Run the FileWatcherService.
|
||||||
func (service *FileWatcherService) Run() (err error) {
|
func (service *FileWatcherService) Run() (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -143,7 +191,7 @@ func (service *FileWatcherService) Run() (err error) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
service.log.WithField("file", filepath.Join(service.directory, service.file)).Info("Watching for file changes to the file")
|
service.log.WithField(logFieldFile, filepath.Join(service.directory, service.file)).Info("Watching file for changes")
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
@ -152,34 +200,36 @@ func (service *FileWatcherService) Run() (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log := service.log.WithFields(map[string]any{logFieldFile: event.Name, logFieldOP: event.Op})
|
||||||
|
|
||||||
if service.file != "" && service.file != filepath.Base(event.Name) {
|
if service.file != "" && service.file != filepath.Base(event.Name) {
|
||||||
service.log.WithFields(map[string]any{"file": event.Name, "op": event.Op}).Tracef("File modification detected to irrelevant file")
|
log.Trace("File modification detected to irrelevant file")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case event.Op&fsnotify.Write == fsnotify.Write, event.Op&fsnotify.Create == fsnotify.Create:
|
case event.Op&fsnotify.Write == fsnotify.Write, event.Op&fsnotify.Create == fsnotify.Create:
|
||||||
service.log.WithFields(map[string]any{"file": event.Name, "op": event.Op}).Debug("File modification was detected")
|
log.Debug("File modification was detected")
|
||||||
|
|
||||||
var reloaded bool
|
var reloaded bool
|
||||||
|
|
||||||
switch reloaded, err = service.reload.Reload(); {
|
switch reloaded, err = service.reload.Reload(); {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
service.log.WithFields(map[string]any{"file": event.Name, "op": event.Op}).WithError(err).Error("Error occurred during reload")
|
log.WithError(err).Error("Error occurred during reload")
|
||||||
case reloaded:
|
case reloaded:
|
||||||
service.log.WithField("file", event.Name).Info("Reloaded successfully")
|
log.Info("Reloaded successfully")
|
||||||
default:
|
default:
|
||||||
service.log.WithField("file", event.Name).Debug("Reload of was triggered but it was skipped")
|
log.Debug("Reload was triggered but it was skipped")
|
||||||
}
|
}
|
||||||
case event.Op&fsnotify.Remove == fsnotify.Remove:
|
case event.Op&fsnotify.Remove == fsnotify.Remove:
|
||||||
service.log.WithFields(map[string]any{"file": event.Name, "op": event.Op}).Debug("File remove was detected")
|
log.Debug("File remove was detected")
|
||||||
}
|
}
|
||||||
case err, ok := <-service.watcher.Errors:
|
case err, ok := <-service.watcher.Errors:
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
service.log.WithError(err).Errorf("Error while watching files")
|
service.log.WithError(err).Error("Error while watching file for changes")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,6 +241,11 @@ func (service *FileWatcherService) Shutdown() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log returns the *logrus.Entry of the FileWatcherService.
|
||||||
|
func (service *FileWatcherService) Log() *logrus.Entry {
|
||||||
|
return service.log
|
||||||
|
}
|
||||||
|
|
||||||
func svcSvrMainFunc(ctx *CmdCtx) (service Service) {
|
func svcSvrMainFunc(ctx *CmdCtx) (service Service) {
|
||||||
switch svr, listener, paths, isTLS, err := server.CreateDefaultServer(ctx.config, ctx.providers); {
|
switch svr, listener, paths, isTLS, err := server.CreateDefaultServer(ctx.config, ctx.providers); {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
|
@ -267,34 +322,35 @@ func servicesRun(ctx *CmdCtx) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.log.Info("Startup Complete")
|
ctx.log.Info("Startup complete")
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case s := <-quit:
|
case s := <-quit:
|
||||||
switch s {
|
ctx.log.WithField("signal", s.String()).Debug("Shutdown initiated due to process signal")
|
||||||
case syscall.SIGINT:
|
|
||||||
ctx.log.WithField("signal", "SIGINT").Debugf("Shutdown started due to signal")
|
|
||||||
case syscall.SIGTERM:
|
|
||||||
ctx.log.WithField("signal", "SIGTERM").Debugf("Shutdown started due to signal")
|
|
||||||
}
|
|
||||||
case <-cctx.Done():
|
case <-cctx.Done():
|
||||||
ctx.log.Debugf("Shutdown started due to context completion")
|
ctx.log.Debug("Shutdown initiated due to context completion")
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
ctx.log.Infof("Shutting down")
|
ctx.log.Info("Shutdown initiated")
|
||||||
|
|
||||||
wgShutdown := &sync.WaitGroup{}
|
wgShutdown := &sync.WaitGroup{}
|
||||||
|
|
||||||
|
ctx.log.Tracef("Shutdown of %d services is required", len(services))
|
||||||
|
|
||||||
for _, service := range services {
|
for _, service := range services {
|
||||||
go func() {
|
wgShutdown.Add(1)
|
||||||
|
|
||||||
|
go func(service Service) {
|
||||||
|
service.Log().Trace("Shutdown of service initiated")
|
||||||
|
|
||||||
service.Shutdown()
|
service.Shutdown()
|
||||||
|
|
||||||
wgShutdown.Done()
|
wgShutdown.Done()
|
||||||
}()
|
|
||||||
|
|
||||||
wgShutdown.Add(1)
|
service.Log().Trace("Shutdown of service complete")
|
||||||
|
}(service)
|
||||||
}
|
}
|
||||||
|
|
||||||
wgShutdown.Wait()
|
wgShutdown.Wait()
|
||||||
|
@ -306,6 +362,8 @@ func servicesRun(ctx *CmdCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = group.Wait(); err != nil {
|
if err = group.Wait(); err != nil {
|
||||||
ctx.log.WithError(err).Errorf("Error occurred waiting for shutdown")
|
ctx.log.WithError(err).Error("Error occurred waiting for shutdown")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.log.Info("Shutdown complete")
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ func waitUntilAutheliaBackendIsReady(dockerEnvironment *DockerEnvironment) error
|
||||||
90*time.Second,
|
90*time.Second,
|
||||||
dockerEnvironment,
|
dockerEnvironment,
|
||||||
"authelia-backend",
|
"authelia-backend",
|
||||||
[]string{"Startup Complete"})
|
[]string{"Startup complete"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitUntilAutheliaFrontendIsReady(dockerEnvironment *DockerEnvironment) error {
|
func waitUntilAutheliaFrontendIsReady(dockerEnvironment *DockerEnvironment) error {
|
||||||
|
|
|
@ -30,11 +30,11 @@
|
||||||
"@fortawesome/free-solid-svg-icons": "6.3.0",
|
"@fortawesome/free-solid-svg-icons": "6.3.0",
|
||||||
"@fortawesome/react-fontawesome": "0.2.0",
|
"@fortawesome/react-fontawesome": "0.2.0",
|
||||||
"@mui/icons-material": "5.11.9",
|
"@mui/icons-material": "5.11.9",
|
||||||
"@mui/material": "5.11.9",
|
"@mui/material": "5.11.10",
|
||||||
"@mui/styles": "5.11.9",
|
"@mui/styles": "5.11.9",
|
||||||
"@simplewebauthn/browser": "7.1.0",
|
"@simplewebauthn/browser": "7.1.0",
|
||||||
"@simplewebauthn/typescript-types": "7.0.0",
|
"@simplewebauthn/typescript-types": "7.0.0",
|
||||||
"axios": "1.3.3",
|
"axios": "1.3.4",
|
||||||
"broadcast-channel": "4.20.2",
|
"broadcast-channel": "4.20.2",
|
||||||
"classnames": "2.3.2",
|
"classnames": "2.3.2",
|
||||||
"i18next": "22.4.10",
|
"i18next": "22.4.10",
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
"qrcode.react": "3.1.0",
|
"qrcode.react": "3.1.0",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-i18next": "12.1.5",
|
"react-i18next": "12.2.0",
|
||||||
"react-loading": "2.0.3",
|
"react-loading": "2.0.3",
|
||||||
"react-router-dom": "6.8.1",
|
"react-router-dom": "6.8.1",
|
||||||
"react18-input-otp": "1.1.2",
|
"react18-input-otp": "1.1.2",
|
||||||
|
@ -154,15 +154,15 @@
|
||||||
"@testing-library/jest-dom": "5.16.5",
|
"@testing-library/jest-dom": "5.16.5",
|
||||||
"@testing-library/react": "14.0.0",
|
"@testing-library/react": "14.0.0",
|
||||||
"@types/jest": "29.4.0",
|
"@types/jest": "29.4.0",
|
||||||
"@types/node": "18.14.0",
|
"@types/node": "18.14.1",
|
||||||
"@types/qrcode.react": "1.0.2",
|
"@types/qrcode.react": "1.0.2",
|
||||||
"@types/react": "18.0.28",
|
"@types/react": "18.0.28",
|
||||||
"@types/react-dom": "18.0.11",
|
"@types/react-dom": "18.0.11",
|
||||||
"@types/zxcvbn": "4.4.1",
|
"@types/zxcvbn": "4.4.1",
|
||||||
"@typescript-eslint/eslint-plugin": "5.52.0",
|
"@typescript-eslint/eslint-plugin": "5.53.0",
|
||||||
"@typescript-eslint/parser": "5.52.0",
|
"@typescript-eslint/parser": "5.53.0",
|
||||||
"@vitejs/plugin-react": "3.1.0",
|
"@vitejs/plugin-react": "3.1.0",
|
||||||
"esbuild": "0.17.8",
|
"esbuild": "0.17.10",
|
||||||
"esbuild-jest": "0.5.0",
|
"esbuild-jest": "0.5.0",
|
||||||
"eslint": "8.34.0",
|
"eslint": "8.34.0",
|
||||||
"eslint-config-prettier": "8.6.0",
|
"eslint-config-prettier": "8.6.0",
|
||||||
|
@ -182,7 +182,7 @@
|
||||||
"prettier": "2.8.4",
|
"prettier": "2.8.4",
|
||||||
"react-test-renderer": "18.2.0",
|
"react-test-renderer": "18.2.0",
|
||||||
"typescript": "4.9.5",
|
"typescript": "4.9.5",
|
||||||
"vite": "4.1.2",
|
"vite": "4.1.4",
|
||||||
"vite-plugin-eslint": "1.8.1",
|
"vite-plugin-eslint": "1.8.1",
|
||||||
"vite-plugin-istanbul": "4.0.0",
|
"vite-plugin-istanbul": "4.0.0",
|
||||||
"vite-plugin-svgr": "2.4.0",
|
"vite-plugin-svgr": "2.4.0",
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue