diff --git a/.gitignore b/.gitignore index 7bb4c5401..1d41f9141 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ authelia-image-dev.tar /authelia __debug_bin + +internal/suites/common/pki/ca/ca.private.pem diff --git a/Dockerfile.coverage b/Dockerfile.coverage index 6189a1cb3..eaa527249 100644 --- a/Dockerfile.coverage +++ b/Dockerfile.coverage @@ -15,7 +15,7 @@ RUN yarn global add pnpm && \ # ======================================= # ===== Build image for the backend ===== # ======================================= -FROM golang:1.19.5-alpine AS builder-backend +FROM golang:1.20.0-alpine AS builder-backend WORKDIR /go/src/app diff --git a/Dockerfile.dev b/Dockerfile.dev index 47791c70b..76294f44e 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -13,7 +13,7 @@ RUN yarn install --frozen-lockfile && yarn build # ======================================= # ===== Build image for the backend ===== # ======================================= -FROM golang:1.19.5-alpine AS builder-backend +FROM golang:1.20.0-alpine AS builder-backend WORKDIR /go/src/app diff --git a/api/openapi.yml b/api/openapi.yml index 7979d6f94..6b8debfa8 100644 --- a/api/openapi.yml +++ b/api/openapi.yml @@ -816,7 +816,7 @@ paths: summary: OAuth 2.0 Authorization Server Metadata description: > This endpoint retrieves the OAuth 2.0 Authorization Server Metadata document (RFC8414) used by clients to - perform discovery for an OAuth 2.0 Authorization Server. See https://www.rfc-editor.org/rfc/rfc8414. + perform discovery for an OAuth 2.0 Authorization Server. See https://datatracker.ietf.org/doc/html/rfc8414. responses: "200": description: OK @@ -2822,8 +2822,8 @@ components: description: > JSON array containing a list of the JWS [JWS] signing algorithms (alg values) [JWA] supported by the UserInfo Endpoint to encode the Claims in a JWT [JWT]. The value none MAY be included. See Also: - JWS: https://datatracker.ietf.org/doc/html/rfc7515 JWA: https://datatracker.ietf.org/doc/html/rfc7518 JWT: - https://datatracker.ietf.org/doc/html/rfc7519 + JWS: https://datatracker.ietf.org/doc/html/rfc7515 JWA: https://datatracker.ietf.org/doc/html/rfc7518 + JWT: https://datatracker.ietf.org/doc/html/rfc7519 type: array example: ["none", "RS256"] items: diff --git a/cmd/authelia-gen/cmd_docs_cli.go b/cmd/authelia-gen/cmd_docs_cli.go index 0bade8795..5e137bff3 100644 --- a/cmd/authelia-gen/cmd_docs_cli.go +++ b/cmd/authelia-gen/cmd_docs_cli.go @@ -108,8 +108,9 @@ func genCLIDocWriteIndex(path, name string) (err error) { func prepend(input string) string { now := time.Now() - pathz := strings.Split(strings.Replace(input, ".md", "", 1), "\\") - parts := strings.Split(pathz[len(pathz)-1], "_") + _, filename := filepath.Split(strings.Replace(input, ".md", "", 1)) + + parts := strings.Split(filename, "_") cmd := parts[0] diff --git a/cmd/authelia-scripts/cmd/bootstrap.go b/cmd/authelia-scripts/cmd/bootstrap.go index 82cd8a0c0..1dc26e749 100644 --- a/cmd/authelia-scripts/cmd/bootstrap.go +++ b/cmd/authelia-scripts/cmd/bootstrap.go @@ -64,7 +64,7 @@ func cmdBootstrapRun(_ *cobra.Command, _ []string) { fmt.Println() bootstrapPrintln("Run 'authelia-scripts suites setup Standalone' to start Authelia and visit https://home.example.com:8080.") - bootstrapPrintln("More details at https://github.com/authelia/authelia/blob/master/docs/getting-started.md") + bootstrapPrintln("More details at https://www.authelia.com/contributing/development/build-and-test/") } var hostEntries = []HostEntry{ diff --git a/config.template.yml b/config.template.yml index 7da204922..1058fecc1 100644 --- a/config.template.yml +++ b/config.template.yml @@ -426,7 +426,7 @@ authentication_backend: ## changed once attributed to a user otherwise it would break the configuration for that user. Technically, ## non-unique attributes like 'mail' can also be used but we don't recommend using them, we instead advise to use ## a filter to perform alternative lookups and the attributes mentioned above (sAMAccountName and uid) to - ## follow https://www.ietf.org/rfc/rfc2307.txt. + ## follow https://datatracker.ietf.org/doc/html/rfc2307. # username_attribute: uid ## The additional_users_dn is prefixed to base_dn and delimited by a comma when searching for users. diff --git a/docs/config/next/config.toml b/docs/config/next/config.toml index 9c5e90da5..e0b6dd4bd 100644 --- a/docs/config/next/config.toml +++ b/docs/config/next/config.toml @@ -1 +1 @@ -canonifyURLs = false +baseurl = "https://authelia-staging.netlify.app/" diff --git a/docs/config/production/config.toml b/docs/config/production/config.toml index 9c5e90da5..e69de29bb 100644 --- a/docs/config/production/config.toml +++ b/docs/config/production/config.toml @@ -1 +0,0 @@ -canonifyURLs = false diff --git a/docs/config/staging/config.toml b/docs/config/staging/config.toml index 31a41916f..e0b6dd4bd 100644 --- a/docs/config/staging/config.toml +++ b/docs/config/staging/config.toml @@ -1,2 +1 @@ -canonifyURLs = false baseurl = "https://authelia-staging.netlify.app/" diff --git a/docs/content/en/configuration/first-factor/file.md b/docs/content/en/configuration/first-factor/file.md index 3ced89c64..856d3da0d 100644 --- a/docs/content/en/configuration/first-factor/file.md +++ b/docs/content/en/configuration/first-factor/file.md @@ -256,8 +256,8 @@ truncation that [Bcrypt] does. It is not supported by many other systems.* Controls the hashing cost when hashing passwords using [Bcrypt]. -[Argon2]: https://www.rfc-editor.org/rfc/rfc9106.html +[Argon2]: https://datatracker.ietf.org/doc/html/rfc9106 [Scrypt]: https://en.wikipedia.org/wiki/Scrypt -[PBKDF2]: https://www.ietf.org/rfc/rfc2898.html +[PBKDF2]: https://datatracker.ietf.org/doc/html/rfc2898 [SHA2 Crypt]: https://www.akkadia.org/drepper/SHA-crypt.txt [Bcrypt]: https://en.wikipedia.org/wiki/Bcrypt diff --git a/docs/content/en/configuration/first-factor/ldap.md b/docs/content/en/configuration/first-factor/ldap.md index 95b91524d..7a0ee0d31 100644 --- a/docs/content/en/configuration/first-factor/ldap.md +++ b/docs/content/en/configuration/first-factor/ldap.md @@ -316,4 +316,4 @@ for your users. [username attribute]: #usernameattribute [TechNet wiki]: https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx -[RFC2307]: https://www.rfc-editor.org/rfc/rfc2307.html +[RFC2307]: https://datatracker.ietf.org/doc/html/rfc2307 diff --git a/docs/content/en/configuration/identity-providers/open-id-connect.md b/docs/content/en/configuration/identity-providers/open-id-connect.md index 5d21f92b7..f0a30ba90 100644 --- a/docs/content/en/configuration/identity-providers/open-id-connect.md +++ b/docs/content/en/configuration/identity-providers/open-id-connect.md @@ -119,7 +119,7 @@ identity_providers: clients: - id: myapp description: My Application - secret: '$plaintext$this_is_a_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. sector_identifier: '' public: false authorization_policy: two_factor @@ -170,9 +170,9 @@ encoded PEM format used to sign/encrypt the [OpenID Connect 1.0] [JWT]'s. When c JSON key's in the JWKs [Discoverable Endpoint](../../integration/openid-connect/introduction.md#discoverable-endpoints) as per [RFC7517]. -[RFC7517]: https://www.rfc-editor.org/rfc/rfc7517 -[x5c]: https://www.rfc-editor.org/rfc/rfc7517#section-4.7 -[x5t]: https://www.rfc-editor.org/rfc/rfc7517#section-4.8 +[RFC7517]: https://datatracker.ietf.org/doc/html/rfc7517 +[x5c]: https://datatracker.ietf.org/doc/html/rfc7517#section-4.7 +[x5t]: https://datatracker.ietf.org/doc/html/rfc7517#section-4.8 The first certificate in the chain must have the public key for the [issuer_private_key](#issuerprivatekey), each certificate in the chain must be valid for the current date, and each certificate in the chain should be signed by the @@ -251,7 +251,7 @@ this value. {{< confkey type="string" default="public_clients_only" required="no" >}} -[Proof Key for Code Exchange](https://www.rfc-editor.org/rfc/rfc7636.html) enforcement policy: if specified, must be +[Proof Key for Code Exchange](https://datatracker.ietf.org/doc/html/rfc7636) enforcement policy: if specified, must be either `never`, `public_clients_only` or `always`. If set to `public_clients_only` (default), [PKCE] will be required for public clients using the @@ -402,9 +402,6 @@ This enables the public client type for this client. This is for clients that ar confidentiality of credentials, you can read more about client types in [RFC6749 Section 2.1]. This is particularly useful for SPA's and CLI tools. This option requires setting the [client secret](#secret) to a blank string. -In addition to the standard rules for redirect URIs, public clients can use the `urn:ietf:wg:oauth:2.0:oob` redirect -URI. - #### redirect_uris {{< confkey type="list(string)" required="yes" >}} @@ -420,7 +417,6 @@ their redirect URIs are as follows: attempt to authorize will fail and an error will be generated. 2. The redirect URIs are case-sensitive. 3. The URI must include a scheme and that scheme must be one of `http` or `https`. -4. The client can ignore rule 3 and use `urn:ietf:wg:oauth:2.0:oob` if it is a [public](#public) client type. #### audience @@ -434,30 +430,41 @@ A list of audiences this client is allowed to request. A list of scopes to allow this client to consume. See [scope definitions](../../integration/openid-connect/introduction.md#scope-definitions) for more information. The -documentation for the application you want to use with Authelia will most-likely provide you with the scopes to allow. +documentation for the application you are trying to configure [OpenID Connect 1.0] for will likely have a list of scopes +or claims required which can be matched with the above guide. #### grant_types {{< confkey type="list(string)" default="refresh_token, authorization_code" required="no" >}} -A list of grant types this client can return. *It is recommended that this isn't configured at this time unless you -know what you're doing*. Valid options are: `implicit`, `refresh_token`, `authorization_code`, `password`, -`client_credentials`. +*__Important Note:__ It is recommended that this isn't configured at this time unless you know what you're doing.* + +The list of grant types this client is permitted to use in order to obtain access to the relevant tokens. + +See the [Grant Types](../../integration/openid-connect/introduction.md#grant-types) section of the +[OpenID Connect 1.0 Integration Guide](../../integration/openid-connect/introduction.md#grant-types) for more information. #### response_types {{< confkey type="list(string)" default="code" required="no" >}} -A list of response types this client can return. *It is recommended that this isn't configured at this time unless you -know what you're doing*. Valid options are: `code`, `code id_token`, `id_token`, `token id_token`, `token`, -`token id_token code`. +*__Important Note:__ It is recommended that this isn't configured at this time unless you know what you're doing.* + +A list of response types this client supports. + +See the [Response Types](../../integration/openid-connect/introduction.md#response-types) section of the +[OpenID Connect 1.0 Integration Guide](../../integration/openid-connect/introduction.md#response-types) for more information. #### response_modes {{< confkey type="list(string)" default="form_post, query, fragment" required="no" >}} -A list of response modes this client can return. It is recommended that this isn't configured at this time unless you -know what you're doing. Potential values are `form_post`, `query`, and `fragment`. +*__Important Note:__ It is recommended that this isn't configured at this time unless you know what you're doing.* + +A list of response modes this client supports. + +See the [Response Modes](../../integration/openid-connect/introduction.md#response-modes) section of the +[OpenID Connect 1.0 Integration Guide](../../integration/openid-connect/introduction.md#response-modes) for more information. #### authorization_policy @@ -495,14 +502,18 @@ more information. {{< confkey type="string" default="auto" required="no" >}} +*__Important Note:__ the `implicit` consent mode is not technically part of the specification. It theoretically could be +misused in certain conditions specifically with public clients or when the client credentials (i.e. client secret) has +been exposed to an attacker. For these reasons this mode is discouraged.* + Configures the consent mode. The following table describes the different modes: -| Value | Description | -|:--------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| -| auto | Automatically determined (default). Uses `explicit` unless [pre_configured_consent_duration] is specified in which case uses `pre-configured`. | -| explicit | Requires the user provide unique explicit consent for every authorization. | -| implicit | Automatically assumes consent for every authorization, never asking the user if they wish to give consent. *__Note:__* this option is not technically part of the specification. | -| pre-configured | Allows the end-user to remember their consent for the [pre_configured_consent_duration]. | +| Value | Description | +|:--------------:|:----------------------------------------------------------------------------------------------------------------------------------------------:| +| auto | Automatically determined (default). Uses `explicit` unless [pre_configured_consent_duration] is specified in which case uses `pre-configured`. | +| explicit | Requires the user provide unique explicit consent for every authorization. | +| implicit | Automatically assumes consent for every authorization, never asking the user if they wish to give consent. | +| pre-configured | Allows the end-user to remember their consent for the [pre_configured_consent_duration]. | [pre_configured_consent_duration]: #preconfiguredconsentduration @@ -530,12 +541,12 @@ To integrate Authelia's [OpenID Connect 1.0] implementation with a relying party [token lifespan]: https://docs.apigee.com/api-platform/antipatterns/oauth-long-expiration [OpenID Connect 1.0]: https://openid.net/connect/ -[JWT]: https://www.rfc-editor.org/rfc/rfc7519.html -[RFC6234]: https://www.rfc-editor.org/rfc/rfc6234.html -[RFC4648]: https://www.rfc-editor.org/rfc/rfc4648.html -[RFC7468]: https://www.rfc-editor.org/rfc/rfc7468.html -[RFC6749 Section 2.1]: https://www.rfc-editor.org/rfc/rfc6749.html#section-2.1 -[PKCE]: https://www.rfc-editor.org/rfc/rfc7636.html +[JWT]: https://datatracker.ietf.org/doc/html/rfc7519 +[RFC6234]: https://datatracker.ietf.org/doc/html/rfc6234 +[RFC4648]: https://datatracker.ietf.org/doc/html/rfc4648 +[RFC7468]: https://datatracker.ietf.org/doc/html/rfc7468 +[RFC6749 Section 2.1]: https://datatracker.ietf.org/doc/html/rfc6749#section-2.1 +[PKCE]: https://datatracker.ietf.org/doc/html/rfc7636 [Authorization Code Flow]: https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth [Subject Identifier Type]: https://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes [Pairwise Identifier Algorithm]: https://openid.net/specs/openid-connect-core-1_0.html#PairwiseAlg diff --git a/docs/content/en/configuration/notifications/smtp.md b/docs/content/en/configuration/notifications/smtp.md index 8558410f9..e22d4f834 100644 --- a/docs/content/en/configuration/notifications/smtp.md +++ b/docs/content/en/configuration/notifications/smtp.md @@ -164,7 +164,7 @@ characters and the user password is changed to this value. {{< confkey type="string" required="yes" >}} The sender is used to construct both the SMTP command `MAIL FROM` and to add the `FROM` header. This address must be -in [RFC5322](https://www.rfc-editor.org/rfc/rfc5322.html#section-3.4) format. This means it must one of two formats: +in [RFC5322](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4) format. This means it must one of two formats: * jsmith@domain.com * John Smith diff --git a/docs/content/en/configuration/prologue/common.md b/docs/content/en/configuration/prologue/common.md index a5ea1ee3f..2c549f75c 100644 --- a/docs/content/en/configuration/prologue/common.md +++ b/docs/content/en/configuration/prologue/common.md @@ -35,10 +35,18 @@ The way this format works is you can either configure an integer or a string in supply an integer, it is considered a representation of seconds. If you supply a string, it parses the string in blocks of quantities and units (number followed by a unit letter). For example `5h` indicates a quantity of 5 units of `h`. +The following is ignored: + - all spaces + - leading zeros + While you can use multiple of these blocks in combination, we suggest keeping it simple and use a single value. ### Unit Legend +#### Short Units + +These values have been available for a long time. + | Unit | Associated Letter | |:-------:|:-----------------:| | Years | y | @@ -49,6 +57,21 @@ While you can use multiple of these blocks in combination, we suggest keeping it | Minutes | m | | Seconds | s | +#### Long Units + +These values are more human readable but have only been available since v4.38.0. + +| Unit | Human Readable Long Unit | +|:------------:|:-----------------------------:| +| Years | `year`, `years` | +| Months | `month`, `months` | +| Weeks | `week`, `weeks` | +| Days | `day`, `days` | +| Hours | `hour`, `hours` | +| Minutes | `minute`, `minutes` | +| Seconds | `second`, `seconds` | +| Milliseconds | `millisecond`, `milliseconds` | + ### Examples | Desired Value | Configuration Examples | @@ -154,7 +177,7 @@ The value must be one or more certificates encoded in the DER base64 ([RFC4648]) ### private_key -{{< confkey type="string" required="yes" >}} +{{< confkey type="string" required="no" >}} *__Important Note:__ This can also be defined using a [secret](../methods/secrets.md) which is __strongly recommended__ especially for containerized deployments.* @@ -163,6 +186,8 @@ The private key to be used with the [certificate_chain](#certificatechain) for m The value must be one private key encoded in the DER base64 ([RFC4648]) encoded PEM format. +[RFC4648]: https://datatracker.ietf.org/doc/html/rfc4648 + ## Server Buffers ### read diff --git a/docs/content/en/configuration/second-factor/time-based-one-time-password.md b/docs/content/en/configuration/second-factor/time-based-one-time-password.md index 0783aa149..b93ca987b 100644 --- a/docs/content/en/configuration/second-factor/time-based-one-time-password.md +++ b/docs/content/en/configuration/second-factor/time-based-one-time-password.md @@ -172,5 +172,5 @@ at least a minimal configuration that has the storage backend connection details See the [CLI Documentation](../../reference/cli/authelia/authelia_storage_user_totp_export.md) for methods to perform exports. -[RFC4226]: https://www.rfc-editor.org/rfc/rfc4226.html -[RFC6238]: https://www.rfc-editor.org/rfc/rfc6238.html +[RFC4226]: https://datatracker.ietf.org/doc/html/rfc4226 +[RFC6238]: https://datatracker.ietf.org/doc/html/rfc6238 diff --git a/docs/content/en/configuration/security/access-control.md b/docs/content/en/configuration/security/access-control.md index 011cec776..5dae020d8 100644 --- a/docs/content/en/configuration/security/access-control.md +++ b/docs/content/en/configuration/security/access-control.md @@ -588,8 +588,8 @@ The match type `Equals` matches if the value extracted from the pattern is equal match value is a list/slice). The regex groups are case-insensitive due to the fact that the regex groups are used in domain criteria and domain names -should not be compared in a case-sensitive way as per the [RFC4343](https://www.rfc-editor.org/rfc/rfc4343.html) -abstract and [RFC3986 Section 3.2.2](https://www.rfc-editor.org/rfc/rfc3986#section-3.2.2). +should not be compared in a case-sensitive way as per the [RFC4343](https://datatracker.ietf.org/doc/html/rfc4343) +abstract and [RFC3986 Section 3.2.2](https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2). We do not currently apply any other normalization to usernames or groups when matching these groups. As such it's generally *__not recommended__* to use these patterns with usernames or groups which contain characters that are not @@ -664,6 +664,6 @@ access_control: policy: bypass ``` -[RFC7231]: https://www.rfc-editor.org/rfc/rfc7231.html -[RFC5789]: https://www.rfc-editor.org/rfc/rfc5789.html -[RFC4918]: https://www.rfc-editor.org/rfc/rfc4918.html +[RFC7231]: https://datatracker.ietf.org/doc/html/rfc7231 +[RFC5789]: https://datatracker.ietf.org/doc/html/rfc5789 +[RFC4918]: https://datatracker.ietf.org/doc/html/rfc4918 diff --git a/docs/content/en/configuration/session/introduction.md b/docs/content/en/configuration/session/introduction.md index f60159845..4a5ed19ca 100644 --- a/docs/content/en/configuration/session/introduction.md +++ b/docs/content/en/configuration/session/introduction.md @@ -137,11 +137,12 @@ cookies for this domain. For example if Authelia is accessible via the URL `https://auth.example.com` the domain should be either `auth.example.com` or `example.com`. -Please note most good DynamicDNS solutions fall into a specially protected group of domains and browsers do not allow -you to write cookies for the root domain. i.e. if you have been assigned `john.duckdns.org` you can't use `duckdns.org` -for the domain value as browsers will not allow `john.duckdns.org` to read or write cookies for `duckdns.org`. +The value must not match a domain on the [Public Suffix List](https://publicsuffix.org/list/) as browsers do not allow +websites to write cookies for these domains. This includes most Dynamic DNS services such as `duckdns.org`. You should +use your domain instead of `duckdns.org` for this value, for example `example.duckdns.org`. -Consequently, if you have `john.duckdns.org` and `mary.duckdns.org` you cannot share cookies between these domains. +Consequently, if you have `example.duckdns.org` and `example-auth.duckdns.org` you cannot share cookies between these +domains. #### authelia_url diff --git a/docs/content/en/contributing/development/environment.md b/docs/content/en/contributing/development/environment.md index 1a81643d6..96fd84e29 100644 --- a/docs/content/en/contributing/development/environment.md +++ b/docs/content/en/contributing/development/environment.md @@ -21,7 +21,7 @@ In order to build and contribute to __Authelia__, you need to make sure the foll * General: * [git] * Backend Development: - * [go] *(v1.19 or greater)* + * [go] *(v1.20 or greater)* * [gcc] * Frontend Development * [Node.js] *(v18 or greater)* diff --git a/docs/content/en/integration/openid-connect/apache-guacamole/index.md b/docs/content/en/integration/openid-connect/apache-guacamole/index.md index 51a8ec5c5..d66c84523 100644 --- a/docs/content/en/integration/openid-connect/apache-guacamole/index.md +++ b/docs/content/en/integration/openid-connect/apache-guacamole/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -38,7 +31,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://guacamole.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `guacamole` -* __Client Secret:__ `guacamole_client_secret` +* __Client Secret:__ `insecure_secret` ## Configuration @@ -66,7 +59,7 @@ The following YAML configuration is an example __Authelia__ ```yaml - id: guacamole description: Apache Guacamole - secret: '$plaintext$guacamole_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/argocd/index.md b/docs/content/en/integration/openid-connect/argocd/index.md index dfb625835..081a76b10 100644 --- a/docs/content/en/integration/openid-connect/argocd/index.md +++ b/docs/content/en/integration/openid-connect/argocd/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -38,7 +31,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://argocd.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `argocd` -* __Client Secret:__ `argocd_client_secret` +* __Client Secret:__ `insecure_secret` * __CLI Client ID:__ `argocd-cli` ## Configuration @@ -51,7 +44,7 @@ To configure [Argo CD] to utilize Authelia as an [OpenID Connect 1.0] Provider u name: Authelia issuer: https://auth.example.com clientID: argocd -clientSecret: argocd_client_secret +clientSecret: insecure_secret cliClientID: argocd-cli requestedScopes: - openid @@ -69,7 +62,7 @@ which will operate with the above example: ```yaml - id: argocd description: Argo CD - secret: '$plaintext$argocd_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/bookstack/index.md b/docs/content/en/integration/openid-connect/bookstack/index.md index 1e1b93e09..adb61041f 100644 --- a/docs/content/en/integration/openid-connect/bookstack/index.md +++ b/docs/content/en/integration/openid-connect/bookstack/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -38,13 +31,13 @@ This example makes the following assumptions: * __Application Root URL:__ `https://bookstack.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `bookstack` -* __Client Secret:__ `bookstack_client_secret` +* __Client Secret:__ `insecure_secret` *__Important Note:__ [BookStack] does not properly URL encode the secret per [RFC6749 Appendix B] at the time this article was last modified (noted at the bottom). This means you'll either have to use only alphanumeric characters for the secret or URL encode the secret yourself.* -[RFC6749 Appendix B]: https://www.rfc-editor.org/rfc/rfc6749#appendix-B +[RFC6749 Appendix B]: https://datatracker.ietf.org/doc/html/rfc6749#appendix-B ## Configuration @@ -58,7 +51,7 @@ To configure [BookStack] to utilize Authelia as an [OpenID Connect 1.0] Provider 2. OIDC_NAME: `Authelia` 3. OIDC_DISPLAY_NAME_CLAIMS: `name` 4. OIDC_CLIENT_ID: `bookstack` - 5. OIDC_CLIENT_SECRET: `bookstack_client_secret` + 5. OIDC_CLIENT_SECRET: `insecure_secret` 6. OIDC_ISSUER: `https://auth.example.com` 7. OIDC_ISSUER_DISCOVER: `true` @@ -71,7 +64,7 @@ which will operate with the above example: ```yaml - id: bookstack description: BookStack - secret: '$plaintext$bookstack_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/cloudflare-zerotrust/index.md b/docs/content/en/integration/openid-connect/cloudflare-zerotrust/index.md index 1a285e77e..9a24e40a5 100644 --- a/docs/content/en/integration/openid-connect/cloudflare-zerotrust/index.md +++ b/docs/content/en/integration/openid-connect/cloudflare-zerotrust/index.md @@ -20,14 +20,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -36,13 +29,13 @@ This example makes the following assumptions: * __Cloudflare Team Name:__ `example-team` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `cloudflare` -* __Client Secret:__ `cloudflare_client_secret` +* __Client Secret:__ `insecure_secret` *__Important Note:__ [Cloudflare Zero Trust] does not properly URL encode the secret per [RFC6749 Appendix B] at the time this article was last modified (noted at the bottom). This means you'll either have to use only alphanumeric characters for the secret or URL encode the secret yourself.* -[RFC6749 Appendix B]: https://www.rfc-editor.org/rfc/rfc6749#appendix-B +[RFC6749 Appendix B]: https://datatracker.ietf.org/doc/html/rfc6749#appendix-B ## Configuration @@ -62,7 +55,7 @@ To configure [Cloudflare Zero Trust] to utilize Authelia as an [OpenID Connect 1 6. Set the following values: 1. Name: `Authelia` 2. App ID: `cloudflare` - 3. Client Secret: `cloudflare_client_secret` + 3. Client Secret: `insecure_secret` 4. Auth URL: `https://auth.example.com/api/oidc/authorization` 5. Token URL: `https://auth.example.com/api/oidc/token` 6. Certificate URL: `https://auth.example.com/jwks.json` @@ -79,7 +72,7 @@ which will operate with the above example: ```yaml - id: cloudflare description: Cloudflare ZeroTrust - secret: '$plaintext$cloudflare_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/gitea/index.md b/docs/content/en/integration/openid-connect/gitea/index.md index 2c388c7c2..386811b9b 100644 --- a/docs/content/en/integration/openid-connect/gitea/index.md +++ b/docs/content/en/integration/openid-connect/gitea/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -38,7 +31,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://gitea.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `gitea` -* __Client Secret:__ `gitea_client_secret` +* __Client Secret:__ `insecure_secret` ## Configuration @@ -54,7 +47,7 @@ To configure [Gitea] to utilize Authelia as an [OpenID Connect 1.0] Provider: 1. Authentication Name: `authelia` 2. OAuth2 Provider: `OpenID Connect` 3. Client ID (Key): `gitea` - 4. Client Secret: `gitea_client_secret` + 4. Client Secret: `insecure_secret` 5. OpenID Connect Auto Discovery URL: `https://auth.example.com/.well-known/openid-configuration` {{< figure src="gitea.png" alt="Gitea" width="300" >}} @@ -86,7 +79,7 @@ will operate with the above example: ```yaml - id: gitea description: Gitea - secret: '$plaintext$gitea_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/gitlab/index.md b/docs/content/en/integration/openid-connect/gitlab/index.md index 52fd4dae0..1620d95e3 100644 --- a/docs/content/en/integration/openid-connect/gitlab/index.md +++ b/docs/content/en/integration/openid-connect/gitlab/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -38,7 +31,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://gitlab.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `gitlab` -* __Client Secret:__ `gitlab_client_secret` +* __Client Secret:__ `insecure_secret` ## Configuration @@ -65,7 +58,7 @@ gitlab_rails['omniauth_providers'] = [ send_scope_to_token_endpoint: "false", client_options: { identifier: "gitlab", - secret: "gitlab_client_secret", + secret: "insecure_secret", redirect_uri: "https://gitlab.example.com/users/auth/openid_connect/callback" } } @@ -82,7 +75,7 @@ which will operate with the above example: ```yaml - id: gitlab description: GitLab - secret: '$plaintext$gitlab_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/grafana/index.md b/docs/content/en/integration/openid-connect/grafana/index.md index 6ac6775b1..916dd4f2a 100644 --- a/docs/content/en/integration/openid-connect/grafana/index.md +++ b/docs/content/en/integration/openid-connect/grafana/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -38,7 +31,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://grafana.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `grafana` -* __Client Secret:__ `grafana_client_secret` +* __Client Secret:__ `insecure_secret` ## Configuration @@ -58,7 +51,7 @@ enabled = true name = Authelia icon = signin client_id = grafana -client_secret = grafana_client_secret +client_secret = insecure_secret scopes = openid profile email groups empty_scopes = false auth_url = https://auth.example.com/api/oidc/authorization @@ -80,7 +73,7 @@ Configure the following environment variables: | GF_AUTH_GENERIC_OAUTH_ENABLED | true | | GF_AUTH_GENERIC_OAUTH_NAME | Authelia | | GF_AUTH_GENERIC_OAUTH_CLIENT_ID | grafana | -| GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET | grafana_client_secret | +| GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET | insecure_secret | | GF_AUTH_GENERIC_OAUTH_SCOPES | openid profile email groups | | GF_AUTH_GENERIC_OAUTH_EMPTY_SCOPES | false | | GF_AUTH_GENERIC_OAUTH_AUTH_URL | https://auth.example.com/api/oidc/authorization | @@ -100,7 +93,7 @@ which will operate with the above example: ```yaml - id: grafana description: Grafana - secret: '$plaintext$grafana_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/harbor/index.md b/docs/content/en/integration/openid-connect/harbor/index.md index 77e120597..ebd832b69 100644 --- a/docs/content/en/integration/openid-connect/harbor/index.md +++ b/docs/content/en/integration/openid-connect/harbor/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -38,7 +31,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://harbor.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `harbor` -* __Client Secret:__ `harbor_client_secret` +* __Client Secret:__ `insecure_secret` ## Configuration @@ -54,7 +47,7 @@ To configure [Harbor] to utilize Authelia as an [OpenID Connect 1.0] Provider: 1. OIDC Provider Name: `Authelia` 2. OIDC Provider Endpoint: `https://auth.example.com` 3. OIDC Client ID: `harbor` - 4. OIDC Client Secret: `harbor_client_secret` + 4. OIDC Client Secret: `insecure_secret` 5. Group Claim Name: `groups` 6. OIDC Scope: `openid,profile,email,groups` 7. For OIDC Admin Group you can specify a group name that matches your authentication backend. @@ -73,7 +66,7 @@ which will operate with the above example: ```yaml - id: harbor description: Harbor - secret: '$plaintext$harbor_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/hashicorp-vault/index.md b/docs/content/en/integration/openid-connect/hashicorp-vault/index.md index 76f7fb61e..80f93009b 100644 --- a/docs/content/en/integration/openid-connect/hashicorp-vault/index.md +++ b/docs/content/en/integration/openid-connect/hashicorp-vault/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -38,7 +31,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://vault.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `vault` -* __Client Secret:__ `vault_client_secret` +* __Client Secret:__ `insecure_secret` ## Configuration @@ -56,7 +49,7 @@ which will operate with the above example: ```yaml - id: vault description: HashiCorp Vault - secret: '$plaintext$vault_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/introduction.md b/docs/content/en/integration/openid-connect/introduction.md index 77271afa6..4b06ae438 100644 --- a/docs/content/en/integration/openid-connect/introduction.md +++ b/docs/content/en/integration/openid-connect/introduction.md @@ -87,6 +87,68 @@ This scope includes the profile information the authentication backend reports a | preferred_username | string | username | The username the user used to login with | | name | string | display_name | The users display name | +## Parameters + +The following section describes advanced parameters which can be used in various endpoints as well as their related +configuration options. + +### Grant Types + +The following describes the various [OAuth 2.0] and [OpenID Connect 1.0] grant types and their support level. The value +field is both the required value for the `grant_type` parameter in the authorization request and the `grant_types` +configuration option. + +| Grant Type | Supported | Value | Notes | +|:-----------------------------------------------:|:---------:|:----------------------------------------------:|:-------------------------------------------------------------------:| +| [OAuth 2.0 Authorization Code] | Yes | `authorization_code` | | +| [OAuth 2.0 Resource Owner Password Credentials] | No | `password` | This Grant Type has been deprecated and should not normally be used | +| [OAuth 2.0 Client Credentials] | Yes | `client_credentials` | | +| [OAuth 2.0 Implicit] | Yes | `implicit` | This Grant Type has been deprecated and should not normally be used | +| [OAuth 2.0 Refresh Token] | Yes | `refresh_token` | | +| [OAuth 2.0 Device Code] | No | `urn:ietf:params:oauth:grant-type:device_code` | | +| + +[OAuth 2.0 Authorization Code]: https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.1 +[OAuth 2.0 Implicit]: https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.2 +[OAuth 2.0 Resource Owner Password Credentials]: https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.3 +[OAuth 2.0 Client Credentials]: https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.4 +[OAuth 2.0 Refresh Token]: https://datatracker.ietf.org/doc/html/rfc6749#section-1.5 +[OAuth 2.0 Device Code]: https://datatracker.ietf.org/doc/html/rfc8628#section-3.4 + +### Response Types + +The following describes the supported response types. See the [OAuth 2.0 Multiple Response Type Encoding Practices] for +more technical information. + +| Flow Type | Values | +|:-------------------------:|:---------------------:| +| [Authorization Code Flow] | `code` | +| [Implicit Flow] | `token id_token` | +| [Implicit Flow] | `id_token` | +| [Implicit Flow] | `token` | +| [Hybrid Flow] | `code token` | +| [Hybrid Flow] | `code id_token` | +| [Hybrid Flow] | `code token id_token` | + +[Authorization Code Flow]: https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth +[Implicit Flow]: https://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowAuth +[Hybrid Flow]: https://openid.net/specs/openid-connect-core-1_0.html#HybridFlowAuth + +[OAuth 2.0 Multiple Response Type Encoding Practices]: https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html + +### Response Modes + +The following describes the supported response modes. See the [OAuth 2.0 Multiple Response Type Encoding Practices] for +more technical information. + +| Name | Value | +|:---------------------:|:-----------:| +| Query String | `query` | +| Fragment | `fragment` | +| [OAuth 2.0 Form Post] | `form_post` | + +[OAuth 2.0 Form Post]: https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html + ## Authentication Method References Authelia currently supports adding the `amr` [Claim] to the [ID Token] utilizing the [RFC8176] Authentication Method @@ -166,16 +228,16 @@ These endpoints implement OpenID Connect elements. [OpenID Connect 1.0]: https://openid.net/connect/ [OpenID Connect Discovery]: https://openid.net/specs/openid-connect-discovery-1_0.html -[OAuth 2.0 Authorization Server Metadata]: https://www.rfc-editor.org/rfc/rfc8414.html +[OAuth 2.0 Authorization Server Metadata]: https://datatracker.ietf.org/doc/html/rfc8414 -[JSON Web Key Sets]: https://www.rfc-editor.org/rfc/rfc7517.html#section-5 +[JSON Web Key Sets]: https://datatracker.ietf.org/doc/html/rfc7517#section-5 [Authorization]: https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint [Token]: https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint [UserInfo]: https://openid.net/specs/openid-connect-core-1_0.html#UserInfo -[Introspection]: https://www.rfc-editor.org/rfc/rfc7662.html -[Revocation]: https://www.rfc-editor.org/rfc/rfc7009.html +[Introspection]: https://datatracker.ietf.org/doc/html/rfc7662 +[Revocation]: https://datatracker.ietf.org/doc/html/rfc7009 -[RFC8176]: https://www.rfc-editor.org/rfc/rfc8176.html -[RFC4122]: https://www.rfc-editor.org/rfc/rfc4122.html +[RFC8176]: https://datatracker.ietf.org/doc/html/rfc8176 +[RFC4122]: https://datatracker.ietf.org/doc/html/rfc4122 [Subject Identifier Types]: https://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes diff --git a/docs/content/en/integration/openid-connect/komga/index.md b/docs/content/en/integration/openid-connect/komga/index.md index e999aea7a..15cea6ded 100644 --- a/docs/content/en/integration/openid-connect/komga/index.md +++ b/docs/content/en/integration/openid-connect/komga/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -38,7 +31,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://komga.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `komga` -* __Client Secret:__ `komga_client_secret` +* __Client Secret:__ `insecure_secret` ## Configuration @@ -58,7 +51,7 @@ spring: registration: authelia: client-id: `komga` - client-secret: `komga_client_secret` + client-secret: `insecure_secret` client-name: Authelia scope: openid,profile,email authorization-grant-type: authorization_code @@ -78,7 +71,7 @@ which will operate with the above example: ```yaml - id: komga description: Komga - secret: '$plaintext$komga_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/nextcloud/index.md b/docs/content/en/integration/openid-connect/nextcloud/index.md index 9731e3943..f21e0d1b6 100644 --- a/docs/content/en/integration/openid-connect/nextcloud/index.md +++ b/docs/content/en/integration/openid-connect/nextcloud/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -38,7 +31,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://nextcloud.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `nextcloud` -* __Client Secret:__ `nextcloud_client_secret` +* __Client Secret:__ `insecure_secret` ## Configuration @@ -55,7 +48,7 @@ $CONFIG = array ( 'lost_password_link' => 'disabled', 'oidc_login_provider_url' => 'https://auth.example.com', 'oidc_login_client_id' => 'nextcloud', - 'oidc_login_client_secret' => 'nextcloud_client_secret', + 'oidc_login_client_secret' => 'insecure_secret', 'oidc_login_auto_redirect' => false, 'oidc_login_end_session_redirect' => false, 'oidc_login_button_text' => 'Log in with Authelia', @@ -94,7 +87,7 @@ which will operate with the above example: ```yaml - id: nextcloud description: NextCloud - secret: '$plaintext$nextcloud_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/outline/index.md b/docs/content/en/integration/openid-connect/outline/index.md index cd565ca87..17e0b1cfb 100644 --- a/docs/content/en/integration/openid-connect/outline/index.md +++ b/docs/content/en/integration/openid-connect/outline/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -38,7 +31,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://outline.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `outline` -* __Client Secret:__ `outline_client_secret` +* __Client Secret:__ `insecure_secret` *__Important Note:__ At the time of this writing [Outline] requires the `offline_access` scope by default. Failure to include this scope will result in an error as [Outline] will attempt to use a refresh token that is never issued.* @@ -55,7 +48,7 @@ URL=https://outline.example.com FORCE_HTTPS=true OIDC_CLIENT_ID=outline -OIDC_CLIENT_SECRET=outline_client_secret +OIDC_CLIENT_SECRET=insecure_secret OIDC_AUTH_URI=https://auth.example.com/api/oidc/authorization OIDC_TOKEN_URI=https://auth.example.com/api/oidc/token OIDC_USERINFO_URI=https://auth.example.com/api/oidc/userinfo @@ -73,7 +66,7 @@ which will operate with the above example: ```yaml - id: outline description: Outline - secret: '$plaintext$outline_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/portainer/index.md b/docs/content/en/integration/openid-connect/portainer/index.md index 5feeb65be..a94fbde44 100644 --- a/docs/content/en/integration/openid-connect/portainer/index.md +++ b/docs/content/en/integration/openid-connect/portainer/index.md @@ -24,14 +24,7 @@ aliases: ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -40,7 +33,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://portainer.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `portainer` -* __Client Secret:__ `portainer_client_secret` +* __Client Secret:__ `insecure_secret` ## Configuration @@ -55,7 +48,7 @@ To configure [Portainer] to utilize Authelia as an [OpenID Connect 1.0] Provider 2. Provider: Custom 3. Enable *Automatic User Provision* if you want users to automatically be created in [Portainer]. 4. Client ID: `portainer` - 5. Client Secret: `portainer_client_secret` + 5. Client Secret: `insecure_secret` 6. Authorization URL: `https://auth.example.com/api/oidc/authorization` 7. Access Token URL: `https://auth.example.com/api/oidc/token` 8. Resource URL: `https://auth.example.com/api/oidc/userinfo` @@ -75,7 +68,7 @@ which will operate with the above example: ```yaml - id: portainer description: Portainer - secret: '$plaintext$portainer_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/proxmox/index.md b/docs/content/en/integration/openid-connect/proxmox/index.md index fab84e943..9e6c608c6 100644 --- a/docs/content/en/integration/openid-connect/proxmox/index.md +++ b/docs/content/en/integration/openid-connect/proxmox/index.md @@ -43,7 +43,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://proxmox.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `proxmox` -* __Client Secret:__ `proxmox_client_secret` +* __Client Secret:__ `insecure_secret` * __Realm__ `authelia` ## Configuration @@ -60,7 +60,7 @@ To configure [Proxmox] to utilize Authelia as an [OpenID Connect 1.0] Provider: 1. Issuer URL: `https://auth.example.com` 2. Realm: `authelia` 3. Client ID: `proxmox` - 4. Client Key: `proxmox_client_secret` + 4. Client Key: `insecure_secret` 5. Username Claim `preferred_username` 6. Scopes: `openid profile email` 7. Enable *Autocreate Users* if you want users to automatically be created in [Proxmox]. @@ -76,7 +76,7 @@ which will operate with the above example: ```yaml - id: proxmox description: Proxmox - secret: '$plaintext$proxmox_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/seafile/index.md b/docs/content/en/integration/openid-connect/seafile/index.md index 0187a179e..d2d77cdba 100644 --- a/docs/content/en/integration/openid-connect/seafile/index.md +++ b/docs/content/en/integration/openid-connect/seafile/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -38,7 +31,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://seafile.example.com` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `seafile` -* __Client Secret:__ `seafile_client_secret` +* __Client Secret:__ `insecure_secret` ## Configuration @@ -55,7 +48,7 @@ To configure [Seafile] to utilize Authelia as an [OpenID Connect 1.0] Provider: ENABLE_OAUTH = True OAUTH_ENABLE_INSECURE_TRANSPORT = False OAUTH_CLIENT_ID = "seafile" -OAUTH_CLIENT_SECRET = "seafile_client_secret" +OAUTH_CLIENT_SECRET = "insecure_secret" OAUTH_REDIRECT_URL = 'https://seafile.example.com/oauth/callback/' OAUTH_PROVIDER_DOMAIN = 'auth.example.com' OAUTH_AUTHORIZATION_URL = 'https://auth.example.com/api/oidc/authorization' @@ -82,7 +75,7 @@ which will operate with the above example: ```yaml - id: seafile description: Seafile - secret: '$plaintext$seafile_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/specific-information.md b/docs/content/en/integration/openid-connect/specific-information.md index a89bf29b6..81d35a99f 100644 --- a/docs/content/en/integration/openid-connect/specific-information.md +++ b/docs/content/en/integration/openid-connect/specific-information.md @@ -34,6 +34,22 @@ using PBKDF2 which can be stored in the Authelia configuration. ### Plaintext -Authelia supports storing the plaintext secret in the configuration. This may be discontinued in the future. Plaintext -is either denoted by the `$plaintext$` prefix where everything after the prefix is the secret. In addition if the secret -does not start with the `$` character it's considered as a plaintext secret for the time being but is deprecated. +Authelia *technically* supports storing the plaintext secret in the configuration. This will likely be completely +unavailable in the future as it was a mistake to implement it like this in the first place. While some other OpenID +Connect 1.0 providers operate in this way, it's more often than not that they operating in this way in error. The +current *technical support* for this is only to prevent massive upheaval to users and give them time to migrate. + +As per [RFC6819 Section 5.1.4.1.3](https://datatracker.ietf.org/doc/html/rfc6819#section-5.1.4.1.3) the secret should +only be stored by the authorization server as hashes / digests unless there is a very specific specification or protocol +that is implemented by the authorization server which requires access to the secret in the clear to operate properly in +which case the secret should be encrypted and not be stored in plaintext. The most likely long term outcome is that the +client configurations will be stored in the database with the secret both salted and peppered. + +Authelia currently does not implement any of the specifications or protocols which require secrets being accessible in +the clear and currently has no plans to implement any of these. As such it's *__strongly discouraged and heavily +deprecated__* and we instead recommended that users remove this from their configuration entirely and use the +[Generating Client Secrets](#generating-client-secrets) guide. + +Plaintext is either denoted by the `$plaintext$` prefix where everything after the prefix is the secret. In addition if +the secret does not start with the `$` character it's considered as a plaintext secret for the time being but is +deprecated as is the `$plaintext$` prefix. diff --git a/docs/content/en/integration/openid-connect/synapse/index.md b/docs/content/en/integration/openid-connect/synapse/index.md index a4e7cb520..1e4b737c4 100644 --- a/docs/content/en/integration/openid-connect/synapse/index.md +++ b/docs/content/en/integration/openid-connect/synapse/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Assumptions @@ -38,7 +31,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://matrix.example.com/` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `synapse` -* __Client Secret:__ `synapse_client_secret` +* __Client Secret:__ `insecure_secret` ## Configuration @@ -56,7 +49,7 @@ oidc_providers: discover: true issuer: "https://auth.example.com" client_id: "synapse" - client_secret: "synapse_client_secret" + client_secret: "insecure_secret" scopes: ["openid", "profile", "email"] allow_existing_users: true user_mapping_provider: @@ -76,7 +69,7 @@ which will operate with the above example: ```yaml - id: synapse description: Synapse - secret: '$plaintext$synapse_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/openid-connect/synology-dsm/index.md b/docs/content/en/integration/openid-connect/synology-dsm/index.md index cb866ba58..a740af86e 100644 --- a/docs/content/en/integration/openid-connect/synology-dsm/index.md +++ b/docs/content/en/integration/openid-connect/synology-dsm/index.md @@ -22,14 +22,7 @@ community: true ## Before You Begin -### Common Notes - -1. You are *__required__* to utilize a unique client id for every client. -2. The client id on this page is merely an example and you can theoretically use any alphanumeric string. -3. You *__should not__* use the client secret in this example, We *__strongly recommend__* reading the - [Generating Client Secrets] guide instead. - -[Generating Client Secrets]: ../specific-information.md#generating-client-secrets +{{% oidc-common %}} ### Specific Notes @@ -43,7 +36,7 @@ This example makes the following assumptions: * __Application Root URL:__ `https://dsm.example.com/` * __Authelia Root URL:__ `https://auth.example.com` * __Client ID:__ `synology-dsm` -* __Client Secret:__ `synology-dsm_client_secret` +* __Client Secret:__ `insecure_secret` ## Configuration @@ -61,7 +54,7 @@ To configure [Synology DSM] to utilize Authelia as an [OpenID Connect 1.0] Provi * Name: `Authelia` * Well Known URL: `https://auth.example.com/.well-known/openid-configuration` * Application ID: `synology-dsm` - * Application Key: `synology-dsm_client_secret` + * Application Key: `insecure_secret` * Redirect URL: `https://dsm.example.com` * Authorisation Scope: `openid profile groups email` * Username Claim: `preferred_username` @@ -78,7 +71,7 @@ which will operate with the above example: ```yaml - id: synology-dsm description: Synology DSM - secret: '$plaintext$synology-dsm_client_secret' + secret: '$pbkdf2-sha512$310000$c8p78n7pUMln0jzvd4aK4Q$JNRBzwAo0ek5qKn50cFzzvE9RXV88h1wJn5KGiHrD0YKtZaR/nCb2CJPOsKaPK0hjf.9yHxzQGZziziccp6Yng' # The digest of 'insecure_secret'. public: false authorization_policy: two_factor redirect_uris: diff --git a/docs/content/en/integration/proxies/caddy.md b/docs/content/en/integration/proxies/caddy.md index 1f2243883..1a8f00d7a 100644 --- a/docs/content/en/integration/proxies/caddy.md +++ b/docs/content/en/integration/proxies/caddy.md @@ -102,7 +102,7 @@ nextcloud.example.com { ## The following commented line is for configuring the Authelia URL in the proxy. We strongly suggest ## this is configured in the Session Cookies section of the Authelia configuration. # uri /api/authz/forward-auth?authelia_url=https://auth.example.com/ - copy_headers Remote-User Remote-Groups Remote-Name Remote-Email + copy_headers Authorization Proxy-Authorization Remote-User Remote-Groups Remote-Email Remote-Name ## This import needs to be included if you're relying on a trusted proxies configuration. import trusted_proxy_list @@ -141,7 +141,7 @@ example.com { handle @nextcloud { forward_auth authelia:9091 { uri /api/authz/forward-auth?authelia_url=https://example.com/authelia/ - copy_headers Remote-User Remote-Groups Remote-Name Remote-Email + copy_headers Authorization Proxy-Authorization Remote-User Remote-Groups Remote-Email Remote-Name ## This import needs to be included if you're relying on a trusted proxies configuration. import trusted_proxy_list @@ -198,10 +198,12 @@ nextcloud.example.com { ## 2. Copy the relevant headers from the auth request and provide them to the backend. @good status 2xx handle_response @good { + request_header Authorization {http.reverse_proxy.header.Authorization} + request_header Proxy-Authorization {http.reverse_proxy.header.Proxy-Authorization} request_header Remote-User {http.reverse_proxy.header.Remote-User} request_header Remote-Groups {http.reverse_proxy.header.Remote-Groups} - request_header Remote-Name {http.reverse_proxy.header.Remote-Name} request_header Remote-Email {http.reverse_proxy.header.Remote-Email} + request_header Remote-Name {http.reverse_proxy.header.Remote-Name} } } diff --git a/docs/content/en/integration/proxies/envoy.md b/docs/content/en/integration/proxies/envoy.md index 25cece96d..76ce52e12 100644 --- a/docs/content/en/integration/proxies/envoy.md +++ b/docs/content/en/integration/proxies/envoy.md @@ -168,6 +168,13 @@ static_resources: - name: envoy.filters.http.ext_authz typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz + transport_api_version: v3 + allowed_headers: + patterns: + - exact: authorization + - exact: proxy-authorization + - exact: accept + - exact: cookie http_service: path_prefix: /api/authz/ext-authz/ server_uri: @@ -177,9 +184,10 @@ static_resources: authorization_request: allowed_headers: patterns: + - exact: authorization + - exact: proxy-authorization - exact: accept - exact: cookie - - exact: proxy-authorization headers_to_add: - key: X-Forwarded-Proto value: '%REQ(:SCHEME)%' @@ -207,9 +215,9 @@ static_resources: clusters: - name: nextcloud connect_timeout: 0.25s - type: LOGICAL_DNS - dns_lookup_family: V4_ONLY - lb_policy: ROUND_ROBIN + type: logical_dns + dns_lookup_family: v4_only + lb_policy: round_robin load_assignment: cluster_name: nextcloud endpoints: @@ -221,9 +229,9 @@ static_resources: port_value: 80 - name: authelia connect_timeout: 0.25s - type: LOGICAL_DNS - dns_lookup_family: V4_ONLY - lb_policy: ROUND_ROBIN + type: logical_dns + dns_lookup_family: v4_only + lb_policy: round_robin load_assignment: cluster_name: authelia endpoints: @@ -233,6 +241,17 @@ static_resources: socket_address: address: authelia port_value: 9091 +layered_runtime: + layers: + - name: static_layer_0 + static_layer: + envoy: + resource_limits: + listener: + example_listener_name: + connection_limit: 10000 + overload: + global_downstream_max_connections: 50000 ``` {{< /details >}} diff --git a/docs/content/en/integration/proxies/haproxy.md b/docs/content/en/integration/proxies/haproxy.md index e8168068b..353ebb9db 100644 --- a/docs/content/en/integration/proxies/haproxy.md +++ b/docs/content/en/integration/proxies/haproxy.md @@ -218,29 +218,53 @@ backend be_authelia server authelia authelia:9091 backend be_nextcloud - # Pass Remote-User, Remote-Name, Remote-Email and Remote-Groups headers + ## Pass the special authorization response headers to the protected application. + acl authorization_exist var(req.auth_response_header.authorization) -m found + acl proxy_authorization_exist var(req.auth_response_header.proxy_authorization) -m found + + http-request set-header Authorization %[var(req.auth_response_header.authorization)] if authorization_exist + http-request set-header Proxy-Authorization %[var(req.auth_response_header.proxy_authorization)] if proxy_authorization_exist + + ## Pass the special metadata response headers to the protected application. acl remote_user_exist var(req.auth_response_header.remote_user) -m found acl remote_groups_exist var(req.auth_response_header.remote_groups) -m found acl remote_name_exist var(req.auth_response_header.remote_name) -m found acl remote_email_exist var(req.auth_response_header.remote_email) -m found + http-request set-header Remote-User %[var(req.auth_response_header.remote_user)] if remote_user_exist http-request set-header Remote-Groups %[var(req.auth_response_header.remote_groups)] if remote_groups_exist http-request set-header Remote-Name %[var(req.auth_response_header.remote_name)] if remote_name_exist http-request set-header Remote-Email %[var(req.auth_response_header.remote_email)] if remote_email_exist + ## Pass the Set-Cookie response headers to the user. + acl set_cookie_exist var(req.auth_response_header.set_cookie) -m found + http-response set-header Set-Cookie %[var(req.auth_response_header.set_cookie)] if set_cookie_exist + server nextcloud nextcloud:443 ssl verify none backend be_heimdall - # Pass Remote-User, Remote-Name, Remote-Email and Remote-Groups headers + ## Pass the special authorization response headers to the protected application. + acl authorization_exist var(req.auth_response_header.authorization) -m found + acl proxy_authorization_exist var(req.auth_response_header.proxy_authorization) -m found + + http-request set-header Authorization %[var(req.auth_response_header.authorization)] if authorization_exist + http-request set-header Proxy-Authorization %[var(req.auth_response_header.proxy_authorization)] if proxy_authorization_exist + + ## Pass the special metadata response headers to the protected application. acl remote_user_exist var(req.auth_response_header.remote_user) -m found acl remote_groups_exist var(req.auth_response_header.remote_groups) -m found acl remote_name_exist var(req.auth_response_header.remote_name) -m found acl remote_email_exist var(req.auth_response_header.remote_email) -m found + http-request set-header Remote-User %[var(req.auth_response_header.remote_user)] if remote_user_exist http-request set-header Remote-Groups %[var(req.auth_response_header.remote_groups)] if remote_groups_exist http-request set-header Remote-Name %[var(req.auth_response_header.remote_name)] if remote_name_exist http-request set-header Remote-Email %[var(req.auth_response_header.remote_email)] if remote_email_exist + ## Pass the Set-Cookie response headers to the user. + acl set_cookie_exist var(req.auth_response_header.set_cookie) -m found + http-response set-header Set-Cookie %[var(req.auth_response_header.set_cookie)] if set_cookie_exist + server heimdall heimdall:443 ssl verify none ``` @@ -325,29 +349,53 @@ listen authelia_proxy server authelia authelia:9091 ssl verify none backend be_nextcloud - # Pass Remote-User, Remote-Name, Remote-Email and Remote-Groups headers + ## Pass the special authorization response headers to the protected application. + acl authorization_exist var(req.auth_response_header.authorization) -m found + acl proxy_authorization_exist var(req.auth_response_header.proxy_authorization) -m found + + http-request set-header Authorization %[var(req.auth_response_header.authorization)] if authorization_exist + http-request set-header Proxy-Authorization %[var(req.auth_response_header.proxy_authorization)] if proxy_authorization_exist + + ## Pass the special metadata response headers to the protected application. acl remote_user_exist var(req.auth_response_header.remote_user) -m found acl remote_groups_exist var(req.auth_response_header.remote_groups) -m found acl remote_name_exist var(req.auth_response_header.remote_name) -m found acl remote_email_exist var(req.auth_response_header.remote_email) -m found + http-request set-header Remote-User %[var(req.auth_response_header.remote_user)] if remote_user_exist http-request set-header Remote-Groups %[var(req.auth_response_header.remote_groups)] if remote_groups_exist http-request set-header Remote-Name %[var(req.auth_response_header.remote_name)] if remote_name_exist http-request set-header Remote-Email %[var(req.auth_response_header.remote_email)] if remote_email_exist + ## Pass the Set-Cookie response headers to the user. + acl set_cookie_exist var(req.auth_response_header.set_cookie) -m found + http-response set-header Set-Cookie %[var(req.auth_response_header.set_cookie)] if set_cookie_exist + server nextcloud nextcloud:443 ssl verify none backend be_heimdall - # Pass Remote-User, Remote-Name, Remote-Email and Remote-Groups headers + ## Pass the special authorization response headers to the protected application. + acl authorization_exist var(req.auth_response_header.authorization) -m found + acl proxy_authorization_exist var(req.auth_response_header.proxy_authorization) -m found + + http-request set-header Authorization %[var(req.auth_response_header.authorization)] if authorization_exist + http-request set-header Proxy-Authorization %[var(req.auth_response_header.proxy_authorization)] if proxy_authorization_exist + + ## Pass the special metadata response headers to the protected application. acl remote_user_exist var(req.auth_response_header.remote_user) -m found acl remote_groups_exist var(req.auth_response_header.remote_groups) -m found acl remote_name_exist var(req.auth_response_header.remote_name) -m found acl remote_email_exist var(req.auth_response_header.remote_email) -m found + http-request set-header Remote-User %[var(req.auth_response_header.remote_user)] if remote_user_exist http-request set-header Remote-Groups %[var(req.auth_response_header.remote_groups)] if remote_groups_exist http-request set-header Remote-Name %[var(req.auth_response_header.remote_name)] if remote_name_exist http-request set-header Remote-Email %[var(req.auth_response_header.remote_email)] if remote_email_exist + ## Pass the Set-Cookie response headers to the user. + acl set_cookie_exist var(req.auth_response_header.set_cookie) -m found + http-response set-header Set-Cookie %[var(req.auth_response_header.set_cookie)] if set_cookie_exist + server heimdall heimdall:443 ssl verify none ``` diff --git a/docs/content/en/integration/proxies/nginx.md b/docs/content/en/integration/proxies/nginx.md index 7f4907b16..373834264 100644 --- a/docs/content/en/integration/proxies/nginx.md +++ b/docs/content/en/integration/proxies/nginx.md @@ -433,17 +433,29 @@ set_escape_uri $target_url $scheme://$http_host$request_uri; ## Uncomment this line if you're using NGINX without the http_set_misc module. # set $target_url $scheme://$http_host$request_uri; -## Save the upstream response headers from Authelia to variables. +## Save the upstream authorization response headers from Authelia to variables. +auth_request_set $authorization $upstream_http_authorization; +auth_request_set $proxy_authorization $upstream_http_proxy_authorization; + +## Inject the authorization response headers from the variables into the request made to the backend. +proxy_set_header Authorization $authorization; +proxy_set_header Proxy-Authorization $proxy_authorization; + +## Save the upstream metadata response headers from Authelia to variables. auth_request_set $user $upstream_http_remote_user; auth_request_set $groups $upstream_http_remote_groups; auth_request_set $name $upstream_http_remote_name; auth_request_set $email $upstream_http_remote_email; -## Inject the response headers from the variables into the request made to the backend. +## Inject the metadata response headers from the variables into the request made to the backend. proxy_set_header Remote-User $user; proxy_set_header Remote-Groups $groups; -proxy_set_header Remote-Name $name; proxy_set_header Remote-Email $email; +proxy_set_header Remote-Name $name; + +## Include the Set-Cookie header if present. +auth_request_set $cookie $upstream_http_set_cookie; +add_header Set-Cookie $cookie; ## If the subreqest returns 200 pass to the backend, if the subrequest returns 401 redirect to the portal. error_page 401 =302 https://auth.example.com/?rd=$target_url; diff --git a/docs/content/en/integration/proxies/traefik.md b/docs/content/en/integration/proxies/traefik.md index 0a93fe046..0d1ce5303 100644 --- a/docs/content/en/integration/proxies/traefik.md +++ b/docs/content/en/integration/proxies/traefik.md @@ -157,7 +157,7 @@ services: ## configured in the Session Cookies section of the Authelia configuration. # - 'traefik.http.middlewares.authelia.forwardAuth.address=http://authelia:9091/api/authz/forward-auth?authelia_url=https%3A%2F%2Fauth.example.com%2F' - 'traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader=true' - - 'traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Authorization,Proxy-Authorization,Remote-User,Remote-Groups,Remote-Name,Remote-Email' + - 'traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Authorization,Proxy-Authorization,Remote-User,Remote-Groups,Remote-Email,Remote-Name' nextcloud: container_name: nextcloud image: linuxserver/nextcloud @@ -503,7 +503,7 @@ This can be avoided a couple different ways: ## configured in the Session Cookies section of the Authelia configuration. # - 'traefik.http.middlewares.authelia.forwardAuth.address=http://authelia:9091/api/authz/forward-auth?authelia_url=https%3A%2F%2Fauth.example.com%2F' - 'traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader=true' -- 'traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Authorization,Proxy-Authorization,Remote-User,Remote-Groups,Remote-Name,Remote-Email' +- 'traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Authorization,Proxy-Authorization,Remote-User,Remote-Groups,Remote-Email,Remote-Name' ``` ## See Also diff --git a/docs/content/en/integration/proxies/traefikv1.md b/docs/content/en/integration/proxies/traefikv1.md index d63dc7414..7f0e0f598 100644 --- a/docs/content/en/integration/proxies/traefikv1.md +++ b/docs/content/en/integration/proxies/traefikv1.md @@ -137,7 +137,7 @@ services: ## configured in the Session Cookies section of the Authelia configuration. # - 'traefik.frontend.auth.forward.address=http://authelia:9091/api/authz/forward-auth?authelia_url=https%3A%2F%2Fauth.example.com%2F' - 'traefik.frontend.auth.forward.trustForwardHeader=true' - - 'traefik.frontend.auth.forward.authResponseHeaders=Authorization,Proxy-Authorization,Remote-User,Remote-Groups,Remote-Name,Remote-Email' + - 'traefik.frontend.auth.forward.authResponseHeaders=Authorization,Proxy-Authorization,Remote-User,Remote-Groups,Remote-Email,Remote-Name' expose: - 443 restart: unless-stopped @@ -156,7 +156,7 @@ services: - 'traefik.frontend.rule=Host:heimdall.example.com' - 'traefik.frontend.auth.forward.address=http://authelia:9091/api/authz/forward-auth/basic' - 'traefik.frontend.auth.forward.trustForwardHeader=true' - - 'traefik.frontend.auth.forward.authResponseHeaders=Authorization,Proxy-Authorization,Remote-User,Remote-Groups,Remote-Name,Remote-Email' + - 'traefik.frontend.auth.forward.authResponseHeaders=Authorization,Proxy-Authorization,Remote-User,Remote-Groups,Remote-Email,Remote-Name' expose: - 443 restart: unless-stopped diff --git a/docs/content/en/overview/security/measures.md b/docs/content/en/overview/security/measures.md index b050512fc..5cd77d588 100644 --- a/docs/content/en/overview/security/measures.md +++ b/docs/content/en/overview/security/measures.md @@ -216,9 +216,9 @@ to port 587 (_the `submission` port, a common alternative that uses STARTTLS ins [docs-config-smtp-port]: ../../configuration/notifications/smtp.md#port [cleartext]: https://cwe.mitre.org/data/definitions/312.html -[service-submissions]: https://www.rfc-editor.org/rfc/rfc8314#section-7.3 -[port-465]: https://www.rfc-editor.org/rfc/rfc8314#section-3.3 -[smtp-auth]: https://www.rfc-editor.org/rfc/rfc6409#section-4.3 +[service-submissions]: https://datatracker.ietf.org/doc/html/rfc8314#section-7.3 +[port-465]: https://datatracker.ietf.org/doc/html/rfc8314#section-3.3 +[smtp-auth]: https://datatracker.ietf.org/doc/html/rfc6409#section-4.3 ## Protection against open redirects diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_generate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_generate.md index 13fc82481..324c96ed2 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_generate.md @@ -35,28 +35,31 @@ authelia crypto certificate ecdsa generate --help ### Options ``` - --ca create the certificate as a certificate authority certificate - -n, --common-name string certificate common name - --country strings certificate country - -b, --curve string Sets the elliptic curve which can be P224, P256, P384, or P521 (default "P256") - -d, --directory string directory where the generated keys, certificates, etc will be stored - --duration duration duration of time the certificate is valid for (default 8760h0m0s) - --extended-usage strings specify the extended usage types of the certificate - --file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt") - --file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem") - --file.certificate string name of the file to export the certificate data to (default "public.crt") - --file.private-key string name of the file to export the private key data to (default "private.pem") - -h, --help help for generate - -l, --locality strings certificate locality - --not-before string earliest date and time the certificate is considered valid formatted as Jan 2 15:04:05 2006 (default is now) - -o, --organization strings certificate organization (default [Authelia]) - --organizational-unit strings certificate organizational unit - --path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed - -p, --postcode strings certificate postcode - --province strings certificate province - --sans strings subject alternative names - --signature string signature algorithm for the certificate (default "SHA256") - -s, --street-address strings certificate street address + --bundle enables generating the certificate bundle if the --path.ca flag is set + --ca create the certificate as a certificate authority certificate + -n, --common-name string certificate common name + --country strings certificate country + -b, --curve string Sets the elliptic curve which can be P224, P256, P384, or P521 (default "P256") + -d, --directory string directory where the generated keys, certificates, etc will be stored + --duration string duration of time the certificate is valid for (default "1y") + --extended-usage strings specify the extended usage types of the certificate + --file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt") + --file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem") + --file.certificate string name of the file to export the certificate data to (default "public.crt") + --file.certificate-bundle string name of the file to export the certificate bundle data to when the --bundle flag is set (default "public.bundle.crt") + --file.private-key string name of the file to export the private key data to (default "private.pem") + -h, --help help for generate + -l, --locality strings certificate locality + --not-after string latest date and time the certificate is considered valid in various formats + --not-before string earliest date and time the certificate is considered valid in various formats (default is now) + -o, --organization strings certificate organization (default [Authelia]) + --organizational-unit strings certificate organizational unit + --path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed + -p, --postcode strings certificate postcode + --province strings certificate province + --sans strings subject alternative names + --signature string signature algorithm for the certificate (default "SHA256") + -s, --street-address strings certificate street address ``` ### Options inherited from parent commands diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_request.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_request.md index 271da38eb..093cff375 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_request.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ecdsa_request.md @@ -39,12 +39,13 @@ authelia crypto certificate ecdsa request --help --country strings certificate country -b, --curve string Sets the elliptic curve which can be P224, P256, P384, or P521 (default "P256") -d, --directory string directory where the generated keys, certificates, etc will be stored - --duration duration duration of time the certificate is valid for (default 8760h0m0s) + --duration string duration of time the certificate is valid for (default "1y") --file.csr string name of the file to export the certificate request data to (default "request.csr") --file.private-key string name of the file to export the private key data to (default "private.pem") -h, --help help for request -l, --locality strings certificate locality - --not-before string earliest date and time the certificate is considered valid formatted as Jan 2 15:04:05 2006 (default is now) + --not-after string latest date and time the certificate is considered valid in various formats + --not-before string earliest date and time the certificate is considered valid in various formats (default is now) -o, --organization strings certificate organization (default [Authelia]) --organizational-unit strings certificate organizational unit -p, --postcode strings certificate postcode diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_generate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_generate.md index 44e806357..7afaf5a9b 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_generate.md @@ -35,27 +35,30 @@ authelia crypto certificate ed25519 request --help ### Options ``` - --ca create the certificate as a certificate authority certificate - -n, --common-name string certificate common name - --country strings certificate country - -d, --directory string directory where the generated keys, certificates, etc will be stored - --duration duration duration of time the certificate is valid for (default 8760h0m0s) - --extended-usage strings specify the extended usage types of the certificate - --file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt") - --file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem") - --file.certificate string name of the file to export the certificate data to (default "public.crt") - --file.private-key string name of the file to export the private key data to (default "private.pem") - -h, --help help for generate - -l, --locality strings certificate locality - --not-before string earliest date and time the certificate is considered valid formatted as Jan 2 15:04:05 2006 (default is now) - -o, --organization strings certificate organization (default [Authelia]) - --organizational-unit strings certificate organizational unit - --path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed - -p, --postcode strings certificate postcode - --province strings certificate province - --sans strings subject alternative names - --signature string signature algorithm for the certificate (default "SHA256") - -s, --street-address strings certificate street address + --bundle enables generating the certificate bundle if the --path.ca flag is set + --ca create the certificate as a certificate authority certificate + -n, --common-name string certificate common name + --country strings certificate country + -d, --directory string directory where the generated keys, certificates, etc will be stored + --duration string duration of time the certificate is valid for (default "1y") + --extended-usage strings specify the extended usage types of the certificate + --file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt") + --file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem") + --file.certificate string name of the file to export the certificate data to (default "public.crt") + --file.certificate-bundle string name of the file to export the certificate bundle data to when the --bundle flag is set (default "public.bundle.crt") + --file.private-key string name of the file to export the private key data to (default "private.pem") + -h, --help help for generate + -l, --locality strings certificate locality + --not-after string latest date and time the certificate is considered valid in various formats + --not-before string earliest date and time the certificate is considered valid in various formats (default is now) + -o, --organization strings certificate organization (default [Authelia]) + --organizational-unit strings certificate organizational unit + --path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed + -p, --postcode strings certificate postcode + --province strings certificate province + --sans strings subject alternative names + --signature string signature algorithm for the certificate (default "SHA256") + -s, --street-address strings certificate street address ``` ### Options inherited from parent commands diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_request.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_request.md index f0f3a5f8d..66d687d98 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_request.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_ed25519_request.md @@ -38,12 +38,13 @@ authelia crypto certificate ed25519 request --help -n, --common-name string certificate common name --country strings certificate country -d, --directory string directory where the generated keys, certificates, etc will be stored - --duration duration duration of time the certificate is valid for (default 8760h0m0s) + --duration string duration of time the certificate is valid for (default "1y") --file.csr string name of the file to export the certificate request data to (default "request.csr") --file.private-key string name of the file to export the private key data to (default "private.pem") -h, --help help for request -l, --locality strings certificate locality - --not-before string earliest date and time the certificate is considered valid formatted as Jan 2 15:04:05 2006 (default is now) + --not-after string latest date and time the certificate is considered valid in various formats + --not-before string earliest date and time the certificate is considered valid in various formats (default is now) -o, --organization strings certificate organization (default [Authelia]) --organizational-unit strings certificate organizational unit -p, --postcode strings certificate postcode diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_generate.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_generate.md index e00aaf877..9b89fba34 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_generate.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_generate.md @@ -35,28 +35,31 @@ authelia crypto certificate rsa generate --help ### Options ``` - -b, --bits int number of RSA bits for the certificate (default 2048) - --ca create the certificate as a certificate authority certificate - -n, --common-name string certificate common name - --country strings certificate country - -d, --directory string directory where the generated keys, certificates, etc will be stored - --duration duration duration of time the certificate is valid for (default 8760h0m0s) - --extended-usage strings specify the extended usage types of the certificate - --file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt") - --file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem") - --file.certificate string name of the file to export the certificate data to (default "public.crt") - --file.private-key string name of the file to export the private key data to (default "private.pem") - -h, --help help for generate - -l, --locality strings certificate locality - --not-before string earliest date and time the certificate is considered valid formatted as Jan 2 15:04:05 2006 (default is now) - -o, --organization strings certificate organization (default [Authelia]) - --organizational-unit strings certificate organizational unit - --path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed - -p, --postcode strings certificate postcode - --province strings certificate province - --sans strings subject alternative names - --signature string signature algorithm for the certificate (default "SHA256") - -s, --street-address strings certificate street address + -b, --bits int number of RSA bits for the certificate (default 2048) + --bundle enables generating the certificate bundle if the --path.ca flag is set + --ca create the certificate as a certificate authority certificate + -n, --common-name string certificate common name + --country strings certificate country + -d, --directory string directory where the generated keys, certificates, etc will be stored + --duration string duration of time the certificate is valid for (default "1y") + --extended-usage strings specify the extended usage types of the certificate + --file.ca-certificate string certificate authority certificate to use when signing this certificate (default "ca.public.crt") + --file.ca-private-key string certificate authority private key to use to signing this certificate (default "ca.private.pem") + --file.certificate string name of the file to export the certificate data to (default "public.crt") + --file.certificate-bundle string name of the file to export the certificate bundle data to when the --bundle flag is set (default "public.bundle.crt") + --file.private-key string name of the file to export the private key data to (default "private.pem") + -h, --help help for generate + -l, --locality strings certificate locality + --not-after string latest date and time the certificate is considered valid in various formats + --not-before string earliest date and time the certificate is considered valid in various formats (default is now) + -o, --organization strings certificate organization (default [Authelia]) + --organizational-unit strings certificate organizational unit + --path.ca string source directory of the certificate authority files, if not provided the certificate will be self-signed + -p, --postcode strings certificate postcode + --province strings certificate province + --sans strings subject alternative names + --signature string signature algorithm for the certificate (default "SHA256") + -s, --street-address strings certificate street address ``` ### Options inherited from parent commands diff --git a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_request.md b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_request.md index 544cbf553..8280c4ee3 100644 --- a/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_request.md +++ b/docs/content/en/reference/cli/authelia/authelia_crypto_certificate_rsa_request.md @@ -39,12 +39,13 @@ authelia crypto certificate rsa request --help -n, --common-name string certificate common name --country strings certificate country -d, --directory string directory where the generated keys, certificates, etc will be stored - --duration duration duration of time the certificate is valid for (default 8760h0m0s) + --duration string duration of time the certificate is valid for (default "1y") --file.csr string name of the file to export the certificate request data to (default "request.csr") --file.private-key string name of the file to export the private key data to (default "private.pem") -h, --help help for request -l, --locality strings certificate locality - --not-before string earliest date and time the certificate is considered valid formatted as Jan 2 15:04:05 2006 (default is now) + --not-after string latest date and time the certificate is considered valid in various formats + --not-before string earliest date and time the certificate is considered valid in various formats (default is now) -o, --organization strings certificate organization (default [Authelia]) --organizational-unit strings certificate organizational unit -p, --postcode strings certificate postcode diff --git a/docs/content/en/reference/guides/ldap.md b/docs/content/en/reference/guides/ldap.md index 557e428c4..9f5626c27 100644 --- a/docs/content/en/reference/guides/ldap.md +++ b/docs/content/en/reference/guides/ldap.md @@ -56,6 +56,9 @@ The following implementations exist: - Specific configuration defaults for [Active Directory] - Special implementation details: - Includes a special encoding format required for changing passwords with [Active Directory] +- `rfc2307bis`: + - Specific configuration defaults for [RFC2307bis] + - No special implementation details - `freeipa`: - Specific configuration defaults for [FreeIPA] - No special implementation details @@ -70,11 +73,17 @@ The following implementations exist: [FreeIPA]: https://www.freeipa.org/ [lldap]: https://github.com/nitnelave/lldap [GLAuth]: https://glauth.github.io/ +[RFC2307bis]: https://datatracker.ietf.org/doc/html/draft-howard-rfc2307bis-02 ### Filter replacements Various replacements occur in the user and groups filter. The replacements either occur at startup or upon an LDAP -search. +search which is indicated by the phase column. + +The phases exist to optimize performance. The replacements in the startup phase are replaced once before the connection +is ever established. In addition to this, during the startup phase we purposefully check the filters for which search +phase replacements exist so we only have to check if the replacement is necessary once, and we don't needlessly perform +every possible replacement on every search regardless of if it's needed or not. #### Users filter replacements @@ -117,6 +126,7 @@ Username column. |:---------------:|:--------------:|:------------:|:----:|:----------:| | custom | N/A | displayName | mail | cn | | activedirectory | sAMAccountName | displayName | mail | cn | +| rfc2307bis | uid | displayName | mail | cn | | freeipa | uid | displayName | mail | cn | | lldap | uid | cn | mail | cn | | glauth | cn | description | mail | cn | @@ -130,20 +140,32 @@ the following conditions: - The [Active Directory] implementation achieves this via the `(!(userAccountControl:1.2.840.113556.1.4.803:=2))` filter. - The [FreeIPA] implementation achieves this via the `(!(nsAccountLock=TRUE))` filter. - The [GLAuth] implementation achieves this via the `(!(accountStatus=inactive))` filter. + - The following implementations have no suitable attribute for this as far as we're aware: + - [RFC2307bis] + - [lldap] - Their password is expired: - The [Active Directory] implementation achieves this via the `(!(pwdLastSet=0))` filter. - The [FreeIPA] implementation achieves this via the `(krbPasswordExpiration>={date-time:generalized})` filter. + - The following implementations have no suitable attribute for this as far as we're aware: + - [RFC2307bis] + - [GLAuth] + - [lldap] - Their account is expired: - The [Active Directory] implementation achieves this via the `(|(!(accountExpires=*))(accountExpires=0)(accountExpires>={date-time:microsoft-nt}))` filter. - The [FreeIPA] implementation achieves this via the `(|(!(krbPrincipalExpiration=*))(krbPrincipalExpiration>={date-time:generalized}))` filter. + - The following implementations have no suitable attribute for this as far as we're aware: + - [RFC2307bis] + - [GLAuth] + - [lldap] -| Implementation | Users Filter | Groups Filter | -|:---------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------:| -| custom | N/A | N/A | -| activedirectory | (&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))(|(!(accountExpires=*))(accountExpires=0)(accountExpires>={date-time:microsoft-nt}))) | (&(member={dn})(|(sAMAccountType=268435456)(sAMAccountType=536870912))) | -| freeipa | (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)(!(nsAccountLock=TRUE))(krbPasswordExpiration>={date-time:generalized})(|(!(krbPrincipalExpiration=*))(krbPrincipalExpiration>={date-time:generalized}))) | (&(member={dn})(objectClass=groupOfNames)) | -| lldap | (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)) | (&(member={dn})(objectClass=groupOfNames)) | -| glauth | (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=posixAccount)(!(accountStatus=inactive))) | (&(uniqueMember={dn})(objectClass=posixGroup)) | +| Implementation | Users Filter | Groups Filter | +|:---------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------:| +| custom | N/A | N/A | +| activedirectory | (&(|({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))(|(!(accountExpires=*))(accountExpires=0)(accountExpires>={date-time:microsoft-nt}))) | (&(member={dn})(|(sAMAccountType=268435456)(sAMAccountType=536870912))) | +| rfc2307bis | (&(|({username_attribute}={input})({mail_attribute}={input}))(|(objectClass=inetOrgPerson)(objectClass=organizationalPerson))) | (&(|(member={dn})(uniqueMember={dn}))(|(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=groupOfMembers))) | +| freeipa | (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)(!(nsAccountLock=TRUE))(krbPasswordExpiration>={date-time:generalized})(|(!(krbPrincipalExpiration=*))(krbPrincipalExpiration>={date-time:generalized}))) | (&(member={dn})(objectClass=groupOfNames)) | +| lldap | (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)) | (&(member={dn})(objectClass=groupOfNames)) | +| glauth | (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=posixAccount)(!(accountStatus=inactive))) | (&(uniqueMember={dn})(objectClass=posixGroup)) | ##### Microsoft Active Directory sAMAccountType diff --git a/docs/content/en/reference/guides/passwords.md b/docs/content/en/reference/guides/passwords.md index 1163fa792..a21fc3bf0 100644 --- a/docs/content/en/reference/guides/passwords.md +++ b/docs/content/en/reference/guides/passwords.md @@ -193,14 +193,14 @@ This table suggests the parameters for the [SHA2 Crypt] algorithm: | Standard CPU | sha512 | 50000 | 16 | | High End CPU | sha512 | 150000 | 16 | -[Argon2]: https://www.rfc-editor.org/rfc/rfc9106.html +[Argon2]: https://datatracker.ietf.org/doc/html/rfc9106 [Scrypt]: https://en.wikipedia.org/wiki/Scrypt -[PBKDF2]: https://www.ietf.org/rfc/rfc2898.html +[PBKDF2]: https://datatracker.ietf.org/doc/html/rfc2898 [SHA2 Crypt]: https://www.akkadia.org/drepper/SHA-crypt.txt [Bcrypt]: https://en.wikipedia.org/wiki/Bcrypt [FIPS-140 compliance]: https://csrc.nist.gov/publications/detail/fips/140/2/final -[RFC9106 Parameter Choice]: https://www.rfc-editor.org/rfc/rfc9106.html#section-4 +[RFC9106 Parameter Choice]: https://datatracker.ietf.org/doc/html/rfc9106#section-4 [YAML]: https://yaml.org/ [crypt hash generate]: ../cli/authelia/authelia_crypto_hash_generate.md [Password Hashing Competition]: https://en.wikipedia.org/wiki/Password_Hashing_Competition diff --git a/docs/content/en/reference/guides/server-asset-overrides.md b/docs/content/en/reference/guides/server-asset-overrides.md index a593af76c..3da947350 100644 --- a/docs/content/en/reference/guides/server-asset-overrides.md +++ b/docs/content/en/reference/guides/server-asset-overrides.md @@ -46,7 +46,7 @@ utilize these overrides should either check for changes to the files in the The locales directory holds folders of internationalization locales. This directory can be utilized to override these locales. They are the names of locales that are returned by the `navigator.langauge` ECMAScript command. These are -generally those in the [RFC5646 / BCP47 Format](https://www.rfc-editor.org/rfc/rfc5646.html) specifically the language +generally those in the [RFC5646 / BCP47 Format](https://datatracker.ietf.org/doc/html/rfc5646) specifically the language codes from [Crowdin](https://support.crowdin.com/api/language-codes/). Each directory has JSON files which you can explore the format of in the diff --git a/docs/content/en/reference/guides/templating.md b/docs/content/en/reference/guides/templating.md index b34cc090f..e0d3b7d44 100644 --- a/docs/content/en/reference/guides/templating.md +++ b/docs/content/en/reference/guides/templating.md @@ -78,6 +78,9 @@ The following functions which mimic the behaviour of helm exist in most templati - kindIs - default - empty +- indent +- nindent +- uuidv4 See the [Helm Documentation](https://helm.sh/docs/chart_template_guide/function_list/) for more information. Please note that only the functions listed above are supported and the functions don't necessarily behave exactly the same. @@ -92,3 +95,7 @@ The following is a list of special functions and their syntax. #### iterate Input is a single uint. Returns a slice of uints from 0 to the provided uint. + +#### fileContent + +Input is a path. Returns the content of a file. diff --git a/docs/content/en/roadmap/active/openid-connect.md b/docs/content/en/roadmap/active/openid-connect.md index 72a4785dc..e49c56565 100644 --- a/docs/content/en/roadmap/active/openid-connect.md +++ b/docs/content/en/roadmap/active/openid-connect.md @@ -39,11 +39,11 @@ Feature List: * [User Consent](https://openid.net/specs/openid-connect-core-1_0.html#Consent) * [Authorization Code Flow](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowSteps) * [OpenID Connect Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) -* [RS256 Signature Strategy](https://www.rfc-editor.org/rfc/rfc7518.html#section-3.1) +* [RS256 Signature Strategy](https://datatracker.ietf.org/doc/html/rfc7518#section-3.1) * Per Client Scope/Grant Type/Response Type Restriction * Per Client Authorization Policy (1FA/2FA) * Per Client List of Valid Redirection URI's -* [Confidential Client Type](https://www.rfc-editor.org/rfc/rfc6749.html#section-2.1) +* [Confidential Client Type](https://datatracker.ietf.org/doc/html/rfc6749#section-2.1) ### Beta 2 @@ -56,7 +56,7 @@ Feature List: * Token/Code Lifespan * Client Debug Messages * Client Audience -* [Public Client Type](https://www.rfc-editor.org/rfc/rfc6749.html#section-2.1) +* [Public Client Type](https://datatracker.ietf.org/doc/html/rfc6749#section-2.1) ### Beta 3 @@ -97,7 +97,7 @@ Feature List: Feature List: -* [JWK's backed by X509 Certificate Chains](https://www.rfc-editor.org/rfc/rfc7517#section-4.7) +* [JWK's backed by X509 Certificate Chains](https://datatracker.ietf.org/doc/html/rfc7517#section-4.7) * Hashed Client Secrets * Per-Client [Consent](https://openid.net/specs/openid-connect-core-1_0.html#Consent) Mode: * Explicit: @@ -115,7 +115,7 @@ Feature List: {{< roadmap-status stage="in-progress" version="v4.38.0" >}} -* [OAuth 2.0 Pushed Authorization Requests](https://www.rfc-editor.org/rfc/rfc9126.html) +* [OAuth 2.0 Pushed Authorization Requests](https://datatracker.ietf.org/doc/html/rfc9126) * Per-Client [Proof Key Code Exchange (PKCE)] Policy ### Beta 7 @@ -177,7 +177,7 @@ Should be implemented alongside [Dynamic Client Registration](#openid-connect-dy {{< roadmap-status stage="complete" version="v4.34.0" >}} -See the [IETF Specification RFC8414](https://www.rfc-editor.org/rfc/rfc8414.html) for more information. +See the [IETF Specification RFC8414](https://datatracker.ietf.org/doc/html/rfc8414) for more information. #### OpenID Connect Session Management @@ -205,9 +205,9 @@ The `preferred_username` claim was missing and was fixed. [Cross Origin Resource Sharing]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS -[RFC8176]: https://www.rfc-editor.org/rfc/rfc8176.html -[RFC8693 Section 4.3]: https://www.rfc-editor.org/rfc/rfc8693.html/#section-4.3 -[RFC4122]: https://www.rfc-editor.org/rfc/rfc4122.html +[RFC8176]: https://datatracker.ietf.org/doc/html/rfc8176 +[RFC8693 Section 4.3]: https://datatracker.ietf.org/doc/html/rfc8693/#section-4.3 +[RFC4122]: https://datatracker.ietf.org/doc/html/rfc4122 [OpenID Connect]: https://openid.net/connect/ [OpenID Connect Front-Channel Logout]: https://openid.net/specs/openid-connect-frontchannel-1_0.html @@ -219,4 +219,4 @@ The `preferred_username` claim was missing and was fixed. [OpenID Connect Core (Subject Identifier Types)]: https://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes [OpenID Connect Core (Pairwise Identifier Algorithm)]: https://openid.net/specs/openid-connect-core-1_0.html#PairwiseAlg [OpenID Connect Core (Mandatory to Implement Features for All OpenID Providers)]: https://openid.net/specs/openid-connect-core-1_0.html#ServerMTI -[Proof Key Code Exchange (PKCE)]: https://www.rfc-editor.org/rfc/rfc7636.html +[Proof Key Code Exchange (PKCE)]: https://datatracker.ietf.org/doc/html/rfc7636 diff --git a/docs/layouts/shortcodes/oidc-common.html b/docs/layouts/shortcodes/oidc-common.html new file mode 100644 index 000000000..0d6c73715 --- /dev/null +++ b/docs/layouts/shortcodes/oidc-common.html @@ -0,0 +1,18 @@ +{{ $specificinfo := "../specific-information/" }}{{ $config := "../../../configuration/identity-providers/open-id-connect.md" }} +{{- with .Get "specificinfo" }}{{ $specificinfo = . }}{{ end }} +{{- with .Get "config" }}{{ $config = . }}{{ end }} +### Common Notes + +1. The [OpenID Connect 1.0](https://openid.net/specs/openid-connect-core-1_0.html) `client_id` parameter: + 1. This *__must__* be a unique value for every client. + 2. The value used in this guide is merely for demonstration purposes and you can theoretically use nearly any + alphanumeric string. +2. The [OpenID Connect 1.0](https://openid.net/specs/openid-connect-core-1_0.html) `secret` parameter: + 1. The value used in this guide is merely for demonstration purposes and you *__should absolutely not__* use this in + production and should instead utilize the + [Generating Client Secrets]({{ $specificinfo }}#generating-client-secrets) guide. + 2. This string may be stored as plaintext in the Authelia configuration but this behaviour is deprecated and is not + guaranteed to be supported in the future. See the [Plaintext]({{ $specificinfo }}#plaintext) guide for more + information. +3. The Configuration example for Authelia is only a portion of the required configuration and it should be used as a + guide in conjunction with the standard [OpenID Connect 1.0 Configuration]({{ $config }}) guide. \ No newline at end of file diff --git a/docs/netlify.toml b/docs/netlify.toml index a31a1275e..93215949a 100644 --- a/docs/netlify.toml +++ b/docs/netlify.toml @@ -5,7 +5,7 @@ [build.environment] NODE_VERSION = "16.18.1" NPM_VERSION = "8.19.2" - GO_VERSION = "1.19.4" + GO_VERSION = "1.19.5" [context.production] command = "pnpm run build" diff --git a/go.mod b/go.mod index 95135bf30..f4c064bcc 100644 --- a/go.mod +++ b/go.mod @@ -1,19 +1,19 @@ module github.com/authelia/authelia/v4 -go 1.19 +go 1.20 require ( github.com/Gurpartap/logrus-stack v0.0.0-20170710170904-89c00d8a28f4 github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d github.com/deckarep/golang-set/v2 v2.1.0 - github.com/duosecurity/duo_api_golang v0.0.0-20221117185402-091daa09e19d + github.com/duosecurity/duo_api_golang v0.0.0-20230203160531-b221c950c2b0 github.com/fasthttp/router v1.4.16 github.com/fasthttp/session/v2 v2.4.16 github.com/fsnotify/fsnotify v1.6.0 github.com/go-asn1-ber/asn1-ber v1.5.4 - github.com/go-crypt/crypt v0.2.3 + github.com/go-crypt/crypt v0.2.5 github.com/go-ldap/ldap/v3 v3.4.4 - github.com/go-rod/rod v0.112.4 + github.com/go-rod/rod v0.112.5 github.com/go-sql-driver/mysql v1.7.0 github.com/go-webauthn/webauthn v0.7.0 github.com/golang-jwt/jwt/v4 v4.4.3 @@ -28,7 +28,7 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 github.com/ory/fosite v0.44.0 github.com/ory/herodot v0.9.13 - github.com/ory/x v0.0.534 + github.com/ory/x v0.0.535 github.com/otiai10/copy v1.9.0 github.com/pkg/errors v0.9.1 github.com/pquerna/otp v1.4.0 @@ -40,9 +40,10 @@ require ( github.com/trustelem/zxcvbn v1.0.1 github.com/valyala/fasthttp v1.44.0 github.com/wneessen/go-mail v0.3.8 + golang.org/x/net v0.6.0 golang.org/x/sync v0.1.0 - golang.org/x/term v0.4.0 - golang.org/x/text v0.6.0 + golang.org/x/term v0.5.0 + golang.org/x/text v0.7.0 gopkg.in/square/go-jose.v2 v2.6.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -64,7 +65,7 @@ require ( github.com/ecordell/optgen v0.0.6 // indirect github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect - github.com/go-crypt/x v0.1.10 // indirect + github.com/go-crypt/x v0.1.12 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect github.com/go-webauthn/revoke v0.1.6 // indirect github.com/golang/glog v1.0.0 // indirect @@ -109,9 +110,8 @@ require ( github.com/ysmood/leakless v0.8.0 // indirect golang.org/x/crypto v0.5.0 // indirect golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.5.0 // indirect golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect - golang.org/x/sys v0.4.0 // indirect + golang.org/x/sys v0.5.0 // indirect golang.org/x/tools v0.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71 // indirect diff --git a/go.sum b/go.sum index 69e08c3b8..e42c33b62 100644 --- a/go.sum +++ b/go.sum @@ -127,8 +127,8 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cu github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/duosecurity/duo_api_golang v0.0.0-20221117185402-091daa09e19d h1:DdF2JKufY7l8IBJuGeanPFR5gVpWJfEh1LWJFM/zDas= -github.com/duosecurity/duo_api_golang v0.0.0-20221117185402-091daa09e19d/go.mod h1:jI+QUTOK3wqIOrUl0Cwnwlgc/P6vs6pZOuQY3aKggwg= +github.com/duosecurity/duo_api_golang v0.0.0-20230203160531-b221c950c2b0 h1:+0VqbFomxHYZLIsuLJ7FjAdjhJTQ4P3/o6paTMx5kAY= +github.com/duosecurity/duo_api_golang v0.0.0-20230203160531-b221c950c2b0/go.mod h1:jI+QUTOK3wqIOrUl0Cwnwlgc/P6vs6pZOuQY3aKggwg= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/ecordell/optgen v0.0.6 h1:aSknPe6ZUBrjwHGp2+6XfmfCGYGD6W0ZDfCmmsrS7s4= @@ -162,10 +162,10 @@ github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrt github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A= github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-crypt/crypt v0.2.3 h1:g9OPe39VmqonsTXP/zo4byEoxrxAAUG+DzBvjzGWvuw= -github.com/go-crypt/crypt v0.2.3/go.mod h1:mbhOIjybuVuh0Vxveb//7UbGV8OCugJC7UPzqs1awYw= -github.com/go-crypt/x v0.1.10 h1:HN8oQGrWcg5xPtIIGwPDWs9MvdYEUJrP7JeNkC46dvM= -github.com/go-crypt/x v0.1.10/go.mod h1:OI04rm/Ojti3mrUFZAJnx66nFbnZ0CVPF7qG49mBZgI= +github.com/go-crypt/crypt v0.2.5 h1:QYGV/OkamPz69fME+JbD0wVmPnAL3C1Ooypqb1FHnHk= +github.com/go-crypt/crypt v0.2.5/go.mod h1:VtajXhpCQlYwf4ekvp1I/6bSFi1YKobq0QInA1AFCQQ= +github.com/go-crypt/x v0.1.12 h1:UQvK75MBYGdeY7PdP/YbkUqiGxNzJq3BlO/lTVT6yuU= +github.com/go-crypt/x v0.1.12/go.mod h1:037K8Cyl2IJUzO297LjhDIeYZYxg7K8yzbCco6ZNtV0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -182,8 +182,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-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-rod/rod v0.112.4 h1:Ck002nM6rCORdVFtD778WxiadS5oJsmqytjXTG5bqiQ= -github.com/go-rod/rod v0.112.4/go.mod h1:ElViL9ABbcshNQw93+11FrYRH92RRhMKleuILo6+5V0= +github.com/go-rod/rod v0.112.5 h1:2mH97UK8We4D2MfX388WqPjG1lDbxx8lLi5MzfvnEo0= +github.com/go-rod/rod v0.112.5/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.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= @@ -459,8 +459,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/go.mod h1:IWDs9kSvFQqw/cQ8zi5ksyYvITiUU4dI7glUrhZcJYo= github.com/ory/viper v1.7.5/go.mod h1:ypOuyJmEUb3oENywQZRgeAMwqgOyDqwboO1tj3DjTaM= -github.com/ory/x v0.0.534 h1:hc49pmcOuHdJ6rbHVGtJJ4/LU88dzDCtEQKfgeo/ecU= -github.com/ory/x v0.0.534/go.mod h1:CQopDsCC9t0tQsddE9UlyRFVEFd2xjKBVcw4nLMMMS0= +github.com/ory/x v0.0.535 h1:muhBRYkAz52J00yEGw6LtwJDF5HhyxM2w0E0V4w5z+o= +github.com/ory/x v0.0.535/go.mod h1:CQopDsCC9t0tQsddE9UlyRFVEFd2xjKBVcw4nLMMMS0= 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/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -749,8 +749,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -854,13 +854,13 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -872,8 +872,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/internal/commands/const.go b/internal/commands/const.go index bd60b22d4..ea56d2f5b 100644 --- a/internal/commands/const.go +++ b/internal/commands/const.go @@ -533,21 +533,19 @@ const ( storageMigrateDirectionDown = "down" ) -const ( - timeLayoutCertificateNotBefore = "Jan 2 15:04:05 2006" -) - const ( cmdFlagNameDirectory = "directory" cmdFlagNamePathCA = "path.ca" + cmdFlagNameBundle = "bundle" - cmdFlagNameFilePrivateKey = "file.private-key" - cmdFlagNameFilePublicKey = "file.public-key" - cmdFlagNameFileCertificate = "file.certificate" - cmdFlagNameFileCAPrivateKey = "file.ca-private-key" - cmdFlagNameFileCACertificate = "file.ca-certificate" - cmdFlagNameFileCSR = "file.csr" + cmdFlagNameFilePrivateKey = "file.private-key" + cmdFlagNameFilePublicKey = "file.public-key" + cmdFlagNameFileCertificate = "file.certificate" + cmdFlagNameFileCertificateBundle = "file.certificate-bundle" + cmdFlagNameFileCAPrivateKey = "file.ca-private-key" + cmdFlagNameFileCACertificate = "file.ca-certificate" + cmdFlagNameFileCSR = "file.csr" cmdFlagNameExtendedUsage = "extended-usage" cmdFlagNameSignature = "signature" @@ -564,6 +562,7 @@ const ( cmdFlagNamePostcode = "postcode" cmdFlagNameNotBefore = "not-before" + cmdFlagNameNotAfter = "not-after" cmdFlagNameDuration = "duration" cmdFlagNamePKCS8 = "pkcs8" @@ -749,4 +748,27 @@ Secrets: way: 'key', 'secret', 'password', 'token'. The available options and the specific secret mapping can be found here: https://www.authelia.com/configuration/methods/secrets/` + + helpTopicTimeLayouts = `Several commands take date time inputs which are parsed. These inputs are parsed with +specific layouts in mind and these layouts are handled in order. + +Format: + + The layouts use a format where specific sequence of characters are representative of a portion of each timestamp. + + See the go documentation for more information on how these layouts work, however the layouts are fairly self + explanatory and you can just use standard unix timestamps if desired. + +Layouts: + + Unix (µs): 1675899060000000 + Unix (ms): 1675899060000 + Unix (s): 1675899060 + Simple: Jan 2 15:04:05 2006 + Date Time: 2006-01-02 15:04:05 + RFC3339: 2006-01-02T15:04:05Z07:00 + RFC1123 with numeric timezone: Mon, 02 Jan 2006 15:04:05 -0700 + Ruby Date: Mon Jan 02 15:04:05 -0700 2006 + ANSIC: Mon Jan _2 15:04:05 2006 + Date: 2006-01-02` ) diff --git a/internal/commands/crypto.go b/internal/commands/crypto.go index 74c8d4099..fffec510c 100644 --- a/internal/commands/crypto.go +++ b/internal/commands/crypto.go @@ -313,7 +313,7 @@ func (ctx *CmdCtx) CryptoCertificateRequestRunE(cmd *cobra.Command, _ []string) b.WriteString(fmt.Sprintf("\n\tSubject Alternative Names: %s\n\n", strings.Join(cryptoSANsToString(template.DNSNames, template.IPAddresses), ", "))) - if privateKeyPath, csrPath, err = cryptoGetWritePathsFromCmd(cmd); err != nil { + if _, privateKeyPath, csrPath, err = cryptoGetWritePathsFromCmd(cmd); err != nil { return err } @@ -329,15 +329,11 @@ func (ctx *CmdCtx) CryptoCertificateRequestRunE(cmd *cobra.Command, _ []string) return fmt.Errorf("failed to create certificate request: %w", err) } - if privateKeyPath, csrPath, err = cryptoGetWritePathsFromCmd(cmd); err != nil { - return err - } - if err = utils.WriteKeyToPEM(privateKey, privateKeyPath, false); err != nil { return err } - if err = utils.WriteCertificateBytesToPEM(csr, csrPath, true); err != nil { + if err = utils.WriteCertificateBytesToPEM(csrPath, true, csr); err != nil { return err } @@ -406,21 +402,23 @@ func (ctx *CmdCtx) CryptoCertificateGenerateRunE(cmd *cobra.Command, _ []string, b.WriteString(fmt.Sprintf("\n\tSubject Alternative Names: %s\n\n", strings.Join(cryptoSANsToString(template.DNSNames, template.IPAddresses), ", "))) var ( - privateKeyPath, certificatePath string - certificate []byte + dir, privateKeyPath, certificatePath, certificateBundlePath string + + bundle bool + certificate []byte ) - if privateKeyPath, certificatePath, err = cryptoGetWritePathsFromCmd(cmd); err != nil { + if dir, privateKeyPath, certificatePath, err = cryptoGetWritePathsFromCmd(cmd); err != nil { + return err + } + + if bundle, certificateBundlePath, err = cryptoGetCertificateBundleFromCmd(cmd, dir, caCertificate); err != nil { return err } b.WriteString("Output Paths:\n") b.WriteString(fmt.Sprintf("\tPrivate Key: %s\n", privateKeyPath)) - b.WriteString(fmt.Sprintf("\tCertificate: %s\n\n", certificatePath)) - - fmt.Print(b.String()) - - b.Reset() + b.WriteString(fmt.Sprintf("\tCertificate: %s\n", certificatePath)) if certificate, err = x509.CreateCertificate(ctx.providers.Random, template, parent, publicKey, signatureKey); err != nil { return fmt.Errorf("failed to create certificate: %w", err) @@ -430,10 +428,24 @@ func (ctx *CmdCtx) CryptoCertificateGenerateRunE(cmd *cobra.Command, _ []string, return err } - if err = utils.WriteCertificateBytesToPEM(certificate, certificatePath, false); err != nil { + if err = utils.WriteCertificateBytesToPEM(certificatePath, false, certificate); err != nil { return err } + if bundle { + b.WriteString(fmt.Sprintf("\tCertificate (bundle): %s\n", certificateBundlePath)) + + if err = utils.WriteCertificateBytesToPEM(certificateBundlePath, false, certificate, caCertificate.Raw); err != nil { + return err + } + } + + b.WriteString("\n") + + fmt.Print(b.String()) + + b.Reset() + return nil } @@ -448,7 +460,7 @@ func (ctx *CmdCtx) CryptoPairGenerateRunE(cmd *cobra.Command, _ []string, privat return err } - if privateKeyPath, publicKeyPath, err = cryptoGetWritePathsFromCmd(cmd); err != nil { + if _, privateKeyPath, publicKeyPath, err = cryptoGetWritePathsFromCmd(cmd); err != nil { return err } diff --git a/internal/commands/crypto_helper.go b/internal/commands/crypto_helper.go index 17ee4060f..774c19548 100644 --- a/internal/commands/crypto_helper.go +++ b/internal/commands/crypto_helper.go @@ -32,8 +32,9 @@ func cmdFlagsCryptoCertificateCommon(cmd *cobra.Command) { cmd.Flags().StringSliceP(cmdFlagNameStreetAddress, "s", nil, "certificate street address") cmd.Flags().StringSliceP(cmdFlagNamePostcode, "p", nil, "certificate postcode") - cmd.Flags().String(cmdFlagNameNotBefore, "", fmt.Sprintf("earliest date and time the certificate is considered valid formatted as %s (default is now)", timeLayoutCertificateNotBefore)) - cmd.Flags().Duration(cmdFlagNameDuration, 365*24*time.Hour, "duration of time the certificate is valid for") + cmd.Flags().String(cmdFlagNameNotBefore, "", "earliest date and time the certificate is considered valid in various formats (default is now)") + cmd.Flags().String(cmdFlagNameNotAfter, "", "latest date and time the certificate is considered valid in various formats") + cmd.Flags().String(cmdFlagNameDuration, "1y", "duration of time the certificate is valid for") cmd.Flags().StringSlice(cmdFlagNameSANs, nil, "subject alternative names") } @@ -42,6 +43,8 @@ func cmdFlagsCryptoCertificateGenerate(cmd *cobra.Command) { cmd.Flags().String(cmdFlagNameFileCAPrivateKey, "ca.private.pem", "certificate authority private key to use to signing this certificate") cmd.Flags().String(cmdFlagNameFileCACertificate, "ca.public.crt", "certificate authority certificate to use when signing this certificate") cmd.Flags().String(cmdFlagNameFileCertificate, "public.crt", "name of the file to export the certificate data to") + cmd.Flags().String(cmdFlagNameFileCertificateBundle, "public.bundle.crt", fmt.Sprintf("name of the file to export the certificate bundle data to when the --%s flag is set", cmdFlagNameBundle)) + cmd.Flags().Bool(cmdFlagNameBundle, false, fmt.Sprintf("enables generating the certificate bundle if the --%s flag is set", cmdFlagNamePathCA)) cmd.Flags().StringSlice(cmdFlagNameExtendedUsage, nil, "specify the extended usage types of the certificate") @@ -91,17 +94,15 @@ func cryptoSANsToString(dnsSANs []string, ipSANs []net.IP) (sans []string) { return sans } -func cryptoGetWritePathsFromCmd(cmd *cobra.Command) (privateKey, publicKey string, err error) { - var dir string - +func cryptoGetWritePathsFromCmd(cmd *cobra.Command) (dir, privateKey, publicKey string, err error) { if dir, err = cmd.Flags().GetString(cmdFlagNameDirectory); err != nil { - return "", "", err + return "", "", "", err } ca, _ := cmd.Flags().GetBool(cmdFlagNameCA) csr := cmd.Use == cmdUseRequest - var private, public string + var pathPrivate, pathPublic string var flagPrivate, flagPublic string @@ -118,15 +119,15 @@ func cryptoGetWritePathsFromCmd(cmd *cobra.Command) (privateKey, publicKey strin flagPrivate, flagPublic = cmdFlagNameFilePrivateKey, cmdFlagNameFileCertificate } - if private, err = cmd.Flags().GetString(flagPrivate); err != nil { - return "", "", err + if pathPrivate, err = cmd.Flags().GetString(flagPrivate); err != nil { + return "", "", "", err } - if public, err = cmd.Flags().GetString(flagPublic); err != nil { - return "", "", err + if pathPublic, err = cmd.Flags().GetString(flagPublic); err != nil { + return "", "", "", err } - return filepath.Join(dir, private), filepath.Join(dir, public), nil + return dir, filepath.Join(dir, pathPrivate), filepath.Join(dir, pathPublic), nil } func (ctx *CmdCtx) cryptoGenPrivateKeyFromCmd(cmd *cobra.Command) (privateKey any, err error) { @@ -169,6 +170,28 @@ func (ctx *CmdCtx) cryptoGenPrivateKeyFromCmd(cmd *cobra.Command) (privateKey an return privateKey, nil } +func cryptoGetCertificateBundleFromCmd(cmd *cobra.Command, dir string, caCertificate *x509.Certificate) (bundle bool, bundlePath string, err error) { + if bundle, err = cmd.Flags().GetBool(cmdFlagNameBundle); err != nil { + return false, "", err + } + + if !bundle { + return bundle, bundlePath, err + } + + if caCertificate == nil { + return false, "", fmt.Errorf("the --%s flag can't be used with self-signed certificates, you can specify the authority path using the --%s flag", cmdFlagNameBundle, cmdFlagNamePathCA) + } + + if bundlePath, err = cmd.Flags().GetString(cmdFlagNameFileCertificateBundle); err != nil { + return false, "", err + } + + bundlePath = filepath.Join(dir, bundlePath) + + return bundle, bundlePath, err +} + func cryptoGetCAFromCmd(cmd *cobra.Command) (privateKey any, cert *x509.Certificate, err error) { if !cmd.Flags().Changed(cmdFlagNamePathCA) { return nil, nil, nil @@ -337,10 +360,10 @@ func cryptoGetSubjectFromCmd(cmd *cobra.Command) (subject *pkix.Name, err error) func (ctx *CmdCtx) cryptoGetCertificateFromCmd(cmd *cobra.Command) (certificate *x509.Certificate, err error) { var ( - ca bool - subject *pkix.Name - notBeforeStr string - duration time.Duration + ca bool + subject *pkix.Name + + notBefore, notAfter time.Time ) if ca, err = cmd.Flags().GetBool(cmdFlagNameCA); err != nil { @@ -351,30 +374,16 @@ func (ctx *CmdCtx) cryptoGetCertificateFromCmd(cmd *cobra.Command) (certificate return nil, err } - if notBeforeStr, err = cmd.Flags().GetString(cmdFlagNameNotBefore); err != nil { - return nil, err - } - - if duration, err = cmd.Flags().GetDuration(cmdFlagNameDuration); err != nil { + if notBefore, notAfter, err = cryptoCertificateValidityFromCmd(cmd); err != nil { return nil, err } var ( - notBefore time.Time serialNumber *big.Int dnsSANs, extKeyUsages []string ipSANs []net.IP ) - switch len(notBeforeStr) { - case 0: - notBefore = time.Now() - default: - if notBefore, err = time.Parse(timeLayoutCertificateNotBefore, notBeforeStr); err != nil { - return nil, fmt.Errorf("failed to parse not before: %w", err) - } - } - serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) if serialNumber, err = ctx.providers.Random.IntErr(serialNumberLimit); err != nil { @@ -396,7 +405,7 @@ func (ctx *CmdCtx) cryptoGetCertificateFromCmd(cmd *cobra.Command) (certificate Subject: *subject, NotBefore: notBefore, - NotAfter: notBefore.Add(duration), + NotAfter: notAfter, IsCA: ca, @@ -415,6 +424,57 @@ func (ctx *CmdCtx) cryptoGetCertificateFromCmd(cmd *cobra.Command) (certificate return certificate, nil } +func cryptoCertificateValidityFromCmd(cmd *cobra.Command) (notBefore, notAfter time.Time, err error) { + never := time.UnixMicro(0) + + switch cmd.Flags().Changed(cmdFlagNameNotBefore) { + case true: + var notBeforeStr string + + if notBeforeStr, err = cmd.Flags().GetString(cmdFlagNameNotBefore); err != nil { + return never, never, err + } + + if notBefore, err = utils.ParseTimeString(notBeforeStr); err != nil { + return never, never, fmt.Errorf("failed to parse not before: %w", err) + } + default: + notBefore = time.Now() + } + + switch useNotAfter := cmd.Flags().Changed(cmdFlagNameNotAfter); { + case useNotAfter && cmd.Flags().Changed(cmdFlagNameDuration): + return never, never, fmt.Errorf("failed to determine not after ") + case useNotAfter: + var notAfterStr string + + if notAfterStr, err = cmd.Flags().GetString(cmdFlagNameNotAfter); err != nil { + return never, never, err + } + + if notAfter, err = utils.ParseTimeString(notAfterStr); err != nil { + return never, never, fmt.Errorf("failed to parse not after: %w", err) + } + default: + var ( + durationStr string + duration time.Duration + ) + + if durationStr, err = cmd.Flags().GetString(cmdFlagNameDuration); err != nil { + return never, never, err + } + + if duration, err = utils.ParseDurationString(durationStr); err != nil { + return never, never, fmt.Errorf("failed to parse duration string: %w", err) + } + + notAfter = notBefore.Add(duration) + } + + return notBefore, notAfter, nil +} + func fmtCryptoHashUse(use string) string { switch use { case cmdUseHashArgon2: diff --git a/internal/commands/root.go b/internal/commands/root.go index 0ac6d8843..7b728eb5a 100644 --- a/internal/commands/root.go +++ b/internal/commands/root.go @@ -58,6 +58,7 @@ func NewRootCmd() (cmd *cobra.Command) { newHelpTopic("config", "Help for the config file/directory paths", helpTopicConfig), newHelpTopic("filters", "help topic for the config filters", helpTopicConfigFilters), + newHelpTopic("time-layouts", "help topic for the various time layouts", helpTopicTimeLayouts), ) return cmd diff --git a/internal/configuration/config.template.yml b/internal/configuration/config.template.yml index 7da204922..1058fecc1 100644 --- a/internal/configuration/config.template.yml +++ b/internal/configuration/config.template.yml @@ -426,7 +426,7 @@ authentication_backend: ## changed once attributed to a user otherwise it would break the configuration for that user. Technically, ## non-unique attributes like 'mail' can also be used but we don't recommend using them, we instead advise to use ## a filter to perform alternative lookups and the attributes mentioned above (sAMAccountName and uid) to - ## follow https://www.ietf.org/rfc/rfc2307.txt. + ## follow https://datatracker.ietf.org/doc/html/rfc2307. # username_attribute: uid ## The additional_users_dn is prefixed to base_dn and delimited by a comma when searching for users. diff --git a/internal/configuration/provider_test.go b/internal/configuration/provider_test.go index 975fccdd4..f60d68651 100644 --- a/internal/configuration/provider_test.go +++ b/internal/configuration/provider_test.go @@ -105,6 +105,9 @@ func TestShouldValidateConfigurationWithFilters(t *testing.T) { testSetEnv(t, "JWT_SECRET", "abc") testSetEnv(t, "AUTHENTICATION_BACKEND_LDAP_PASSWORD", "abc") + t.Setenv("ABC_CLIENT_SECRET", "$plaintext$example-abc") + t.Setenv("XYZ_CLIENT_SECRET", "$plaintext$example-xyz") + t.Setenv("ANOTHER_CLIENT_SECRET", "$plaintext$example-123") t.Setenv("SERVICES_SERVER", "10.10.10.10") t.Setenv("ROOT_DOMAIN", "example.org") @@ -118,6 +121,11 @@ func TestShouldValidateConfigurationWithFilters(t *testing.T) { assert.Equal(t, "api-123456789.example.org", config.DuoAPI.Hostname) assert.Equal(t, "10.10.10.10", config.Notifier.SMTP.Host) assert.Equal(t, "10.10.10.10", config.Session.Redis.Host) + + require.Len(t, config.IdentityProviders.OIDC.Clients, 3) + assert.Equal(t, "$plaintext$example-abc", config.IdentityProviders.OIDC.Clients[0].Secret.String()) + assert.Equal(t, "$plaintext$example-xyz", config.IdentityProviders.OIDC.Clients[1].Secret.String()) + assert.Equal(t, "$plaintext$example-123", config.IdentityProviders.OIDC.Clients[2].Secret.String()) } func TestShouldNotIgnoreInvalidEnvs(t *testing.T) { diff --git a/internal/configuration/schema/authentication.go b/internal/configuration/schema/authentication.go index bd7d8914b..c44954c9d 100644 --- a/internal/configuration/schema/authentication.go +++ b/internal/configuration/schema/authentication.go @@ -199,6 +199,20 @@ var DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory = }, } +// DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis represents the default LDAP config for the LDAPImplementationRFC2307bis Implementation. +var DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis = LDAPAuthenticationBackend{ + UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(|(objectClass=inetOrgPerson)(objectClass=organizationalPerson)))", + UsernameAttribute: ldapAttrUserID, + MailAttribute: ldapAttrMail, + DisplayNameAttribute: ldapAttrDisplayName, + GroupsFilter: "(&(|(member={dn})(uniqueMember={dn}))(|(objectClass=groupOfNames)(objectClass=groupOfUniqueNames)(objectClass=groupOfMembers)))", + GroupNameAttribute: ldapAttrCommonName, + Timeout: time.Second * 5, + TLS: &TLSConfig{ + MinimumVersion: TLSVersion{tls.VersionTLS12}, + }, +} + // DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA represents the default LDAP config for the LDAPImplementationFreeIPA Implementation. var DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA = LDAPAuthenticationBackend{ UsersFilter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)(!(nsAccountLock=TRUE))(krbPasswordExpiration>={date-time:generalized})(|(!(krbPrincipalExpiration=*))(krbPrincipalExpiration>={date-time:generalized})))", diff --git a/internal/configuration/schema/const.go b/internal/configuration/schema/const.go index 726f23e01..6f0ef781f 100644 --- a/internal/configuration/schema/const.go +++ b/internal/configuration/schema/const.go @@ -65,6 +65,9 @@ const ( // LDAPImplementationActiveDirectory is the string for the Active Directory LDAP implementation. LDAPImplementationActiveDirectory = "activedirectory" + // LDAPImplementationRFC2307bis is the string for the RFC2307bis LDAP implementation. + LDAPImplementationRFC2307bis = "rfc2307bis" + // LDAPImplementationFreeIPA is the string for the FreeIPA LDAP implementation. LDAPImplementationFreeIPA = "freeipa" diff --git a/internal/configuration/test_resources/config.filtered.yml b/internal/configuration/test_resources/config.filtered.yml index eed860eaf..0a5d84daf 100644 --- a/internal/configuration/test_resources/config.filtered.yml +++ b/internal/configuration/test_resources/config.filtered.yml @@ -174,4 +174,21 @@ notifier: port: 1025 sender: 'admin@{{ env "ROOT_DOMAIN" }}' disable_require_tls: true + +identity_providers: + oidc: + cors: + allowed_origins: + - https://google.com + - https://example.com + clients: + - id: abc + secret: '${ABC_CLIENT_SECRET}' + consent_mode: explicit + - id: xyz + secret: '$XYZ_CLIENT_SECRET' + consent_mode: explicit + - id: '123' + secret: $ANOTHER_CLIENT_SECRET + consent_mode: explicit ... diff --git a/internal/configuration/validator/authentication.go b/internal/configuration/validator/authentication.go index f05d264c2..bcd64fabf 100644 --- a/internal/configuration/validator/authentication.go +++ b/internal/configuration/validator/authentication.go @@ -321,49 +321,19 @@ func validateLDAPAuthenticationBackend(config *schema.AuthenticationBackend, val config.LDAP.Implementation = schema.LDAPImplementationCustom } - var implementation *schema.LDAPAuthenticationBackend - - switch config.LDAP.Implementation { - case schema.LDAPImplementationCustom: - implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom - case schema.LDAPImplementationActiveDirectory: - implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory - case schema.LDAPImplementationFreeIPA: - implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA - case schema.LDAPImplementationLLDAP: - implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationLLDAP - case schema.LDAPImplementationGLAuth: - implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationGLAuth - default: - validator.Push(fmt.Errorf(errFmtLDAPAuthBackendImplementation, config.LDAP.Implementation, strings.Join(validLDAPImplementations, "', '"))) - } - - configDefaultTLS := &schema.TLSConfig{} - - if implementation != nil { - if config.LDAP.Timeout == 0 { - config.LDAP.Timeout = implementation.Timeout - } - - configDefaultTLS = &schema.TLSConfig{ - MinimumVersion: implementation.TLS.MinimumVersion, - MaximumVersion: implementation.TLS.MaximumVersion, - } - - setDefaultImplementationLDAPAuthenticationBackendProfileAttributes(config.LDAP, implementation) - } + defaultTLS := validateLDAPAuthenticationBackendImplementation(config, validator) if config.LDAP.URL == "" { validator.Push(fmt.Errorf(errFmtLDAPAuthBackendMissingOption, "url")) } else { - configDefaultTLS.ServerName = validateLDAPAuthenticationBackendURL(config.LDAP, validator) + defaultTLS.ServerName = validateLDAPAuthenticationBackendURL(config.LDAP, validator) } if config.LDAP.TLS == nil { config.LDAP.TLS = &schema.TLSConfig{} } - if err := ValidateTLSConfig(config.LDAP.TLS, configDefaultTLS); err != nil { + if err := ValidateTLSConfig(config.LDAP.TLS, defaultTLS); err != nil { validator.Push(fmt.Errorf(errFmtLDAPAuthBackendTLSConfigInvalid, err)) } @@ -382,6 +352,44 @@ func validateLDAPAuthenticationBackend(config *schema.AuthenticationBackend, val validateLDAPRequiredParameters(config, validator) } +func validateLDAPAuthenticationBackendImplementation(config *schema.AuthenticationBackend, validator *schema.StructValidator) *schema.TLSConfig { + var implementation *schema.LDAPAuthenticationBackend + + switch config.LDAP.Implementation { + case schema.LDAPImplementationCustom: + implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationCustom + case schema.LDAPImplementationActiveDirectory: + implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationActiveDirectory + case schema.LDAPImplementationRFC2307bis: + implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis + case schema.LDAPImplementationFreeIPA: + implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationFreeIPA + case schema.LDAPImplementationLLDAP: + implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationLLDAP + case schema.LDAPImplementationGLAuth: + implementation = &schema.DefaultLDAPAuthenticationBackendConfigurationImplementationGLAuth + default: + validator.Push(fmt.Errorf(errFmtLDAPAuthBackendImplementation, config.LDAP.Implementation, strings.Join(validLDAPImplementations, "', '"))) + } + + tlsconfig := &schema.TLSConfig{} + + if implementation != nil { + if config.LDAP.Timeout == 0 { + config.LDAP.Timeout = implementation.Timeout + } + + tlsconfig = &schema.TLSConfig{ + MinimumVersion: implementation.TLS.MinimumVersion, + MaximumVersion: implementation.TLS.MaximumVersion, + } + + setDefaultImplementationLDAPAuthenticationBackendProfileAttributes(config.LDAP, implementation) + } + + return tlsconfig +} + func ldapImplementationShouldSetStr(config, implementation string) bool { return config == "" && implementation != "" } diff --git a/internal/configuration/validator/authentication_test.go b/internal/configuration/validator/authentication_test.go index 4db6efba5..cc540f064 100644 --- a/internal/configuration/validator/authentication_test.go +++ b/internal/configuration/validator/authentication_test.go @@ -609,7 +609,7 @@ func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorWhenImplementat suite.Assert().Len(suite.validator.Warnings(), 0) suite.Require().Len(suite.validator.Errors(), 1) - suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: ldap: option 'implementation' is configured as 'masd' but must be one of the following values: 'custom', 'activedirectory', 'freeipa', 'lldap'") + suite.Assert().EqualError(suite.validator.Errors()[0], "authentication_backend: ldap: option 'implementation' is configured as 'masd' but must be one of the following values: 'custom', 'activedirectory', 'rfc2307bis', 'freeipa', 'lldap', 'glauth'") } func (suite *LDAPAuthenticationBackendSuite) TestShouldRaiseErrorWhenURLNotProvided() { @@ -1002,6 +1002,108 @@ func TestActiveDirectoryAuthenticationBackend(t *testing.T) { suite.Run(t, new(ActiveDirectoryAuthenticationBackendSuite)) } +type RFC2307bisAuthenticationBackendSuite struct { + suite.Suite + config schema.AuthenticationBackend + validator *schema.StructValidator +} + +func (suite *RFC2307bisAuthenticationBackendSuite) SetupTest() { + suite.validator = schema.NewStructValidator() + suite.config = schema.AuthenticationBackend{} + suite.config.LDAP = &schema.LDAPAuthenticationBackend{} + suite.config.LDAP.Implementation = schema.LDAPImplementationRFC2307bis + suite.config.LDAP.URL = testLDAPURL + suite.config.LDAP.User = testLDAPUser + suite.config.LDAP.Password = testLDAPPassword + suite.config.LDAP.BaseDN = testLDAPBaseDN + suite.config.LDAP.TLS = schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.TLS +} + +func (suite *RFC2307bisAuthenticationBackendSuite) TestShouldSetDefaults() { + ValidateAuthenticationBackend(&suite.config, suite.validator) + + suite.Assert().Len(suite.validator.Warnings(), 0) + suite.Assert().Len(suite.validator.Errors(), 0) + + suite.Assert().Equal( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.Timeout, + suite.config.LDAP.Timeout) + suite.Assert().Equal( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.AdditionalUsersDN, + suite.config.LDAP.AdditionalUsersDN) + suite.Assert().Equal( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.AdditionalGroupsDN, + suite.config.LDAP.AdditionalGroupsDN) + suite.Assert().Equal( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.UsersFilter, + suite.config.LDAP.UsersFilter) + suite.Assert().Equal( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.UsernameAttribute, + suite.config.LDAP.UsernameAttribute) + suite.Assert().Equal( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.DisplayNameAttribute, + suite.config.LDAP.DisplayNameAttribute) + suite.Assert().Equal( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.MailAttribute, + suite.config.LDAP.MailAttribute) + suite.Assert().Equal( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.GroupsFilter, + suite.config.LDAP.GroupsFilter) + suite.Assert().Equal( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.GroupNameAttribute, + suite.config.LDAP.GroupNameAttribute) +} + +func (suite *RFC2307bisAuthenticationBackendSuite) TestShouldOnlySetDefaultsIfNotManuallyConfigured() { + suite.config.LDAP.Timeout = time.Second * 2 + suite.config.LDAP.UsersFilter = "(&({username_attribute}={input})(objectClass=Person))" + suite.config.LDAP.UsernameAttribute = "o" + suite.config.LDAP.MailAttribute = "Email" + suite.config.LDAP.DisplayNameAttribute = "Given" + suite.config.LDAP.GroupsFilter = "(&(member={dn})(objectClass=posixGroup)(objectClass=top))" + suite.config.LDAP.GroupNameAttribute = "gid" + suite.config.LDAP.AdditionalUsersDN = "OU=users,OU=OpenLDAP" + suite.config.LDAP.AdditionalGroupsDN = "OU=groups,OU=OpenLDAP" + + ValidateAuthenticationBackend(&suite.config, suite.validator) + + suite.Assert().NotEqual( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.Timeout, + suite.config.LDAP.Timeout) + suite.Assert().NotEqual( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.AdditionalUsersDN, + suite.config.LDAP.AdditionalUsersDN) + suite.Assert().NotEqual( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.AdditionalGroupsDN, + suite.config.LDAP.AdditionalGroupsDN) + suite.Assert().NotEqual( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.Timeout, + suite.config.LDAP.Timeout) + suite.Assert().NotEqual( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.UsersFilter, + suite.config.LDAP.UsersFilter) + suite.Assert().NotEqual( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.UsernameAttribute, + suite.config.LDAP.UsernameAttribute) + suite.Assert().NotEqual( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.DisplayNameAttribute, + suite.config.LDAP.DisplayNameAttribute) + suite.Assert().NotEqual( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.MailAttribute, + suite.config.LDAP.MailAttribute) + suite.Assert().NotEqual( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.GroupsFilter, + suite.config.LDAP.GroupsFilter) + suite.Assert().NotEqual( + schema.DefaultLDAPAuthenticationBackendConfigurationImplementationRFC2307bis.GroupNameAttribute, + suite.config.LDAP.GroupNameAttribute) +} + +func TestRFC2307bisAuthenticationBackend(t *testing.T) { + suite.Run(t, new(RFC2307bisAuthenticationBackendSuite)) +} + type FreeIPAAuthenticationBackendSuite struct { suite.Suite config schema.AuthenticationBackend diff --git a/internal/configuration/validator/configuration_test.go b/internal/configuration/validator/configuration_test.go index 0abf16372..77e35c3b7 100644 --- a/internal/configuration/validator/configuration_test.go +++ b/internal/configuration/validator/configuration_test.go @@ -160,7 +160,7 @@ func TestShouldRaiseErrorOnInvalidCertificatesDirectory(t *testing.T) { func TestShouldNotRaiseErrorOnValidCertificatesDirectory(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultConfig() - config.CertificatesDirectory = "../../suites/common/ssl" + config.CertificatesDirectory = "../../suites/common/pki" ValidateConfiguration(&config, validator) diff --git a/internal/configuration/validator/const.go b/internal/configuration/validator/const.go index 7573a02cc..8730518de 100644 --- a/internal/configuration/validator/const.go +++ b/internal/configuration/validator/const.go @@ -267,7 +267,9 @@ const ( errFmtSessionDomainDuplicateCookieScope = "session: domain config %s: option 'domain' shares the same cookie domain scope as another configured session domain" errFmtSessionDomainPortalURLInsecure = "session: domain config %s: option 'authelia_url' does not have a secure scheme with a value of '%s'" errFmtSessionDomainPortalURLNotInCookieScope = "session: domain config %s: option 'authelia_url' does not share a cookie scope with domain '%s' with a value of '%s'" - errFmtSessionDomainInvalidDomain = "session: domain config %s: option 'domain' is not a valid domain" + errFmtSessionDomainInvalidDomain = "session: domain config %s: option 'domain' is not a valid cookie domain" + errFmtSessionDomainInvalidDomainNoDots = "session: domain config %s: option 'domain' is not a valid cookie domain: must have at least a single period" + errFmtSessionDomainInvalidDomainPublic = "session: domain config %s: option 'domain' is not a valid cookie domain: the domain is part of the special public suffix list" ) // Regulation Error Consts. @@ -337,7 +339,14 @@ const ( ) var ( - validLDAPImplementations = []string{schema.LDAPImplementationCustom, schema.LDAPImplementationActiveDirectory, schema.LDAPImplementationFreeIPA, schema.LDAPImplementationLLDAP} + validLDAPImplementations = []string{ + schema.LDAPImplementationCustom, + schema.LDAPImplementationActiveDirectory, + schema.LDAPImplementationRFC2307bis, + schema.LDAPImplementationFreeIPA, + schema.LDAPImplementationLLDAP, + schema.LDAPImplementationGLAuth, + } ) const ( diff --git a/internal/configuration/validator/session.go b/internal/configuration/validator/session.go index 08fdfeb0e..f63d24ded 100644 --- a/internal/configuration/validator/session.go +++ b/internal/configuration/validator/session.go @@ -104,12 +104,22 @@ func validateSessionDomainName(i int, config *schema.SessionConfiguration, valid switch { case d.Domain == "": validator.Push(fmt.Errorf(errFmtSessionDomainRequired, sessionDomainDescriptor(i, d))) + return case strings.HasPrefix(d.Domain, "*."): validator.Push(fmt.Errorf(errFmtSessionDomainMustBeRoot, sessionDomainDescriptor(i, d), d.Domain)) + return case strings.HasPrefix(d.Domain, "."): validator.PushWarning(fmt.Errorf(errFmtSessionDomainHasPeriodPrefix, sessionDomainDescriptor(i, d))) + case !strings.Contains(d.Domain, "."): + validator.Push(fmt.Errorf(errFmtSessionDomainInvalidDomainNoDots, sessionDomainDescriptor(i, d))) + return case !reDomainCharacters.MatchString(d.Domain): validator.Push(fmt.Errorf(errFmtSessionDomainInvalidDomain, sessionDomainDescriptor(i, d))) + return + } + + if isCookieDomainAPublicSuffix(d.Domain) { + validator.Push(fmt.Errorf(errFmtSessionDomainInvalidDomainPublic, sessionDomainDescriptor(i, d))) } } diff --git a/internal/configuration/validator/session_test.go b/internal/configuration/validator/session_test.go index d677df581..f8db62b5b 100644 --- a/internal/configuration/validator/session_test.go +++ b/internal/configuration/validator/session_test.go @@ -586,45 +586,6 @@ func TestShouldRaiseErrorOnBadRedisTLSOptionsMinVerGreaterThanMax(t *testing.T) assert.EqualError(t, validator.Errors()[0], "session: redis: tls: option combination of 'minimum_version' and 'maximum_version' is invalid: minimum version TLS1.3 is greater than the maximum version TLS1.0") } -func TestShouldRaiseErrorWhenDomainNotSet(t *testing.T) { - validator := schema.NewStructValidator() - config := newDefaultSessionConfig() - config.Domain = "" - config.Cookies = []schema.SessionCookieConfiguration{} - - ValidateSession(&config, validator) - - assert.False(t, validator.HasWarnings()) - assert.Len(t, validator.Errors(), 1) - assert.EqualError(t, validator.Errors()[0], "session: option 'domain' is required") -} - -func TestShouldRaiseErrorWhenDomainIsWildcard(t *testing.T) { - validator := schema.NewStructValidator() - config := newDefaultSessionConfig() - config.Domain = "*.example.com" - - ValidateSession(&config, validator) - - assert.Len(t, validator.Warnings(), 0) - require.Len(t, validator.Errors(), 1) - - assert.EqualError(t, validator.Errors()[0], "session: domain config #1 (domain '*.example.com'): option 'domain' must be the domain you wish to protect not a wildcard domain but it is configured as '*.example.com'") -} - -func TestShouldRaiseErrorWhenDomainNameIsInvalid(t *testing.T) { - validator := schema.NewStructValidator() - config := newDefaultSessionConfig() - config.Domain = "example!.com" - - ValidateSession(&config, validator) - - assert.Len(t, validator.Warnings(), 0) - require.Len(t, validator.Errors(), 1) - - assert.EqualError(t, validator.Errors()[0], "session: domain config #1 (domain 'example!.com'): option 'domain' is not a valid domain") -} - func TestShouldRaiseErrorWhenHaveDuplicatedDomainName(t *testing.T) { validator := schema.NewStructValidator() config := newDefaultSessionConfig() @@ -675,10 +636,18 @@ func TestShouldRaiseErrorWhenDomainIsInvalid(t *testing.T) { testCases := []struct { name string have string + warnings []string expected []string }{ - {"ShouldRaiseErrorOnMissingDomain", "", []string{"session: domain config #1 (domain ''): option 'domain' is required"}}, - {"ShouldNotRaiseErrorOnValidDomain", exampleDotCom, nil}, + {"ShouldNotRaiseErrorOnValidDomain", exampleDotCom, nil, nil}, + {"ShouldRaiseErrorOnMissingDomain", "", nil, []string{"session: domain config #1 (domain ''): option 'domain' is required"}}, + {"ShouldRaiseErrorOnDomainWithInvalidChars", "example!.com", nil, []string{"session: domain config #1 (domain 'example!.com'): option 'domain' is not a valid cookie domain"}}, + {"ShouldRaiseErrorOnDomainWithoutDots", "localhost", nil, []string{"session: domain config #1 (domain 'localhost'): option 'domain' is not a valid cookie domain: must have at least a single period"}}, + {"ShouldRaiseErrorOnPublicDomainDuckDNS", "duckdns.org", nil, []string{"session: domain config #1 (domain 'duckdns.org'): option 'domain' is not a valid cookie domain: the domain is part of the special public suffix list"}}, + {"ShouldNotRaiseErrorOnSuffixOfPublicDomainDuckDNS", "example.duckdns.org", nil, nil}, + {"ShouldRaiseWarningOnDomainWithLeadingDot", ".example.com", []string{"session: domain config #1 (domain '.example.com'): option 'domain' has a prefix of '.' which is not supported or intended behaviour: you can use this at your own risk but we recommend removing it"}, nil}, + {"ShouldRaiseErrorOnDomainWithLeadingStarDot", "*.example.com", nil, []string{"session: domain config #1 (domain '*.example.com'): option 'domain' must be the domain you wish to protect not a wildcard domain but it is configured as '*.example.com'"}}, + {"ShouldRaiseErrorOnDomainNotSet", "", nil, []string{"session: domain config #1 (domain ''): option 'domain' is required"}}, } for _, tc := range testCases { @@ -692,14 +661,18 @@ func TestShouldRaiseErrorWhenDomainIsInvalid(t *testing.T) { SessionCookieCommonConfiguration: schema.SessionCookieCommonConfiguration{ Domain: tc.have, }, - AutheliaURL: MustParseURL("https://auth.example.com")}, + }, } ValidateSession(&config, validator) - assert.Len(t, validator.Warnings(), 0) + require.Len(t, validator.Warnings(), len(tc.warnings)) require.Len(t, validator.Errors(), len(tc.expected)) + for i, expected := range tc.warnings { + assert.EqualError(t, validator.Warnings()[i], expected) + } + for i, expected := range tc.expected { assert.EqualError(t, validator.Errors()[i], expected) } diff --git a/internal/configuration/validator/util.go b/internal/configuration/validator/util.go new file mode 100644 index 000000000..b68bfee7a --- /dev/null +++ b/internal/configuration/validator/util.go @@ -0,0 +1,15 @@ +package validator + +import ( + "strings" + + "golang.org/x/net/publicsuffix" +) + +func isCookieDomainAPublicSuffix(domain string) (valid bool) { + var suffix string + + suffix, _ = publicsuffix.PublicSuffix(domain) + + return len(strings.TrimLeft(domain, ".")) == len(suffix) +} diff --git a/internal/configuration/validator/util_test.go b/internal/configuration/validator/util_test.go new file mode 100644 index 000000000..54c9bc711 --- /dev/null +++ b/internal/configuration/validator/util_test.go @@ -0,0 +1,40 @@ +package validator + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIsCookieDomainValid(t *testing.T) { + testCases := []struct { + domain string + expected bool + }{ + {"example.com", false}, + {".example.com", false}, + {"*.example.com", false}, + {"authelia.com", false}, + {"duckdns.org", true}, + {".duckdns.org", true}, + {"example.duckdns.org", false}, + {"192.168.2.1", false}, + {"localhost", true}, + {"com", true}, + {"randomnada", true}, + } + + for _, tc := range testCases { + name := "ShouldFail" + + if tc.expected { + name = "ShouldPass" + } + + t.Run(tc.domain, func(t *testing.T) { + t.Run(name, func(t *testing.T) { + assert.Equal(t, tc.expected, isCookieDomainAPublicSuffix(tc.domain)) + }) + }) + } +} diff --git a/internal/middlewares/cors.go b/internal/middlewares/cors.go index 8de1aaf84..006615bcb 100644 --- a/internal/middlewares/cors.go +++ b/internal/middlewares/cors.go @@ -234,11 +234,11 @@ func (p *CORSPolicy) handleOPTIONS(ctx *fasthttp.RequestCtx) { /* The OPTIONS method should not return a 204 as per the following specifications when read together: - RFC7231 (https://www.rfc-editor.org/rfc/rfc7231#section-4.3.7): + RFC7231 (https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.7): A server MUST generate a Content-Length field with a value of "0" if no payload body is to be sent in the response. - RFC7230 (https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2): + RFC7230 (https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2): A server MUST NOT send a Content-Length header field in any response with a status code of 1xx (Informational) or 204 (No Content). */ diff --git a/internal/mocks/random.go b/internal/mocks/random.go index 9bab56ddd..497bc4d1e 100644 --- a/internal/mocks/random.go +++ b/internal/mocks/random.go @@ -121,33 +121,48 @@ func (mr *MockRandomMockRecorder) IntErr(arg0 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IntErr", reflect.TypeOf((*MockRandom)(nil).IntErr), arg0) } -// Integer mocks base method. -func (m *MockRandom) Integer(arg0 int) int { +// Intn mocks base method. +func (m *MockRandom) Intn(arg0 int) int { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Integer", arg0) + ret := m.ctrl.Call(m, "Intn", arg0) ret0, _ := ret[0].(int) return ret0 } -// Integer indicates an expected call of Integer. -func (mr *MockRandomMockRecorder) Integer(arg0 interface{}) *gomock.Call { +// Intn indicates an expected call of Intn. +func (mr *MockRandomMockRecorder) Intn(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Integer", reflect.TypeOf((*MockRandom)(nil).Integer), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Intn", reflect.TypeOf((*MockRandom)(nil).Intn), arg0) } -// IntegerErr mocks base method. -func (m *MockRandom) IntegerErr(arg0 int) (int, error) { +// IntnErr mocks base method. +func (m *MockRandom) IntnErr(arg0 int) (int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IntegerErr", arg0) + ret := m.ctrl.Call(m, "IntnErr", arg0) ret0, _ := ret[0].(int) ret1, _ := ret[1].(error) return ret0, ret1 } -// IntegerErr indicates an expected call of IntegerErr. -func (mr *MockRandomMockRecorder) IntegerErr(arg0 interface{}) *gomock.Call { +// IntnErr indicates an expected call of IntnErr. +func (mr *MockRandomMockRecorder) IntnErr(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IntegerErr", reflect.TypeOf((*MockRandom)(nil).IntegerErr), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IntnErr", reflect.TypeOf((*MockRandom)(nil).IntnErr), arg0) +} + +// Prime mocks base method. +func (m *MockRandom) Prime(arg0 int) (*big.Int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Prime", arg0) + ret0, _ := ret[0].(*big.Int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Prime indicates an expected call of Prime. +func (mr *MockRandomMockRecorder) Prime(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Prime", reflect.TypeOf((*MockRandom)(nil).Prime), arg0) } // Read mocks base method. diff --git a/internal/notification/smtp_notifier.go b/internal/notification/smtp_notifier.go index a42fe62f4..a7533e67b 100644 --- a/internal/notification/smtp_notifier.go +++ b/internal/notification/smtp_notifier.go @@ -163,8 +163,8 @@ func (n *SMTPNotifier) Send(ctx context.Context, recipient mail.Address, subject } func (n *SMTPNotifier) setMessageID(msg *gomail.Msg, domain string) { - rn := n.random.Integer(100000000) - rm := n.random.Integer(10000) + rn := n.random.Intn(100000000) + rm := n.random.Intn(10000) rs := n.random.StringCustom(17, random.CharSetAlphaNumeric) pid := os.Getpid() + rm diff --git a/internal/oidc/store.go b/internal/oidc/store.go index 91b8b8a11..d192ed1b8 100644 --- a/internal/oidc/store.go +++ b/internal/oidc/store.go @@ -180,7 +180,7 @@ func (s *Store) DeleteAccessTokenSession(ctx context.Context, signature string) return s.revokeSessionBySignature(ctx, storage.OAuth2SessionTypeAccessToken, signature) } -// RevokeAccessToken revokes an access token as specified in: https://tools.ietf.org/html/rfc7009#section-2.1 +// RevokeAccessToken revokes an access token as specified in: https://datatracker.ietf.org/doc/html/rfc7009#section-2.1 // If the token passed to the request is an access token, the server MAY revoke the respective refresh token as well. // This implements a portion of oauth2.TokenRevocationStorage. func (s *Store) RevokeAccessToken(ctx context.Context, requestID string) (err error) { @@ -205,7 +205,7 @@ func (s *Store) DeleteRefreshTokenSession(ctx context.Context, signature string) return s.revokeSessionBySignature(ctx, storage.OAuth2SessionTypeRefreshToken, signature) } -// RevokeRefreshToken revokes a refresh token as specified in: https://tools.ietf.org/html/rfc7009#section-2.1 +// RevokeRefreshToken revokes a refresh token as specified in: https://datatracker.ietf.org/doc/html/rfc7009#section-2.1 // If the particular token is a refresh token and the authorization server supports the revocation of access tokens, // then the authorization server SHOULD also invalidate all access tokens based on the same authorization grant (see Implementation Note). // This implements a portion of oauth2.TokenRevocationStorage. @@ -213,7 +213,7 @@ func (s *Store) RevokeRefreshToken(ctx context.Context, requestID string) (err e return s.provider.DeactivateOAuth2SessionByRequestID(ctx, storage.OAuth2SessionTypeRefreshToken, requestID) } -// RevokeRefreshTokenMaybeGracePeriod revokes an access token as specified in: https://tools.ietf.org/html/rfc7009#section-2.1 +// RevokeRefreshTokenMaybeGracePeriod revokes an access token as specified in: https://datatracker.ietf.org/doc/html/rfc7009#section-2.1 // If the token passed to the request is an access token, the server MAY revoke the respective refresh token as well. // This implements a portion of oauth2.TokenRevocationStorage. func (s *Store) RevokeRefreshTokenMaybeGracePeriod(ctx context.Context, requestID string, signature string) (err error) { diff --git a/internal/random/const.go b/internal/random/const.go index 4a171f17f..99a9add61 100644 --- a/internal/random/const.go +++ b/internal/random/const.go @@ -25,7 +25,7 @@ const ( CharSetSymbolic = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" // CharSetSymbolicRFC3986Unreserved are RFC3986 unreserved symbol characters. - // See https://www.rfc-editor.org/rfc/rfc3986#section-2.3. + // See https://datatracker.ietf.org/doc/html/rfc3986#section-2.3. CharSetSymbolicRFC3986Unreserved = "-._~" // CharSetAlphaNumeric are literally just valid alphanumeric printable ASCII chars. @@ -35,7 +35,7 @@ const ( CharSetASCII = CharSetAlphabetic + CharSetNumeric + CharSetSymbolic // CharSetRFC3986Unreserved are RFC3986 unreserved characters. - // See https://www.rfc-editor.org/rfc/rfc3986#section-2.3. + // See https://datatracker.ietf.org/doc/html/rfc3986#section-2.3. CharSetRFC3986Unreserved = CharSetAlphabetic + CharSetNumeric + CharSetSymbolicRFC3986Unreserved // CharSetUnambiguousUpper are a set of unambiguous uppercase characters. diff --git a/internal/random/crypto.go b/internal/random/cryptographical.go similarity index 83% rename from internal/random/crypto.go rename to internal/random/cryptographical.go index bff1e0dce..caa78e320 100644 --- a/internal/random/crypto.go +++ b/internal/random/cryptographical.go @@ -18,11 +18,7 @@ func (r *Cryptographical) Read(p []byte) (n int, err error) { // BytesErr returns random data as bytes with the standard random.DefaultN length and can contain any byte values // (including unreadable byte values). If an error is returned from the random read this function returns it. func (r *Cryptographical) BytesErr() (data []byte, err error) { - data = make([]byte, DefaultN) - - _, err = rand.Read(data) - - return data, err + return r.BytesCustomErr(0, nil) } // Bytes returns random data as bytes with the standard random.DefaultN length and can contain any byte values @@ -49,8 +45,10 @@ func (r *Cryptographical) BytesCustomErr(n int, charset []byte) (data []byte, er t := len(charset) - for i := 0; i < n; i++ { - data[i] = charset[data[i]%byte(t)] + if t > 0 { + for i := 0; i < n; i++ { + data[i] = charset[data[i]%byte(t)] + } } return data, nil @@ -81,6 +79,36 @@ func (r *Cryptographical) StringCustom(n int, characters string) (data string) { return string(r.BytesCustom(n, []byte(characters))) } +// IntnErr returns a random int error combination with a maximum of n. +func (r *Cryptographical) IntnErr(n int) (value int, err error) { + if n <= 0 { + return 0, fmt.Errorf("n must be more than 0") + } + + max := big.NewInt(int64(n)) + + var result *big.Int + + if result, err = r.IntErr(max); err != nil { + return 0, err + } + + value = int(result.Int64()) + + if value < 0 { + return 0, fmt.Errorf("generated number is too big for int") + } + + return value, nil +} + +// Intn returns a random int with a maximum of n. +func (r *Cryptographical) Intn(n int) (value int) { + value, _ = r.IntnErr(n) + + return value +} + // IntErr returns a random *big.Int error combination with a maximum of max. func (r *Cryptographical) IntErr(max *big.Int) (value *big.Int, err error) { if max == nil { @@ -105,32 +133,8 @@ func (r *Cryptographical) Int(max *big.Int) (value *big.Int) { return value } -// IntegerErr returns a random int error combination with a maximum of n. -func (r *Cryptographical) IntegerErr(n int) (value int, err error) { - if n <= 0 { - return 0, fmt.Errorf("n must be more than 0") - } - - max := big.NewInt(int64(n)) - - var result *big.Int - - if result, err = r.IntErr(max); err != nil { - return 0, err - } - - value = int(result.Int64()) - - if value < 0 { - return 0, fmt.Errorf("generated number is too big for int") - } - - return value, nil -} - -// Integer returns a random int with a maximum of n. -func (r *Cryptographical) Integer(n int) (value int) { - value, _ = r.IntegerErr(n) - - return value +// Prime returns a number of the given bit length that is prime with high probability. Prime will return error for any +// error returned by rand.Read or if bits < 2. +func (r *Cryptographical) Prime(bits int) (prime *big.Int, err error) { + return rand.Prime(rand.Reader, bits) } diff --git a/internal/random/math.go b/internal/random/mathematical.go similarity index 75% rename from internal/random/math.go rename to internal/random/mathematical.go index d95a2d7f7..24b8e34d3 100644 --- a/internal/random/math.go +++ b/internal/random/mathematical.go @@ -1,26 +1,36 @@ package random import ( + crand "crypto/rand" "fmt" "math/big" "math/rand" + "sync" "time" ) // NewMathematical runs rand.Seed with the current time and returns a random.Provider, specifically *random.Mathematical. func NewMathematical() *Mathematical { - rand.Seed(time.Now().UnixNano()) - - return &Mathematical{} + return &Mathematical{ + rand: rand.New(rand.NewSource(time.Now().UnixNano())), //nolint:gosec + lock: &sync.Mutex{}, + } } // Mathematical is the random.Provider which uses math/rand and is COMPLETELY UNSAFE FOR PRODUCTION IN MOST SITUATIONS. // Use random.Cryptographical instead. -type Mathematical struct{} +type Mathematical struct { + rand *rand.Rand + lock *sync.Mutex +} // Read implements the io.Reader interface. func (r *Mathematical) Read(p []byte) (n int, err error) { - return rand.Read(p) //nolint:gosec + r.lock.Lock() + + defer r.lock.Unlock() + + return r.rand.Read(p) } // BytesErr returns random data as bytes with the standard random.DefaultN length and can contain any byte values @@ -28,7 +38,7 @@ func (r *Mathematical) Read(p []byte) (n int, err error) { func (r *Mathematical) BytesErr() (data []byte, err error) { data = make([]byte, DefaultN) - if _, err = rand.Read(data); err != nil { //nolint:gosec + if _, err = r.Read(data); err != nil { return nil, err } @@ -53,7 +63,7 @@ func (r *Mathematical) BytesCustomErr(n int, charset []byte) (data []byte, err e data = make([]byte, n) - if _, err = rand.Read(data); err != nil { //nolint:gosec + if _, err = r.Read(data); err != nil { return nil, err } @@ -91,17 +101,18 @@ func (r *Mathematical) StringCustom(n int, characters string) (data string) { return string(r.BytesCustom(n, []byte(characters))) } -// IntErr returns a random *big.Int error combination with a maximum of max. -func (r *Mathematical) IntErr(max *big.Int) (value *big.Int, err error) { - if max == nil { - return nil, fmt.Errorf("max is required") - } +// Intn returns a random int with a maximum of n. +func (r *Mathematical) Intn(n int) int { + r.lock.Lock() - if max.Sign() <= 0 { - return nil, fmt.Errorf("max must be 1 or more") - } + defer r.lock.Unlock() - return big.NewInt(int64(rand.Intn(max.Sign()))), nil //nolint:gosec + return r.rand.Intn(n) +} + +// IntnErr returns a random int error combination with a maximum of n. +func (r *Mathematical) IntnErr(n int) (output int, err error) { + return r.Intn(n), nil } // Int returns a random *big.Int with a maximum of max. @@ -115,12 +126,25 @@ func (r *Mathematical) Int(max *big.Int) (value *big.Int) { return value } -// IntegerErr returns a random int error combination with a maximum of n. -func (r *Mathematical) IntegerErr(n int) (output int, err error) { - return r.Integer(n), nil +// IntErr returns a random *big.Int error combination with a maximum of max. +func (r *Mathematical) IntErr(max *big.Int) (value *big.Int, err error) { + if max == nil { + return nil, fmt.Errorf("max is required") + } + + if max.Sign() <= 0 { + return nil, fmt.Errorf("max must be 1 or more") + } + + r.lock.Lock() + + defer r.lock.Unlock() + + return big.NewInt(int64(r.Intn(max.Sign()))), nil } -// Integer returns a random int with a maximum of n. -func (r *Mathematical) Integer(n int) int { - return rand.Intn(n) //nolint:gosec +// Prime returns a number of the given bit length that is prime with high probability. Prime will return error for any +// error returned by rand.Read or if bits < 2. +func (r *Mathematical) Prime(bits int) (prime *big.Int, err error) { + return crand.Prime(r, bits) } diff --git a/internal/random/provider.go b/internal/random/provider.go index 7eeda72ab..41becf4b0 100644 --- a/internal/random/provider.go +++ b/internal/random/provider.go @@ -32,15 +32,19 @@ type Provider interface { // StringCustom is an overload of GenerateCustom which takes a characters string and returns a string. StringCustom(n int, characters string) (data string) + // Intn returns a random integer with a maximum of n. + Intn(n int) (value int) + + // IntnErr returns a random int error combination with a maximum of n. + IntnErr(n int) (value int, err error) + // IntErr returns a random *big.Int error combination with a maximum of max. IntErr(max *big.Int) (value *big.Int, err error) // Int returns a random *big.Int with a maximum of max. Int(max *big.Int) (value *big.Int) - // IntegerErr returns a random int error combination with a maximum of n. - IntegerErr(n int) (value int, err error) - - // Integer returns a random integer with a maximum of n. - Integer(n int) (value int) + // Prime returns a number of the given bit length that is prime with high probability. Prime will return error for any + // error returned by rand.Read or if bits < 2. + Prime(bits int) (prime *big.Int, err error) } diff --git a/internal/suites/ActiveDirectory/configuration.yml b/internal/suites/ActiveDirectory/configuration.yml index 31f09189f..26044c7e5 100644 --- a/internal/suites/ActiveDirectory/configuration.yml +++ b/internal/suites/ActiveDirectory/configuration.yml @@ -10,8 +10,8 @@ default_redirection_url: https://home.example.com:8080/ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/ActiveDirectory/docker-compose.yml b/internal/suites/ActiveDirectory/docker-compose.yml index 84634997e..c2bc0b1cf 100644 --- a/internal/suites/ActiveDirectory/docker-compose.yml +++ b/internal/suites/ActiveDirectory/docker-compose.yml @@ -4,5 +4,5 @@ services: authelia-backend: volumes: - './ActiveDirectory/configuration.yml:/config/configuration.yml:ro' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/BypassAll/configuration.yml b/internal/suites/BypassAll/configuration.yml index 8e5157fdc..e5906d1dd 100644 --- a/internal/suites/BypassAll/configuration.yml +++ b/internal/suites/BypassAll/configuration.yml @@ -6,8 +6,8 @@ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/BypassAll/docker-compose.yml b/internal/suites/BypassAll/docker-compose.yml index 943aa1b94..05abf964c 100644 --- a/internal/suites/BypassAll/docker-compose.yml +++ b/internal/suites/BypassAll/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './BypassAll/configuration.yml:/config/configuration.yml:ro' - './BypassAll/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/CLI/configuration.yml b/internal/suites/CLI/configuration.yml index a01f2a06b..9c4b95d50 100644 --- a/internal/suites/CLI/configuration.yml +++ b/internal/suites/CLI/configuration.yml @@ -6,8 +6,8 @@ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/CLI/docker-compose.yml b/internal/suites/CLI/docker-compose.yml index 180ba191e..886561fd6 100644 --- a/internal/suites/CLI/docker-compose.yml +++ b/internal/suites/CLI/docker-compose.yml @@ -6,7 +6,7 @@ services: - './CLI/configuration.yml:/config/configuration.yml:ro' - './CLI/storage.yml:/config/configuration.storage.yml:ro' - './CLI/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' - '/tmp:/tmp' user: ${USER_ID}:${GROUP_ID} ... diff --git a/internal/suites/Caddy/configuration.yml b/internal/suites/Caddy/configuration.yml index 38031dcdc..b57c30d69 100644 --- a/internal/suites/Caddy/configuration.yml +++ b/internal/suites/Caddy/configuration.yml @@ -9,8 +9,8 @@ server: port: 9091 asset_path: /config/assets/ tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem endpoints: authz: caddy: diff --git a/internal/suites/Caddy/docker-compose.yml b/internal/suites/Caddy/docker-compose.yml index cc2b579b4..b478ae4c2 100644 --- a/internal/suites/Caddy/docker-compose.yml +++ b/internal/suites/Caddy/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './Caddy/configuration.yml:/config/configuration.yml:ro' - './Caddy/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/Docker/configuration.yml b/internal/suites/Docker/configuration.yml index 095e9fdb1..776790973 100644 --- a/internal/suites/Docker/configuration.yml +++ b/internal/suites/Docker/configuration.yml @@ -9,8 +9,8 @@ default_redirection_url: https://home.example.com:8080/ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/Docker/docker-compose.yml b/internal/suites/Docker/docker-compose.yml index 0e1c25b29..b8b22f644 100644 --- a/internal/suites/Docker/docker-compose.yml +++ b/internal/suites/Docker/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './Docker/configuration.yml:/config/configuration.yml:ro' - './Docker/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/DuoPush/configuration.yml b/internal/suites/DuoPush/configuration.yml index 79c40ec3a..59565ac2b 100644 --- a/internal/suites/DuoPush/configuration.yml +++ b/internal/suites/DuoPush/configuration.yml @@ -9,8 +9,8 @@ default_redirection_url: https://home.example.com:8080/ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: trace diff --git a/internal/suites/DuoPush/docker-compose.yml b/internal/suites/DuoPush/docker-compose.yml index f5afb5812..1a3d12015 100644 --- a/internal/suites/DuoPush/docker-compose.yml +++ b/internal/suites/DuoPush/docker-compose.yml @@ -5,7 +5,7 @@ services: volumes: - './DuoPush/configuration.yml:/config/configuration.yml:ro' - './DuoPush/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' - '/tmp:/tmp' user: ${USER_ID}:${GROUP_ID} ... diff --git a/internal/suites/Envoy/configuration.yml b/internal/suites/Envoy/configuration.yml index 6a5ff2021..f04cd8b5d 100644 --- a/internal/suites/Envoy/configuration.yml +++ b/internal/suites/Envoy/configuration.yml @@ -9,8 +9,8 @@ server: port: 9091 asset_path: /config/assets/ tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem endpoints: authz: ext-authz: diff --git a/internal/suites/Envoy/docker-compose.yml b/internal/suites/Envoy/docker-compose.yml index 194d32ab4..33e143eea 100644 --- a/internal/suites/Envoy/docker-compose.yml +++ b/internal/suites/Envoy/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './Envoy/configuration.yml:/config/configuration.yml:ro' - './Envoy/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/HAProxy/configuration.yml b/internal/suites/HAProxy/configuration.yml index ddbe9e58e..e9685844a 100644 --- a/internal/suites/HAProxy/configuration.yml +++ b/internal/suites/HAProxy/configuration.yml @@ -8,8 +8,8 @@ jwt_secret: unsecure_secret server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/HAProxy/docker-compose.yml b/internal/suites/HAProxy/docker-compose.yml index c6f7a5dc1..fefc9d50c 100644 --- a/internal/suites/HAProxy/docker-compose.yml +++ b/internal/suites/HAProxy/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './HAProxy/configuration.yml:/config/configuration.yml:ro' - './HAProxy/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/HighAvailability/configuration.yml b/internal/suites/HighAvailability/configuration.yml index 530b9bdf3..c1d3002e5 100644 --- a/internal/suites/HighAvailability/configuration.yml +++ b/internal/suites/HighAvailability/configuration.yml @@ -8,8 +8,8 @@ jwt_secret: unsecure_secret server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/HighAvailability/docker-compose.yml b/internal/suites/HighAvailability/docker-compose.yml index 15bc66e04..35ee85ce2 100644 --- a/internal/suites/HighAvailability/docker-compose.yml +++ b/internal/suites/HighAvailability/docker-compose.yml @@ -4,5 +4,5 @@ services: authelia-backend: volumes: - './HighAvailability/configuration.yml:/config/configuration.yml:ro' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/LDAP/configuration.yml b/internal/suites/LDAP/configuration.yml index 120e89224..d9c2ad7ee 100644 --- a/internal/suites/LDAP/configuration.yml +++ b/internal/suites/LDAP/configuration.yml @@ -10,8 +10,8 @@ default_redirection_url: https://home.example.com:8080/ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/LDAP/docker-compose.yml b/internal/suites/LDAP/docker-compose.yml index e00299c59..fa0e0a38c 100644 --- a/internal/suites/LDAP/docker-compose.yml +++ b/internal/suites/LDAP/docker-compose.yml @@ -4,5 +4,5 @@ services: authelia-backend: volumes: - './LDAP/configuration.yml:/config/configuration.yml:ro' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/MariaDB/configuration.yml b/internal/suites/MariaDB/configuration.yml index e575b1408..cd46fe740 100644 --- a/internal/suites/MariaDB/configuration.yml +++ b/internal/suites/MariaDB/configuration.yml @@ -9,8 +9,8 @@ default_redirection_url: https://home.example.com:8080/ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/MariaDB/docker-compose.yml b/internal/suites/MariaDB/docker-compose.yml index dbe20d3b2..625399c40 100644 --- a/internal/suites/MariaDB/docker-compose.yml +++ b/internal/suites/MariaDB/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './MariaDB/configuration.yml:/config/configuration.yml:ro' - './MariaDB/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/MultiCookieDomain/configuration.yml b/internal/suites/MultiCookieDomain/configuration.yml index 30e194678..8102b658e 100644 --- a/internal/suites/MultiCookieDomain/configuration.yml +++ b/internal/suites/MultiCookieDomain/configuration.yml @@ -9,8 +9,8 @@ theme: auto server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem telemetry: metrics: diff --git a/internal/suites/MultiCookieDomain/docker-compose.yml b/internal/suites/MultiCookieDomain/docker-compose.yml index 1a2f0122b..4f0535f7a 100644 --- a/internal/suites/MultiCookieDomain/docker-compose.yml +++ b/internal/suites/MultiCookieDomain/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './MultiCookieDomain/configuration.yml:/config/configuration.yml:ro' - './MultiCookieDomain/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/MySQL/configuration.yml b/internal/suites/MySQL/configuration.yml index 7dd065be9..18a998436 100644 --- a/internal/suites/MySQL/configuration.yml +++ b/internal/suites/MySQL/configuration.yml @@ -6,8 +6,8 @@ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/MySQL/docker-compose.yml b/internal/suites/MySQL/docker-compose.yml index a360680e1..b4771444c 100644 --- a/internal/suites/MySQL/docker-compose.yml +++ b/internal/suites/MySQL/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './MySQL/configuration.yml:/config/configuration.yml:ro' - './MySQL/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/NetworkACL/configuration.yml b/internal/suites/NetworkACL/configuration.yml index c07cfe3ee..3c29c965e 100644 --- a/internal/suites/NetworkACL/configuration.yml +++ b/internal/suites/NetworkACL/configuration.yml @@ -6,8 +6,8 @@ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/NetworkACL/docker-compose.yml b/internal/suites/NetworkACL/docker-compose.yml index ae77fe1fc..cd78e2fbf 100644 --- a/internal/suites/NetworkACL/docker-compose.yml +++ b/internal/suites/NetworkACL/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './NetworkACL/configuration.yml:/config/configuration.yml:ro' - './NetworkACL/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/OIDC/configuration.yml b/internal/suites/OIDC/configuration.yml index 0b1d17f2f..14ebd61b4 100644 --- a/internal/suites/OIDC/configuration.yml +++ b/internal/suites/OIDC/configuration.yml @@ -2,8 +2,8 @@ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug @@ -64,72 +64,6 @@ identity_providers: oidc: enable_client_debug_messages: true hmac_secret: IVPWBkAdJHje3uz7LtFTDU2pFUfh39Xm - issuer_certificate_chain: | - -----BEGIN CERTIFICATE----- - MIIC6DCCAdCgAwIBAgIRAIxvm0gFgsbh3D22rSZLuFQwDQYJKoZIhvcNAQELBQAw - EzERMA8GA1UEChMIQXV0aGVsaWEwIBcNMjIxMDAyMDAzMDQyWhgPMjEyMjA5MDgw - MDMwNDJaMBMxETAPBgNVBAoTCEF1dGhlbGlhMIIBIjANBgkqhkiG9w0BAQEFAAOC - AQ8AMIIBCgKCAQEAy71EOkV3jOpVQtVTH5HYcI4PryUCiAEyxAIuO+66gaAa4aCd - UCRr8iO/pt5nOwPxjPo+hMHhkcKpX7evj+wgYXAccpIQFSCYWTJkaXFL0jL7yFuE - 5xpjgRM/x6FfK0IbN5WmVWO9EjesbyMCyDoYpjwzIrxnB70F9Y0nrXst1SnW/Sy0 - 01BQZNzD1tky1KDvEkw7L5mMPZFZMr5wV+ELvbo1LLvvrGYhhzbXWk7pPbxT0gAa - 7yVvQbDKuCDqssAUyQa2JdlDaQocpldtK6l+dc3IsSWKd2UMouta75ngr9E1igy3 - t7owMRqH8NjwKHt6KQeDVSdBnWNjG572vaRimQIDAQABozUwMzAOBgNVHQ8BAf8E - BAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADANBgkqhkiG - 9w0BAQsFAAOCAQEAaZJ09yGa+DGr/iTqshGdPKNCtcf/CXCkL52xiI7DzLxDt30P - 8vCuXXrrTGBY7eWYupcNy/MyqaUrz1ED+map3nQzZQBJ9vWIfr01B9phkg/WSaNJ - 1DlYtbPYzr86BlGP1V5d3Wv6JqF3tkWHI0kI38CT68fWdDKrfa5j3JdZGIVJW+51 - U0IE3Nqhfc76YzwQ3sNX5FT2Fr55RowH+l5OBPk0Bcztq58XmyPR/bvPfDASt8iS - DBT+0iiDiwk6LvOkasL8p7nuh5Grc9LMEYXY/QMUbkIWhIVRFlqyJA9s8vGHx1D4 - 96iYKudj+yvO17Szzr/NNmcwETbCs4j6P6QeiA== - -----END CERTIFICATE----- - -----BEGIN CERTIFICATE----- - MIIDBTCCAe2gAwIBAgIQAK/NIAl3Bdg4Xk0y/ZGL7jANBgkqhkiG9w0BAQsFADAT - MREwDwYDVQQKEwhBdXRoZWxpYTAgFw0yMjEwMDIwMDMwMjFaGA8yMTIyMDkwODAw - MzAyMVowEzERMA8GA1UEChMIQXV0aGVsaWEwggEiMA0GCSqGSIb3DQEBAQUAA4IB - DwAwggEKAoIBAQCg7jdO1HmydfkPzTtz57pvAS3YOdBT0hlNjJ4N2lrKhNnixrzK - +4R1dWQDP2SHbZQ0TskF8eQ8HhTr7AsApotTthJFkUgV2g+bv7wVroz0Hok5xtd4 - bnpOvG3YUCP13Nk3ZVxdQXqR3/G3MrbyiXVPcgU+0giJ8EBykbtMu8L79/1iyk+m - w4fZfzTOeorRgspO3z3+pTAib2MCTA7bby1dX9qI/ysFPLdbJYfNQDxij8SzNLyJ - EkQ4kh3jKXf1VcZjbQTtYTZ3JJDqM08OxGMKuXUxPHd72Xlb+Fzql8LjYdEy/YKA - 3r8FMf14lzcjvxtLnFXh//hiXh4+xgXMkrLZAgMBAAGjUzBRMA4GA1UdDwEB/wQE - AwICpDAPBgNVHSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE - FGKpXiZA+8VQyMBqTTep+dVTthSbMA0GCSqGSIb3DQEBCwUAA4IBAQAE4DJg+Rb4 - iiocvxxQ85lhh94ql++E8MKuzIdN7ORs+ybUnsDD1WFDebubroTQuTSBkFrNuGNJ - 8B7NZsHiWWLvNsrnxxeC5CicqfhSDti0rKWsbGyeoq7Kqok5E4pwOzeRsxL2e/Hm - G6LsUQuQMUG2vxKNynqmJS4VpgSVkiGhUfURFuRRDuRpVQ/XTl7jDIGf/ls7TAZq - 1AnmnSi4Cqy4hrTnwYUYkFCcH69onUKAoaVNl1eAH7ogxakz32WyWObY98NBrjzA - I6VQlaQNSHtdFqDpu7NWJZZZSgN4BknbMYQEPNYCm701cPB4ahJbpg5C3pVPFSql - Bc9iI6nN3PCr - -----END CERTIFICATE----- - issuer_private_key: | - -----BEGIN RSA PRIVATE KEY----- - MIIEowIBAAKCAQEAy71EOkV3jOpVQtVTH5HYcI4PryUCiAEyxAIuO+66gaAa4aCd - UCRr8iO/pt5nOwPxjPo+hMHhkcKpX7evj+wgYXAccpIQFSCYWTJkaXFL0jL7yFuE - 5xpjgRM/x6FfK0IbN5WmVWO9EjesbyMCyDoYpjwzIrxnB70F9Y0nrXst1SnW/Sy0 - 01BQZNzD1tky1KDvEkw7L5mMPZFZMr5wV+ELvbo1LLvvrGYhhzbXWk7pPbxT0gAa - 7yVvQbDKuCDqssAUyQa2JdlDaQocpldtK6l+dc3IsSWKd2UMouta75ngr9E1igy3 - t7owMRqH8NjwKHt6KQeDVSdBnWNjG572vaRimQIDAQABAoIBAA/EhhM8bRQqzo5t - lBFNaELNu8kCRD/iV9tzj8BzqVt+2JW9qG8bYn9K5Po1HCglFfyjIVOE7cAqIJGX - 1a59x8PCuXDkfPolm6TLkZnXeta5u2K2MoLwN+M1aio5AvSGGTUkD8tr/KX8SQwQ - 2ZZFaML0xcBadF7U8jEey4NRlSp5/voiIAB+FrJHepZBz2XJYCX5s2vYLPMn+51R - 1HyO0n2aQ9H1Na8aBjTfAp9GDKJWBV3bSM7cVaLGlMFj/HNXUNVnSsVsJj0tdWKz - K6r9zPskLnS+eNjCgqrOtZSqJ7M3PL0/PoTFPrr1Fevr+soKWCaPF94Ib94O9SEq - scvP3kECgYEA0HBdGab0HjcZgFtsIaMm+eBcDhUmUrvMPUw6FmspKnc8wplscONW - wrDGhR0dpT8+aAMD5jFC2pvyHjI5AWkW+53LB15j6SVzUlUMfS3VTwE2prLtDHDs - nCDW2+fXY2kjv45efZGpMGbLJVePx2RCPzUlAlc14lzxnHgpo7eho1cCgYEA+jpi - Eo/Jqa5CNd4hrXqFxZTFtU2Mn38ZKI3QK/l47/347yHLebjsYIIwJRoHenxWxNlz - Y+BZ38vkP+f9BGAVGiRcyMmIJU0X305wKwl26Y2Q/tEm2OpwmDboD2pL9byi9vfY - bz7pQGK/l9j86KofRwVJJRLsofPI1SsjnC8c448CgYAkpg0IjJ1RjriSJADwLSKW - PseQxlE1rMVtZbC07mSPjeWGBbnWY3KGytQs5YCn5GXRne4alEC/9Tlt68CwKc0b - spPXGNaSUL5lFIUcoWlm+bylNMKPNG+1x+RfR/VMCll5vcuJYooP85L2Xt3t3gfz - 2yFFtxXHVjY5H7uaiJgIAwKBgQDvkGXEj5TqtsL8/6YOiHb6Kuz+Hzi6mtxjTyI2 - d6mpWuWxTBGaf8kOvJWLb9gpFFGeNPGcdXaWJIZqCJjcT4Dkflu2f/uwepaYXGhX - S8Bk6fwfee5PTmRt1mNmHsaKhgcfmznDh9+YnPIBVuULe5RmUlEtBWk3xEZKj/qP - 1Ss7UQKBgAwZQz+h5Z/XOJH3Qs5nJBKAZUiYkj3ux7G6tjx0cz7XcUYd/6enBpkY - JeqVHB6G+bMRLwb+Hc5Vgpbd5GdaUWo8udaghHgSGPUVcn0lK38XhYek6ACGz7Lo - xEfgtKoBlUq+uPb8H05HY0t9KybA3LA5wkRYYnJ17/nkZtrrJAmX - -----END RSA PRIVATE KEY----- clients: - id: oidc-tester-app secret: foobar diff --git a/internal/suites/OIDC/docker-compose.yml b/internal/suites/OIDC/docker-compose.yml index 2da124b77..7f545a02a 100644 --- a/internal/suites/OIDC/docker-compose.yml +++ b/internal/suites/OIDC/docker-compose.yml @@ -2,9 +2,11 @@ version: '3' services: authelia-backend: + environment: + AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_CERTIFICATE_CHAIN_FILE: /pki/public.oidc.bundle.crt + AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE: /pki/private.oidc.pem volumes: - './OIDC/configuration.yml:/config/configuration.yml:ro' - './OIDC/users.yml:/config/users.yml' - - './OIDC/keypair/key.pem:/config/issuer.pem:ro' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/OIDC/keypair/key.pem b/internal/suites/OIDC/keypair/key.pem deleted file mode 100644 index c5df003c7..000000000 --- a/internal/suites/OIDC/keypair/key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAvOFmoEJFt1JkfdlwM3vJFg5rrY9d6LyyqezjZkBZDQ4qdEEU -dCrbW8ISFTtg9sfbrS3qingUzVP9VOfYPMC3r0ugjJXjhvJdBSaoLlzL3saeyrXk -frOOvkcWKzeOynqUNPhKy9dchmuLALFfd/Jy7Wzq0y7XxGeNidEmFjMAf9dwf6/+ -PjQjbG7zBFu/XSajITPHlDXPVDd0j2qw2wu5Z9iqn4LRXnAFnC438hZZKZU/+JxU -2ezr6Sefiy8XTC2kDiq3cgLeEjSywlJOs+4TLjVS/3h75sh2Wk0xVaSwjPEjCOgm -a+2E3GJrGdQBiAjMSu101VBVwHUHaLDCn1T4NwIDAQABAoIBADWkupXnXI99Ogc4 -GxK0JF88Rz6qyhwQg5mZKthejCwWCt6roRiBF33O933KOHa+OljMAqHDCv1pzjgw -BIz0mvaRPw7OfylTajHNUdShDFHADVc7I6MMcgz+eYBarhY5jCAjKHMOPjv7DSZs -OdYCKLvfxC2oTyV714n9uZhyccDcvQpkgZuBDL0oxPom1GOI8TGhPjxvFOovEHWA -Q8q9XY4cUVNDikZmvpgeUkJHWYHYb+11vKeSupnYD03yJ3sDy+F6+m+3/XmzFbXb -1p43ermHQsMfDlxPyulUUI0viSo2UhlMC/moAb9FusOv+dTl2lt0gGqzDJ9gg1z1 -XpHRnwkCgYEA5x48dyxd4lydtVYef9sBmbLJEYozsYyOwLcnrLSNaZxeCza1exyR -QIRogswoLDacxrYvO8FY6LtAEMkisv732M29zthBPm5wyoSZiM1X2YfQXKsmyh2h -x1/yCWv/BQjj68A8IAxToaXxSG4WAr/X00RGUkXgkgw122FxcmGuFyUCgYEA0TcR -dnt/oRMK4aCZHcBgTknzDfxKlJh4S0C9WjxKgr8IlW4LTeVSBuuqOObOQYImEhtw -TRTKZIViL0roDF79cioQSp1Tk5h6uy8wr6VyhWRnWfTz2/azoTHnmQ780rtAuEI/ -NvE6FiqwikJLjma1YJoRfr/bfmgMdxcYbJI1MSsCgYAEZ5Yda1IKu1siFpcUNrdM -F5UvaWPc0WHzGEqARxye06UTL6K7yuqVwTBAteVaGlxYiSZTTDcGkHMDHuIzaRqO -HjWs2IA90VsC8Q4ABnHTKnx1F6nwlin8I774IP/GN8ooNwyuS63YWdJEYBy5RrC1 -TQrODJjgD62DFdNUq7nmpQKBgFMJEzI+Q+KPJ0NztTG8t7x61y/W0Vb2yM+9Syn0 -QfJwlZyRR4VMHelHQZFB8dzIJgoLv9+n/8gztEtm5IB8dwUHst2aYaBz5UpDqYQd -Gz3cIrTuZpcH7DVvFCeIbknJLh+zk1lgFpjTqqvFMi27kANeQtFWnmwmKcRec0As -K1ZvAoGAV/3YB44/zIoB590+yhpx2HTmDPVHH+J+5O71Pi1D9W13ClBFLrE69wo+ -IQLIstBI5tGOGeuQNjXhDKJ1U30xppZXcnebrkA+oOo+6dy20zghFR2maAGXfWFU -pM4GsSnSTm0bXPebVouQFqhj7LqcQQzCqRDThmw/Lp1tJUmu40g= ------END RSA PRIVATE KEY----- diff --git a/internal/suites/OIDC/keypair/key.pub b/internal/suites/OIDC/keypair/key.pub deleted file mode 100644 index b8e37ffa4..000000000 --- a/internal/suites/OIDC/keypair/key.pub +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN RSA PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvOFmoEJFt1JkfdlwM3vJ -Fg5rrY9d6LyyqezjZkBZDQ4qdEEUdCrbW8ISFTtg9sfbrS3qingUzVP9VOfYPMC3 -r0ugjJXjhvJdBSaoLlzL3saeyrXkfrOOvkcWKzeOynqUNPhKy9dchmuLALFfd/Jy -7Wzq0y7XxGeNidEmFjMAf9dwf6/+PjQjbG7zBFu/XSajITPHlDXPVDd0j2qw2wu5 -Z9iqn4LRXnAFnC438hZZKZU/+JxU2ezr6Sefiy8XTC2kDiq3cgLeEjSywlJOs+4T -LjVS/3h75sh2Wk0xVaSwjPEjCOgma+2E3GJrGdQBiAjMSu101VBVwHUHaLDCn1T4 -NwIDAQAB ------END RSA PUBLIC KEY----- diff --git a/internal/suites/OIDCTraefik/configuration.yml b/internal/suites/OIDCTraefik/configuration.yml index 2e089fda9..f5e936cca 100644 --- a/internal/suites/OIDCTraefik/configuration.yml +++ b/internal/suites/OIDCTraefik/configuration.yml @@ -2,8 +2,8 @@ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug @@ -65,72 +65,6 @@ identity_providers: oidc: enable_client_debug_messages: true hmac_secret: IVPWBkAdJHje3uz7LtFTDU2pFUfh39Xm - issuer_certificate_chain: | - -----BEGIN CERTIFICATE----- - MIIC6DCCAdCgAwIBAgIRAIxvm0gFgsbh3D22rSZLuFQwDQYJKoZIhvcNAQELBQAw - EzERMA8GA1UEChMIQXV0aGVsaWEwIBcNMjIxMDAyMDAzMDQyWhgPMjEyMjA5MDgw - MDMwNDJaMBMxETAPBgNVBAoTCEF1dGhlbGlhMIIBIjANBgkqhkiG9w0BAQEFAAOC - AQ8AMIIBCgKCAQEAy71EOkV3jOpVQtVTH5HYcI4PryUCiAEyxAIuO+66gaAa4aCd - UCRr8iO/pt5nOwPxjPo+hMHhkcKpX7evj+wgYXAccpIQFSCYWTJkaXFL0jL7yFuE - 5xpjgRM/x6FfK0IbN5WmVWO9EjesbyMCyDoYpjwzIrxnB70F9Y0nrXst1SnW/Sy0 - 01BQZNzD1tky1KDvEkw7L5mMPZFZMr5wV+ELvbo1LLvvrGYhhzbXWk7pPbxT0gAa - 7yVvQbDKuCDqssAUyQa2JdlDaQocpldtK6l+dc3IsSWKd2UMouta75ngr9E1igy3 - t7owMRqH8NjwKHt6KQeDVSdBnWNjG572vaRimQIDAQABozUwMzAOBgNVHQ8BAf8E - BAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADANBgkqhkiG - 9w0BAQsFAAOCAQEAaZJ09yGa+DGr/iTqshGdPKNCtcf/CXCkL52xiI7DzLxDt30P - 8vCuXXrrTGBY7eWYupcNy/MyqaUrz1ED+map3nQzZQBJ9vWIfr01B9phkg/WSaNJ - 1DlYtbPYzr86BlGP1V5d3Wv6JqF3tkWHI0kI38CT68fWdDKrfa5j3JdZGIVJW+51 - U0IE3Nqhfc76YzwQ3sNX5FT2Fr55RowH+l5OBPk0Bcztq58XmyPR/bvPfDASt8iS - DBT+0iiDiwk6LvOkasL8p7nuh5Grc9LMEYXY/QMUbkIWhIVRFlqyJA9s8vGHx1D4 - 96iYKudj+yvO17Szzr/NNmcwETbCs4j6P6QeiA== - -----END CERTIFICATE----- - -----BEGIN CERTIFICATE----- - MIIDBTCCAe2gAwIBAgIQAK/NIAl3Bdg4Xk0y/ZGL7jANBgkqhkiG9w0BAQsFADAT - MREwDwYDVQQKEwhBdXRoZWxpYTAgFw0yMjEwMDIwMDMwMjFaGA8yMTIyMDkwODAw - MzAyMVowEzERMA8GA1UEChMIQXV0aGVsaWEwggEiMA0GCSqGSIb3DQEBAQUAA4IB - DwAwggEKAoIBAQCg7jdO1HmydfkPzTtz57pvAS3YOdBT0hlNjJ4N2lrKhNnixrzK - +4R1dWQDP2SHbZQ0TskF8eQ8HhTr7AsApotTthJFkUgV2g+bv7wVroz0Hok5xtd4 - bnpOvG3YUCP13Nk3ZVxdQXqR3/G3MrbyiXVPcgU+0giJ8EBykbtMu8L79/1iyk+m - w4fZfzTOeorRgspO3z3+pTAib2MCTA7bby1dX9qI/ysFPLdbJYfNQDxij8SzNLyJ - EkQ4kh3jKXf1VcZjbQTtYTZ3JJDqM08OxGMKuXUxPHd72Xlb+Fzql8LjYdEy/YKA - 3r8FMf14lzcjvxtLnFXh//hiXh4+xgXMkrLZAgMBAAGjUzBRMA4GA1UdDwEB/wQE - AwICpDAPBgNVHSUECDAGBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE - FGKpXiZA+8VQyMBqTTep+dVTthSbMA0GCSqGSIb3DQEBCwUAA4IBAQAE4DJg+Rb4 - iiocvxxQ85lhh94ql++E8MKuzIdN7ORs+ybUnsDD1WFDebubroTQuTSBkFrNuGNJ - 8B7NZsHiWWLvNsrnxxeC5CicqfhSDti0rKWsbGyeoq7Kqok5E4pwOzeRsxL2e/Hm - G6LsUQuQMUG2vxKNynqmJS4VpgSVkiGhUfURFuRRDuRpVQ/XTl7jDIGf/ls7TAZq - 1AnmnSi4Cqy4hrTnwYUYkFCcH69onUKAoaVNl1eAH7ogxakz32WyWObY98NBrjzA - I6VQlaQNSHtdFqDpu7NWJZZZSgN4BknbMYQEPNYCm701cPB4ahJbpg5C3pVPFSql - Bc9iI6nN3PCr - -----END CERTIFICATE----- - issuer_private_key: | - -----BEGIN RSA PRIVATE KEY----- - MIIEowIBAAKCAQEAy71EOkV3jOpVQtVTH5HYcI4PryUCiAEyxAIuO+66gaAa4aCd - UCRr8iO/pt5nOwPxjPo+hMHhkcKpX7evj+wgYXAccpIQFSCYWTJkaXFL0jL7yFuE - 5xpjgRM/x6FfK0IbN5WmVWO9EjesbyMCyDoYpjwzIrxnB70F9Y0nrXst1SnW/Sy0 - 01BQZNzD1tky1KDvEkw7L5mMPZFZMr5wV+ELvbo1LLvvrGYhhzbXWk7pPbxT0gAa - 7yVvQbDKuCDqssAUyQa2JdlDaQocpldtK6l+dc3IsSWKd2UMouta75ngr9E1igy3 - t7owMRqH8NjwKHt6KQeDVSdBnWNjG572vaRimQIDAQABAoIBAA/EhhM8bRQqzo5t - lBFNaELNu8kCRD/iV9tzj8BzqVt+2JW9qG8bYn9K5Po1HCglFfyjIVOE7cAqIJGX - 1a59x8PCuXDkfPolm6TLkZnXeta5u2K2MoLwN+M1aio5AvSGGTUkD8tr/KX8SQwQ - 2ZZFaML0xcBadF7U8jEey4NRlSp5/voiIAB+FrJHepZBz2XJYCX5s2vYLPMn+51R - 1HyO0n2aQ9H1Na8aBjTfAp9GDKJWBV3bSM7cVaLGlMFj/HNXUNVnSsVsJj0tdWKz - K6r9zPskLnS+eNjCgqrOtZSqJ7M3PL0/PoTFPrr1Fevr+soKWCaPF94Ib94O9SEq - scvP3kECgYEA0HBdGab0HjcZgFtsIaMm+eBcDhUmUrvMPUw6FmspKnc8wplscONW - wrDGhR0dpT8+aAMD5jFC2pvyHjI5AWkW+53LB15j6SVzUlUMfS3VTwE2prLtDHDs - nCDW2+fXY2kjv45efZGpMGbLJVePx2RCPzUlAlc14lzxnHgpo7eho1cCgYEA+jpi - Eo/Jqa5CNd4hrXqFxZTFtU2Mn38ZKI3QK/l47/347yHLebjsYIIwJRoHenxWxNlz - Y+BZ38vkP+f9BGAVGiRcyMmIJU0X305wKwl26Y2Q/tEm2OpwmDboD2pL9byi9vfY - bz7pQGK/l9j86KofRwVJJRLsofPI1SsjnC8c448CgYAkpg0IjJ1RjriSJADwLSKW - PseQxlE1rMVtZbC07mSPjeWGBbnWY3KGytQs5YCn5GXRne4alEC/9Tlt68CwKc0b - spPXGNaSUL5lFIUcoWlm+bylNMKPNG+1x+RfR/VMCll5vcuJYooP85L2Xt3t3gfz - 2yFFtxXHVjY5H7uaiJgIAwKBgQDvkGXEj5TqtsL8/6YOiHb6Kuz+Hzi6mtxjTyI2 - d6mpWuWxTBGaf8kOvJWLb9gpFFGeNPGcdXaWJIZqCJjcT4Dkflu2f/uwepaYXGhX - S8Bk6fwfee5PTmRt1mNmHsaKhgcfmznDh9+YnPIBVuULe5RmUlEtBWk3xEZKj/qP - 1Ss7UQKBgAwZQz+h5Z/XOJH3Qs5nJBKAZUiYkj3ux7G6tjx0cz7XcUYd/6enBpkY - JeqVHB6G+bMRLwb+Hc5Vgpbd5GdaUWo8udaghHgSGPUVcn0lK38XhYek6ACGz7Lo - xEfgtKoBlUq+uPb8H05HY0t9KybA3LA5wkRYYnJ17/nkZtrrJAmX - -----END RSA PRIVATE KEY----- clients: - id: oidc-tester-app secret: foobar diff --git a/internal/suites/OIDCTraefik/docker-compose.yml b/internal/suites/OIDCTraefik/docker-compose.yml index a5f4dd820..4ffae1fda 100644 --- a/internal/suites/OIDCTraefik/docker-compose.yml +++ b/internal/suites/OIDCTraefik/docker-compose.yml @@ -2,9 +2,11 @@ version: '3' services: authelia-backend: + environment: + AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_CERTIFICATE_CHAIN_FILE: /pki/public.oidc.bundle.crt + AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE: /pki/private.oidc.pem volumes: - './OIDCTraefik/configuration.yml:/config/configuration.yml:ro' - './OIDCTraefik/users.yml:/config/users.yml' - - './OIDCTraefik/keypair/key.pem:/config/issuer.pem:ro' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/OIDCTraefik/keypair/key.pem b/internal/suites/OIDCTraefik/keypair/key.pem deleted file mode 100644 index c5df003c7..000000000 --- a/internal/suites/OIDCTraefik/keypair/key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAvOFmoEJFt1JkfdlwM3vJFg5rrY9d6LyyqezjZkBZDQ4qdEEU -dCrbW8ISFTtg9sfbrS3qingUzVP9VOfYPMC3r0ugjJXjhvJdBSaoLlzL3saeyrXk -frOOvkcWKzeOynqUNPhKy9dchmuLALFfd/Jy7Wzq0y7XxGeNidEmFjMAf9dwf6/+ -PjQjbG7zBFu/XSajITPHlDXPVDd0j2qw2wu5Z9iqn4LRXnAFnC438hZZKZU/+JxU -2ezr6Sefiy8XTC2kDiq3cgLeEjSywlJOs+4TLjVS/3h75sh2Wk0xVaSwjPEjCOgm -a+2E3GJrGdQBiAjMSu101VBVwHUHaLDCn1T4NwIDAQABAoIBADWkupXnXI99Ogc4 -GxK0JF88Rz6qyhwQg5mZKthejCwWCt6roRiBF33O933KOHa+OljMAqHDCv1pzjgw -BIz0mvaRPw7OfylTajHNUdShDFHADVc7I6MMcgz+eYBarhY5jCAjKHMOPjv7DSZs -OdYCKLvfxC2oTyV714n9uZhyccDcvQpkgZuBDL0oxPom1GOI8TGhPjxvFOovEHWA -Q8q9XY4cUVNDikZmvpgeUkJHWYHYb+11vKeSupnYD03yJ3sDy+F6+m+3/XmzFbXb -1p43ermHQsMfDlxPyulUUI0viSo2UhlMC/moAb9FusOv+dTl2lt0gGqzDJ9gg1z1 -XpHRnwkCgYEA5x48dyxd4lydtVYef9sBmbLJEYozsYyOwLcnrLSNaZxeCza1exyR -QIRogswoLDacxrYvO8FY6LtAEMkisv732M29zthBPm5wyoSZiM1X2YfQXKsmyh2h -x1/yCWv/BQjj68A8IAxToaXxSG4WAr/X00RGUkXgkgw122FxcmGuFyUCgYEA0TcR -dnt/oRMK4aCZHcBgTknzDfxKlJh4S0C9WjxKgr8IlW4LTeVSBuuqOObOQYImEhtw -TRTKZIViL0roDF79cioQSp1Tk5h6uy8wr6VyhWRnWfTz2/azoTHnmQ780rtAuEI/ -NvE6FiqwikJLjma1YJoRfr/bfmgMdxcYbJI1MSsCgYAEZ5Yda1IKu1siFpcUNrdM -F5UvaWPc0WHzGEqARxye06UTL6K7yuqVwTBAteVaGlxYiSZTTDcGkHMDHuIzaRqO -HjWs2IA90VsC8Q4ABnHTKnx1F6nwlin8I774IP/GN8ooNwyuS63YWdJEYBy5RrC1 -TQrODJjgD62DFdNUq7nmpQKBgFMJEzI+Q+KPJ0NztTG8t7x61y/W0Vb2yM+9Syn0 -QfJwlZyRR4VMHelHQZFB8dzIJgoLv9+n/8gztEtm5IB8dwUHst2aYaBz5UpDqYQd -Gz3cIrTuZpcH7DVvFCeIbknJLh+zk1lgFpjTqqvFMi27kANeQtFWnmwmKcRec0As -K1ZvAoGAV/3YB44/zIoB590+yhpx2HTmDPVHH+J+5O71Pi1D9W13ClBFLrE69wo+ -IQLIstBI5tGOGeuQNjXhDKJ1U30xppZXcnebrkA+oOo+6dy20zghFR2maAGXfWFU -pM4GsSnSTm0bXPebVouQFqhj7LqcQQzCqRDThmw/Lp1tJUmu40g= ------END RSA PRIVATE KEY----- diff --git a/internal/suites/OIDCTraefik/keypair/key.pub b/internal/suites/OIDCTraefik/keypair/key.pub deleted file mode 100644 index b8e37ffa4..000000000 --- a/internal/suites/OIDCTraefik/keypair/key.pub +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN RSA PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvOFmoEJFt1JkfdlwM3vJ -Fg5rrY9d6LyyqezjZkBZDQ4qdEEUdCrbW8ISFTtg9sfbrS3qingUzVP9VOfYPMC3 -r0ugjJXjhvJdBSaoLlzL3saeyrXkfrOOvkcWKzeOynqUNPhKy9dchmuLALFfd/Jy -7Wzq0y7XxGeNidEmFjMAf9dwf6/+PjQjbG7zBFu/XSajITPHlDXPVDd0j2qw2wu5 -Z9iqn4LRXnAFnC438hZZKZU/+JxU2ezr6Sefiy8XTC2kDiq3cgLeEjSywlJOs+4T -LjVS/3h75sh2Wk0xVaSwjPEjCOgma+2E3GJrGdQBiAjMSu101VBVwHUHaLDCn1T4 -NwIDAQAB ------END RSA PUBLIC KEY----- diff --git a/internal/suites/OneFactorOnly/configuration.yml b/internal/suites/OneFactorOnly/configuration.yml index bc3ac4485..4e54656cd 100644 --- a/internal/suites/OneFactorOnly/configuration.yml +++ b/internal/suites/OneFactorOnly/configuration.yml @@ -9,8 +9,8 @@ default_redirection_url: https://home.example.com:8080/ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/OneFactorOnly/docker-compose.yml b/internal/suites/OneFactorOnly/docker-compose.yml index fc9276507..45e24b23a 100644 --- a/internal/suites/OneFactorOnly/docker-compose.yml +++ b/internal/suites/OneFactorOnly/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './OneFactorOnly/configuration.yml:/config/configuration.yml:ro' - './OneFactorOnly/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/PathPrefix/configuration.yml b/internal/suites/PathPrefix/configuration.yml index decb58436..95c5861ed 100644 --- a/internal/suites/PathPrefix/configuration.yml +++ b/internal/suites/PathPrefix/configuration.yml @@ -9,8 +9,8 @@ server: port: 9091 path: auth tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/PathPrefix/docker-compose.yml b/internal/suites/PathPrefix/docker-compose.yml index 428f056ce..46574bfb5 100644 --- a/internal/suites/PathPrefix/docker-compose.yml +++ b/internal/suites/PathPrefix/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './PathPrefix/configuration.yml:/config/configuration.yml:ro' - './PathPrefix/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/Postgres/configuration.yml b/internal/suites/Postgres/configuration.yml index ebeba850a..2276a4763 100644 --- a/internal/suites/Postgres/configuration.yml +++ b/internal/suites/Postgres/configuration.yml @@ -9,8 +9,8 @@ default_redirection_url: https://home.example.com:8080/ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/Postgres/docker-compose.yml b/internal/suites/Postgres/docker-compose.yml index 187ba6661..ba7ed9059 100644 --- a/internal/suites/Postgres/docker-compose.yml +++ b/internal/suites/Postgres/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './Postgres/configuration.yml:/config/configuration.yml:ro' - './Postgres/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/ShortTimeouts/configuration.yml b/internal/suites/ShortTimeouts/configuration.yml index 82bcb9149..3a3cb945c 100644 --- a/internal/suites/ShortTimeouts/configuration.yml +++ b/internal/suites/ShortTimeouts/configuration.yml @@ -9,8 +9,8 @@ default_redirection_url: https://home.example.com:8080/ server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/ShortTimeouts/docker-compose.yml b/internal/suites/ShortTimeouts/docker-compose.yml index 6568c9d45..08a85dadc 100644 --- a/internal/suites/ShortTimeouts/docker-compose.yml +++ b/internal/suites/ShortTimeouts/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './ShortTimeouts/configuration.yml:/config/configuration.yml:ro' - './ShortTimeouts/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/Standalone/configuration.yml b/internal/suites/Standalone/configuration.yml index 0deb53017..19fba7a36 100644 --- a/internal/suites/Standalone/configuration.yml +++ b/internal/suites/Standalone/configuration.yml @@ -8,8 +8,8 @@ theme: auto server: port: 9091 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem telemetry: metrics: diff --git a/internal/suites/Standalone/docker-compose.yml b/internal/suites/Standalone/docker-compose.yml index 1aaabf6b4..3bda7e4f4 100644 --- a/internal/suites/Standalone/docker-compose.yml +++ b/internal/suites/Standalone/docker-compose.yml @@ -8,7 +8,7 @@ services: volumes: - './Standalone/configuration.yml:/config/configuration.yml:ro' - './Standalone/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' - '/tmp:/tmp' user: ${USER_ID}:${GROUP_ID} ... diff --git a/internal/suites/Traefik/configuration.yml b/internal/suites/Traefik/configuration.yml index babc67281..e4cb5c403 100644 --- a/internal/suites/Traefik/configuration.yml +++ b/internal/suites/Traefik/configuration.yml @@ -9,8 +9,8 @@ server: port: 9091 asset_path: /config/assets/ tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/Traefik/docker-compose.yml b/internal/suites/Traefik/docker-compose.yml index a80813d91..051059c9a 100644 --- a/internal/suites/Traefik/docker-compose.yml +++ b/internal/suites/Traefik/docker-compose.yml @@ -5,5 +5,5 @@ services: volumes: - './Traefik/configuration.yml:/config/configuration.yml:ro' - './Traefik/users.yml:/config/users.yml' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/Traefik2/configuration.yml b/internal/suites/Traefik2/configuration.yml index 93da678a0..cf45b4ca6 100644 --- a/internal/suites/Traefik2/configuration.yml +++ b/internal/suites/Traefik2/configuration.yml @@ -9,8 +9,8 @@ server: port: 9091 asset_path: /config/assets/ tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem endpoints: authz: forward-auth: diff --git a/internal/suites/Traefik2/docker-compose.yml b/internal/suites/Traefik2/docker-compose.yml index 4cdf56953..e24d2eada 100644 --- a/internal/suites/Traefik2/docker-compose.yml +++ b/internal/suites/Traefik2/docker-compose.yml @@ -7,5 +7,5 @@ services: - './Traefik2/users.yml:/config/users.yml' - './Traefik2/favicon.ico:/config/assets/favicon.ico' - './Traefik2/logo.png:/config/assets/logo.png' - - './common/ssl:/config/ssl:ro' + - './common/pki:/pki:ro' ... diff --git a/internal/suites/common/pki/ca.public.crt b/internal/suites/common/pki/ca.public.crt new file mode 100644 index 000000000..98244a4ce --- /dev/null +++ b/internal/suites/common/pki/ca.public.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIRAPl83YWFsuwIwxBRmdJyLLQwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMFsxETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEwMC4GA1UEAxMnQXV0aGVsaWEgRGV2 +ZWxvcG1lbnQgU3RhbmRhbG9uZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA2RtD74ISXHruAIIkIRTLGf5VK0b7iN5+CPW8qWjg74PCnid1 +3DOqVCZ3HSXMP0iaH5rd+WAYojQo5Z1uZ75tXgzYjt6tyXG5H1nN1fkmjkHyNORP +abOZtngVaixvlT/hsONXszFdqogXhhI4DtEo0lvxJcnOHER4QVylM4YgDMF85jXi +VD893Y6Luik9B6FXLVK9iAJ5MfvD/r8kEPLsDTl2u/Ye0q4igVDJq9tOtb2enhlz +HtipYhzzNwEzQwy3tjzP9xpQG6XE6/JW20gQaBvoRBN64DMgRlh1/8ZVyYE8v/B1 +vRVpSgmyCdDJeaRYZ6J+hO3LXBXU20CVZsM5VQIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUlrBVtyTWJQWRimLeZXr2 +mrOzy2gwDQYJKoZIhvcNAQELBQADggEBAKXjAw5v8VTM6EDiUvR8XdiikYkycAG/ +hcEt+QLkkBb72+tUNYbr57YJeJuqQcaPTBUQrIXsID8JV5dQJFfyIG2s3G0iuN70 +W4fSRPqsSBIcyOK+2APLjkYV8qwLdh03Lyll4SZo7PCK8ItemsIK1NWhd74N49fm ++a8eyY5bgfA0FMkjY/ts4gAnYExGRoLOQRu/CgOvBlj2KQUrSNptze1rNlP32b63 +eUv1wf/ajK2TxI1pQgkeu2lM3Tyu7q7J4UVn0UY0wtZvHtw2+UBGKZB3ok6ejBy2 +HMjgLGuayGjhyUN8zRkuSvBynuI2wGhIlHklEbaQW5oFKbniXRqdzc4= +-----END CERTIFICATE----- diff --git a/internal/suites/common/pki/ca/ca.public.crt b/internal/suites/common/pki/ca/ca.public.crt new file mode 100644 index 000000000..98244a4ce --- /dev/null +++ b/internal/suites/common/pki/ca/ca.public.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIRAPl83YWFsuwIwxBRmdJyLLQwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMFsxETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEwMC4GA1UEAxMnQXV0aGVsaWEgRGV2 +ZWxvcG1lbnQgU3RhbmRhbG9uZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA2RtD74ISXHruAIIkIRTLGf5VK0b7iN5+CPW8qWjg74PCnid1 +3DOqVCZ3HSXMP0iaH5rd+WAYojQo5Z1uZ75tXgzYjt6tyXG5H1nN1fkmjkHyNORP +abOZtngVaixvlT/hsONXszFdqogXhhI4DtEo0lvxJcnOHER4QVylM4YgDMF85jXi +VD893Y6Luik9B6FXLVK9iAJ5MfvD/r8kEPLsDTl2u/Ye0q4igVDJq9tOtb2enhlz +HtipYhzzNwEzQwy3tjzP9xpQG6XE6/JW20gQaBvoRBN64DMgRlh1/8ZVyYE8v/B1 +vRVpSgmyCdDJeaRYZ6J+hO3LXBXU20CVZsM5VQIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUlrBVtyTWJQWRimLeZXr2 +mrOzy2gwDQYJKoZIhvcNAQELBQADggEBAKXjAw5v8VTM6EDiUvR8XdiikYkycAG/ +hcEt+QLkkBb72+tUNYbr57YJeJuqQcaPTBUQrIXsID8JV5dQJFfyIG2s3G0iuN70 +W4fSRPqsSBIcyOK+2APLjkYV8qwLdh03Lyll4SZo7PCK8ItemsIK1NWhd74N49fm ++a8eyY5bgfA0FMkjY/ts4gAnYExGRoLOQRu/CgOvBlj2KQUrSNptze1rNlP32b63 +eUv1wf/ajK2TxI1pQgkeu2lM3Tyu7q7J4UVn0UY0wtZvHtw2+UBGKZB3ok6ejBy2 +HMjgLGuayGjhyUN8zRkuSvBynuI2wGhIlHklEbaQW5oFKbniXRqdzc4= +-----END CERTIFICATE----- diff --git a/internal/suites/common/pki/gen.sh b/internal/suites/common/pki/gen.sh new file mode 100755 index 000000000..7331639bd --- /dev/null +++ b/internal/suites/common/pki/gen.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# go run ./cmd/authelia crypto certificate rsa generate --directory ./internal/suites/common/pki/ca -n 'Authelia Development Standalone Root CA' --not-before 'Jan 1 00:00:00 2000' --not-after 'Jan 1 00:00:00 2100' -o 'Authelia' --organizational-unit 'Development' --ca +# cp ./internal/suites/common/pki/ca/ca.public.crt ./internal/suites/common/pki/ca.public.crt +go run ./cmd/authelia crypto certificate rsa generate --directory ./internal/suites/common/pki --path.ca ./internal/suites/common/pki/ca -n '*.example.com' --sans '*.example.com,example.com' --not-before 'Jan 1 00:00:00 2000' --not-after 'Jan 1 00:00:00 2100' -o 'Authelia' --organizational-unit 'Development' --bundle +go run ./cmd/authelia crypto certificate rsa generate --directory ./internal/suites/common/pki --path.ca ./internal/suites/common/pki/ca --file.certificate public.backend.crt --file.certificate-bundle public.backend.bundle.crt --file.private-key private.backend.pem -n 'login.example.com' --sans 'login.example.com,authelia' --not-before 'Jan 1 00:00:00 2000' --not-after 'Jan 1 00:00:00 2100' -o 'Authelia' --organizational-unit 'Development' --bundle +go run ./cmd/authelia crypto certificate rsa generate --directory ./internal/suites/common/pki --path.ca ./internal/suites/common/pki/ca --file.certificate public.oidc.crt --file.certificate-bundle public.oidc.bundle.crt --file.private-key private.oidc.pem -n 'login.example.com' --sans 'login.example.com,login.example1.com,login.example2.com,login.example3,com' --not-before 'Jan 1 00:00:00 2000' --not-after 'Jan 1 00:00:00 2100' -o 'Authelia' --organizational-unit 'Development' --bundle diff --git a/internal/suites/common/pki/private.backend.pem b/internal/suites/common/pki/private.backend.pem new file mode 100644 index 000000000..5ea04fc99 --- /dev/null +++ b/internal/suites/common/pki/private.backend.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA9sWvS9YsIUlm4w3ikVUjsCg1hbwyb/BSEGpRsVG8Oox0t62R +MEIG70lPfMg2IeJZDDdFreLru3WXjHgo4ovp6bcyDtSkE7sRMhw8sATmmHNI0/Mz +ImDS4r87LP5JqYY4iS6c24j41HaKBMhTEk2oQ0fXGOP4/q6Pzu4JClaF0ZGrQbdp +dL+5aPL/0UX2Y3Ybq08vRQ8X5LUrKdEnrBeChrbfybjhOyNtllt49CmUsRYQVro5 +A2VTfroWSU7UfVUBPlI9UrATNvBmX+5fbctM6Go30dWsRXnlk4IcZHoUaA+6satK +HoWqzY9T4cQuNDSCTMe3TVT8VgYjrGWe9tQYRQIDAQABAoIBAGzgTXZFOVU6YHWf +I66BhOxs4ShvH0W6H0r0zbRRXp3qaHi90IgdKZgbnUFtyExs5GL6Y/jTXLRproKg +ZVGG755ZYHGgqf+2kmCsiq4Si3cJrkEtVQs+8uxt+Prh+rgb6wfDlBtcNITxA/YW +OGij8LA2mxV1R99+Px7KcRypjgMmx0Dp3NDoYE9Hj2VRVRLTo06WpZ7Mo9zfXtx6 +MHeJwmSerWzERvUHmrX4hG8Do3cygYnd8EartBjCIa/qambXlz7uG1ip3/v05VJi +w28VUVEERASy2W/OJjwe8QSmUQ/1HzKz+Vv/WCEvVINQr/o4TwJeZrASQ6bj1JCa +CVR8mCUCgYEA+lZhEYnmuypNhJsBwQJJIvqIIF4zrRqojax5kWAiRDJY2AYAxozG +K/WP3NWrR+k+Q+wdzad9QBddLru1ykhBSPLGbvU2cupyiSDMg6R5vL4xcdWSD1Ej +VKSUxSgP0ue7GeMsTgr8vT59UG7R6Mc6+H5ZLt6q3DsOwqs8He6NSa8CgYEA/Fqp +HhaOSz85GWPtMUdsXJC14WiKmKDaCYxiQ9QUP8l7M8xPSiarhh9xc2EZDjSOR/SU +jmDSCFUvQHE0H9xdWp69W15bxnD6Z4uSrAFWThsRdp9kRckcKLUDuumoeOL3WI3x +gS49YS5uEP08oSPpsD4P98Llw+l/UimFI4RDHksCgYEAvpC86d4BL59fTT+2URgN +VrxCnek4C2FMyDRwgpMc4q805JWFR5/oR5RyRFi/P0m15Xy7n08N0Jk4jRfFpkvk +rsRo/BRcs5P3Rp4aMWgmZ+CcwRwkSNaqP4fd3EvH5/QRgP5nPq2sgd8tA+qojjwD +jyCXgU9t36JxdQ1nAR4Une8CgYEAx+7APGFcfUtq3q3n13oh5TiVkS+1VvVhqdz6 +YYjePidQIBrH2xTGIm45AVO1eSa0b1fcdu1Immd7F1BZHsEFiW1o0sHwbklGatEO +9I3epeUWMehYll2enLXFbcn/uz7+/r7+zv0mjh8t/vHTnkuIsySInCBiz5PoVt0k +aZ45Wv8CgYAGj1ojQXs3SWQ+YY+rWrcMJ8atz9M4e7s8gEFiSp68ooi1kiVEKA2S +h4O79oksTAS1mgHiG237X6mJMkENpbPh8FR0hTcXbSyd7Ruki6h0LQnyXPGoV6KF +sojGWnJVDAtDMIT/z+tY4aeJbcicIgwS9oZ+dXQ/eQZiGKGOVexzwQ== +-----END RSA PRIVATE KEY----- diff --git a/internal/suites/common/pki/private.oidc.pem b/internal/suites/common/pki/private.oidc.pem new file mode 100644 index 000000000..ef8f5741b --- /dev/null +++ b/internal/suites/common/pki/private.oidc.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA0x+u2Kkd1VZGkj7FDwgoXQp0fx1mx5VXd2VEJN9yYTXzlNRZ +Taw8WrOcud7hsBPw3DkhbCjEzvw0Ee+DjwtSCotKbtsBwjyLCegjluPHKUvsVNYZ +m19TxYY2erx7gohdEcmCGnpWSPRUAKBasIfpM0q6LXG70o8vTuKS82Ub++Sgl1Pa +kRL/e/KBUYFZksGEMK1oiPiOtRoJF+vUhRf46ZBg3aZ/HLNvcT5TAMgRRws+K3ek +C5+h5oXFexUosj2DCxcjTbsL7C5nqfR3jwmjrBaGN8KnloEDvC84+OsN/nE2PLa5 +c1kTlRCvKd0gmRuucOKsJ6zvYf/hAqp/WCj1MQIDAQABAoIBAAOHCP3XvYbd/Sne +YJ6CrWH4lb+19wyooyB8kanoDdov85TuA1v3375IN/snDTBK9QBI+BT9jWRD9H7E +OLeAIevJLgIyKJJdPpl4xndz8NTwzs8QELd23Uh0mJ5uXcXtj1iHvGPC3YQ0iN7F +zx4Z9zyDKB8wQkofWFQCFyB39QK9ZGDW4ZstVb57fS62SuqFPW/rO2qSpsuUUwgy +Z2P2NqoqtqLIyw3qbsJCArzGoHuMCtjKDYenf8wJxORAsAGAREj71w2bQ20cMMIA +w30jgoXtEC9zS2BOb3mUBHiDOKnn4vwlNd7wiLPdZIGP75G4EkI4AHLhJQ1a5YuF +8E6V9AECgYEA1LSQVdWggvHTQnj5PHr5k7+YkL/MeIvOkLW5s0r7Lt3x45bAFaQh +XVZIXrynv62IZmTzCPwOwrXGJJieT0Ctom0XHgtp8nu7Okxk4AISRfjy7J03EXsJ +cS508IJ1B3HZepGvVwp+geJ0r9JmQ19JqZsJ7VENYoPKtYRZ9aV7CUECgYEA/hi1 +Yw2FcSBk/kXVlcWvKtohY6NISgI5U1Kp7T16ZH3anpew6WwQ3GfueVet714BdwaZ +knqiiMvaTAOG66KYHCzRBSeXOozT/0N9AfKqS1y7xW+mR2nUrAiWCL95uZpB9SxE +3gylWULV4/+wlF006tEcJ5qiXymAAYv+wEg+f/ECgYBu2XLm6J/v3esFF1p8RHJQ +p2bw+KOspt+N1sbiQ09IC26F9wg/vvuMUu0AQj0BzYPqKO3nXsSqgGS0qbzG/KQA +o+2KQNSEBCt8pFdlzm6LfMPMv9n1CDPRgi57MOGgcZqvH8FLETMAqW26O2ID9mLD +OwMfZEAfeSNpGYJwXD8UgQKBgQC+0k1+Csx47YwKzOUeqivncZL7occLFWp5oa3N +ZYsB5uYEjgSk96wd6ctUwzzzc1SET6eLMp/XPcg9p7RuR1gWaK28QkQ3C0W2ALfj +e5raJ9U366YjIV4+p+AMx8chVLBN8CXz3+lZBHFe3Ul90hWIduu+7kkcUC06fCkf +u+F78QKBgFajhBPESe344ixG/fASpsVe2Yg14SgYCeWkinOe856zABY8dkfWWBIq +KX2eq1WJXErHWDuuNPP3Jol1CouqqHseqYQ+SaOhlHdoGws70bsIvBHrtj7NiEQZ +HFLhEk+OnnG+wJ1jQ5cseA4kbTuPjEL0NNVk7OSndiuxnnDbe91R +-----END RSA PRIVATE KEY----- diff --git a/internal/suites/common/pki/private.pem b/internal/suites/common/pki/private.pem new file mode 100644 index 000000000..91bb09086 --- /dev/null +++ b/internal/suites/common/pki/private.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA0XIlKyTMa1e+vaOnT8kTJza2lacZMoykLr4NmxcQnKRe09Xd +U6IqhsaaielJe2JdkzHKQID+F/jxlNWqbHU65KSPfMtJ59De4boZ0DjuzKoiCV77 +HBj4mZg2PWEyerZU+JPLMhtIpnlbrzTeEjBpma51nXi/ELREYZsstEWNZ2RVaxwL +MKlAeDNVJotiLPMYA1rRJNa5Z3U9GPgy6l/F66NUd8klRuqJGeLDmlBu7NoRKhCX +DDk9VlATS5dBCde8rh/mGbkmNGrAa5sJFGaCZ9bDvroV31r2GdevbBY9+kXc3Vmi +eAlUarz5/B6jlV+CpwzKaGqcRSjEVMHobeb50wIDAQABAoIBAQCZSq/FefNbhScH +aSXlkUdBZhwQP/KDOshXpaYTorf3zZ3R8S9CLOhvKCCnW2T6ty3Bs6lRuJdAOGWo +BxHqu4pVGdQjBC6dShQ2pZyK94Bfrw2mSiwDjos072CTX/YwNg7OuGz5yVpM7Xmb +LFh0e5Zucm+Gx38f3LBHt+jqMBWkW0ir79kCn+pWzb5exMbr5khE1DbTLT4fu2he +1BYtq3aF3H1hxLsFGCSNBz0ocgTeRomrFH/gvn+WHBuS1GGR9gRFUqAC9ty4ej+l +yZ6n3Dt2bzNk7t/59s1FJoT4cYUQuxUnUxN+MHFIp9anDEUqO7yfw7GVFaLmj5lV +rnZNfV8RAoGBAPxc0cPO7eGvtFF26rJSacBqDvxLef4dEcRsyLHGbcLV2EhChSRy +ukHG8JZpDaG5dzFP0MRMNQ/TgrBOLypEH9QQgRDS+vx3xDQv/dtcsrQi1JTQ7K97 +Nye3dZnH5YwW7SuZPcrBqc7NnGLWwAP9gJH9BULQEYPztkLimHMfrVMHAoGBANR2 ++DMb3/TTtCI+XjWhUPMH7pgKjzP9UrkUYosRmSikAttJZYmWhy3sfDbzSm/y+G5r +aECJ3SwhdzRkUStUPi2z7L9zIdysKhXrZqxx3eiT9lX5en/CY57tTHU5U/Gco7ue +LToBLa/QVhUpQsM14GtTCx6kVt/1Ca9vMhKJhbPVAoGBAJKgY4h/bJuaeQx0KX0e +gS848CgKuoC45x/XjOwtvIxdr2Kcs7svpaSeMB9UPoVeuzA9jbDgDlx5qg9B/gly +t4OBa1wZGZcjBy7DS53uyC39psIoebyjvLIo1/1XtbmlgHu6d7qct0rfECQlXj9z +RQaNmkbtmZ+vNJC8E5OgLhZ1AoGAEMHlZ5qOOnAsJ/tFUPONP+3jOqiyjMYxLRnX +f+J+cv8knokWchimRs/9KBReTaAbShI8ocJ96EonbcFvyXwWf2JOjPcWt6H4m8v6 +SCWe/AYXisZnjAYX92P+AMzpuwfAvj6GkKmhIdnLwFWFx4HLVouxN9R8aaOZBPY/ +O8kO+5UCgYEAhyz0n7kvOqafNSgjTbXGoxTXWhgVEJYtEAd5xj5XzMeprVEY68+l +goJc6ww+Etq5/ghbtONW5d9Zy+BNcVMtZkNJr7j6XCzm0VEa6ZiKZK2HpZrkvbif +YQ3YOkW6583FXQCF67MuR2lbcDcLX9qgLT6MbAwiSL4Ow8qnLpz4CHA= +-----END RSA PRIVATE KEY----- diff --git a/internal/suites/common/pki/public.backend.bundle.crt b/internal/suites/common/pki/public.backend.bundle.crt new file mode 100644 index 000000000..fb651b78e --- /dev/null +++ b/internal/suites/common/pki/public.backend.bundle.crt @@ -0,0 +1,43 @@ +-----BEGIN CERTIFICATE----- +MIIDqzCCApOgAwIBAgIRAMThBFxQ+GQhzdihMNsQxgEwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMEUxETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEaMBgGA1UEAxMRbG9naW4uZXhhbXBs +ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD2xa9L1iwhSWbj +DeKRVSOwKDWFvDJv8FIQalGxUbw6jHS3rZEwQgbvSU98yDYh4lkMN0Wt4uu7dZeM +eCjii+nptzIO1KQTuxEyHDywBOaYc0jT8zMiYNLivzss/kmphjiJLpzbiPjUdooE +yFMSTahDR9cY4/j+ro/O7gkKVoXRkatBt2l0v7lo8v/RRfZjdhurTy9FDxfktSsp +0SesF4KGtt/JuOE7I22WW3j0KZSxFhBWujkDZVN+uhZJTtR9VQE+Uj1SsBM28GZf +7l9ty0zoajfR1axFeeWTghxkehRoD7qxq0oeharNj1PhxC40NIJMx7dNVPxWBiOs +ZZ721BhFAgMBAAGjfjB8MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEF +BQcDATAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFJawVbck1iUFkYpi3mV69pqz +s8toMCYGA1UdEQQfMB2CEWxvZ2luLmV4YW1wbGUuY29tgghhdXRoZWxpYTANBgkq +hkiG9w0BAQsFAAOCAQEALqCLqIAM8wi0M12hMs4dARRtEEAZm/ff8B18SgBuES79 +qeas6pggPRmpfM3Ogjk+t8qG02yQeAF9zqAFXaI46kQxQohKcCrfW96pX91Tvuwc +x+3xsnHWj+FoI99uUGldDjVJoePXXB7wKB3/26o7dlcWry7y04cURvD3v/v/zABw +hPB5+t+5lB+kGSZg7ChnCDBLJx8/y9JTHKbZL3kHenvPHOn+T6aRQKNmAGpGwqV4 +Eq+lB/YKU9JADarOF5FCTux677JO1XdDcnooGZmbUrKbjzO/NnbREjBRZYfqJiV6 +uTz/I2MJ7IUiYh18xT3ZL2oUbnWly+TnR9oWnwSqLg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIRAPl83YWFsuwIwxBRmdJyLLQwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMFsxETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEwMC4GA1UEAxMnQXV0aGVsaWEgRGV2 +ZWxvcG1lbnQgU3RhbmRhbG9uZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA2RtD74ISXHruAIIkIRTLGf5VK0b7iN5+CPW8qWjg74PCnid1 +3DOqVCZ3HSXMP0iaH5rd+WAYojQo5Z1uZ75tXgzYjt6tyXG5H1nN1fkmjkHyNORP +abOZtngVaixvlT/hsONXszFdqogXhhI4DtEo0lvxJcnOHER4QVylM4YgDMF85jXi +VD893Y6Luik9B6FXLVK9iAJ5MfvD/r8kEPLsDTl2u/Ye0q4igVDJq9tOtb2enhlz +HtipYhzzNwEzQwy3tjzP9xpQG6XE6/JW20gQaBvoRBN64DMgRlh1/8ZVyYE8v/B1 +vRVpSgmyCdDJeaRYZ6J+hO3LXBXU20CVZsM5VQIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUlrBVtyTWJQWRimLeZXr2 +mrOzy2gwDQYJKoZIhvcNAQELBQADggEBAKXjAw5v8VTM6EDiUvR8XdiikYkycAG/ +hcEt+QLkkBb72+tUNYbr57YJeJuqQcaPTBUQrIXsID8JV5dQJFfyIG2s3G0iuN70 +W4fSRPqsSBIcyOK+2APLjkYV8qwLdh03Lyll4SZo7PCK8ItemsIK1NWhd74N49fm ++a8eyY5bgfA0FMkjY/ts4gAnYExGRoLOQRu/CgOvBlj2KQUrSNptze1rNlP32b63 +eUv1wf/ajK2TxI1pQgkeu2lM3Tyu7q7J4UVn0UY0wtZvHtw2+UBGKZB3ok6ejBy2 +HMjgLGuayGjhyUN8zRkuSvBynuI2wGhIlHklEbaQW5oFKbniXRqdzc4= +-----END CERTIFICATE----- diff --git a/internal/suites/common/pki/public.backend.crt b/internal/suites/common/pki/public.backend.crt new file mode 100644 index 000000000..4ee5fe280 --- /dev/null +++ b/internal/suites/common/pki/public.backend.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDqzCCApOgAwIBAgIRAMThBFxQ+GQhzdihMNsQxgEwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMEUxETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEaMBgGA1UEAxMRbG9naW4uZXhhbXBs +ZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD2xa9L1iwhSWbj +DeKRVSOwKDWFvDJv8FIQalGxUbw6jHS3rZEwQgbvSU98yDYh4lkMN0Wt4uu7dZeM +eCjii+nptzIO1KQTuxEyHDywBOaYc0jT8zMiYNLivzss/kmphjiJLpzbiPjUdooE +yFMSTahDR9cY4/j+ro/O7gkKVoXRkatBt2l0v7lo8v/RRfZjdhurTy9FDxfktSsp +0SesF4KGtt/JuOE7I22WW3j0KZSxFhBWujkDZVN+uhZJTtR9VQE+Uj1SsBM28GZf +7l9ty0zoajfR1axFeeWTghxkehRoD7qxq0oeharNj1PhxC40NIJMx7dNVPxWBiOs +ZZ721BhFAgMBAAGjfjB8MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEF +BQcDATAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFJawVbck1iUFkYpi3mV69pqz +s8toMCYGA1UdEQQfMB2CEWxvZ2luLmV4YW1wbGUuY29tgghhdXRoZWxpYTANBgkq +hkiG9w0BAQsFAAOCAQEALqCLqIAM8wi0M12hMs4dARRtEEAZm/ff8B18SgBuES79 +qeas6pggPRmpfM3Ogjk+t8qG02yQeAF9zqAFXaI46kQxQohKcCrfW96pX91Tvuwc +x+3xsnHWj+FoI99uUGldDjVJoePXXB7wKB3/26o7dlcWry7y04cURvD3v/v/zABw +hPB5+t+5lB+kGSZg7ChnCDBLJx8/y9JTHKbZL3kHenvPHOn+T6aRQKNmAGpGwqV4 +Eq+lB/YKU9JADarOF5FCTux677JO1XdDcnooGZmbUrKbjzO/NnbREjBRZYfqJiV6 +uTz/I2MJ7IUiYh18xT3ZL2oUbnWly+TnR9oWnwSqLg== +-----END CERTIFICATE----- diff --git a/internal/suites/common/pki/public.bundle.crt b/internal/suites/common/pki/public.bundle.crt new file mode 100644 index 000000000..f1a59f447 --- /dev/null +++ b/internal/suites/common/pki/public.bundle.crt @@ -0,0 +1,43 @@ +-----BEGIN CERTIFICATE----- +MIIDpjCCAo6gAwIBAgIRAIVWl6KyC+LSDXvq138YbKkwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMEExETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEWMBQGA1UEAwwNKi5leGFtcGxlLmNv +bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANFyJSskzGtXvr2jp0/J +Eyc2tpWnGTKMpC6+DZsXEJykXtPV3VOiKobGmonpSXtiXZMxykCA/hf48ZTVqmx1 +OuSkj3zLSefQ3uG6GdA47syqIgle+xwY+JmYNj1hMnq2VPiTyzIbSKZ5W6803hIw +aZmudZ14vxC0RGGbLLRFjWdkVWscCzCpQHgzVSaLYizzGANa0STWuWd1PRj4Mupf +xeujVHfJJUbqiRniw5pQbuzaESoQlww5PVZQE0uXQQnXvK4f5hm5JjRqwGubCRRm +gmfWw766Fd9a9hnXr2wWPfpF3N1ZongJVGq8+fweo5VfgqcMymhqnEUoxFTB6G3m ++dMCAwEAAaN9MHswDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMB +MAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUlrBVtyTWJQWRimLeZXr2mrOzy2gw +JQYDVR0RBB4wHIINKi5leGFtcGxlLmNvbYILZXhhbXBsZS5jb20wDQYJKoZIhvcN +AQELBQADggEBAKF2dga/ZrglllTHZBqQdf//DkHpHfW/awxkOYDGKFNAosIQhn5d +cBC6fctnPugPw+97J6IaggP6ZDC8umlARWwsImxU2A6/uDoTZGdN3xrr2i0GOvho +bfz5FKJFte4MNYUii+IeuXJrzK7mZYXOS0iJwRmVs7euI2EZNQwE6ckMILRX2CmR +6CmvCrxKYhxZoo2P/tV+x5LZELHZ654rmUcug0mSJrtM6Hai94JazmYVfLWzLqvW +bTNav1MLJzqm32O9nFIBWOzq1Z77gdW/VnPwMeKBDwC/6p05p8b4kdsc+HtRq77M +5cObzCy4GcKIIgW5ovlTiLkAmWIkCUxIKMU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIRAPl83YWFsuwIwxBRmdJyLLQwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMFsxETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEwMC4GA1UEAxMnQXV0aGVsaWEgRGV2 +ZWxvcG1lbnQgU3RhbmRhbG9uZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA2RtD74ISXHruAIIkIRTLGf5VK0b7iN5+CPW8qWjg74PCnid1 +3DOqVCZ3HSXMP0iaH5rd+WAYojQo5Z1uZ75tXgzYjt6tyXG5H1nN1fkmjkHyNORP +abOZtngVaixvlT/hsONXszFdqogXhhI4DtEo0lvxJcnOHER4QVylM4YgDMF85jXi +VD893Y6Luik9B6FXLVK9iAJ5MfvD/r8kEPLsDTl2u/Ye0q4igVDJq9tOtb2enhlz +HtipYhzzNwEzQwy3tjzP9xpQG6XE6/JW20gQaBvoRBN64DMgRlh1/8ZVyYE8v/B1 +vRVpSgmyCdDJeaRYZ6J+hO3LXBXU20CVZsM5VQIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUlrBVtyTWJQWRimLeZXr2 +mrOzy2gwDQYJKoZIhvcNAQELBQADggEBAKXjAw5v8VTM6EDiUvR8XdiikYkycAG/ +hcEt+QLkkBb72+tUNYbr57YJeJuqQcaPTBUQrIXsID8JV5dQJFfyIG2s3G0iuN70 +W4fSRPqsSBIcyOK+2APLjkYV8qwLdh03Lyll4SZo7PCK8ItemsIK1NWhd74N49fm ++a8eyY5bgfA0FMkjY/ts4gAnYExGRoLOQRu/CgOvBlj2KQUrSNptze1rNlP32b63 +eUv1wf/ajK2TxI1pQgkeu2lM3Tyu7q7J4UVn0UY0wtZvHtw2+UBGKZB3ok6ejBy2 +HMjgLGuayGjhyUN8zRkuSvBynuI2wGhIlHklEbaQW5oFKbniXRqdzc4= +-----END CERTIFICATE----- diff --git a/internal/suites/common/pki/public.crt b/internal/suites/common/pki/public.crt new file mode 100644 index 000000000..bae8cd61d --- /dev/null +++ b/internal/suites/common/pki/public.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDpjCCAo6gAwIBAgIRAIVWl6KyC+LSDXvq138YbKkwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMEExETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEWMBQGA1UEAwwNKi5leGFtcGxlLmNv +bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANFyJSskzGtXvr2jp0/J +Eyc2tpWnGTKMpC6+DZsXEJykXtPV3VOiKobGmonpSXtiXZMxykCA/hf48ZTVqmx1 +OuSkj3zLSefQ3uG6GdA47syqIgle+xwY+JmYNj1hMnq2VPiTyzIbSKZ5W6803hIw +aZmudZ14vxC0RGGbLLRFjWdkVWscCzCpQHgzVSaLYizzGANa0STWuWd1PRj4Mupf +xeujVHfJJUbqiRniw5pQbuzaESoQlww5PVZQE0uXQQnXvK4f5hm5JjRqwGubCRRm +gmfWw766Fd9a9hnXr2wWPfpF3N1ZongJVGq8+fweo5VfgqcMymhqnEUoxFTB6G3m ++dMCAwEAAaN9MHswDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMB +MAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUlrBVtyTWJQWRimLeZXr2mrOzy2gw +JQYDVR0RBB4wHIINKi5leGFtcGxlLmNvbYILZXhhbXBsZS5jb20wDQYJKoZIhvcN +AQELBQADggEBAKF2dga/ZrglllTHZBqQdf//DkHpHfW/awxkOYDGKFNAosIQhn5d +cBC6fctnPugPw+97J6IaggP6ZDC8umlARWwsImxU2A6/uDoTZGdN3xrr2i0GOvho +bfz5FKJFte4MNYUii+IeuXJrzK7mZYXOS0iJwRmVs7euI2EZNQwE6ckMILRX2CmR +6CmvCrxKYhxZoo2P/tV+x5LZELHZ654rmUcug0mSJrtM6Hai94JazmYVfLWzLqvW +bTNav1MLJzqm32O9nFIBWOzq1Z77gdW/VnPwMeKBDwC/6p05p8b4kdsc+HtRq77M +5cObzCy4GcKIIgW5ovlTiLkAmWIkCUxIKMU= +-----END CERTIFICATE----- diff --git a/internal/suites/common/pki/public.oidc.bundle.crt b/internal/suites/common/pki/public.oidc.bundle.crt new file mode 100644 index 000000000..0874215dd --- /dev/null +++ b/internal/suites/common/pki/public.oidc.bundle.crt @@ -0,0 +1,44 @@ +-----BEGIN CERTIFICATE----- +MIID3zCCAsegAwIBAgIQZjmlbZI+QaeqQpApxA2eDjANBgkqhkiG9w0BAQsFADBb +MREwDwYDVQQKEwhBdXRoZWxpYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxMDAuBgNV +BAMTJ0F1dGhlbGlhIERldmVsb3BtZW50IFN0YW5kYWxvbmUgUm9vdCBDQTAgFw0w +MDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowRTERMA8GA1UEChMIQXV0aGVs +aWExFDASBgNVBAsTC0RldmVsb3BtZW50MRowGAYDVQQDExFsb2dpbi5leGFtcGxl +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANMfrtipHdVWRpI+ +xQ8IKF0KdH8dZseVV3dlRCTfcmE185TUWU2sPFqznLne4bAT8Nw5IWwoxM78NBHv +g48LUgqLSm7bAcI8iwnoI5bjxylL7FTWGZtfU8WGNnq8e4KIXRHJghp6Vkj0VACg +WrCH6TNKui1xu9KPL07ikvNlG/vkoJdT2pES/3vygVGBWZLBhDCtaIj4jrUaCRfr +1IUX+OmQYN2mfxyzb3E+UwDIEUcLPit3pAufoeaFxXsVKLI9gwsXI027C+wuZ6n0 +d48Jo6wWhjfCp5aBA7wvOPjrDf5xNjy2uXNZE5UQryndIJkbrnDirCes72H/4QKq +f1go9TECAwEAAaOBsjCBrzAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYB +BQUHAwEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSWsFW3JNYlBZGKYt5levaa +s7PLaDBZBgNVHREEUjBQghFsb2dpbi5leGFtcGxlLmNvbYISbG9naW4uZXhhbXBs +ZTEuY29tghJsb2dpbi5leGFtcGxlMi5jb22CDmxvZ2luLmV4YW1wbGUzggNjb20w +DQYJKoZIhvcNAQELBQADggEBAH46LB6fFF+5dbFhEa8rsDX17oZPVsIMHi+vhmMh +aS5IACOpmc3q/yyhZelNwB/MRzlPziQwpqwr9B5SQ9UOBvZDuv9ESXYHlVHSIGo9 ++3Ax9fvxLVpF3E62whr+d8YHjXE85UgUKaDAWYCAVB7fkY7WfyS3t8IxgJVa+oMZ +sLeI4YmheKdgRZsE+83VcNUVuGhsh3R5NKFo46tonpbdx13Eg2k3IInKAkZmTA5D +YoPfPTDbd1BOC+h2C0s+guUyoG1Fi5DzS/x8xNoRcZ7/fkdcboAXa8dlVZeqGRky +ddYggjZYnqGaD9qKFAox4EqkCYB1XwNeUPUapdvGICC7UGc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDhTCCAm2gAwIBAgIRAPl83YWFsuwIwxBRmdJyLLQwDQYJKoZIhvcNAQELBQAw +WzERMA8GA1UEChMIQXV0aGVsaWExFDASBgNVBAsTC0RldmVsb3BtZW50MTAwLgYD +VQQDEydBdXRoZWxpYSBEZXZlbG9wbWVudCBTdGFuZGFsb25lIFJvb3QgQ0EwIBcN +MDAwMTAxMDAwMDAwWhgPMjEwMDAxMDEwMDAwMDBaMFsxETAPBgNVBAoTCEF1dGhl +bGlhMRQwEgYDVQQLEwtEZXZlbG9wbWVudDEwMC4GA1UEAxMnQXV0aGVsaWEgRGV2 +ZWxvcG1lbnQgU3RhbmRhbG9uZSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA2RtD74ISXHruAIIkIRTLGf5VK0b7iN5+CPW8qWjg74PCnid1 +3DOqVCZ3HSXMP0iaH5rd+WAYojQo5Z1uZ75tXgzYjt6tyXG5H1nN1fkmjkHyNORP +abOZtngVaixvlT/hsONXszFdqogXhhI4DtEo0lvxJcnOHER4QVylM4YgDMF85jXi +VD893Y6Luik9B6FXLVK9iAJ5MfvD/r8kEPLsDTl2u/Ye0q4igVDJq9tOtb2enhlz +HtipYhzzNwEzQwy3tjzP9xpQG6XE6/JW20gQaBvoRBN64DMgRlh1/8ZVyYE8v/B1 +vRVpSgmyCdDJeaRYZ6J+hO3LXBXU20CVZsM5VQIDAQABo0IwQDAOBgNVHQ8BAf8E +BAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUlrBVtyTWJQWRimLeZXr2 +mrOzy2gwDQYJKoZIhvcNAQELBQADggEBAKXjAw5v8VTM6EDiUvR8XdiikYkycAG/ +hcEt+QLkkBb72+tUNYbr57YJeJuqQcaPTBUQrIXsID8JV5dQJFfyIG2s3G0iuN70 +W4fSRPqsSBIcyOK+2APLjkYV8qwLdh03Lyll4SZo7PCK8ItemsIK1NWhd74N49fm ++a8eyY5bgfA0FMkjY/ts4gAnYExGRoLOQRu/CgOvBlj2KQUrSNptze1rNlP32b63 +eUv1wf/ajK2TxI1pQgkeu2lM3Tyu7q7J4UVn0UY0wtZvHtw2+UBGKZB3ok6ejBy2 +HMjgLGuayGjhyUN8zRkuSvBynuI2wGhIlHklEbaQW5oFKbniXRqdzc4= +-----END CERTIFICATE----- diff --git a/internal/suites/common/pki/public.oidc.crt b/internal/suites/common/pki/public.oidc.crt new file mode 100644 index 000000000..e0a658852 --- /dev/null +++ b/internal/suites/common/pki/public.oidc.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID3zCCAsegAwIBAgIQZjmlbZI+QaeqQpApxA2eDjANBgkqhkiG9w0BAQsFADBb +MREwDwYDVQQKEwhBdXRoZWxpYTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxMDAuBgNV +BAMTJ0F1dGhlbGlhIERldmVsb3BtZW50IFN0YW5kYWxvbmUgUm9vdCBDQTAgFw0w +MDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowRTERMA8GA1UEChMIQXV0aGVs +aWExFDASBgNVBAsTC0RldmVsb3BtZW50MRowGAYDVQQDExFsb2dpbi5leGFtcGxl +LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANMfrtipHdVWRpI+ +xQ8IKF0KdH8dZseVV3dlRCTfcmE185TUWU2sPFqznLne4bAT8Nw5IWwoxM78NBHv +g48LUgqLSm7bAcI8iwnoI5bjxylL7FTWGZtfU8WGNnq8e4KIXRHJghp6Vkj0VACg +WrCH6TNKui1xu9KPL07ikvNlG/vkoJdT2pES/3vygVGBWZLBhDCtaIj4jrUaCRfr +1IUX+OmQYN2mfxyzb3E+UwDIEUcLPit3pAufoeaFxXsVKLI9gwsXI027C+wuZ6n0 +d48Jo6wWhjfCp5aBA7wvOPjrDf5xNjy2uXNZE5UQryndIJkbrnDirCes72H/4QKq +f1go9TECAwEAAaOBsjCBrzAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYB +BQUHAwEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSWsFW3JNYlBZGKYt5levaa +s7PLaDBZBgNVHREEUjBQghFsb2dpbi5leGFtcGxlLmNvbYISbG9naW4uZXhhbXBs +ZTEuY29tghJsb2dpbi5leGFtcGxlMi5jb22CDmxvZ2luLmV4YW1wbGUzggNjb20w +DQYJKoZIhvcNAQELBQADggEBAH46LB6fFF+5dbFhEa8rsDX17oZPVsIMHi+vhmMh +aS5IACOpmc3q/yyhZelNwB/MRzlPziQwpqwr9B5SQ9UOBvZDuv9ESXYHlVHSIGo9 ++3Ax9fvxLVpF3E62whr+d8YHjXE85UgUKaDAWYCAVB7fkY7WfyS3t8IxgJVa+oMZ +sLeI4YmheKdgRZsE+83VcNUVuGhsh3R5NKFo46tonpbdx13Eg2k3IInKAkZmTA5D +YoPfPTDbd1BOC+h2C0s+guUyoG1Fi5DzS/x8xNoRcZ7/fkdcboAXa8dlVZeqGRky +ddYggjZYnqGaD9qKFAox4EqkCYB1XwNeUPUapdvGICC7UGc= +-----END CERTIFICATE----- diff --git a/internal/suites/common/ssl/cert.pem b/internal/suites/common/ssl/cert.pem deleted file mode 100644 index 9fabcb421..000000000 --- a/internal/suites/common/ssl/cert.pem +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIC/jCCAeagAwIBAgIRAKF0IRxC55eee6icERVf6fgwDQYJKoZIhvcNAQELBQAw -EjEQMA4GA1UEChMHQWNtZSBDbzAgFw0yMDAzMDExMjMzMzlaGA8yMTIwMDIwNjEy -MzMzOVowEjEQMA4GA1UEChMHQWNtZSBDbzCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAMi7/oSazFIxP3rHsSLjw5XPnpMKEaVwU1zLRzW6W80BDa/ER5to -I3POGLv8lAhtUwB6WvyilrCZfs/D5lkcCxswafU/2LNppFuODnW+PG9eobgOy6Nv -f+KbnZFPRV7PB2yK6DqMyb+tbTQ7F6rEf4i6n28DI0dNyNvUCk0ld3o93LZBvC/D -/+Ulf3Vtdfsd2TckXvdA8lH4VGQJ+FIxhboTlbW8VJlk1V7FZef7+m867kOnPSaj -zv5yygrIA0XPaMAZC/SZrXHMdhvcs43fgmmTel7JD4Sy/Z/pmFlrZr5Xa8jcWycJ -ILLuPnXhgKstgq5wtDkTMZ6rpgMrKcjMKcMCAwEAAaNNMEswDgYDVR0PAQH/BAQD -AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwFgYDVR0RBA8w -DYILZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBABdWkbipzPivAvvamMmQ -5iPPeStfdr5MBxJGT9nPbeXdtS/13FJnspLBMMYOw/2AZk7VFrNjxkXc4NHZSlGz -FcGMlSO40fyirdYaQTDtS230ucLB+LzfZx37y9dKpEKVmQ151kKJjJ4hAZ47LmAQ -aFoDLRo7PA2HmnJ60GrI9wVp96uy1sQ6PcToIyMcVEQ/tLEEow+ykSeiZb9+qBKV -K9GUcu2LorhBtUMmEWs0TJElaf6eKUoG6JXM2byulDg24w5b9gC26kAlHWc5WDU5 -pAXOjlN/OYHB0sDbYViWIL390376fYIfu2N5EDKY4QjEYsWEs4Wm9HVS9IgHP/Gi -Xbo= ------END CERTIFICATE----- diff --git a/internal/suites/common/ssl/key.pem b/internal/suites/common/ssl/key.pem deleted file mode 100644 index a190f8b44..000000000 --- a/internal/suites/common/ssl/key.pem +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDIu/6EmsxSMT96 -x7Ei48OVz56TChGlcFNcy0c1ulvNAQ2vxEebaCNzzhi7/JQIbVMAelr8opawmX7P -w+ZZHAsbMGn1P9izaaRbjg51vjxvXqG4Dsujb3/im52RT0Vezwdsiug6jMm/rW00 -OxeqxH+Iup9vAyNHTcjb1ApNJXd6Pdy2Qbwvw//lJX91bXX7Hdk3JF73QPJR+FRk -CfhSMYW6E5W1vFSZZNVexWXn+/pvOu5Dpz0mo87+csoKyANFz2jAGQv0ma1xzHYb -3LON34Jpk3peyQ+Esv2f6ZhZa2a+V2vI3FsnCSCy7j514YCrLYKucLQ5EzGeq6YD -KynIzCnDAgMBAAECggEAC13R0LJvRWwyewJZvm8FQTNreEoGq8aLgeKk2p792cLo -gn5ry5n+/+y4q9RmkX+XRpynEE0omUFn09306jDTVCvOpCuEWsxtmR2XJgWqqGfE -Yoa78zo6FJvZNUQ22mKAuh23frFAL1FjsKRz96B+1EA1DPUxhzUZXZFJMAsiE9LZ -PxqPmnqXbPZsOb1XG33TAdCp6CC3H8KHICC+i4IC8prjKHGH/Q1saoNw8jmgwv0S -DelQUbEtqfmE6BmyTGxdeu4uW2Nv/wcENwySAOPKi5gstlbSKTa4IpKGp7CdquWi -stUW6pnSiEeDrDAzwC8uWdncOvnkAy2lRJkz/F9YoQKBgQDrCCqYdvGshecBBnfQ -fowxak2YBfG2jhAKPMHzrvQn5FIb+11x/jeXPEfOB6FShIzZ97JpFIpH3tcONlj3 -OVzGCTD6WdRTcltzXVneJtNog7DliNFY4YmIPmQJ+y+EvJW1rSZTZAZI1Nbijg3n -fSd0PTzvgOGHSl1//RI1mFx7MwKBgQDapIPPSF0yf1UJ6Hhzam5NHGZ9fSqV5Qs0 -Gi7uM08iDV5K7xiPglBkbN2EuMlgVnHaa5g8X897uwRSYR6nL4PRvcJiNSvnhWhe -+K3x7iHewIPYVfcghoqzuPKsXH2Zm26usdXHxBBa3IBbKtGaHnAd9h65AOUYAmAx -C2BzN90XMQKBgE2MjEFyPZunMulrsOziVG+Zm7ClhXOuvCwkj/pPp8/hzhXdgp+y -ObV09lxMuDX59l+VExEI7fd414yg8gngq3PMZJS2PxCpkvMlwhlCxk6d5ShXVHv3 -LuH9dBS3BJ7PerZPQ24QeuJdF+n45S2UZgg8jHaaF9AEAYXRgsicVSdxAoGAJI0U -K/bg/awjv0BJwqGsRt/Ukm32TJC5ysAF0HRrajnp5YULChKy9dbtQV7S63QIHIeY -L5+kw/6DvnHV+gULeGjMsjZJXK8Ev7u6+JLivqZYZDYa1iknztvAVegwZxmA61t3 -bantQgNSwerql2U3QQsAH9Vydw0On6RTP2+7WkECgYBWD3u64hBKmAxPkqPotkgI -w/jdOlv8FLHO79+oH1PtKvkzspcYaecKGDm/RNLIXLYnt0AmZEK4qQ4/zDFaR/rc -AhoxK2cKTRltMrhp1ivtFfLggVGogtYNxEnjnsD4KMvH3SjSNdt06YgtZ92++fOp -UsE8Mpf4/G5X7DmcHJHk+w== ------END PRIVATE KEY----- diff --git a/internal/suites/example/compose/authelia/Dockerfile.backend b/internal/suites/example/compose/authelia/Dockerfile.backend index f2f8578db..045f56b9b 100644 --- a/internal/suites/example/compose/authelia/Dockerfile.backend +++ b/internal/suites/example/compose/authelia/Dockerfile.backend @@ -1,4 +1,4 @@ -FROM golang:1.19.5-alpine +FROM golang:1.20.0-alpine ARG USER_ID ARG GROUP_ID diff --git a/internal/suites/example/compose/caddy/Dockerfile b/internal/suites/example/compose/caddy/Dockerfile index 3b5cb28e4..215f40b54 100644 --- a/internal/suites/example/compose/caddy/Dockerfile +++ b/internal/suites/example/compose/caddy/Dockerfile @@ -1,7 +1,7 @@ -FROM caddy:2.6.2-builder AS builder +FROM caddy:2.6.3-builder AS builder RUN xcaddy build fix-empty-copy-headers -FROM caddy:2.6.2 +FROM caddy:2.6.3 COPY --from=builder /usr/bin/caddy /usr/bin/caddy diff --git a/internal/suites/example/compose/caddy/docker-compose.yml b/internal/suites/example/compose/caddy/docker-compose.yml index fefa0b7f3..c8578f3a1 100644 --- a/internal/suites/example/compose/caddy/docker-compose.yml +++ b/internal/suites/example/compose/caddy/docker-compose.yml @@ -3,7 +3,7 @@ version: '3' services: caddy: # build: ./example/compose/caddy/ # used for debugging - image: caddy:2.6.2-alpine + image: caddy:2.6.3-alpine volumes: - ./example/compose/caddy/Caddyfile:/etc/caddy/Caddyfile networks: diff --git a/internal/suites/example/compose/envoy/docker-compose.yml b/internal/suites/example/compose/envoy/docker-compose.yml index 807f99967..4941537df 100644 --- a/internal/suites/example/compose/envoy/docker-compose.yml +++ b/internal/suites/example/compose/envoy/docker-compose.yml @@ -2,10 +2,12 @@ version: '3' services: envoy: - image: envoyproxy/envoy:v1.25.0 + image: envoyproxy/envoy:v1.25.1 volumes: - ./example/compose/envoy/envoy.yaml:/etc/envoy/envoy.yaml - - ./example/compose/nginx/portal/ssl:/etc/ssl + - ./common/pki:/pki + ports: + - 9901:9901 networks: authelianet: ipv4_address: 192.168.240.100 diff --git a/internal/suites/example/compose/envoy/envoy.yaml b/internal/suites/example/compose/envoy/envoy.yaml index f43d28649..7af1e2e90 100644 --- a/internal/suites/example/compose/envoy/envoy.yaml +++ b/internal/suites/example/compose/envoy/envoy.yaml @@ -1,4 +1,10 @@ --- +# Enable the admin interface at http://192.168.240.100:9901/ for debugging. +admin: + address: + socket_address: + address: 0.0.0.0 + port_value: 9901 static_resources: listeners: - name: listener_0 @@ -78,6 +84,13 @@ static_resources: - name: envoy.filters.http.ext_authz typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz + transport_api_version: v3 + allowed_headers: + patterns: + - exact: authorization + - exact: proxy-authorization + - exact: accept + - exact: cookie http_service: path_prefix: /api/authz/ext-authz/ server_uri: @@ -85,18 +98,16 @@ static_resources: cluster: authelia-backend timeout: 0.25s authorization_request: - allowed_headers: - patterns: - - exact: accept - - exact: cookie - - exact: proxy-authorization headers_to_add: - key: X-Forwarded-Proto value: '%REQ(:SCHEME)%' authorization_response: allowed_upstream_headers: patterns: + - exact: authorization + - exact: proxy-authorization - prefix: remote- + - prefix: authelia- allowed_client_headers: patterns: - exact: set-cookie @@ -114,9 +125,9 @@ static_resources: common_tls_context: tls_certificates: - certificate_chain: - filename: /etc/ssl/server.cert + filename: /pki/public.bundle.crt private_key: - filename: /etc/ssl/server.key + filename: /pki/private.pem clusters: - name: authelia-frontend transport_socket_matches: @@ -135,9 +146,9 @@ static_resources: typed_config: "@type": type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer connect_timeout: 0.25s - type: STRICT_DNS + type: strict_dns dns_lookup_family: V4_ONLY - lb_policy: ROUND_ROBIN + lb_policy: round_robin load_assignment: cluster_name: authelia-frontend endpoints: @@ -168,9 +179,9 @@ static_resources: enableTLS: true - name: authelia-backend connect_timeout: 0.25s - type: LOGICAL_DNS - dns_lookup_family: V4_ONLY - lb_policy: ROUND_ROBIN + type: logical_dns + dns_lookup_family: v4_only + lb_policy: round_robin load_assignment: cluster_name: authelia-backend endpoints: @@ -187,9 +198,9 @@ static_resources: common_tls_context: {} - name: smtp connect_timeout: 0.25s - type: LOGICAL_DNS - dns_lookup_family: V4_ONLY - lb_policy: ROUND_ROBIN + type: logical_dns + dns_lookup_family: v4_only + lb_policy: round_robin load_assignment: cluster_name: smtp endpoints: @@ -201,9 +212,9 @@ static_resources: port_value: 1080 - name: httpbin connect_timeout: 0.25s - type: LOGICAL_DNS - dns_lookup_family: V4_ONLY - lb_policy: ROUND_ROBIN + type: logical_dns + dns_lookup_family: v4_only + lb_policy: round_robin load_assignment: cluster_name: httpbin endpoints: @@ -215,9 +226,9 @@ static_resources: port_value: 8000 - name: nginx-backend connect_timeout: 0.25s - type: LOGICAL_DNS - dns_lookup_family: V4_ONLY - lb_policy: ROUND_ROBIN + type: logical_dns + dns_lookup_family: v4_only + lb_policy: round_robin load_assignment: cluster_name: nginx-backend endpoints: @@ -227,4 +238,15 @@ static_resources: socket_address: address: nginx-backend port_value: 80 +layered_runtime: + layers: + - name: static_layer_0 + static_layer: + envoy: + resource_limits: + listener: + example_listener_name: + connection_limit: 10000 + overload: + global_downstream_max_connections: 50000 ... diff --git a/internal/suites/example/compose/haproxy/haproxy.cfg b/internal/suites/example/compose/haproxy/haproxy.cfg index 68e16148a..529920b8a 100644 --- a/internal/suites/example/compose/haproxy/haproxy.cfg +++ b/internal/suites/example/compose/haproxy/haproxy.cfg @@ -82,15 +82,28 @@ backend fe_authelia server authelia-backend authelia-backend:9091 check backup resolvers docker ssl verify none backend be_httpbin + ## Pass the special authorization response headers to the protected application. + acl authorization_exist var(req.auth_response_header.authorization) -m found + acl proxy_authorization_exist var(req.auth_response_header.proxy_authorization) -m found + + http-request set-header Authorization %[var(req.auth_response_header.authorization)] if authorization_exist + http-request set-header Proxy-Authorization %[var(req.auth_response_header.proxy_authorization)] if proxy_authorization_exist + + ## Pass the special metadata response headers to the protected application. acl remote_user_exist var(req.auth_response_header.remote_user) -m found acl remote_groups_exist var(req.auth_response_header.remote_groups) -m found acl remote_name_exist var(req.auth_response_header.remote_name) -m found acl remote_email_exist var(req.auth_response_header.remote_email) -m found + http-request set-header Remote-User %[var(req.auth_response_header.remote_user)] if remote_user_exist http-request set-header Remote-Groups %[var(req.auth_response_header.remote_groups)] if remote_groups_exist http-request set-header Remote-Name %[var(req.auth_response_header.remote_name)] if remote_name_exist http-request set-header Remote-Email %[var(req.auth_response_header.remote_email)] if remote_email_exist + ## Pass the Set-Cookie response headers to the user. + acl set_cookie_exist var(req.auth_response_header.set_cookie) -m found + http-response set-header Set-Cookie %[var(req.auth_response_header.set_cookie)] if set_cookie_exist + server httpbin-backend httpbin:8000 resolvers docker backend be_mail diff --git a/internal/suites/example/compose/haproxy/http.lua b/internal/suites/example/compose/haproxy/http.lua index 44809c8ed..064eb5dda 100644 --- a/internal/suites/example/compose/haproxy/http.lua +++ b/internal/suites/example/compose/haproxy/http.lua @@ -752,9 +752,9 @@ M.base64 = {} --- URL safe base64 encoder -- -- Padding ('=') is omited, as permited per RFC --- https://tools.ietf.org/html/rfc4648 +-- https://datatracker.ietf.org/doc/html/rfc4648 -- in order to follow JSON Web Signature RFC --- https://tools.ietf.org/html/rfc7515 +-- https://datatracker.ietf.org/doc/html/rfc7515 -- -- @param s String (can be binary data) to encode -- @param enc Function which implements base64 encoder (e.g. HAProxy base64 fetch) diff --git a/internal/suites/example/compose/httpbin/docker-compose.yml b/internal/suites/example/compose/httpbin/docker-compose.yml index 15683d340..f1dffa0d4 100644 --- a/internal/suites/example/compose/httpbin/docker-compose.yml +++ b/internal/suites/example/compose/httpbin/docker-compose.yml @@ -12,7 +12,7 @@ services: - 'traefik.frontend.auth.forward.address=https://authelia-backend:9091/api/authz/forward-auth' - 'traefik.frontend.auth.forward.tls.insecureSkipVerify=true' - 'traefik.frontend.auth.forward.trustForwardHeader=true' - - 'traefik.frontend.auth.forward.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email' + - 'traefik.frontend.auth.forward.authResponseHeaders=Authorization,Proxy-Authorization,Remote-User,Remote-Groups,Remote-Email,Remote-Name' # Traefik 2.x - 'traefik.enable=true' - 'traefik.http.routers.httpbin.rule=Host(`public.example.com`) && Path(`/headers`)' diff --git a/internal/suites/example/compose/k3d/docker-compose.yml b/internal/suites/example/compose/k3d/docker-compose.yml index 0f463249b..db82d3ba4 100644 --- a/internal/suites/example/compose/k3d/docker-compose.yml +++ b/internal/suites/example/compose/k3d/docker-compose.yml @@ -2,11 +2,11 @@ version: '3' services: k3d: - image: ghcr.io/k3d-io/k3d:5.4.6-dind + image: ghcr.io/k3d-io/k3d:5.4.7-dind volumes: - './example/kube:/authelia' - './example/kube/authelia/configs/configuration.yml:/configmaps/authelia/configuration.yml' - - './common/ssl:/configmaps/authelia/ssl' + - './common/pki:/configmaps/authelia/ssl' - './example/compose/ldap/ldif:/configmaps/ldap' - './example/compose/nginx/backend:/configmaps/nginx-backend' privileged: true diff --git a/internal/suites/example/compose/mariadb/docker-compose.yml b/internal/suites/example/compose/mariadb/docker-compose.yml index 114a75325..5cb80ed0a 100644 --- a/internal/suites/example/compose/mariadb/docker-compose.yml +++ b/internal/suites/example/compose/mariadb/docker-compose.yml @@ -2,7 +2,7 @@ version: '3' services: mariadb: - image: mariadb:10.10.2 + image: mariadb:10.10.3 environment: - MYSQL_ROOT_PASSWORD=rootpassword - MYSQL_USER=admin diff --git a/internal/suites/example/compose/nginx/backend/docker-compose.yml b/internal/suites/example/compose/nginx/backend/docker-compose.yml index e71ed8dbd..b6abe101b 100644 --- a/internal/suites/example/compose/nginx/backend/docker-compose.yml +++ b/internal/suites/example/compose/nginx/backend/docker-compose.yml @@ -9,7 +9,7 @@ services: - 'traefik.frontend.auth.forward.address=https://authelia-backend:9091/api/authz/forward-auth' # yamllint disable-line rule:line-length - 'traefik.frontend.auth.forward.tls.insecureSkipVerify=true' - 'traefik.frontend.auth.forward.trustForwardHeader=true' - - 'traefik.frontend.auth.forward.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email' + - 'traefik.frontend.auth.forward.authResponseHeaders=Authorization,Proxy-Authorization,Remote-User,Remote-Groups,Remote-Email,Remote-Name' # Traefik 2.x - 'traefik.enable=true' - 'traefik.http.routers.protectedapps.rule=Host(`home.example.com`,`public.example.com`,`secure.example.com`,`admin.example.com`,`singlefactor.example.com`)' # yamllint disable-line rule:line-length diff --git a/internal/suites/example/compose/nginx/portal/docker-compose.yml b/internal/suites/example/compose/nginx/portal/docker-compose.yml index 517e192fb..4ff9dc3d9 100644 --- a/internal/suites/example/compose/nginx/portal/docker-compose.yml +++ b/internal/suites/example/compose/nginx/portal/docker-compose.yml @@ -5,7 +5,7 @@ services: image: nginx:alpine volumes: - ./example/compose/nginx/portal/nginx.conf:/etc/nginx/nginx.conf - - ./example/compose/nginx/portal/ssl:/etc/ssl + - ./common/pki:/pki networks: authelianet: aliases: diff --git a/internal/suites/example/compose/nginx/portal/nginx.conf b/internal/suites/example/compose/nginx/portal/nginx.conf index 0af06dfa4..3d97aeebc 100644 --- a/internal/suites/example/compose/nginx/portal/nginx.conf +++ b/internal/suites/example/compose/nginx/portal/nginx.conf @@ -16,8 +16,8 @@ http { set $backend_endpoint https://authelia-backend:9091; set $metrics_endpoint http://authelia-backend:9959; - ssl_certificate /etc/ssl/server.cert; - ssl_certificate_key /etc/ssl/server.key; + ssl_certificate /pki/public.bundle.crt; + ssl_certificate_key /pki/private.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "SAMEORIGIN"; @@ -128,8 +128,8 @@ http { resolver 127.0.0.11 ipv6=off; set $upstream_endpoint http://nginx-backend; - ssl_certificate /etc/ssl/server.cert; - ssl_certificate_key /etc/ssl/server.key; + ssl_certificate /pki/public.bundle.crt; + ssl_certificate_key /pki/private.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "SAMEORIGIN"; @@ -148,12 +148,12 @@ http { server_name ~^(public|admin|secure|dev|singlefactor|mx[1-2])(\.mail)?\.(?example([0-9])*\.com)$; resolver 127.0.0.11 ipv6=off; - set $upstream_verify https://authelia-backend:9091/api/authz/auth-request; + set $upstream_authelia https://authelia-backend:9091/api/authz/auth-request; set $upstream_endpoint http://nginx-backend; set $upstream_headers http://httpbin:8000/headers; - ssl_certificate /etc/ssl/server.cert; - ssl_certificate_key /etc/ssl/server.key; + ssl_certificate /pki/public.bundle.crt; + ssl_certificate_key /pki/private.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "SAMEORIGIN"; @@ -163,22 +163,38 @@ http { # Reverse proxy to the backend. It is protected by Authelia by forwarding authorization checks # to the virtual endpoint introduced by nginx and declared in the next block. location / { - auth_request /auth_verify; + ## Send a subrequest to Authelia to verify if the user is authenticated and has permission to access the resource. + auth_request /authelia; - auth_request_set $user $upstream_http_remote_user; - proxy_set_header Remote-User $user; + ## Set the $target_url variable based on the original request. + set $target_url $scheme://$http_host$request_uri; - auth_request_set $groups $upstream_http_remote_groups; - proxy_set_header Remote-Groups $groups; + ## Save the upstream authorization response headers from Authelia to variables. + auth_request_set $authorization $upstream_http_authorization; + auth_request_set $proxy_authorization $upstream_http_proxy_authorization; - auth_request_set $name $upstream_http_remote_name; - proxy_set_header Remote-Name $name; + ## Inject the authorization response headers from the variables into the request made to the backend. + proxy_set_header Authorization $authorization; + proxy_set_header Proxy-Authorization $proxy_authorization; - auth_request_set $email $upstream_http_remote_email; - proxy_set_header Remote-Email $email; + ## Save the upstream metadata response headers from Authelia to variables. + auth_request_set $user $upstream_http_remote_user; + auth_request_set $groups $upstream_http_remote_groups; + auth_request_set $name $upstream_http_remote_name; + auth_request_set $email $upstream_http_remote_email; - # Route the request to the correct virtual host in the backend. - proxy_set_header Host $http_host; + ## Inject the metadata response headers from the variables into the request made to the backend. + proxy_set_header Remote-User $user; + proxy_set_header Remote-Groups $groups; + proxy_set_header Remote-Email $email; + proxy_set_header Remote-Name $name; + + ## Include the Set-Cookie header if present. + auth_request_set $cookie $upstream_http_set_cookie; + add_header Set-Cookie $cookie; + + ## If the subreqest returns 200 pass to the backend, if the subrequest returns 401 redirect to the portal. + error_page 401 =302 https://login.$basedomain:8080/?rd=$target_url; # Authelia relies on Proxy-Authorization header to authenticate in basic auth. # but for the sake of simplicity (because Authorization in supported in most @@ -186,22 +202,17 @@ http { # Proxy-Authorization before sending it to Authelia. proxy_set_header Proxy-Authorization $http_authorization; - # mitigate HTTPoxy Vulnerability - # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ - proxy_set_header Proxy ""; - - # Set the `target_url` variable based on the request. It will be used to build the portal - # URL with the correct redirection parameter. - set $target_url $scheme://$http_host$request_uri; - error_page 401 =302 https://login.$basedomain:8080/?rd=$target_url; + # Route the request to the correct virtual host in the backend. + proxy_set_header Host $http_host; proxy_pass $upstream_endpoint; } # Virtual endpoint forwarding requests to Authelia server. - location /auth_verify { - internal; - proxy_set_header X-Real-IP $remote_addr; + location /authelia { + ## Essential Proxy Configuration + internal; + proxy_pass $upstream_authelia; # Provide either X-Original-URL and X-Forwarded-Proto or # X-Forwarded-Proto, X-Forwarded-Host and X-Forwarded-URI or both. @@ -209,39 +220,67 @@ http { # # X-Forwarded-Proto is mandatory since Authelia uses the "trust proxy" option. # See https://expressjs.com/en/guide/behind-proxies.html - proxy_set_header X-Original-Method $request_method; - proxy_set_header X-Original-URL $scheme://$http_host$request_uri; - - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Original-Method $request_method; + proxy_set_header X-Original-URL $scheme://$http_host$request_uri; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Content-Length ""; + proxy_set_header Connection ""; # Authelia can receive Proxy-Authorization to authenticate however most of the clients # support Authorization instead. Therefore we rewrite Authorization into Proxy-Authorization. proxy_set_header Proxy-Authorization $http_authorization; - proxy_pass_request_body off; - proxy_set_header Content-Length ""; + ## Basic Proxy Configuration + proxy_pass_request_body off; + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; # Timeout if the real server is dead + proxy_redirect http:// $scheme://; + proxy_http_version 1.1; + proxy_cache_bypass $cookie_session; + proxy_no_cache $cookie_session; + proxy_buffers 4 32k; + client_body_buffer_size 128k; - proxy_pass $upstream_verify; + ## Advanced Proxy Configuration + send_timeout 5m; + proxy_read_timeout 240; + proxy_send_timeout 240; + proxy_connect_timeout 240; } # Used by suites to test the forwarded users and groups headers produced by Authelia. location /headers { - auth_request /auth_verify; + ## Send a subrequest to Authelia to verify if the user is authenticated and has permission to access the resource. + auth_request /authelia; - auth_request_set $user $upstream_http_remote_user; - proxy_set_header Remote-User $user; + ## Set the $target_url variable based on the original request. + set $target_url $scheme://$http_host$request_uri; - auth_request_set $groups $upstream_http_remote_groups; - proxy_set_header Remote-Groups $groups; + ## Save the upstream authorization response headers from Authelia to variables. + auth_request_set $authorization $upstream_http_authorization; + auth_request_set $proxy_authorization $upstream_http_proxy_authorization; - auth_request_set $name $upstream_http_remote_name; - proxy_set_header Remote-Name $name; + ## Inject the authorization response headers from the variables into the request made to the backend. + proxy_set_header Authorization $authorization; + proxy_set_header Proxy-Authorization $proxy_authorization; - auth_request_set $email $upstream_http_remote_email; - proxy_set_header Remote-Email $email; + ## Save the upstream metadata response headers from Authelia to variables. + auth_request_set $user $upstream_http_remote_user; + auth_request_set $groups $upstream_http_remote_groups; + auth_request_set $name $upstream_http_remote_name; + auth_request_set $email $upstream_http_remote_email; - set $target_url $scheme://$http_host$request_uri; - error_page 401 =302 https://login.$basedomain:8080/?rd=$target_url; + ## Inject the metadata response headers from the variables into the request made to the backend. + proxy_set_header Remote-User $user; + proxy_set_header Remote-Groups $groups; + proxy_set_header Remote-Email $email; + proxy_set_header Remote-Name $name; + + ## Include the Set-Cookie header if present. + auth_request_set $cookie $upstream_http_set_cookie; + add_header Set-Cookie $cookie; + + ## If the subreqest returns 200 pass to the backend, if the subrequest returns 401 redirect to the portal. + error_page 401 =302 https://login.$basedomain:8080/?rd=$target_url; proxy_pass $upstream_headers; } @@ -253,11 +292,11 @@ http { server_name ~^oidc(-public)?\.(?example([0-9])*\.com)$; resolver 127.0.0.11 ipv6=off; - set $upstream_verify https://authelia-backend:9091/api/authz/auth-request; + set $upstream_authelia https://authelia-backend:9091/api/authz/auth-request; set $upstream_endpoint http://oidc-client:8080; - ssl_certificate /etc/ssl/server.cert; - ssl_certificate_key /etc/ssl/server.key; + ssl_certificate /pki/public.bundle.crt; + ssl_certificate_key /pki/private.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "SAMEORIGIN"; @@ -267,27 +306,50 @@ http { # Reverse proxy to the backend. It is protected by Authelia by forwarding authorization checks # to the virtual endpoint introduced by nginx and declared in the next block. location / { - auth_request /auth_verify; + ## Send a subrequest to Authelia to verify if the user is authenticated and has permission to access the resource. + auth_request /authelia; + + ## Set the $target_url variable based on the original request. + set $target_url $scheme://$http_host$request_uri; + + ## Save the upstream authorization response headers from Authelia to variables. + auth_request_set $authorization $upstream_http_authorization; + auth_request_set $proxy_authorization $upstream_http_proxy_authorization; + + ## Inject the authorization response headers from the variables into the request made to the backend. + proxy_set_header Authorization $authorization; + proxy_set_header Proxy-Authorization $proxy_authorization; + + ## Save the upstream metadata response headers from Authelia to variables. + auth_request_set $user $upstream_http_remote_user; + auth_request_set $groups $upstream_http_remote_groups; + auth_request_set $name $upstream_http_remote_name; + auth_request_set $email $upstream_http_remote_email; + + ## Inject the metadata response headers from the variables into the request made to the backend. + proxy_set_header Remote-User $user; + proxy_set_header Remote-Groups $groups; + proxy_set_header Remote-Email $email; + proxy_set_header Remote-Name $name; + + ## Include the Set-Cookie header if present. + auth_request_set $cookie $upstream_http_set_cookie; + add_header Set-Cookie $cookie; + + ## If the subreqest returns 200 pass to the backend, if the subrequest returns 401 redirect to the portal. + error_page 401 =302 https://login.$basedomain:8080/?rd=$target_url; # Route the request to the correct virtual host in the backend. proxy_set_header Host $http_host; - # mitigate HTTPoxy Vulnerability - # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ - proxy_set_header Proxy ""; - - # Set the `target_url` variable based on the request. It will be used to build the portal - # URL with the correct redirection parameter. - set $target_url $scheme://$http_host$request_uri; - error_page 401 =302 https://login.$basedomain:8080/?rd=$target_url; - proxy_pass $upstream_endpoint; } # Virtual endpoint forwarding requests to Authelia server. - location /auth_verify { - internal; - proxy_set_header X-Real-IP $remote_addr; + location /authelia { + ## Essential Proxy Configuration + internal; + proxy_pass $upstream_authelia; # Provide either X-Original-URL and X-Forwarded-Proto or # X-Forwarded-Proto, X-Forwarded-Host and X-Forwarded-URI or both. @@ -295,19 +357,31 @@ http { # # X-Forwarded-Proto is mandatory since Authelia uses the "trust proxy" option. # See https://expressjs.com/en/guide/behind-proxies.html - proxy_set_header X-Original-Method $request_method; - proxy_set_header X-Original-URL $scheme://$http_host$request_uri; - - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Original-Method $request_method; + proxy_set_header X-Original-URL $scheme://$http_host$request_uri; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Content-Length ""; + proxy_set_header Connection ""; # Authelia can receive Proxy-Authorization to authenticate however most of the clients # support Authorization instead. Therefore we rewrite Authorization into Proxy-Authorization. proxy_set_header Proxy-Authorization $http_authorization; - proxy_pass_request_body off; - proxy_set_header Content-Length ""; + ## Basic Proxy Configuration + proxy_pass_request_body off; + proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; # Timeout if the real server is dead + proxy_redirect http:// $scheme://; + proxy_http_version 1.1; + proxy_cache_bypass $cookie_session; + proxy_no_cache $cookie_session; + proxy_buffers 4 32k; + client_body_buffer_size 128k; - proxy_pass $upstream_verify; + ## Advanced Proxy Configuration + send_timeout 5m; + proxy_read_timeout 240; + proxy_send_timeout 240; + proxy_connect_timeout 240; } } @@ -319,8 +393,8 @@ http { resolver 127.0.0.11 ipv6=off; set $upstream_endpoint http://smtp:1080; - ssl_certificate /etc/ssl/server.cert; - ssl_certificate_key /etc/ssl/server.key; + ssl_certificate /pki/public.bundle.crt; + ssl_certificate_key /pki/private.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "SAMEORIGIN"; @@ -341,8 +415,8 @@ http { resolver 127.0.0.11 ipv6=off; set $upstream_endpoint http://duo-api:3000; - ssl_certificate /etc/ssl/server.cert; - ssl_certificate_key /etc/ssl/server.key; + ssl_certificate /pki/public.bundle.crt; + ssl_certificate_key /pki/private.pem; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "SAMEORIGIN"; @@ -360,8 +434,8 @@ http { listen 8080 ssl; server_name _; - ssl_certificate /etc/ssl/server.cert; - ssl_certificate_key /etc/ssl/server.key; + ssl_certificate /pki/public.bundle.crt; + ssl_certificate_key /pki/private.pem; return 301 https://home.example.com:8080/; } diff --git a/internal/suites/example/compose/nginx/portal/ssl/server.cert b/internal/suites/example/compose/nginx/portal/ssl/server.cert deleted file mode 100644 index 0fd2ff140..000000000 --- a/internal/suites/example/compose/nginx/portal/ssl/server.cert +++ /dev/null @@ -1,19 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDEzCCAfugAwIBAgIUJZXxXExVQPJhc8TnlD+uAAYHlvwwDQYJKoZIhvcNAQEL -BQAwGDEWMBQGA1UEAwwNKi5leGFtcGxlLmNvbTAgFw0xOTA5MjYyMDAwMTBaGA8y -MTE5MDkwMjIwMDAxMFowGDEWMBQGA1UEAwwNKi5leGFtcGxlLmNvbTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3DFTAdrxG6iOj5UjSeB5lMjMQQyeYm -OxUvswwwBzmQYPUt0inAJ9QmXJ8i9Fbye8HHYUeqE5zsEfeHir81MiWfhi9oUzJt -u3bmxGLDXYaApejd18hBKITX6MYogmK2lWrl/F9zPYxc2xM/fqWnGg2xwdrMmida -hZjDUfh0rtoz8zqOzJaiiDoFMwNO+NTGmDbeOwBFYOF1OTkS3aJWwJCLZmINUG8h -Z3YPR+SL8CpGGl0xhJYAwXD1AtMlYwAteTILqrqvo2XkGsvuj0mx0w/D0DDpC48g -oSNsRIVTW3Ql3uu+kXDFtkf4I63Ctt85rZk1kX3QtYmS0pRzvmyY/b0CAwEAAaNT -MFEwHQYDVR0OBBYEFMTozK79Kp813+8TstjXRFw1MTE5MB8GA1UdIwQYMBaAFMTo -zK79Kp813+8TstjXRFw1MTE5MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL -BQADggEBALf1bJf3qF3m54+q98E6lSE+34yi/rVdzB9reAW1QzvvqdJRtsfjt39R -SznsbmrvCfK4SLyOj9Uhd8Z6bASPPNsUux1XAGN4AqaGmlYI8b7j3LhKCdRBZQ0I -zWgPhocyWwp5VkFe68zR06NHme/2B6eBRFsdd/69DIOv9YnEGUHk3A/9v1zvolt9 -krW57Oz63zWGYXmtPPTD8of/Ya6NKqwonVx1MUQ5QzqH3WySYhRsIYqwUEXm9jt5 -GEM3Nx0phEltaOLXa71nqS/Rhg/5Kod0cFaNoSKb6N93I8bqKKTK0m5wMJ5Fisrm -Pw5+AIar7RT5gHU2DD2/OTb9bXXww8I= ------END CERTIFICATE----- diff --git a/internal/suites/example/compose/nginx/portal/ssl/server.key b/internal/suites/example/compose/nginx/portal/ssl/server.key deleted file mode 100644 index 268a2a1c3..000000000 --- a/internal/suites/example/compose/nginx/portal/ssl/server.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAvcMVMB2vEbqI6PlSNJ4HmUyMxBDJ5iY7FS+zDDAHOZBg9S3S -KcAn1CZcnyL0VvJ7wcdhR6oTnOwR94eKvzUyJZ+GL2hTMm27dubEYsNdhoCl6N3X -yEEohNfoxiiCYraVauX8X3M9jFzbEz9+pacaDbHB2syaJ1qFmMNR+HSu2jPzOo7M -lqKIOgUzA0741MaYNt47AEVg4XU5ORLdolbAkItmYg1QbyFndg9H5IvwKkYaXTGE -lgDBcPUC0yVjAC15Mguquq+jZeQay+6PSbHTD8PQMOkLjyChI2xEhVNbdCXe676R -cMW2R/gjrcK23zmtmTWRfdC1iZLSlHO+bJj9vQIDAQABAoIBAEZvkP/JJOCJwqPn -V3IcbmmilmV4bdi1vByDFgyiDyx4wOSA24+PubjvfFW9XcCgRPuKjDtTj/AhWBHv -B7stfa2lZuNV7/u562mZArA+IAr62Zp0LdIxDV8x3T8gbjVB3HhPYbv0RJZDKTYd -zV6jhfIrVu9mHpoY6ZnodhapCPYIyk/d49KBIHZuAc25CUjMXgTeaVtf0c996036 -UxW6ef33wAOJAvW0RCvbXAJfmBeEq2qQlkjTIlpYx71fhZWexHifi8Ouv3Zonc+1 -/P2Adq5uzYVBT92f9RKHg9QxxNzVrLjSMaxyvUtWQCAQfW0tFIRdqBGsHYsQrFtI -F4yzv8ECgYEA7ntpyN9HD9Z9lYQzPCR73sFCLM+ID99aVij0wHuxK97bkSyyvkLd -7MyTaym3lg1UEqWNWBCLvFULZx7F0Ah6qCzD4ymm3Bj/ADpWWPgljBI0AFml+HHs -hcATmXUrj5QbLyhiP2gmJjajp1o/rgATx6ED66seSynD6JOH8wUhhZUCgYEAy7OA -06PF8GfseNsTqlDjNF0K7lOqd21S0prdwrsJLiVzUlfMM25MLE0XLDUutCnRheeh -IlcuDoBsVTxz6rkvFGD74N+pgXlN4CicsBq5ofK060PbqCQhSII3fmHobrZ9Cr75 -HmBjAxHx998SKaAAGbBbcYGUAp521i1pH5CEPYkCgYEAkUd1Zf0+2RMdZhwm6hh/ -rW+l1I6IoMK70YkZsLipccRNld7Y9LbfYwYtODcts6di9AkOVfueZJiaXbONZfIE -Zrb+jkAteh9wGL9xIrnohbABJcV3Kiaco84jInUSmGDtPokncOENfHIEuEpuSJ2b -bx1TuhmAVuGWivR0+ULC7RECgYEAgS0cDRpWc9Xzh9Cl7+PLsXEvdWNpPsL9OsEq -0Ep7z9+/+f/jZtoTRCS/BTHUpDvAuwHglT5j3p5iFMt5VuiIiovWLwynGYwrbnNS -qfrIrYKUaH1n1oDS+oBZYLQGCe9/7EifAjxtjYzbvSyg//SPG7tSwfBCREbpZXj2 -qSWkNsECgYA/mCDzCTlrrWPuiepo6kTmN+4TnFA+hJI6NccDVQ+jvbqEdoJ4SW4L -zqfZSZRFJMNpSgIqkQNRPJqMP0jQ5KRtJrjMWBnYxktwKz9fDg2R2MxdFgMF2LH2 -HEMMhFHlv8NDjVOXh1KwRoltNGVWYsSrD9wKU9GhRCEfmNCGrvBcEg== ------END RSA PRIVATE KEY----- diff --git a/internal/suites/example/compose/redis/templates/master.conf b/internal/suites/example/compose/redis/templates/master.conf index 59b22cc1b..50e985d0d 100644 --- a/internal/suites/example/compose/redis/templates/master.conf +++ b/internal/suites/example/compose/redis/templates/master.conf @@ -1617,7 +1617,7 @@ notify-keyspace-events "" ############################### GOPHER SERVER ################################# # Redis contains an implementation of the Gopher protocol, as specified in -# the RFC 1436 (https://www.ietf.org/rfc/rfc1436.txt). +# the RFC 1436 (https://datatracker.ietf.org/doc/html/rfc1436). # # The Gopher protocol was very popular in the late '90s. It is an alternative # to the web, and the implementation both server and client side is so simple diff --git a/internal/suites/example/compose/redis/templates/slave.conf b/internal/suites/example/compose/redis/templates/slave.conf index a65aa2bb3..47aa8338f 100644 --- a/internal/suites/example/compose/redis/templates/slave.conf +++ b/internal/suites/example/compose/redis/templates/slave.conf @@ -1617,7 +1617,7 @@ notify-keyspace-events "" ############################### GOPHER SERVER ################################# # Redis contains an implementation of the Gopher protocol, as specified in -# the RFC 1436 (https://www.ietf.org/rfc/rfc1436.txt). +# the RFC 1436 (https://datatracker.ietf.org/doc/html/rfc1436). # # The Gopher protocol was very popular in the late '90s. It is an alternative # to the web, and the implementation both server and client side is so simple diff --git a/internal/suites/example/compose/traefik2/docker-compose.yml b/internal/suites/example/compose/traefik2/docker-compose.yml index ea30cf683..04b198e7e 100644 --- a/internal/suites/example/compose/traefik2/docker-compose.yml +++ b/internal/suites/example/compose/traefik2/docker-compose.yml @@ -15,7 +15,7 @@ services: - 'traefik.http.middlewares.authelia.forwardauth.address=https://authelia-backend:9091${PathPrefix}/api/authz/forward-auth' # yamllint disable-line rule:line-length - 'traefik.http.middlewares.authelia.forwardauth.tls.insecureSkipVerify=true' - 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true' - - 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups, Remote-Name, Remote-Email' # yamllint disable-line rule:line-length + - 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Authorization,Proxy-Authorization,Remote-User,Remote-Groups,Remote-Email,Remote-Name' # yamllint disable-line rule:line-length command: - '--accesslog=true' - '--api' diff --git a/internal/suites/example/kube/authelia/authelia.yml b/internal/suites/example/kube/authelia/authelia.yml index 90e138189..39450cc63 100644 --- a/internal/suites/example/kube/authelia/authelia.yml +++ b/internal/suites/example/kube/authelia/authelia.yml @@ -33,7 +33,7 @@ spec: mountPath: /config/configuration.yml readOnly: true - name: authelia-ssl - mountPath: /config/ssl + mountPath: /pki readOnly: true - name: secrets mountPath: /config/secrets diff --git a/internal/suites/example/kube/authelia/configs/configuration.yml b/internal/suites/example/kube/authelia/configs/configuration.yml index 19eec843f..8b8dc8180 100644 --- a/internal/suites/example/kube/authelia/configs/configuration.yml +++ b/internal/suites/example/kube/authelia/configs/configuration.yml @@ -8,8 +8,8 @@ default_redirection_url: https://home.example.com:8080 server: port: 443 tls: - certificate: /config/ssl/cert.pem - key: /config/ssl/key.pem + certificate: /pki/public.backend.crt + key: /pki/private.backend.pem log: level: debug diff --git a/internal/suites/example/kube/storage/mariadb.yml b/internal/suites/example/kube/storage/mariadb.yml index 5e0837665..d9cab0ca9 100644 --- a/internal/suites/example/kube/storage/mariadb.yml +++ b/internal/suites/example/kube/storage/mariadb.yml @@ -18,7 +18,7 @@ spec: spec: containers: - name: mariadb - image: mariadb:10.10.2 + image: mariadb:10.10.3 ports: - containerPort: 3306 readinessProbe: diff --git a/internal/suites/suite_cli_test.go b/internal/suites/suite_cli_test.go index cb7229f63..f214d1301 100644 --- a/internal/suites/suite_cli_test.go +++ b/internal/suites/suite_cli_test.go @@ -402,7 +402,7 @@ func (s *CLISuite) TestShouldGenerateCertificateRSAWithNotBefore() { func (s *CLISuite) TestShouldFailGenerateCertificateRSAWithInvalidNotBefore() { output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "rsa", "generate", "--common-name=example.com", "--sans='*.example.com'", "--not-before", "Jan", "--directory=/tmp/"}) s.Assert().NotNil(err) - s.Assert().Contains(output, "Error: failed to parse not before: parsing time \"Jan\" as \"Jan 2 15:04:05 2006\": cannot parse \"\" as \"2\"") + s.Assert().Contains(output, "Error: failed to parse not before: failed to find a suitable time layout for time 'Jan'") } func (s *CLISuite) TestShouldGenerateCertificateRSAWith4096Bits() { @@ -555,7 +555,7 @@ func (s *CLISuite) TestShouldGenerateCertificateEd25519() { func (s *CLISuite) TestShouldFailGenerateCertificateParseNotBefore() { output, err := s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "crypto", "certificate", "ecdsa", "generate", "--not-before=invalid", "--common-name=example.com", "--sans='*.example.com'", "--directory=/tmp/"}) s.Assert().NotNil(err) - s.Assert().Contains(output, "Error: failed to parse not before: parsing time \"invalid\" as \"Jan 2 15:04:05 2006\": cannot parse \"invalid\" as \"Jan\"") + s.Assert().Contains(output, "Error: failed to parse not before: failed to find a suitable time layout for time 'invalid'") } func (s *CLISuite) TestShouldFailGenerateCertificateECDSA() { diff --git a/internal/templates/funcs.go b/internal/templates/funcs.go index 7d173f636..f8be41e3d 100644 --- a/internal/templates/funcs.go +++ b/internal/templates/funcs.go @@ -17,62 +17,68 @@ import ( "strconv" "strings" "time" + + "github.com/google/uuid" ) // FuncMap returns the template FuncMap commonly used in several templates. func FuncMap() map[string]any { return map[string]any{ - "iterate": FuncIterate, - "env": FuncGetEnv, - "expandenv": FuncExpandEnv, - "split": FuncStringSplit, - "splitList": FuncStringSplitList, - "join": FuncElemsJoin, - "contains": FuncStringContains, - "hasPrefix": FuncStringHasPrefix, - "hasSuffix": FuncStringHasSuffix, - "lower": strings.ToLower, - "keys": FuncKeys, - "sortAlpha": FuncSortAlpha, - "upper": strings.ToUpper, - "title": strings.ToTitle, - "trim": strings.TrimSpace, - "trimAll": FuncStringTrimAll, - "trimSuffix": FuncStringTrimSuffix, - "trimPrefix": FuncStringTrimPrefix, - "replace": FuncStringReplace, - "quote": FuncStringQuote, - "sha1sum": FuncHashSum(sha1.New), - "sha256sum": FuncHashSum(sha256.New), - "sha512sum": FuncHashSum(sha512.New), - "squote": FuncStringSQuote, - "now": time.Now, - "b64enc": FuncB64Enc, - "b64dec": FuncB64Dec, - "b32enc": FuncB32Enc, - "b32dec": FuncB32Dec, - "list": FuncList, - "dict": FuncDict, - "get": FuncGet, - "set": FuncSet, - "isAbs": path.IsAbs, - "base": path.Base, - "dir": path.Dir, - "ext": path.Ext, - "clean": path.Clean, - "osBase": filepath.Base, - "osClean": filepath.Clean, - "osDir": filepath.Dir, - "osExt": filepath.Ext, - "osIsAbs": filepath.IsAbs, - "deepEqual": reflect.DeepEqual, - "typeOf": FuncTypeOf, - "typeIs": FuncTypeIs, - "typeIsLike": FuncTypeIsLike, - "kindOf": FuncKindOf, - "kindIs": FuncKindIs, - "default": FuncDefault, - "empty": FuncEmpty, + "iterate": FuncIterate, + "fileContent": FuncFileContent, + "env": FuncGetEnv, + "expandenv": FuncExpandEnv, + "split": FuncStringSplit, + "splitList": FuncStringSplitList, + "join": FuncElemsJoin, + "contains": FuncStringContains, + "hasPrefix": FuncStringHasPrefix, + "hasSuffix": FuncStringHasSuffix, + "lower": strings.ToLower, + "keys": FuncKeys, + "sortAlpha": FuncSortAlpha, + "upper": strings.ToUpper, + "title": strings.ToTitle, + "trim": strings.TrimSpace, + "trimAll": FuncStringTrimAll, + "trimSuffix": FuncStringTrimSuffix, + "trimPrefix": FuncStringTrimPrefix, + "replace": FuncStringReplace, + "quote": FuncStringQuote, + "sha1sum": FuncHashSum(sha1.New), + "sha256sum": FuncHashSum(sha256.New), + "sha512sum": FuncHashSum(sha512.New), + "squote": FuncStringSQuote, + "now": time.Now, + "b64enc": FuncB64Enc, + "b64dec": FuncB64Dec, + "b32enc": FuncB32Enc, + "b32dec": FuncB32Dec, + "list": FuncList, + "dict": FuncDict, + "get": FuncGet, + "set": FuncSet, + "isAbs": path.IsAbs, + "base": path.Base, + "dir": path.Dir, + "ext": path.Ext, + "clean": path.Clean, + "osBase": filepath.Base, + "osClean": filepath.Clean, + "osDir": filepath.Dir, + "osExt": filepath.Ext, + "osIsAbs": filepath.IsAbs, + "deepEqual": reflect.DeepEqual, + "typeOf": FuncTypeOf, + "typeIs": FuncTypeIs, + "typeIsLike": FuncTypeIsLike, + "kindOf": FuncKindOf, + "kindIs": FuncKindIs, + "default": FuncDefault, + "empty": FuncEmpty, + "indent": FuncIndent, + "nindent": FuncNewlineIndent, + "uuidv4": FuncUUIDv4, } } @@ -384,3 +390,31 @@ func FuncEmpty(v any) bool { return false } } + +// FuncIndent is a helper function that provides similar functionality to the helm indent func. +func FuncIndent(indent int, value string) string { + padding := strings.Repeat(" ", indent) + + return padding + strings.ReplaceAll(value, "\n", "\n"+padding) +} + +// FuncNewlineIndent is a helper function that provides similar functionality to the helm nindent func. +func FuncNewlineIndent(indent int, value string) string { + return "\n" + FuncIndent(indent, value) +} + +// FuncUUIDv4 is a helper function that provides similar functionality to the helm uuidv4 func. +func FuncUUIDv4() string { + return uuid.New().String() +} + +// FuncFileContent returns the file content. +func FuncFileContent(path string) (data string, err error) { + var raw []byte + + if raw, err = os.ReadFile(path); err != nil { + return "", err + } + + return string(raw), nil +} diff --git a/internal/templates/funcs_test.go b/internal/templates/funcs_test.go index a3eb5b23f..90aa6e177 100644 --- a/internal/templates/funcs_test.go +++ b/internal/templates/funcs_test.go @@ -638,3 +638,23 @@ func TestFuncEmpty(t *testing.T) { }) } } + +func TestFuncIndent(t *testing.T) { + testCases := []struct { + name string + have string + indent int + expected []string + }{ + {"ShouldIndentZeroMultiLine", "abc\n123", 0, []string{"abc\n123", "\nabc\n123"}}, + {"ShouldIndentOneMultiLine", "abc\n123", 1, []string{" abc\n 123", "\n abc\n 123"}}, + {"ShouldIndentOneSingleLine", "abc", 1, []string{" abc", "\n abc"}}, + {"ShouldIndentZeroSingleLine", "abc", 0, []string{"abc", "\nabc"}}, + } + + for _, tc := range testCases { + for i, f := range []func(i int, v string) string{FuncIndent, FuncNewlineIndent} { + assert.Equal(t, tc.expected[i], f(tc.indent, tc.have)) + } + } +} diff --git a/internal/utils/const.go b/internal/utils/const.go index cb02b5459..3ce72025f 100644 --- a/internal/utils/const.go +++ b/internal/utils/const.go @@ -70,9 +70,22 @@ const ( ) var ( + // StandardTimeLayouts is the set of standard time layouts used with ParseTimeString. + StandardTimeLayouts = []string{ + "Jan 2 15:04:05 2006", + time.DateTime, + time.RFC3339, + time.RFC1123Z, + time.RubyDate, + time.ANSIC, + time.DateOnly, + } + standardDurationUnits = []string{"ns", "us", "µs", "μs", "ms", "s", "m", "h"} - reDurationSeconds = regexp.MustCompile(`^\d+$`) - reDurationStandard = regexp.MustCompile(`(?P[1-9]\d*?)(?P[^\d\s]+)`) + + reOnlyNumeric = regexp.MustCompile(`^\d+$`) + reDurationStandard = regexp.MustCompile(`(?P[1-9]\d*?)(?P[^\d\s]+)`) + reNumeric = regexp.MustCompile(`\d+`) ) // Duration unit types. diff --git a/internal/utils/crypto.go b/internal/utils/crypto.go index 17481a5cf..425b5f10b 100644 --- a/internal/utils/crypto.go +++ b/internal/utils/crypto.go @@ -307,7 +307,7 @@ func NewX509CertPool(directory string) (certPool *x509.CertPool, warnings []erro } // WriteCertificateBytesToPEM writes a certificate/csr to a file in the PEM format. -func WriteCertificateBytesToPEM(cert []byte, path string, csr bool) (err error) { +func WriteCertificateBytesToPEM(path string, csr bool, certs ...[]byte) (err error) { out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { return fmt.Errorf("failed to open %s for writing: %w", path, err) @@ -318,10 +318,12 @@ func WriteCertificateBytesToPEM(cert []byte, path string, csr bool) (err error) blockType = BlockTypeCertificateRequest } - if err = pem.Encode(out, &pem.Block{Bytes: cert, Type: blockType}); err != nil { - _ = out.Close() + for _, cert := range certs { + if err = pem.Encode(out, &pem.Block{Bytes: cert, Type: blockType}); err != nil { + _ = out.Close() - return err + return err + } } return out.Close() @@ -545,7 +547,7 @@ func X509ParseKeyUsage(keyUsages []string, ca bool) (keyUsage x509.KeyUsage) { func X509ParseExtendedKeyUsage(extKeyUsages []string, ca bool) (extKeyUsage []x509.ExtKeyUsage) { if len(extKeyUsages) == 0 { if ca { - extKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny} + extKeyUsage = []x509.ExtKeyUsage{} } else { extKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth} } diff --git a/internal/utils/crypto_test.go b/internal/utils/crypto_test.go index dc7889996..99ab52cf8 100644 --- a/internal/utils/crypto_test.go +++ b/internal/utils/crypto_test.go @@ -52,9 +52,9 @@ func TestShouldNotReturnErrWhenX509DirectoryExist(t *testing.T) { } func TestShouldReadCertsFromDirectoryButNotKeys(t *testing.T) { - pool, warnings, errors := NewX509CertPool("../suites/common/ssl/") + pool, warnings, errors := NewX509CertPool("../suites/common/pki/") assert.NotNil(t, pool) - require.Len(t, errors, 1) + require.Len(t, errors, 3) if runtime.GOOS == "windows" { require.Len(t, warnings, 1) @@ -63,7 +63,9 @@ func TestShouldReadCertsFromDirectoryButNotKeys(t *testing.T) { assert.Len(t, warnings, 0) } - assert.EqualError(t, errors[0], "could not import certificate key.pem") + assert.EqualError(t, errors[0], "could not import certificate private.backend.pem") + assert.EqualError(t, errors[1], "could not import certificate private.oidc.pem") + assert.EqualError(t, errors[2], "could not import certificate private.pem") } func TestShouldGenerateCertificateAndPersistIt(t *testing.T) { @@ -441,7 +443,7 @@ func TestX509ParseExtendedKeyUsage(t *testing.T) { expected []x509.ExtKeyUsage }{ {"ShouldParseDefault", nil, false, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}}, - {"ShouldParseDefaultCA", nil, true, []x509.ExtKeyUsage{x509.ExtKeyUsageAny}}, + {"ShouldParseDefaultCA", nil, true, []x509.ExtKeyUsage{}}, {"ShouldParseAny", [][]string{{"any"}, {"Any"}, {"any", "server_auth"}}, false, []x509.ExtKeyUsage{x509.ExtKeyUsageAny}}, {"ShouldParseServerAuth", [][]string{{"server_auth"}, {"Server_Auth"}, {"serverauth"}, {"serverAuth"}}, false, []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}}, {"ShouldParseClientAuth", [][]string{{"client_auth"}, {"Client_Auth"}, {"clientauth"}, {"clientAuth"}}, false, []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}}, diff --git a/internal/utils/time.go b/internal/utils/time.go index 4844e108e..c044f899a 100644 --- a/internal/utils/time.go +++ b/internal/utils/time.go @@ -3,6 +3,7 @@ package utils import ( "fmt" "strconv" + "strings" "time" ) @@ -12,44 +13,75 @@ func StandardizeDurationString(input string) (output string, err error) { return "0s", nil } - matches := reDurationStandard.FindAllStringSubmatch(input, -1) + matches := reDurationStandard.FindAllStringSubmatch(strings.ReplaceAll(input, " ", ""), -1) if len(matches) == 0 { return "", fmt.Errorf("could not parse '%s' as a duration", input) } - var d int + var ( + o string + q int + ) for _, match := range matches { - if d, err = strconv.Atoi(match[1]); err != nil { - return "", fmt.Errorf("could not parse the numeric portion of '%s' in duration string '%s': %w", match[0], input, err) + if q, err = strconv.Atoi(match[1]); err != nil { + return "", err } - unit := match[2] - - switch { - case IsStringInSlice(unit, standardDurationUnits): - output += fmt.Sprintf("%d%s", d, unit) - case unit == DurationUnitDays: - output += fmt.Sprintf("%dh", d*HoursInDay) - case unit == DurationUnitWeeks: - output += fmt.Sprintf("%dh", d*HoursInWeek) - case unit == DurationUnitMonths: - output += fmt.Sprintf("%dh", d*HoursInMonth) - case unit == DurationUnitYears: - output += fmt.Sprintf("%dh", d*HoursInYear) - default: - return "", fmt.Errorf("could not parse the units portion of '%s' in duration string '%s': the unit '%s' is not valid", match[0], input, unit) + if o, err = standardizeQuantityAndUnits(q, match[2]); err != nil { + return "", fmt.Errorf("could not parse the units portion of '%s' in duration string '%s': %w", match[0], input, err) } + + output += o } return output, nil } +func standardizeQuantityAndUnits(qty int, unit string) (output string, err error) { + switch { + case IsStringInSlice(unit, standardDurationUnits): + return fmt.Sprintf("%d%s", qty, unit), nil + case len(unit) == 1: + switch unit { + case DurationUnitDays: + return fmt.Sprintf("%dh", qty*HoursInDay), nil + case DurationUnitWeeks: + return fmt.Sprintf("%dh", qty*HoursInWeek), nil + case DurationUnitMonths: + return fmt.Sprintf("%dh", qty*HoursInMonth), nil + case DurationUnitYears: + return fmt.Sprintf("%dh", qty*HoursInYear), nil + } + default: + switch unit { + case "millisecond", "milliseconds": + return fmt.Sprintf("%dms", qty), nil + case "second", "seconds": + return fmt.Sprintf("%ds", qty), nil + case "minute", "minutes": + return fmt.Sprintf("%dm", qty), nil + case "hour", "hours": + return fmt.Sprintf("%dh", qty), nil + case "day", "days": + return fmt.Sprintf("%dh", qty*HoursInDay), nil + case "week", "weeks": + return fmt.Sprintf("%dh", qty*HoursInWeek), nil + case "month", "months": + return fmt.Sprintf("%dh", qty*HoursInMonth), nil + case "year", "years": + return fmt.Sprintf("%dh", qty*HoursInYear), nil + } + } + + return "", fmt.Errorf("the unit '%s' is not valid", unit) +} + // ParseDurationString standardizes a duration string with StandardizeDurationString then uses time.ParseDuration to // convert it into a time.Duration. func ParseDurationString(input string) (duration time.Duration, err error) { - if reDurationSeconds.MatchString(input) { + if reOnlyNumeric.MatchString(input) { var seconds int if seconds, err = strconv.Atoi(input); err != nil { @@ -68,6 +100,50 @@ func ParseDurationString(input string) (duration time.Duration, err error) { return time.ParseDuration(out) } +// ParseTimeString attempts to parse a string with several time formats. +func ParseTimeString(input string) (t time.Time, err error) { + return ParseTimeStringWithLayouts(input, StandardTimeLayouts) +} + +// ParseTimeStringWithLayouts attempts to parse a string with several time formats. The format with the most matching +// characters is returned. +func ParseTimeStringWithLayouts(input string, layouts []string) (match time.Time, err error) { + _, match, err = matchParseTimeStringWithLayouts(input, layouts) + + return +} + +func matchParseTimeStringWithLayouts(input string, layouts []string) (index int, match time.Time, err error) { + if reOnlyNumeric.MatchString(input) { + var u int64 + + if u, err = strconv.ParseInt(input, 10, 64); err != nil { + return -999, match, fmt.Errorf("time value was detected as an integer but the integer could not be parsed: %w", err) + } + + switch { + case u > 32503554000000: // 2999-12-31 00:00:00 in unix time (milliseconds). + return -3, time.UnixMicro(u), nil + case u > 946645200000: // 2000-01-01 00:00:00 in unix time (milliseconds). + return -2, time.UnixMilli(u), nil + default: + return -1, time.Unix(u, 0), nil + } + } + + var layout string + + for index, layout = range layouts { + if match, err = time.Parse(layout, input); err == nil { + if len(match.Format(layout))-len(input) == 0 { + return index, match, nil + } + } + } + + return -998, time.UnixMilli(0), fmt.Errorf("failed to find a suitable time layout for time '%s'", input) +} + // UnixNanoTimeToMicrosoftNTEpoch converts a unix timestamp in nanosecond format to win32 epoch format. func UnixNanoTimeToMicrosoftNTEpoch(nano int64) (t uint64) { return uint64(nano/100) + timeUnixEpochAsMicrosoftNTEpoch diff --git a/internal/utils/time_test.go b/internal/utils/time_test.go index 4cd651c9c..39b011fa6 100644 --- a/internal/utils/time_test.go +++ b/internal/utils/time_test.go @@ -1,63 +1,112 @@ package utils import ( + "fmt" + "strings" "testing" "time" "github.com/stretchr/testify/assert" ) -func TestParseDurationString_ShouldParseDurationString(t *testing.T) { - duration, err := ParseDurationString("1h") +func TestParseDurationString(t *testing.T) { + testCases := []struct { + name string + have []string + raw bool + expected time.Duration + err string + }{ + {"ShouldParseStringsForMillisecond", []string{"%d ms", "%d millisecond", "%d milliseconds"}, false, time.Millisecond, ""}, + {"ShouldParseStringsForSecond", []string{"%d s", "%d second", "%d seconds"}, false, time.Second, ""}, + {"ShouldParseStringsForMinute", []string{"%d m", "%d minute", "%d minutes"}, false, time.Minute, ""}, + {"ShouldParseStringsForHour", []string{"%d h", "%d hour", "%d hours"}, false, time.Hour, ""}, + {"ShouldParseStringsForDay", []string{"%d d", "%d day", "%d days"}, false, time.Hour * HoursInDay, ""}, + {"ShouldParseStringsForWeek", []string{"%d w", "%d week", "%d weeks"}, false, time.Hour * HoursInWeek, ""}, + {"ShouldParseStringsForMonth", []string{"%d M", "%d month", "%d months"}, false, time.Hour * HoursInMonth, ""}, + {"ShouldParseStringsForYear", []string{"%d y", "%d year", "%d years"}, false, time.Hour * HoursInYear, ""}, + {"ShouldParseStringsDecimals", []string{"100"}, true, time.Second * 100, ""}, + {"ShouldParseStringsDecimalNull", []string{""}, true, time.Second * 0, ""}, + } - assert.NoError(t, err) - assert.Equal(t, 60*time.Minute, duration) -} + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + for _, f := range tc.have { + if tc.raw { + t.Run(f, func(t *testing.T) { + actual, actualErr := ParseDurationString(f) -func TestParseDurationString_ShouldParseBlankString(t *testing.T) { - duration, err := ParseDurationString("") + if tc.err == "" { + assert.NoError(t, actualErr) + assert.Equal(t, tc.expected, actual) + } else { + assert.EqualError(t, actualErr, tc.err) + } + }) + } else { + for _, d := range []int{1, 5, 20} { + input := fmt.Sprintf(f, d) - assert.NoError(t, err) - assert.Equal(t, time.Second*0, duration) -} + inputNoSpace := strings.ReplaceAll(input, " ", "") -func TestParseDurationString_ShouldParseDurationStringAllUnits(t *testing.T) { - duration, err := ParseDurationString("1y") + t.Run(inputNoSpace, func(t *testing.T) { + t.Run("WithSpaces", func(t *testing.T) { + actual, actualErr := ParseDurationString(input) - assert.NoError(t, err) - assert.Equal(t, time.Hour*24*365, duration) + if tc.err == "" { + assert.NoError(t, actualErr) + assert.Equal(t, tc.expected*time.Duration(d), actual) + } else { + assert.EqualError(t, actualErr, tc.err) + } - duration, err = ParseDurationString("1M") + t.Run("LeadingZeros", func(t *testing.T) { + inputActual := reNumeric.ReplaceAllStringFunc(input, func(s string) string { + return "000" + s + }) - assert.NoError(t, err) - assert.Equal(t, time.Hour*24*30, duration) + actual, actualErr := ParseDurationString(inputActual) - duration, err = ParseDurationString("1w") + if tc.err == "" { + assert.NoError(t, actualErr) + assert.Equal(t, tc.expected*time.Duration(d), actual) + } else { + assert.EqualError(t, actualErr, tc.err) + } + }) + }) - assert.NoError(t, err) - assert.Equal(t, time.Hour*24*7, duration) + t.Run("WithoutSpaces", func(t *testing.T) { + actual, actualErr := ParseDurationString(inputNoSpace) - duration, err = ParseDurationString("1d") + if tc.err == "" { + assert.NoError(t, actualErr) + assert.Equal(t, tc.expected*time.Duration(d), actual) + } else { + assert.EqualError(t, actualErr, tc.err) + } - assert.NoError(t, err) - assert.Equal(t, time.Hour*24, duration) + t.Run("LeadingZeros", func(t *testing.T) { + inputActual := reNumeric.ReplaceAllStringFunc(inputNoSpace, func(s string) string { + return "000" + s + }) - duration, err = ParseDurationString("1h") + actual, actualErr := ParseDurationString(inputActual) - assert.NoError(t, err) - assert.Equal(t, time.Hour, duration) - - duration, err = ParseDurationString("1s") - - assert.NoError(t, err) - assert.Equal(t, time.Second, duration) -} - -func TestParseDurationString_ShouldParseSecondsString(t *testing.T) { - duration, err := ParseDurationString("100") - - assert.NoError(t, err) - assert.Equal(t, 100*time.Second, duration) + if tc.err == "" { + assert.NoError(t, actualErr) + assert.Equal(t, tc.expected*time.Duration(d), actual) + } else { + assert.EqualError(t, actualErr, tc.err) + } + }) + }) + }) + } + } + } + }) + } } func TestParseDurationString_ShouldNotParseDurationStringWithOutOfOrderQuantitiesAndUnits(t *testing.T) { @@ -74,18 +123,11 @@ func TestParseDurationString_ShouldNotParseBadDurationString(t *testing.T) { assert.Equal(t, time.Duration(0), duration) } -func TestParseDurationString_ShouldParseDurationStringWithMultiValueUnits(t *testing.T) { - duration, err := ParseDurationString("10ms") +func TestParseDurationString_ShouldNotParseBadDurationStringAlt(t *testing.T) { + duration, err := ParseDurationString("10abcxyz") - assert.NoError(t, err) - assert.Equal(t, time.Duration(10)*time.Millisecond, duration) -} - -func TestParseDurationString_ShouldParseDurationStringWithLeadingZero(t *testing.T) { - duration, err := ParseDurationString("005h") - - assert.NoError(t, err) - assert.Equal(t, time.Duration(5)*time.Hour, duration) + assert.EqualError(t, err, "could not parse the units portion of '10abcxyz' in duration string '10abcxyz': the unit 'abcxyz' is not valid") + assert.Equal(t, time.Duration(0), duration) } func TestParseDurationString_ShouldParseMultiUnitValues(t *testing.T) { @@ -130,3 +172,35 @@ func TestShouldConvertKnownUnixNanoTimeToKnownWin32Epoch(t *testing.T) { assert.Equal(t, win32Epoch, UnixNanoTimeToMicrosoftNTEpoch(exampleNanoTime)) assert.Equal(t, timeUnixEpochAsMicrosoftNTEpoch, UnixNanoTimeToMicrosoftNTEpoch(0)) } + +func TestParseTimeString(t *testing.T) { + testCases := []struct { + name string + have string + index int + expected time.Time + err string + }{ + {"ShouldParseIntegerAsUnix", "1675899060", -1, time.Unix(1675899060, 0), ""}, + {"ShouldParseIntegerAsUnixMilli", "1675899060000", -2, time.Unix(1675899060, 0), ""}, + {"ShouldParseIntegerAsUnixMicro", "1675899060000000", -3, time.Unix(1675899060, 0), ""}, + {"ShouldNotParseSuperLargeInteger", "9999999999999999999999999999999999999999", -999, time.Unix(0, 0), "time value was detected as an integer but the integer could not be parsed: strconv.ParseInt: parsing \"9999999999999999999999999999999999999999\": value out of range"}, + {"ShouldParseSimpleTime", "Jan 2 15:04:05 2006", 0, time.Unix(1136214245, 0), ""}, + {"ShouldNotParseInvalidTime", "abc", -998, time.Unix(0, 0), "failed to find a suitable time layout for time 'abc'"}, + {"ShouldMatchDate", "2020-05-01", 6, time.Unix(1588291200, 0), ""}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + index, actual, err := matchParseTimeStringWithLayouts(tc.have, StandardTimeLayouts) + + if tc.err == "" { + assert.NoError(t, err) + assert.Equal(t, tc.index, index) + assert.Equal(t, tc.expected.UnixNano(), actual.UnixNano()) + } else { + assert.EqualError(t, err, tc.err) + } + }) + } +} diff --git a/web/package.json b/web/package.json index 4c757ce17..b37e6b350 100644 --- a/web/package.json +++ b/web/package.json @@ -21,14 +21,14 @@ "@emotion/cache": "11.10.5", "@emotion/react": "11.10.5", "@emotion/styled": "11.10.5", - "@fortawesome/fontawesome-svg-core": "6.2.1", - "@fortawesome/free-regular-svg-icons": "6.2.1", - "@fortawesome/free-solid-svg-icons": "6.2.1", + "@fortawesome/fontawesome-svg-core": "6.3.0", + "@fortawesome/free-regular-svg-icons": "6.3.0", + "@fortawesome/free-solid-svg-icons": "6.3.0", "@fortawesome/react-fontawesome": "0.2.0", "@mui/icons-material": "5.11.0", - "@mui/material": "5.11.7", + "@mui/material": "5.11.8", "@mui/styles": "5.11.7", - "axios": "1.3.0", + "axios": "1.3.2", "broadcast-channel": "4.20.2", "classnames": "2.3.2", "i18next": "22.4.9", @@ -37,9 +37,9 @@ "qrcode.react": "3.1.0", "react": "18.2.0", "react-dom": "18.2.0", - "react-i18next": "12.1.4", + "react-i18next": "12.1.5", "react-loading": "2.0.3", - "react-router-dom": "6.8.0", + "react-router-dom": "6.8.1", "react18-input-otp": "1.1.2", "zxcvbn": "4.4.2" }, @@ -148,17 +148,17 @@ "@testing-library/jest-dom": "5.16.5", "@testing-library/react": "13.4.0", "@types/jest": "29.4.0", - "@types/node": "18.11.18", + "@types/node": "18.13.0", "@types/qrcode.react": "1.0.2", "@types/react": "18.0.27", "@types/react-dom": "18.0.10", "@types/zxcvbn": "4.4.1", - "@typescript-eslint/eslint-plugin": "5.50.0", - "@typescript-eslint/parser": "5.50.0", - "@vitejs/plugin-react": "3.0.1", - "esbuild": "0.17.5", + "@typescript-eslint/eslint-plugin": "5.51.0", + "@typescript-eslint/parser": "5.51.0", + "@vitejs/plugin-react": "3.1.0", + "esbuild": "0.17.7", "esbuild-jest": "0.5.0", - "eslint": "8.33.0", + "eslint": "8.34.0", "eslint-config-prettier": "8.6.0", "eslint-config-react-app": "7.0.1", "eslint-formatter-rdjson": "1.0.5", @@ -169,14 +169,14 @@ "eslint-plugin-react": "7.32.2", "eslint-plugin-react-hooks": "4.6.0", "husky": "8.0.3", - "jest": "29.4.1", - "jest-environment-jsdom": "29.4.1", + "jest": "29.4.2", + "jest-environment-jsdom": "29.4.2", "jest-transform-stub": "2.0.0", "jest-watch-typeahead": "2.2.2", - "prettier": "2.8.3", + "prettier": "2.8.4", "react-test-renderer": "18.2.0", "typescript": "4.9.5", - "vite": "4.0.4", + "vite": "4.1.1", "vite-plugin-eslint": "1.8.1", "vite-plugin-istanbul": "4.0.0", "vite-plugin-svgr": "2.4.0", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 88db78386..a92eb43e0 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -6,31 +6,31 @@ specifiers: '@emotion/cache': 11.10.5 '@emotion/react': 11.10.5 '@emotion/styled': 11.10.5 - '@fortawesome/fontawesome-svg-core': 6.2.1 - '@fortawesome/free-regular-svg-icons': 6.2.1 - '@fortawesome/free-solid-svg-icons': 6.2.1 + '@fortawesome/fontawesome-svg-core': 6.3.0 + '@fortawesome/free-regular-svg-icons': 6.3.0 + '@fortawesome/free-solid-svg-icons': 6.3.0 '@fortawesome/react-fontawesome': 0.2.0 '@limegrass/eslint-plugin-import-alias': 1.0.6 '@mui/icons-material': 5.11.0 - '@mui/material': 5.11.7 + '@mui/material': 5.11.8 '@mui/styles': 5.11.7 '@testing-library/jest-dom': 5.16.5 '@testing-library/react': 13.4.0 '@types/jest': 29.4.0 - '@types/node': 18.11.18 + '@types/node': 18.13.0 '@types/qrcode.react': 1.0.2 '@types/react': 18.0.27 '@types/react-dom': 18.0.10 '@types/zxcvbn': 4.4.1 - '@typescript-eslint/eslint-plugin': 5.50.0 - '@typescript-eslint/parser': 5.50.0 - '@vitejs/plugin-react': 3.0.1 - axios: 1.3.0 + '@typescript-eslint/eslint-plugin': 5.51.0 + '@typescript-eslint/parser': 5.51.0 + '@vitejs/plugin-react': 3.1.0 + axios: 1.3.2 broadcast-channel: 4.20.2 classnames: 2.3.2 - esbuild: 0.17.5 + esbuild: 0.17.7 esbuild-jest: 0.5.0 - eslint: 8.33.0 + eslint: 8.34.0 eslint-config-prettier: 8.6.0 eslint-config-react-app: 7.0.1 eslint-formatter-rdjson: 1.0.5 @@ -44,21 +44,21 @@ specifiers: i18next: 22.4.9 i18next-browser-languagedetector: 7.0.1 i18next-http-backend: 2.1.1 - jest: 29.4.1 - jest-environment-jsdom: 29.4.1 + jest: 29.4.2 + jest-environment-jsdom: 29.4.2 jest-transform-stub: 2.0.0 jest-watch-typeahead: 2.2.2 - prettier: 2.8.3 + prettier: 2.8.4 qrcode.react: 3.1.0 react: 18.2.0 react-dom: 18.2.0 - react-i18next: 12.1.4 + react-i18next: 12.1.5 react-loading: 2.0.3 - react-router-dom: 6.8.0 + react-router-dom: 6.8.1 react-test-renderer: 18.2.0 react18-input-otp: 1.1.2 typescript: 4.9.5 - vite: 4.0.4 + vite: 4.1.1 vite-plugin-eslint: 1.8.1 vite-plugin-istanbul: 4.0.0 vite-plugin-svgr: 2.4.0 @@ -69,14 +69,14 @@ dependencies: '@emotion/cache': 11.10.5 '@emotion/react': 11.10.5_3stiutgnnbnfnf3uowm5cip22i '@emotion/styled': 11.10.5_jrh5enlbqfbnumycmktdqgd6se - '@fortawesome/fontawesome-svg-core': 6.2.1 - '@fortawesome/free-regular-svg-icons': 6.2.1 - '@fortawesome/free-solid-svg-icons': 6.2.1 - '@fortawesome/react-fontawesome': 0.2.0_z27bm67dtmuyyvss23ckjdrcuy - '@mui/icons-material': 5.11.0_m3y2ykptchyoygtoroit6l3ehq - '@mui/material': 5.11.7_rqh7qj4464ntrqrt6banhaqg4q + '@fortawesome/fontawesome-svg-core': 6.3.0 + '@fortawesome/free-regular-svg-icons': 6.3.0 + '@fortawesome/free-solid-svg-icons': 6.3.0 + '@fortawesome/react-fontawesome': 0.2.0_d5rbrisxfyemehbvmdbryvgjte + '@mui/icons-material': 5.11.0_3psqo62dtzuc5tpd3awdluze4i + '@mui/material': 5.11.8_rqh7qj4464ntrqrt6banhaqg4q '@mui/styles': 5.11.7_3stiutgnnbnfnf3uowm5cip22i - axios: 1.3.0 + axios: 1.3.2 broadcast-channel: 4.20.2 classnames: 2.3.2 i18next: 22.4.9 @@ -85,51 +85,51 @@ dependencies: qrcode.react: 3.1.0_react@18.2.0 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - react-i18next: 12.1.4_iakk3dtjhjpukdoa4oua5khgci + react-i18next: 12.1.5_iakk3dtjhjpukdoa4oua5khgci react-loading: 2.0.3_react@18.2.0 - react-router-dom: 6.8.0_biqbaboplfbrettd7655fr4n2y + react-router-dom: 6.8.1_biqbaboplfbrettd7655fr4n2y react18-input-otp: 1.1.2_biqbaboplfbrettd7655fr4n2y zxcvbn: 4.4.2 devDependencies: '@commitlint/cli': 17.4.2 '@commitlint/config-conventional': 17.4.2 - '@limegrass/eslint-plugin-import-alias': 1.0.6_eslint@8.33.0 + '@limegrass/eslint-plugin-import-alias': 1.0.6_eslint@8.34.0 '@testing-library/jest-dom': 5.16.5 '@testing-library/react': 13.4.0_biqbaboplfbrettd7655fr4n2y '@types/jest': 29.4.0 - '@types/node': 18.11.18 + '@types/node': 18.13.0 '@types/qrcode.react': 1.0.2 '@types/react': 18.0.27 '@types/react-dom': 18.0.10 '@types/zxcvbn': 4.4.1 - '@typescript-eslint/eslint-plugin': 5.50.0_go4drrxstycfikanvu45pi4vgq - '@typescript-eslint/parser': 5.50.0_4vsywjlpuriuw3tl5oq6zy5a64 - '@vitejs/plugin-react': 3.0.1_vite@4.0.4 - esbuild: 0.17.5 - esbuild-jest: 0.5.0_esbuild@0.17.5 - eslint: 8.33.0 - eslint-config-prettier: 8.6.0_eslint@8.33.0 - eslint-config-react-app: 7.0.1_rc2dcjzdq7kivixrc2dtl3hu7e + '@typescript-eslint/eslint-plugin': 5.51.0_z4swst3wuuqk4hlme4ajzslgh4 + '@typescript-eslint/parser': 5.51.0_7kw3g6rralp5ps6mg3uyzz6azm + '@vitejs/plugin-react': 3.1.0_vite@4.1.1 + esbuild: 0.17.7 + esbuild-jest: 0.5.0_esbuild@0.17.7 + eslint: 8.34.0 + eslint-config-prettier: 8.6.0_eslint@8.34.0 + eslint-config-react-app: 7.0.1_i52m234xbggdiu6ew4jj35mjea eslint-formatter-rdjson: 1.0.5 - eslint-import-resolver-typescript: 3.5.3_ohdts44xlqyeyrlje4qnefqeay - eslint-plugin-import: 2.27.5_nowqz4jutkd4a233czbfk7jsgu - eslint-plugin-jsx-a11y: 6.7.1_eslint@8.33.0 - eslint-plugin-prettier: 4.2.1_jqplj6qf3uqpxpu4gdyhwwasnq - eslint-plugin-react: 7.32.2_eslint@8.33.0 - eslint-plugin-react-hooks: 4.6.0_eslint@8.33.0 + eslint-import-resolver-typescript: 3.5.3_mvgyw3chnqkp6sgfmmtihyjpnm + eslint-plugin-import: 2.27.5_inmo4nrctlhmfx73hzu6aogupa + eslint-plugin-jsx-a11y: 6.7.1_eslint@8.34.0 + eslint-plugin-prettier: 4.2.1_u5wnrdwibbfomslmnramz52buy + eslint-plugin-react: 7.32.2_eslint@8.34.0 + eslint-plugin-react-hooks: 4.6.0_eslint@8.34.0 husky: 8.0.3 - jest: 29.4.1_@types+node@18.11.18 - jest-environment-jsdom: 29.4.1 + jest: 29.4.2_@types+node@18.13.0 + jest-environment-jsdom: 29.4.2 jest-transform-stub: 2.0.0 - jest-watch-typeahead: 2.2.2_jest@29.4.1 - prettier: 2.8.3 + jest-watch-typeahead: 2.2.2_jest@29.4.2 + prettier: 2.8.4 react-test-renderer: 18.2.0_react@18.2.0 typescript: 4.9.5 - vite: 4.0.4_@types+node@18.11.18 - vite-plugin-eslint: 1.8.1_eslint@8.33.0+vite@4.0.4 - vite-plugin-istanbul: 4.0.0_vite@4.0.4 - vite-plugin-svgr: 2.4.0_vite@4.0.4 + vite: 4.1.1_@types+node@18.13.0 + vite-plugin-eslint: 1.8.1_eslint@8.34.0+vite@4.1.1 + vite-plugin-istanbul: 4.0.0_vite@4.1.1 + vite-plugin-svgr: 2.4.0_vite@4.1.1 vite-tsconfig-paths: 4.0.5_typescript@4.9.5 packages: @@ -203,7 +203,7 @@ packages: - supports-color dev: true - /@babel/eslint-parser/7.18.2_wyhkjhzegujbjwddfb5na6gduu: + /@babel/eslint-parser/7.18.2_4hiysdvhwszrzvk6njkclnrv5u: resolution: {integrity: sha512-oFQYkE8SuH14+uR51JVAmdqwKYXGRjEXx7s+WiagVjqQ+HPE+nnwyF2qlVG8evUsUHmPcA+6YXMEDbIhEyQc5A==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} peerDependencies: @@ -214,7 +214,7 @@ packages: optional: true dependencies: '@babel/core': 7.18.6 - eslint: 8.33.0 + eslint: 8.34.0 eslint-scope: 5.1.1 eslint-visitor-keys: 2.1.0 semver: 6.3.0 @@ -2109,15 +2109,15 @@ packages: '@commitlint/execute-rule': 17.4.0 '@commitlint/resolve-extends': 17.4.0 '@commitlint/types': 17.4.0 - '@types/node': 18.11.18 + '@types/node': 18.13.0 chalk: 4.1.2 cosmiconfig: 8.0.0 - cosmiconfig-typescript-loader: 4.0.0_wup64ucrbpz6nyxdtffrcfuej4 + cosmiconfig-typescript-loader: 4.0.0_675xcr52t65rpohei3x75qh2i4 lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 resolve-from: 5.0.0 - ts-node: 10.9.0_bdgp3l2zgaopogaavxusmetvge + ts-node: 10.9.0_4bewfcp2iebiwuold25d6rgcsy typescript: 4.9.5 transitivePeerDependencies: - '@swc/core' @@ -2335,8 +2335,8 @@ packages: dev: true optional: true - /@esbuild/android-arm/0.17.5: - resolution: {integrity: sha512-crmPUzgCmF+qZXfl1YkiFoUta2XAfixR1tEnr/gXIixE+WL8Z0BGqfydP5oox0EUOgQMMRgtATtakyAcClQVqQ==} + /@esbuild/android-arm/0.17.7: + resolution: {integrity: sha512-Np6Lg8VUiuzHP5XvHU7zfSVPN4ILdiOhxA1GQ1uvCK2T2l3nI8igQV0c9FJx4hTkq8WGqhGEvn5UuRH8jMkExg==} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -2353,8 +2353,8 @@ packages: dev: true optional: true - /@esbuild/android-arm64/0.17.5: - resolution: {integrity: sha512-KHWkDqYAMmKZjY4RAN1PR96q6UOtfkWlTS8uEwWxdLtkRt/0F/csUhXIrVfaSIFxnscIBMPynGfhsMwQDRIBQw==} + /@esbuild/android-arm64/0.17.7: + resolution: {integrity: sha512-fOUBZvcbtbQJIj2K/LMKcjULGfXLV9R4qjXFsi3UuqFhIRJHz0Fp6kFjsMFI6vLuPrfC5G9Dmh+3RZOrSKY2Lg==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -2371,8 +2371,8 @@ packages: dev: true optional: true - /@esbuild/android-x64/0.17.5: - resolution: {integrity: sha512-8fI/AnIdmWz/+1iza2WrCw8kwXK9wZp/yZY/iS8ioC+U37yJCeppi9EHY05ewJKN64ASoBIseufZROtcFnX5GA==} + /@esbuild/android-x64/0.17.7: + resolution: {integrity: sha512-6YILpPvop1rPAvaO/n2iWQL45RyTVTR/1SK7P6Xi2fyu+hpEeX22fE2U2oJd1sfpovUJOWTRdugjddX6QCup3A==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -2389,8 +2389,8 @@ packages: dev: true optional: true - /@esbuild/darwin-arm64/0.17.5: - resolution: {integrity: sha512-EAvaoyIySV6Iif3NQCglUNpnMfHSUgC5ugt2efl3+QDntucJe5spn0udNZjTgNi6tKVqSceOw9tQ32liNZc1Xw==} + /@esbuild/darwin-arm64/0.17.7: + resolution: {integrity: sha512-7i0gfFsDt1BBiurZz5oZIpzfxqy5QkJmhXdtrf2Hma/gI9vL2AqxHhRBoI1NeWc9IhN1qOzWZrslhiXZweMSFg==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -2407,8 +2407,8 @@ packages: dev: true optional: true - /@esbuild/darwin-x64/0.17.5: - resolution: {integrity: sha512-ha7QCJh1fuSwwCgoegfdaljowwWozwTDjBgjD3++WAy/qwee5uUi1gvOg2WENJC6EUyHBOkcd3YmLDYSZ2TPPA==} + /@esbuild/darwin-x64/0.17.7: + resolution: {integrity: sha512-hRvIu3vuVIcv4SJXEKOHVsNssM5tLE2xWdb9ZyJqsgYp+onRa5El3VJ4+WjTbkf/A2FD5wuMIbO2FCTV39LE0w==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -2425,8 +2425,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-arm64/0.17.5: - resolution: {integrity: sha512-VbdXJkn2aI2pQ/wxNEjEcnEDwPpxt3CWWMFYmO7CcdFBoOsABRy2W8F3kjbF9F/pecEUDcI3b5i2w+By4VQFPg==} + /@esbuild/freebsd-arm64/0.17.7: + resolution: {integrity: sha512-2NJjeQ9kiabJkVXLM3sHkySqkL1KY8BeyLams3ITyiLW10IwDL0msU5Lq1cULCn9zNxt1Seh1I6QrqyHUvOtQw==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -2443,8 +2443,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-x64/0.17.5: - resolution: {integrity: sha512-olgGYND1/XnnWxwhjtY3/ryjOG/M4WfcA6XH8dBTH1cxMeBemMODXSFhkw71Kf4TeZFFTN25YOomaNh0vq2iXg==} + /@esbuild/freebsd-x64/0.17.7: + resolution: {integrity: sha512-8kSxlbjuLYMoIgvRxPybirHJeW45dflyIgHVs+jzMYJf87QOay1ZUTzKjNL3vqHQjmkSn8p6KDfHVrztn7Rprw==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -2461,8 +2461,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm/0.17.5: - resolution: {integrity: sha512-YBdCyQwA3OQupi6W2/WO4FnI+NWFWe79cZEtlbqSESOHEg7a73htBIRiE6uHPQe7Yp5E4aALv+JxkRLGEUL7tw==} + /@esbuild/linux-arm/0.17.7: + resolution: {integrity: sha512-07RsAAzznWqdfJC+h3L2UVWwnUHepsFw5GmzySnUspHHb7glJ1+47rvlcH0SeUtoVOs8hF4/THgZbtJRyALaJA==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -2479,8 +2479,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm64/0.17.5: - resolution: {integrity: sha512-8a0bqSwu3OlLCfu2FBbDNgQyBYdPJh1B9PvNX7jMaKGC9/KopgHs37t+pQqeMLzcyRqG6z55IGNQAMSlCpBuqg==} + /@esbuild/linux-arm64/0.17.7: + resolution: {integrity: sha512-43Bbhq3Ia/mGFTCRA4NlY8VRH3dLQltJ4cqzhSfq+cdvdm9nKJXVh4NUkJvdZgEZIkf/ufeMmJ0/22v9btXTcw==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -2497,8 +2497,8 @@ packages: dev: true optional: true - /@esbuild/linux-ia32/0.17.5: - resolution: {integrity: sha512-uCwm1r/+NdP7vndctgq3PoZrnmhmnecWAr114GWMRwg2QMFFX+kIWnp7IO220/JLgnXK/jP7VKAFBGmeOYBQYQ==} + /@esbuild/linux-ia32/0.17.7: + resolution: {integrity: sha512-ViYkfcfnbwOoTS7xE4DvYFv7QOlW8kPBuccc4erJ0jx2mXDPR7e0lYOH9JelotS9qe8uJ0s2i3UjUvjunEp53A==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -2515,8 +2515,8 @@ packages: dev: true optional: true - /@esbuild/linux-loong64/0.17.5: - resolution: {integrity: sha512-3YxhSBl5Sb6TtBjJu+HP93poBruFzgXmf3PVfIe4xOXMj1XpxboYZyw3W8BhoX/uwxzZz4K1I99jTE/5cgDT1g==} + /@esbuild/linux-loong64/0.17.7: + resolution: {integrity: sha512-H1g+AwwcqYQ/Hl/sMcopRcNLY/fysIb/ksDfCa3/kOaHQNhBrLeDYw+88VAFV5U6oJL9GqnmUj72m9Nv3th3hA==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -2533,8 +2533,8 @@ packages: dev: true optional: true - /@esbuild/linux-mips64el/0.17.5: - resolution: {integrity: sha512-Hy5Z0YVWyYHdtQ5mfmfp8LdhVwGbwVuq8mHzLqrG16BaMgEmit2xKO+iDakHs+OetEx0EN/2mUzDdfdktI+Nmg==} + /@esbuild/linux-mips64el/0.17.7: + resolution: {integrity: sha512-MDLGrVbTGYtmldlbcxfeDPdhxttUmWoX3ovk9u6jc8iM+ueBAFlaXKuUMCoyP/zfOJb+KElB61eSdBPSvNcCEg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -2551,8 +2551,8 @@ packages: dev: true optional: true - /@esbuild/linux-ppc64/0.17.5: - resolution: {integrity: sha512-5dbQvBLbU/Y3Q4ABc9gi23hww1mQcM7KZ9KBqabB7qhJswYMf8WrDDOSw3gdf3p+ffmijMd28mfVMvFucuECyg==} + /@esbuild/linux-ppc64/0.17.7: + resolution: {integrity: sha512-UWtLhRPKzI+v2bKk4j9rBpGyXbLAXLCOeqt1tLVAt1mfagHpFjUzzIHCpPiUfY3x1xY5e45/+BWzGpqqvSglNw==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -2569,8 +2569,8 @@ packages: dev: true optional: true - /@esbuild/linux-riscv64/0.17.5: - resolution: {integrity: sha512-fp/KUB/ZPzEWGTEUgz9wIAKCqu7CjH1GqXUO2WJdik1UNBQ7Xzw7myIajpxztE4Csb9504ERiFMxZg5KZ6HlZQ==} + /@esbuild/linux-riscv64/0.17.7: + resolution: {integrity: sha512-3C/RTKqZauUwBYtIQAv7ELTJd+H2dNKPyzwE2ZTbz2RNrNhNHRoeKnG5C++eM6nSZWUCLyyaWfq1v1YRwBS/+A==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -2587,8 +2587,8 @@ packages: dev: true optional: true - /@esbuild/linux-s390x/0.17.5: - resolution: {integrity: sha512-kRV3yw19YDqHTp8SfHXfObUFXlaiiw4o2lvT1XjsPZ++22GqZwSsYWJLjMi1Sl7j9qDlDUduWDze/nQx0d6Lzw==} + /@esbuild/linux-s390x/0.17.7: + resolution: {integrity: sha512-x7cuRSCm998KFZqGEtSo8rI5hXLxWji4znZkBhg2FPF8A8lxLLCsSXe2P5utf0RBQflb3K97dkEH/BJwTqrbDw==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -2605,8 +2605,8 @@ packages: dev: true optional: true - /@esbuild/linux-x64/0.17.5: - resolution: {integrity: sha512-vnxuhh9e4pbtABNLbT2ANW4uwQ/zvcHRCm1JxaYkzSehugoFd5iXyC4ci1nhXU13mxEwCnrnTIiiSGwa/uAF1g==} + /@esbuild/linux-x64/0.17.7: + resolution: {integrity: sha512-1Z2BtWgM0Wc92WWiZR5kZ5eC+IetI++X+nf9NMbUvVymt74fnQqwgM5btlTW7P5uCHfq03u5MWHjIZa4o+TnXQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -2623,8 +2623,8 @@ packages: dev: true optional: true - /@esbuild/netbsd-x64/0.17.5: - resolution: {integrity: sha512-cigBpdiSx/vPy7doUyImsQQBnBjV5f1M99ZUlaJckDAJjgXWl6y9W17FIfJTy8TxosEF6MXq+fpLsitMGts2nA==} + /@esbuild/netbsd-x64/0.17.7: + resolution: {integrity: sha512-//VShPN4hgbmkDjYNCZermIhj8ORqoPNmAnwSPqPtBB0xOpHrXMlJhsqLNsgoBm0zi/5tmy//WyL6g81Uq2c6Q==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -2641,8 +2641,8 @@ packages: dev: true optional: true - /@esbuild/openbsd-x64/0.17.5: - resolution: {integrity: sha512-VdqRqPVIjjZfkf40LrqOaVuhw9EQiAZ/GNCSM2UplDkaIzYVsSnycxcFfAnHdWI8Gyt6dO15KHikbpxwx+xHbw==} + /@esbuild/openbsd-x64/0.17.7: + resolution: {integrity: sha512-IQ8BliXHiOsbQEOHzc7mVLIw2UYPpbOXJQ9cK1nClNYQjZthvfiA6rWZMz4BZpVzHZJ+/H2H23cZwRJ1NPYOGg==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -2659,8 +2659,8 @@ packages: dev: true optional: true - /@esbuild/sunos-x64/0.17.5: - resolution: {integrity: sha512-ItxPaJ3MBLtI4nK+mALLEoUs6amxsx+J1ibnfcYMkqaCqHST1AkF4aENpBehty3czqw64r/XqL+W9WqU6kc2Qw==} + /@esbuild/sunos-x64/0.17.7: + resolution: {integrity: sha512-phO5HvU3SyURmcW6dfQXX4UEkFREUwaoiTgi1xH+CAFKPGsrcG6oDp1U70yQf5lxRKujoSCEIoBr0uFykJzN2g==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -2677,8 +2677,8 @@ packages: dev: true optional: true - /@esbuild/win32-arm64/0.17.5: - resolution: {integrity: sha512-4u2Q6qsJTYNFdS9zHoAi80spzf78C16m2wla4eJPh4kSbRv+BpXIfl6TmBSWupD8e47B1NrTfrOlEuco7mYQtg==} + /@esbuild/win32-arm64/0.17.7: + resolution: {integrity: sha512-G/cRKlYrwp1B0uvzEdnFPJ3A6zSWjnsRrWivsEW0IEHZk+czv0Bmiwa51RncruHLjQ4fGsvlYPmCmwzmutPzHA==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -2695,8 +2695,8 @@ packages: dev: true optional: true - /@esbuild/win32-ia32/0.17.5: - resolution: {integrity: sha512-KYlm+Xu9TXsfTWAcocLuISRtqxKp/Y9ZBVg6CEEj0O5J9mn7YvBKzAszo2j1ndyzUPk+op+Tie2PJeN+BnXGqQ==} + /@esbuild/win32-ia32/0.17.7: + resolution: {integrity: sha512-/yMNVlMew07NrOflJdRAZcMdUoYTOCPbCHx0eHtg55l87wXeuhvYOPBQy5HLX31Ku+W2XsBD5HnjUjEUsTXJug==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -2713,8 +2713,8 @@ packages: dev: true optional: true - /@esbuild/win32-x64/0.17.5: - resolution: {integrity: sha512-XgA9qWRqby7xdYXuF6KALsn37QGBMHsdhmnpjfZtYxKxbTOwfnDM6MYi2WuUku5poNaX2n9XGVr20zgT/2QwCw==} + /@esbuild/win32-x64/0.17.7: + resolution: {integrity: sha512-K9/YybM6WZO71x73Iyab6mwieHtHjm9hrPR/a9FBPZmFO3w+fJaM2uu2rt3JYf/rZR24MFwTliI8VSoKKOtYtg==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -2739,43 +2739,43 @@ packages: - supports-color dev: true - /@fortawesome/fontawesome-common-types/6.2.1: - resolution: {integrity: sha512-Sz07mnQrTekFWLz5BMjOzHl/+NooTdW8F8kDQxjWwbpOJcnoSg4vUDng8d/WR1wOxM0O+CY9Zw0nR054riNYtQ==} + /@fortawesome/fontawesome-common-types/6.3.0: + resolution: {integrity: sha512-4BC1NMoacEBzSXRwKjZ/X/gmnbp/HU5Qqat7E8xqorUtBFZS+bwfGH5/wqOC2K6GV0rgEobp3OjGRMa5fK9pFg==} engines: {node: '>=6'} requiresBuild: true dev: false - /@fortawesome/fontawesome-svg-core/6.2.1: - resolution: {integrity: sha512-HELwwbCz6C1XEcjzyT1Jugmz2NNklMrSPjZOWMlc+ZsHIVk+XOvOXLGGQtFBwSyqfJDNgRq4xBCwWOaZ/d9DEA==} + /@fortawesome/fontawesome-svg-core/6.3.0: + resolution: {integrity: sha512-uz9YifyKlixV6AcKlOX8WNdtF7l6nakGyLYxYaCa823bEBqyj/U2ssqtctO38itNEwXb8/lMzjdoJ+aaJuOdrw==} engines: {node: '>=6'} requiresBuild: true dependencies: - '@fortawesome/fontawesome-common-types': 6.2.1 + '@fortawesome/fontawesome-common-types': 6.3.0 dev: false - /@fortawesome/free-regular-svg-icons/6.2.1: - resolution: {integrity: sha512-wiqcNDNom75x+pe88FclpKz7aOSqS2lOivZeicMV5KRwOAeypxEYWAK/0v+7r+LrEY30+qzh8r2XDaEHvoLsMA==} + /@fortawesome/free-regular-svg-icons/6.3.0: + resolution: {integrity: sha512-cZnwiVHZ51SVzWHOaNCIA+u9wevZjCuAGSvSYpNlm6A4H4Vhwh8481Bf/5rwheIC3fFKlgXxLKaw8Xeroz8Ntg==} engines: {node: '>=6'} requiresBuild: true dependencies: - '@fortawesome/fontawesome-common-types': 6.2.1 + '@fortawesome/fontawesome-common-types': 6.3.0 dev: false - /@fortawesome/free-solid-svg-icons/6.2.1: - resolution: {integrity: sha512-oKuqrP5jbfEPJWTij4sM+/RvgX+RMFwx3QZCZcK9PrBDgxC35zuc7AOFsyMjMd/PIFPeB2JxyqDr5zs/DZFPPw==} + /@fortawesome/free-solid-svg-icons/6.3.0: + resolution: {integrity: sha512-x5tMwzF2lTH8pyv8yeZRodItP2IVlzzmBuD1M7BjawWgg9XAvktqJJ91Qjgoaf8qJpHQ8FEU9VxRfOkLhh86QA==} engines: {node: '>=6'} requiresBuild: true dependencies: - '@fortawesome/fontawesome-common-types': 6.2.1 + '@fortawesome/fontawesome-common-types': 6.3.0 dev: false - /@fortawesome/react-fontawesome/0.2.0_z27bm67dtmuyyvss23ckjdrcuy: + /@fortawesome/react-fontawesome/0.2.0_d5rbrisxfyemehbvmdbryvgjte: resolution: {integrity: sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==} peerDependencies: '@fortawesome/fontawesome-svg-core': ~1 || ~6 react: '>=16.3 || 18' dependencies: - '@fortawesome/fontawesome-svg-core': 6.2.1 + '@fortawesome/fontawesome-svg-core': 6.3.0 prop-types: 15.8.1 react: 18.2.0 dev: false @@ -2816,20 +2816,20 @@ packages: engines: {node: '>=8'} dev: true - /@jest/console/29.4.1: - resolution: {integrity: sha512-m+XpwKSi3PPM9znm5NGS8bBReeAJJpSkL1OuFCqaMaJL2YX9YXLkkI+MBchMPwu+ZuM2rynL51sgfkQteQ1CKQ==} + /@jest/console/29.4.2: + resolution: {integrity: sha512-0I/rEJwMpV9iwi9cDEnT71a5nNGK9lj8Z4+1pRAU2x/thVXCDnaTGrvxyK+cAqZTFVFCiR+hfVrP4l2m+dCmQg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.4.1 - '@types/node': 18.11.18 + '@jest/types': 29.4.2 + '@types/node': 18.13.0 chalk: 4.1.2 - jest-message-util: 29.4.1 - jest-util: 29.4.1 + jest-message-util: 29.4.2 + jest-util: 29.4.2 slash: 3.0.0 dev: true - /@jest/core/29.4.1: - resolution: {integrity: sha512-RXFTohpBqpaTebNdg5l3I5yadnKo9zLBajMT0I38D0tDhreVBYv3fA8kywthI00sWxPztWLD3yjiUkewwu/wKA==} + /@jest/core/29.4.2: + resolution: {integrity: sha512-KGuoQah0P3vGNlaS/l9/wQENZGNKGoWb+OPxh3gz+YzG7/XExvYu34MzikRndQCdM2S0tzExN4+FL37i6gZmCQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -2837,32 +2837,32 @@ packages: node-notifier: optional: true dependencies: - '@jest/console': 29.4.1 - '@jest/reporters': 29.4.1 - '@jest/test-result': 29.4.1 - '@jest/transform': 29.4.1 - '@jest/types': 29.4.1 - '@types/node': 18.11.18 + '@jest/console': 29.4.2 + '@jest/reporters': 29.4.2 + '@jest/test-result': 29.4.2 + '@jest/transform': 29.4.2 + '@jest/types': 29.4.2 + '@types/node': 18.13.0 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.3.2 exit: 0.1.2 graceful-fs: 4.2.10 - jest-changed-files: 29.4.0 - jest-config: 29.4.1_@types+node@18.11.18 - jest-haste-map: 29.4.1 - jest-message-util: 29.4.1 - jest-regex-util: 29.2.0 - jest-resolve: 29.4.1 - jest-resolve-dependencies: 29.4.1 - jest-runner: 29.4.1 - jest-runtime: 29.4.1 - jest-snapshot: 29.4.1 - jest-util: 29.4.1 - jest-validate: 29.4.1 - jest-watcher: 29.4.1 + jest-changed-files: 29.4.2 + jest-config: 29.4.2_@types+node@18.13.0 + jest-haste-map: 29.4.2 + jest-message-util: 29.4.2 + jest-regex-util: 29.4.2 + jest-resolve: 29.4.2 + jest-resolve-dependencies: 29.4.2 + jest-runner: 29.4.2 + jest-runtime: 29.4.2 + jest-snapshot: 29.4.2 + jest-util: 29.4.2 + jest-validate: 29.4.2 + jest-watcher: 29.4.2 micromatch: 4.0.5 - pretty-format: 29.4.1 + pretty-format: 29.4.2 slash: 3.0.0 strip-ansi: 6.0.1 transitivePeerDependencies: @@ -2870,59 +2870,66 @@ packages: - ts-node dev: true - /@jest/environment/29.4.1: - resolution: {integrity: sha512-pJ14dHGSQke7Q3mkL/UZR9ZtTOxqskZaC91NzamEH4dlKRt42W+maRBXiw/LWkdJe+P0f/zDR37+SPMplMRlPg==} + /@jest/environment/29.4.2: + resolution: {integrity: sha512-JKs3VUtse0vQfCaFGJRX1bir9yBdtasxziSyu+pIiEllAQOe4oQhdCYIf3+Lx+nGglFktSKToBnRJfD5QKp+NQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/fake-timers': 29.4.1 - '@jest/types': 29.4.1 - '@types/node': 18.11.18 - jest-mock: 29.4.1 + '@jest/fake-timers': 29.4.2 + '@jest/types': 29.4.2 + '@types/node': 18.13.0 + jest-mock: 29.4.2 dev: true /@jest/expect-utils/29.4.1: resolution: {integrity: sha512-w6YJMn5DlzmxjO00i9wu2YSozUYRBhIoJ6nQwpMYcBMtiqMGJm1QBzOf6DDgRao8dbtpDoaqLg6iiQTvv0UHhQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - jest-get-type: 29.2.0 + jest-get-type: 29.4.2 dev: true - /@jest/expect/29.4.1: - resolution: {integrity: sha512-ZxKJP5DTUNF2XkpJeZIzvnzF1KkfrhEF6Rz0HGG69fHl6Bgx5/GoU3XyaeFYEjuuKSOOsbqD/k72wFvFxc3iTw==} + /@jest/expect-utils/29.4.2: + resolution: {integrity: sha512-Dd3ilDJpBnqa0GiPN7QrudVs0cczMMHtehSo2CSTjm3zdHx0RcpmhFNVEltuEFeqfLIyWKFI224FsMSQ/nsJQA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - expect: 29.4.1 - jest-snapshot: 29.4.1 + jest-get-type: 29.4.2 + dev: true + + /@jest/expect/29.4.2: + resolution: {integrity: sha512-NUAeZVApzyaeLjfWIV/64zXjA2SS+NuUPHpAlO7IwVMGd5Vf9szTl9KEDlxY3B4liwLO31os88tYNHl6cpjtKQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + expect: 29.4.2 + jest-snapshot: 29.4.2 transitivePeerDependencies: - supports-color dev: true - /@jest/fake-timers/29.4.1: - resolution: {integrity: sha512-/1joI6rfHFmmm39JxNfmNAO3Nwm6Y0VoL5fJDy7H1AtWrD1CgRtqJbN9Ld6rhAkGO76qqp4cwhhxJ9o9kYjQMw==} + /@jest/fake-timers/29.4.2: + resolution: {integrity: sha512-Ny1u0Wg6kCsHFWq7A/rW/tMhIedq2siiyHyLpHCmIhP7WmcAmd2cx95P+0xtTZlj5ZbJxIRQi4OPydZZUoiSQQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.4.1 + '@jest/types': 29.4.2 '@sinonjs/fake-timers': 10.0.2 - '@types/node': 18.11.18 - jest-message-util: 29.4.1 - jest-mock: 29.4.1 - jest-util: 29.4.1 + '@types/node': 18.13.0 + jest-message-util: 29.4.2 + jest-mock: 29.4.2 + jest-util: 29.4.2 dev: true - /@jest/globals/29.4.1: - resolution: {integrity: sha512-znoK2EuFytbHH0ZSf2mQK2K1xtIgmaw4Da21R2C/NE/+NnItm5mPEFQmn8gmF3f0rfOlmZ3Y3bIf7bFj7DHxAA==} + /@jest/globals/29.4.2: + resolution: {integrity: sha512-zCk70YGPzKnz/I9BNFDPlK+EuJLk21ur/NozVh6JVM86/YYZtZHqxFFQ62O9MWq7uf3vIZnvNA0BzzrtxD9iyg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.4.1 - '@jest/expect': 29.4.1 - '@jest/types': 29.4.1 - jest-mock: 29.4.1 + '@jest/environment': 29.4.2 + '@jest/expect': 29.4.2 + '@jest/types': 29.4.2 + jest-mock: 29.4.2 transitivePeerDependencies: - supports-color dev: true - /@jest/reporters/29.4.1: - resolution: {integrity: sha512-AISY5xpt2Xpxj9R6y0RF1+O6GRy9JsGa8+vK23Lmzdy1AYcpQn5ItX79wJSsTmfzPKSAcsY1LNt/8Y5Xe5LOSg==} + /@jest/reporters/29.4.2: + resolution: {integrity: sha512-10yw6YQe75zCgYcXgEND9kw3UZZH5tJeLzWv4vTk/2mrS1aY50A37F+XT2hPO5OqQFFnUWizXD8k1BMiATNfUw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -2931,12 +2938,12 @@ packages: optional: true dependencies: '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.4.1 - '@jest/test-result': 29.4.1 - '@jest/transform': 29.4.1 - '@jest/types': 29.4.1 + '@jest/console': 29.4.2 + '@jest/test-result': 29.4.2 + '@jest/transform': 29.4.2 + '@jest/types': 29.4.2 '@jridgewell/trace-mapping': 0.3.15 - '@types/node': 18.11.18 + '@types/node': 18.13.0 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -2947,9 +2954,9 @@ packages: istanbul-lib-report: 3.0.0 istanbul-lib-source-maps: 4.0.1 istanbul-reports: 3.1.5 - jest-message-util: 29.4.1 - jest-util: 29.4.1 - jest-worker: 29.4.1 + jest-message-util: 29.4.2 + jest-util: 29.4.2 + jest-worker: 29.4.2 slash: 3.0.0 string-length: 4.0.2 strip-ansi: 6.0.1 @@ -2965,8 +2972,15 @@ packages: '@sinclair/typebox': 0.25.21 dev: true - /@jest/source-map/29.2.0: - resolution: {integrity: sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==} + /@jest/schemas/29.4.2: + resolution: {integrity: sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.25.21 + dev: true + + /@jest/source-map/29.4.2: + resolution: {integrity: sha512-tIoqV5ZNgYI9XCKXMqbYe5JbumcvyTgNN+V5QW4My033lanijvCD0D4PI9tBw4pRTqWOc00/7X3KVvUh+qnF4Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jridgewell/trace-mapping': 0.3.15 @@ -2974,23 +2988,23 @@ packages: graceful-fs: 4.2.10 dev: true - /@jest/test-result/29.4.1: - resolution: {integrity: sha512-WRt29Lwt+hEgfN8QDrXqXGgCTidq1rLyFqmZ4lmJOpVArC8daXrZWkWjiaijQvgd3aOUj2fM8INclKHsQW9YyQ==} + /@jest/test-result/29.4.2: + resolution: {integrity: sha512-HZsC3shhiHVvMtP+i55MGR5bPcc3obCFbA5bzIOb8pCjwBZf11cZliJncCgaVUbC5yoQNuGqCkC0Q3t6EItxZA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/console': 29.4.1 - '@jest/types': 29.4.1 + '@jest/console': 29.4.2 + '@jest/types': 29.4.2 '@types/istanbul-lib-coverage': 2.0.4 collect-v8-coverage: 1.0.1 dev: true - /@jest/test-sequencer/29.4.1: - resolution: {integrity: sha512-v5qLBNSsM0eHzWLXsQ5fiB65xi49A3ILPSFQKPXzGL4Vyux0DPZAIN7NAFJa9b4BiTDP9MBF/Zqc/QA1vuiJ0w==} + /@jest/test-sequencer/29.4.2: + resolution: {integrity: sha512-9Z2cVsD6CcObIVrWigHp2McRJhvCxL27xHtrZFgNC1RwnoSpDx6fZo8QYjJmziFlW9/hr78/3sxF54S8B6v8rg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/test-result': 29.4.1 + '@jest/test-result': 29.4.2 graceful-fs: 4.2.10 - jest-haste-map: 29.4.1 + jest-haste-map: 29.4.2 slash: 3.0.0 dev: true @@ -3017,25 +3031,25 @@ packages: - supports-color dev: true - /@jest/transform/29.4.1: - resolution: {integrity: sha512-5w6YJrVAtiAgr0phzKjYd83UPbCXsBRTeYI4BXokv9Er9CcrH9hfXL/crCvP2d2nGOcovPUnlYiLPFLZrkG5Hg==} + /@jest/transform/29.4.2: + resolution: {integrity: sha512-kf1v5iTJHn7p9RbOsBuc/lcwyPtJaZJt5885C98omWz79NIeD3PfoiiaPSu7JyCyFzNOIzKhmMhQLUhlTL9BvQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/core': 7.20.12 - '@jest/types': 29.4.1 + '@jest/types': 29.4.2 '@jridgewell/trace-mapping': 0.3.15 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 convert-source-map: 2.0.0 fast-json-stable-stringify: 2.1.0 graceful-fs: 4.2.10 - jest-haste-map: 29.4.1 - jest-regex-util: 29.2.0 - jest-util: 29.4.1 + jest-haste-map: 29.4.2 + jest-regex-util: 29.4.2 + jest-util: 29.4.2 micromatch: 4.0.5 pirates: 4.0.5 slash: 3.0.0 - write-file-atomic: 5.0.0 + write-file-atomic: 4.0.2 transitivePeerDependencies: - supports-color dev: true @@ -3046,19 +3060,19 @@ packages: dependencies: '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.11.18 + '@types/node': 18.13.0 '@types/yargs': 15.0.14 chalk: 4.1.2 dev: true - /@jest/types/29.4.1: - resolution: {integrity: sha512-zbrAXDUOnpJ+FMST2rV7QZOgec8rskg2zv8g2ajeqitp4tvZiyqTCYXANrKsM+ryj5o+LI+ZN2EgU9drrkiwSA==} + /@jest/types/29.4.2: + resolution: {integrity: sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/schemas': 29.4.0 + '@jest/schemas': 29.4.2 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.11.18 + '@types/node': 18.13.0 '@types/yargs': 17.0.10 chalk: 4.1.2 dev: true @@ -3108,12 +3122,12 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true - /@limegrass/eslint-plugin-import-alias/1.0.6_eslint@8.33.0: + /@limegrass/eslint-plugin-import-alias/1.0.6_eslint@8.34.0: resolution: {integrity: sha512-BtPmdHbL4NmkVh2wMnOboyOCrdLOpBqwwtBIsB0/giTiALw/UTHD9TyH4vVnbDOuWPZQgE6kKloJ9G77FApt7w==} peerDependencies: eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 dependencies: - eslint: 8.33.0 + eslint: 8.34.0 find-up: 5.0.0 fs-extra: 10.1.0 micromatch: 4.0.5 @@ -3121,8 +3135,8 @@ packages: tsconfig-paths: 3.14.1 dev: true - /@mui/base/5.0.0-alpha.116_5ndqzdd6t4rivxsukjv3i3ak2q: - resolution: {integrity: sha512-VwhifWdrfHc4/ZdqRZ4Gf+7P39sovNN24By1YVZdvJ9fvp0Sr8sNftGUCjYXXz+xCXVBQDXvhfxMwZrj2MvJvA==} + /@mui/base/5.0.0-alpha.117_5ndqzdd6t4rivxsukjv3i3ak2q: + resolution: {integrity: sha512-3GlRSZdSrvDQ4k03dSV2rM+97JbNWimFOqGsE7n7Mi8WuBSYCgnPe56bQp3E5cShOrTn11dGH8FRCmVMcCEXqQ==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || 18 @@ -3145,11 +3159,11 @@ packages: react-is: 18.2.0 dev: false - /@mui/core-downloads-tracker/5.11.7: - resolution: {integrity: sha512-lZgX7XQTk0zVcpwEa80r+T4y09dosnUxWvFPSikU/2Hh5wnyNOek8WfJwGCNsaRiXJHMi5eHY+z8oku4u5lgNw==} + /@mui/core-downloads-tracker/5.11.8: + resolution: {integrity: sha512-n/uJRIwZAaJaROaOA4VzycxDo27cusnrRzfycnAkAP5gBndwOJQ1CXjd1Y7hJe5eorj/ukixC7IZD+qCClMCMg==} dev: false - /@mui/icons-material/5.11.0_m3y2ykptchyoygtoroit6l3ehq: + /@mui/icons-material/5.11.0_3psqo62dtzuc5tpd3awdluze4i: resolution: {integrity: sha512-I2LaOKqO8a0xcLGtIozC9xoXjZAto5G5gh0FYUMAlbsIHNHIjn4Xrw9rvjY20vZonyiGrZNMAlAXYkY6JvhF6A==} engines: {node: '>=12.0.0'} peerDependencies: @@ -3161,13 +3175,13 @@ packages: optional: true dependencies: '@babel/runtime': 7.20.6 - '@mui/material': 5.11.7_rqh7qj4464ntrqrt6banhaqg4q + '@mui/material': 5.11.8_rqh7qj4464ntrqrt6banhaqg4q '@types/react': 18.0.27 react: 18.2.0 dev: false - /@mui/material/5.11.7_rqh7qj4464ntrqrt6banhaqg4q: - resolution: {integrity: sha512-wDv7Pc6kMe9jeWkmCLt4JChd1lPc2u23JQHpB35L2VwQowpNFoDfIwqi0sYCnZTMKlRc7lza8LqwSwHl2G52Rw==} + /@mui/material/5.11.8_rqh7qj4464ntrqrt6banhaqg4q: + resolution: {integrity: sha512-MpIVmtj9VJBhPHvPWoMkfCPpmVGXT4q43PtCJsdKIdc7W9/nG3Kpqw2oWyw+UxG5xG7eLhmfRFGPKvj4/WopEQ==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -3186,9 +3200,9 @@ packages: '@babel/runtime': 7.20.7 '@emotion/react': 11.10.5_3stiutgnnbnfnf3uowm5cip22i '@emotion/styled': 11.10.5_jrh5enlbqfbnumycmktdqgd6se - '@mui/base': 5.0.0-alpha.116_5ndqzdd6t4rivxsukjv3i3ak2q - '@mui/core-downloads-tracker': 5.11.7 - '@mui/system': 5.11.7_gzalmy7izvhol7vh4xfy3dq6ua + '@mui/base': 5.0.0-alpha.117_5ndqzdd6t4rivxsukjv3i3ak2q + '@mui/core-downloads-tracker': 5.11.8 + '@mui/system': 5.11.8_gzalmy7izvhol7vh4xfy3dq6ua '@mui/types': 7.2.3_@types+react@18.0.27 '@mui/utils': 5.11.7_react@18.2.0 '@types/react': 18.0.27 @@ -3219,8 +3233,8 @@ packages: react: 18.2.0 dev: false - /@mui/styled-engine/5.11.0_dovxhg2tvkkxkdnqyoum6wzcxm: - resolution: {integrity: sha512-AF06K60Zc58qf0f7X+Y/QjaHaZq16znliLnGc9iVrV/+s8Ln/FCoeNuFvhlCbZZQ5WQcJvcy59zp0nXrklGGPQ==} + /@mui/styled-engine/5.11.8_dovxhg2tvkkxkdnqyoum6wzcxm: + resolution: {integrity: sha512-iSpZp9AoeictsDi5xAQ4PGXu7mKtQyzMl7ZaWpHIGMFpsNnfY3NQNg+wkj/gpsAZ+Zg+IIyD+t+ig71Kr9fa0w==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.4.1 @@ -3272,8 +3286,8 @@ packages: react: 18.2.0 dev: false - /@mui/system/5.11.7_gzalmy7izvhol7vh4xfy3dq6ua: - resolution: {integrity: sha512-uGB6hBxGlAdlmbLdTtUZYNPXkgQGGnKxHdkRATqsu7UlCxNsc/yS5NCEWy/3c4pnelD1LDLD39WrntP9mwhfkQ==} + /@mui/system/5.11.8_gzalmy7izvhol7vh4xfy3dq6ua: + resolution: {integrity: sha512-zhroUcxAw2x/dISBJKhGbD70DOYCwMFRo7o/LUYTiUfQkfmLhRfEf1bopWgY9nYstn7QOxOq9fA3aR3pHrUTbw==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -3292,7 +3306,7 @@ packages: '@emotion/react': 11.10.5_3stiutgnnbnfnf3uowm5cip22i '@emotion/styled': 11.10.5_jrh5enlbqfbnumycmktdqgd6se '@mui/private-theming': 5.11.7_3stiutgnnbnfnf3uowm5cip22i - '@mui/styled-engine': 5.11.0_dovxhg2tvkkxkdnqyoum6wzcxm + '@mui/styled-engine': 5.11.8_dovxhg2tvkkxkdnqyoum6wzcxm '@mui/types': 7.2.3_@types+react@18.0.27 '@mui/utils': 5.11.7_react@18.2.0 '@types/react': 18.0.27 @@ -3364,8 +3378,8 @@ packages: resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==} dev: false - /@remix-run/router/1.3.1: - resolution: {integrity: sha512-+eun1Wtf72RNRSqgU7qM2AMX/oHp+dnx7BHk1qhK5ZHzdHTUU4LA1mGG1vT+jMc8sbhG3orvsfOmryjzx2PzQw==} + /@remix-run/router/1.3.2: + resolution: {integrity: sha512-t54ONhl/h75X94SWsHGQ4G/ZrCEguKSRQr7DrjTciJXW0YU1QhlwYeycvK5JgkzlxmvrK7wq1NB/PLtHxoiDcA==} engines: {node: '>=14'} dev: false @@ -3674,7 +3688,7 @@ packages: /@types/graceful-fs/4.1.5: resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 dev: true /@types/istanbul-lib-coverage/2.0.4: @@ -3703,7 +3717,7 @@ packages: /@types/jsdom/20.0.0: resolution: {integrity: sha512-YfAchFs0yM1QPDrLm2VHe+WHGtqms3NXnXAMolrgrVP6fgBHHXy1ozAbo/dFtPNtZC/m66bPiCTWYmqp1F14gA==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 '@types/tough-cookie': 4.0.2 parse5: 7.0.0 dev: true @@ -3720,8 +3734,8 @@ packages: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} dev: true - /@types/node/18.11.18: - resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} + /@types/node/18.13.0: + resolution: {integrity: sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==} dev: true /@types/normalize-package-data/2.4.1: @@ -3810,8 +3824,8 @@ packages: resolution: {integrity: sha512-3NoqvZC2W5gAC5DZbTpCeJ251vGQmgcWIHQJGq2J240HY6ErQ9aWKkwfoKJlHLx+A83WPNTZ9+3cd2ILxbvr1w==} dev: true - /@typescript-eslint/eslint-plugin/5.50.0_go4drrxstycfikanvu45pi4vgq: - resolution: {integrity: sha512-vwksQWSFZiUhgq3Kv7o1Jcj0DUNylwnIlGvKvLLYsq8pAWha6/WCnXUeaSoNNha/K7QSf2+jvmkxggC1u3pIwQ==} + /@typescript-eslint/eslint-plugin/5.51.0_z4swst3wuuqk4hlme4ajzslgh4: + resolution: {integrity: sha512-wcAwhEWm1RgNd7dxD/o+nnLW8oH+6RK1OGnmbmkj/GGoDPV1WWMVP0FXYQBivKHdwM1pwii3bt//RC62EriIUQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -3821,12 +3835,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.50.0_4vsywjlpuriuw3tl5oq6zy5a64 - '@typescript-eslint/scope-manager': 5.50.0 - '@typescript-eslint/type-utils': 5.50.0_4vsywjlpuriuw3tl5oq6zy5a64 - '@typescript-eslint/utils': 5.50.0_4vsywjlpuriuw3tl5oq6zy5a64 + '@typescript-eslint/parser': 5.51.0_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/scope-manager': 5.51.0 + '@typescript-eslint/type-utils': 5.51.0_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/utils': 5.51.0_7kw3g6rralp5ps6mg3uyzz6azm debug: 4.3.4 - eslint: 8.33.0 + eslint: 8.34.0 grapheme-splitter: 1.0.4 ignore: 5.2.0 natural-compare-lite: 1.4.0 @@ -3838,21 +3852,21 @@ packages: - supports-color dev: true - /@typescript-eslint/experimental-utils/5.30.6_4vsywjlpuriuw3tl5oq6zy5a64: + /@typescript-eslint/experimental-utils/5.30.6_7kw3g6rralp5ps6mg3uyzz6azm: resolution: {integrity: sha512-bqvT+0L8IjtW7MCrMgm9oVNxs4g7mESro1mm5c1/SNfTnHuFTf9OUX1WzVkTz75M9cp//UrTrSmGvK48NEKshQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@typescript-eslint/utils': 5.30.6_4vsywjlpuriuw3tl5oq6zy5a64 - eslint: 8.33.0 + '@typescript-eslint/utils': 5.30.6_7kw3g6rralp5ps6mg3uyzz6azm + eslint: 8.34.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/parser/5.50.0_4vsywjlpuriuw3tl5oq6zy5a64: - resolution: {integrity: sha512-KCcSyNaogUDftK2G9RXfQyOCt51uB5yqC6pkUYqhYh8Kgt+DwR5M0EwEAxGPy/+DH6hnmKeGsNhiZRQxjH71uQ==} + /@typescript-eslint/parser/5.51.0_7kw3g6rralp5ps6mg3uyzz6azm: + resolution: {integrity: sha512-fEV0R9gGmfpDeRzJXn+fGQKcl0inIeYobmmUWijZh9zA7bxJ8clPhV9up2ZQzATxAiFAECqPQyMDB4o4B81AaA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3861,11 +3875,11 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.50.0 - '@typescript-eslint/types': 5.50.0 - '@typescript-eslint/typescript-estree': 5.50.0_typescript@4.9.5 + '@typescript-eslint/scope-manager': 5.51.0 + '@typescript-eslint/types': 5.51.0 + '@typescript-eslint/typescript-estree': 5.51.0_typescript@4.9.5 debug: 4.3.4 - eslint: 8.33.0 + eslint: 8.34.0 typescript: 4.9.5 transitivePeerDependencies: - supports-color @@ -3879,16 +3893,16 @@ packages: '@typescript-eslint/visitor-keys': 5.30.6 dev: true - /@typescript-eslint/scope-manager/5.50.0: - resolution: {integrity: sha512-rt03kaX+iZrhssaT974BCmoUikYtZI24Vp/kwTSy841XhiYShlqoshRFDvN1FKKvU2S3gK+kcBW1EA7kNUrogg==} + /@typescript-eslint/scope-manager/5.51.0: + resolution: {integrity: sha512-gNpxRdlx5qw3yaHA0SFuTjW4rxeYhpHxt491PEcKF8Z6zpq0kMhe0Tolxt0qjlojS+/wArSDlj/LtE69xUJphQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.50.0 - '@typescript-eslint/visitor-keys': 5.50.0 + '@typescript-eslint/types': 5.51.0 + '@typescript-eslint/visitor-keys': 5.51.0 dev: true - /@typescript-eslint/type-utils/5.50.0_4vsywjlpuriuw3tl5oq6zy5a64: - resolution: {integrity: sha512-dcnXfZ6OGrNCO7E5UY/i0ktHb7Yx1fV6fnQGGrlnfDhilcs6n19eIRcvLBqx6OQkrPaFlDPk3OJ0WlzQfrV0bQ==} + /@typescript-eslint/type-utils/5.51.0_7kw3g6rralp5ps6mg3uyzz6azm: + resolution: {integrity: sha512-QHC5KKyfV8sNSyHqfNa0UbTbJ6caB8uhcx2hYcWVvJAZYJRBo5HyyZfzMdRx8nvS+GyMg56fugMzzWnojREuQQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -3897,10 +3911,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.50.0_typescript@4.9.5 - '@typescript-eslint/utils': 5.50.0_4vsywjlpuriuw3tl5oq6zy5a64 + '@typescript-eslint/typescript-estree': 5.51.0_typescript@4.9.5 + '@typescript-eslint/utils': 5.51.0_7kw3g6rralp5ps6mg3uyzz6azm debug: 4.3.4 - eslint: 8.33.0 + eslint: 8.34.0 tsutils: 3.21.0_typescript@4.9.5 typescript: 4.9.5 transitivePeerDependencies: @@ -3912,8 +3926,8 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/types/5.50.0: - resolution: {integrity: sha512-atruOuJpir4OtyNdKahiHZobPKFvZnBnfDiyEaBf6d9vy9visE7gDjlmhl+y29uxZ2ZDgvXijcungGFjGGex7w==} + /@typescript-eslint/types/5.51.0: + resolution: {integrity: sha512-SqOn0ANn/v6hFn0kjvLwiDi4AzR++CBZz0NV5AnusT2/3y32jdc0G4woXPWHCumWtUXZKPAS27/9vziSsC9jnw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true @@ -3938,8 +3952,8 @@ packages: - supports-color dev: true - /@typescript-eslint/typescript-estree/5.50.0_typescript@4.9.5: - resolution: {integrity: sha512-Gq4zapso+OtIZlv8YNAStFtT6d05zyVCK7Fx3h5inlLBx2hWuc/0465C2mg/EQDDU2LKe52+/jN4f0g9bd+kow==} + /@typescript-eslint/typescript-estree/5.51.0_typescript@4.9.5: + resolution: {integrity: sha512-TSkNupHvNRkoH9FMA3w7TazVFcBPveAAmb7Sz+kArY6sLT86PA5Vx80cKlYmd8m3Ha2SwofM1KwraF24lM9FvA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -3947,8 +3961,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.50.0 - '@typescript-eslint/visitor-keys': 5.50.0 + '@typescript-eslint/types': 5.51.0 + '@typescript-eslint/visitor-keys': 5.51.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -3959,7 +3973,7 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.30.6_4vsywjlpuriuw3tl5oq6zy5a64: + /@typescript-eslint/utils/5.30.6_7kw3g6rralp5ps6mg3uyzz6azm: resolution: {integrity: sha512-xFBLc/esUbLOJLk9jKv0E9gD/OH966M40aY9jJ8GiqpSkP2xOV908cokJqqhVd85WoIvHVHYXxSFE4cCSDzVvA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -3969,28 +3983,28 @@ packages: '@typescript-eslint/scope-manager': 5.30.6 '@typescript-eslint/types': 5.30.6 '@typescript-eslint/typescript-estree': 5.30.6_typescript@4.9.5 - eslint: 8.33.0 + eslint: 8.34.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.33.0 + eslint-utils: 3.0.0_eslint@8.34.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/utils/5.50.0_4vsywjlpuriuw3tl5oq6zy5a64: - resolution: {integrity: sha512-v/AnUFImmh8G4PH0NDkf6wA8hujNNcrwtecqW4vtQ1UOSNBaZl49zP1SHoZ/06e+UiwzHpgb5zP5+hwlYYWYAw==} + /@typescript-eslint/utils/5.51.0_7kw3g6rralp5ps6mg3uyzz6azm: + resolution: {integrity: sha512-76qs+5KWcaatmwtwsDJvBk4H76RJQBFe+Gext0EfJdC3Vd2kpY2Pf//OHHzHp84Ciw0/rYoGTDnIAr3uWhhJYw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@types/json-schema': 7.0.11 '@types/semver': 7.3.12 - '@typescript-eslint/scope-manager': 5.50.0 - '@typescript-eslint/types': 5.50.0 - '@typescript-eslint/typescript-estree': 5.50.0_typescript@4.9.5 - eslint: 8.33.0 + '@typescript-eslint/scope-manager': 5.51.0 + '@typescript-eslint/types': 5.51.0 + '@typescript-eslint/typescript-estree': 5.51.0_typescript@4.9.5 + eslint: 8.34.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.33.0 + eslint-utils: 3.0.0_eslint@8.34.0 semver: 7.3.8 transitivePeerDependencies: - supports-color @@ -4005,26 +4019,26 @@ packages: eslint-visitor-keys: 3.3.0 dev: true - /@typescript-eslint/visitor-keys/5.50.0: - resolution: {integrity: sha512-cdMeD9HGu6EXIeGOh2yVW6oGf9wq8asBgZx7nsR/D36gTfQ0odE5kcRYe5M81vjEFAcPeugXrHg78Imu55F6gg==} + /@typescript-eslint/visitor-keys/5.51.0: + resolution: {integrity: sha512-Oh2+eTdjHjOFjKA27sxESlA87YPSOJafGCR0md5oeMdh1ZcCfAGCIOL216uTBAkAIptvLIfKQhl7lHxMJet4GQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.50.0 + '@typescript-eslint/types': 5.51.0 eslint-visitor-keys: 3.3.0 dev: true - /@vitejs/plugin-react/3.0.1_vite@4.0.4: - resolution: {integrity: sha512-mx+QvYwIbbpOIJw+hypjnW1lAbKDHtWK5ibkF/V1/oMBu8HU/chb+SnqJDAsLq1+7rGqjktCEomMTM5KShzUKQ==} + /@vitejs/plugin-react/3.1.0_vite@4.1.1: + resolution: {integrity: sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^4.0.0 + vite: ^4.1.0-beta.0 dependencies: '@babel/core': 7.20.12 '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.20.12 '@babel/plugin-transform-react-jsx-source': 7.19.6_@babel+core@7.20.12 magic-string: 0.27.0 react-refresh: 0.14.0 - vite: 4.0.4_@types+node@18.11.18 + vite: 4.1.1_@types+node@18.13.0 transitivePeerDependencies: - supports-color dev: true @@ -4292,8 +4306,8 @@ packages: engines: {node: '>=4'} dev: true - /axios/1.3.0: - resolution: {integrity: sha512-oCye5nHhTypzkdLIvF9SaHfr8UAquqCn1KY3j8vsrjeol8yohAdGxIpRPbF1bOLsx33HOAatdfMX1yzsj2cHwg==} + /axios/1.3.2: + resolution: {integrity: sha512-1M3O703bYqYuPhbHeya5bnhpYVsDDRyQSabNja04mZtboLNSuZ4YrltestrLXfHgmzua4TpUqRiVKbiQuo2epw==} dependencies: follow-redirects: 1.15.1 form-data: 4.0.0 @@ -4330,8 +4344,8 @@ packages: - supports-color dev: true - /babel-jest/29.4.1_@babel+core@7.20.12: - resolution: {integrity: sha512-xBZa/pLSsF/1sNpkgsiT3CmY7zV1kAsZ9OxxtrFqYucnOuRftXAfcJqcDVyOPeN4lttWTwhLdu0T9f8uvoPEUg==} + /babel-jest/29.4.2_@babel+core@7.20.12: + resolution: {integrity: sha512-vcghSqhtowXPG84posYkkkzcZsdayFkubUgbE3/1tuGbX7AQtwCkkNA/wIbB0BMjuCPoqTkiDyKN7Ty7d3uwNQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.8.0 @@ -4340,10 +4354,10 @@ packages: optional: true dependencies: '@babel/core': 7.20.12 - '@jest/transform': 29.4.1 + '@jest/transform': 29.4.2 '@types/babel__core': 7.1.19 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.4.0_@babel+core@7.20.12 + babel-preset-jest: 29.4.2_@babel+core@7.20.12 chalk: 4.1.2 graceful-fs: 4.2.10 slash: 3.0.0 @@ -4380,8 +4394,8 @@ packages: '@types/babel__traverse': 7.17.1 dev: true - /babel-plugin-jest-hoist/29.4.0: - resolution: {integrity: sha512-a/sZRLQJEmsmejQ2rPEUe35nO1+C9dc9O1gplH1SXmJxveQSRUYdBk8yGZG/VOUuZs1u2aHZJusEGoRMbhhwCg==} + /babel-plugin-jest-hoist/29.4.2: + resolution: {integrity: sha512-5HZRCfMeWypFEonRbEkwWXtNS1sQK159LhRVyRuLzyfVBxDy/34Tr/rg4YVi0SScSJ4fqeaR/OIeceJ/LaQ0pQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/template': 7.20.7 @@ -4507,8 +4521,8 @@ packages: babel-preset-current-node-syntax: 1.0.1_@babel+core@7.18.6 dev: true - /babel-preset-jest/29.4.0_@babel+core@7.20.12: - resolution: {integrity: sha512-fUB9vZflUSM3dO/6M2TCAepTzvA4VkOvl67PjErcrQMGt9Eve7uazaeyCZ2th3UtI7ljpiBJES0F7A1vBRsLZA==} + /babel-preset-jest/29.4.2_@babel+core@7.20.12: + resolution: {integrity: sha512-ecWdaLY/8JyfUDr0oELBMpj3R5I1L6ZqG+kRJmwqfHtLWuPrJStR0LUkvUhfykJWTsXXMnohsayN/twltBbDrQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.0.0 @@ -4517,7 +4531,7 @@ packages: optional: true dependencies: '@babel/core': 7.20.12 - babel-plugin-jest-hoist: 29.4.0 + babel-plugin-jest-hoist: 29.4.2 babel-preset-current-node-syntax: 1.0.1_@babel+core@7.20.12 dev: true @@ -4872,7 +4886,7 @@ packages: semver: 7.0.0 dev: true - /cosmiconfig-typescript-loader/4.0.0_wup64ucrbpz6nyxdtffrcfuej4: + /cosmiconfig-typescript-loader/4.0.0_675xcr52t65rpohei3x75qh2i4: resolution: {integrity: sha512-cVpucSc2Tf+VPwCCR7SZzmQTQkPbkk4O01yXsYqXBIbjE1bhwqSyAgYQkRK1un4i0OPziTleqFhdkmOc4RQ/9g==} engines: {node: '>=12', npm: '>=6'} peerDependencies: @@ -4881,9 +4895,9 @@ packages: ts-node: '>=10' typescript: '>=3' dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 cosmiconfig: 8.0.0 - ts-node: 10.9.0_bdgp3l2zgaopogaavxusmetvge + ts-node: 10.9.0_4bewfcp2iebiwuold25d6rgcsy typescript: 4.9.5 dev: true @@ -5121,8 +5135,8 @@ packages: engines: {node: '>=8'} dev: true - /diff-sequences/29.3.1: - resolution: {integrity: sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==} + /diff-sequences/29.4.2: + resolution: {integrity: sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true @@ -5276,7 +5290,7 @@ packages: is-symbol: 1.0.4 dev: true - /esbuild-jest/0.5.0_esbuild@0.17.5: + /esbuild-jest/0.5.0_esbuild@0.17.7: resolution: {integrity: sha512-AMZZCdEpXfNVOIDvURlqYyHwC8qC1/BFjgsrOiSL1eyiIArVtHL8YAC83Shhn16cYYoAWEW17yZn0W/RJKJKHQ==} peerDependencies: esbuild: '>=0.8.50' @@ -5284,7 +5298,7 @@ packages: '@babel/core': 7.18.6 '@babel/plugin-transform-modules-commonjs': 7.18.6_@babel+core@7.18.6 babel-jest: 26.6.3_@babel+core@7.18.6 - esbuild: 0.17.5 + esbuild: 0.17.7 transitivePeerDependencies: - supports-color dev: true @@ -5319,34 +5333,34 @@ packages: '@esbuild/win32-x64': 0.16.17 dev: true - /esbuild/0.17.5: - resolution: {integrity: sha512-Bu6WLCc9NMsNoMJUjGl3yBzTjVLXdysMltxQWiLAypP+/vQrf+3L1Xe8fCXzxaECus2cEJ9M7pk4yKatEwQMqQ==} + /esbuild/0.17.7: + resolution: {integrity: sha512-+5hHlrK108fT6C6/40juy0w4DYKtyZ5NjfBlTccBdsFutR7WBxpIY633JzZJewdsCy8xWA/u2z0MSniIJwufYg==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.17.5 - '@esbuild/android-arm64': 0.17.5 - '@esbuild/android-x64': 0.17.5 - '@esbuild/darwin-arm64': 0.17.5 - '@esbuild/darwin-x64': 0.17.5 - '@esbuild/freebsd-arm64': 0.17.5 - '@esbuild/freebsd-x64': 0.17.5 - '@esbuild/linux-arm': 0.17.5 - '@esbuild/linux-arm64': 0.17.5 - '@esbuild/linux-ia32': 0.17.5 - '@esbuild/linux-loong64': 0.17.5 - '@esbuild/linux-mips64el': 0.17.5 - '@esbuild/linux-ppc64': 0.17.5 - '@esbuild/linux-riscv64': 0.17.5 - '@esbuild/linux-s390x': 0.17.5 - '@esbuild/linux-x64': 0.17.5 - '@esbuild/netbsd-x64': 0.17.5 - '@esbuild/openbsd-x64': 0.17.5 - '@esbuild/sunos-x64': 0.17.5 - '@esbuild/win32-arm64': 0.17.5 - '@esbuild/win32-ia32': 0.17.5 - '@esbuild/win32-x64': 0.17.5 + '@esbuild/android-arm': 0.17.7 + '@esbuild/android-arm64': 0.17.7 + '@esbuild/android-x64': 0.17.7 + '@esbuild/darwin-arm64': 0.17.7 + '@esbuild/darwin-x64': 0.17.7 + '@esbuild/freebsd-arm64': 0.17.7 + '@esbuild/freebsd-x64': 0.17.7 + '@esbuild/linux-arm': 0.17.7 + '@esbuild/linux-arm64': 0.17.7 + '@esbuild/linux-ia32': 0.17.7 + '@esbuild/linux-loong64': 0.17.7 + '@esbuild/linux-mips64el': 0.17.7 + '@esbuild/linux-ppc64': 0.17.7 + '@esbuild/linux-riscv64': 0.17.7 + '@esbuild/linux-s390x': 0.17.7 + '@esbuild/linux-x64': 0.17.7 + '@esbuild/netbsd-x64': 0.17.7 + '@esbuild/openbsd-x64': 0.17.7 + '@esbuild/sunos-x64': 0.17.7 + '@esbuild/win32-arm64': 0.17.7 + '@esbuild/win32-ia32': 0.17.7 + '@esbuild/win32-x64': 0.17.7 dev: true /escalade/3.1.1: @@ -5380,16 +5394,16 @@ packages: source-map: 0.6.1 dev: true - /eslint-config-prettier/8.6.0_eslint@8.33.0: + /eslint-config-prettier/8.6.0_eslint@8.34.0: resolution: {integrity: sha512-bAF0eLpLVqP5oEVUFKpMA+NnRFICwn9X8B5jrR9FcqnYBuPbqWEjTEspPWMj5ye6czoSLDweCzSo3Ko7gGrZaA==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.33.0 + eslint: 8.34.0 dev: true - /eslint-config-react-app/7.0.1_rc2dcjzdq7kivixrc2dtl3hu7e: + /eslint-config-react-app/7.0.1_i52m234xbggdiu6ew4jj35mjea: resolution: {integrity: sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -5400,20 +5414,20 @@ packages: optional: true dependencies: '@babel/core': 7.18.6 - '@babel/eslint-parser': 7.18.2_wyhkjhzegujbjwddfb5na6gduu + '@babel/eslint-parser': 7.18.2_4hiysdvhwszrzvk6njkclnrv5u '@rushstack/eslint-patch': 1.1.4 - '@typescript-eslint/eslint-plugin': 5.50.0_go4drrxstycfikanvu45pi4vgq - '@typescript-eslint/parser': 5.50.0_4vsywjlpuriuw3tl5oq6zy5a64 + '@typescript-eslint/eslint-plugin': 5.51.0_z4swst3wuuqk4hlme4ajzslgh4 + '@typescript-eslint/parser': 5.51.0_7kw3g6rralp5ps6mg3uyzz6azm babel-preset-react-app: 10.0.1 confusing-browser-globals: 1.0.11 - eslint: 8.33.0 - eslint-plugin-flowtype: 8.0.3_eslint@8.33.0 - eslint-plugin-import: 2.27.5_nowqz4jutkd4a233czbfk7jsgu - eslint-plugin-jest: 25.7.0_mxgixfkotof7s3ejq6qsq3dgw4 - eslint-plugin-jsx-a11y: 6.7.1_eslint@8.33.0 - eslint-plugin-react: 7.32.2_eslint@8.33.0 - eslint-plugin-react-hooks: 4.6.0_eslint@8.33.0 - eslint-plugin-testing-library: 5.5.1_4vsywjlpuriuw3tl5oq6zy5a64 + eslint: 8.34.0 + eslint-plugin-flowtype: 8.0.3_eslint@8.34.0 + eslint-plugin-import: 2.27.5_inmo4nrctlhmfx73hzu6aogupa + eslint-plugin-jest: 25.7.0_yay6cfgue2en3qfwluk5knwgsy + eslint-plugin-jsx-a11y: 6.7.1_eslint@8.34.0 + eslint-plugin-react: 7.32.2_eslint@8.34.0 + eslint-plugin-react-hooks: 4.6.0_eslint@8.34.0 + eslint-plugin-testing-library: 5.5.1_7kw3g6rralp5ps6mg3uyzz6azm typescript: 4.9.5 transitivePeerDependencies: - '@babel/plugin-syntax-flow' @@ -5438,7 +5452,7 @@ packages: - supports-color dev: true - /eslint-import-resolver-typescript/3.5.3_ohdts44xlqyeyrlje4qnefqeay: + /eslint-import-resolver-typescript/3.5.3_mvgyw3chnqkp6sgfmmtihyjpnm: resolution: {integrity: sha512-njRcKYBc3isE42LaTcJNVANR3R99H9bAxBDMNDr2W7yq5gYPxbU3MkdhsQukxZ/Xg9C2vcyLlDsbKfRDg0QvCQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -5447,8 +5461,8 @@ packages: dependencies: debug: 4.3.4 enhanced-resolve: 5.10.0 - eslint: 8.33.0 - eslint-plugin-import: 2.27.5_nowqz4jutkd4a233czbfk7jsgu + eslint: 8.34.0 + eslint-plugin-import: 2.27.5_inmo4nrctlhmfx73hzu6aogupa get-tsconfig: 4.2.0 globby: 13.1.2 is-core-module: 2.10.0 @@ -5458,7 +5472,7 @@ packages: - supports-color dev: true - /eslint-module-utils/2.7.4_4lq3tljpmtdh3elqaianviuctu: + /eslint-module-utils/2.7.4_7d5otxxipfjcaqho6psg7iyp4e: resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} engines: {node: '>=4'} peerDependencies: @@ -5479,16 +5493,16 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.50.0_4vsywjlpuriuw3tl5oq6zy5a64 + '@typescript-eslint/parser': 5.51.0_7kw3g6rralp5ps6mg3uyzz6azm debug: 3.2.7 - eslint: 8.33.0 + eslint: 8.34.0 eslint-import-resolver-node: 0.3.7 - eslint-import-resolver-typescript: 3.5.3_ohdts44xlqyeyrlje4qnefqeay + eslint-import-resolver-typescript: 3.5.3_mvgyw3chnqkp6sgfmmtihyjpnm transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-flowtype/8.0.3_eslint@8.33.0: + /eslint-plugin-flowtype/8.0.3_eslint@8.34.0: resolution: {integrity: sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -5501,12 +5515,12 @@ packages: '@babel/plugin-transform-react-jsx': optional: true dependencies: - eslint: 8.33.0 + eslint: 8.34.0 lodash: 4.17.21 string-natural-compare: 3.0.1 dev: true - /eslint-plugin-import/2.27.5_nowqz4jutkd4a233czbfk7jsgu: + /eslint-plugin-import/2.27.5_inmo4nrctlhmfx73hzu6aogupa: resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} engines: {node: '>=4'} peerDependencies: @@ -5516,15 +5530,15 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.50.0_4vsywjlpuriuw3tl5oq6zy5a64 + '@typescript-eslint/parser': 5.51.0_7kw3g6rralp5ps6mg3uyzz6azm array-includes: 3.1.6 array.prototype.flat: 1.3.1 array.prototype.flatmap: 1.3.1 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.33.0 + eslint: 8.34.0 eslint-import-resolver-node: 0.3.7 - eslint-module-utils: 2.7.4_4lq3tljpmtdh3elqaianviuctu + eslint-module-utils: 2.7.4_7d5otxxipfjcaqho6psg7iyp4e has: 1.0.3 is-core-module: 2.11.0 is-glob: 4.0.3 @@ -5539,7 +5553,7 @@ packages: - supports-color dev: true - /eslint-plugin-jest/25.7.0_mxgixfkotof7s3ejq6qsq3dgw4: + /eslint-plugin-jest/25.7.0_yay6cfgue2en3qfwluk5knwgsy: resolution: {integrity: sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} peerDependencies: @@ -5552,16 +5566,16 @@ packages: jest: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 5.50.0_go4drrxstycfikanvu45pi4vgq - '@typescript-eslint/experimental-utils': 5.30.6_4vsywjlpuriuw3tl5oq6zy5a64 - eslint: 8.33.0 - jest: 29.4.1_@types+node@18.11.18 + '@typescript-eslint/eslint-plugin': 5.51.0_z4swst3wuuqk4hlme4ajzslgh4 + '@typescript-eslint/experimental-utils': 5.30.6_7kw3g6rralp5ps6mg3uyzz6azm + eslint: 8.34.0 + jest: 29.4.2_@types+node@18.13.0 transitivePeerDependencies: - supports-color - typescript dev: true - /eslint-plugin-jsx-a11y/6.7.1_eslint@8.33.0: + /eslint-plugin-jsx-a11y/6.7.1_eslint@8.34.0: resolution: {integrity: sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==} engines: {node: '>=4.0'} peerDependencies: @@ -5576,7 +5590,7 @@ packages: axobject-query: 3.1.1 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 8.33.0 + eslint: 8.34.0 has: 1.0.3 jsx-ast-utils: 3.3.3 language-tags: 1.0.5 @@ -5586,7 +5600,7 @@ packages: semver: 6.3.0 dev: true - /eslint-plugin-prettier/4.2.1_jqplj6qf3uqpxpu4gdyhwwasnq: + /eslint-plugin-prettier/4.2.1_u5wnrdwibbfomslmnramz52buy: resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -5597,22 +5611,22 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint: 8.33.0 - eslint-config-prettier: 8.6.0_eslint@8.33.0 - prettier: 2.8.3 + eslint: 8.34.0 + eslint-config-prettier: 8.6.0_eslint@8.34.0 + prettier: 2.8.4 prettier-linter-helpers: 1.0.0 dev: true - /eslint-plugin-react-hooks/4.6.0_eslint@8.33.0: + /eslint-plugin-react-hooks/4.6.0_eslint@8.34.0: resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: - eslint: 8.33.0 + eslint: 8.34.0 dev: true - /eslint-plugin-react/7.32.2_eslint@8.33.0: + /eslint-plugin-react/7.32.2_eslint@8.34.0: resolution: {integrity: sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==} engines: {node: '>=4'} peerDependencies: @@ -5622,7 +5636,7 @@ packages: array.prototype.flatmap: 1.3.1 array.prototype.tosorted: 1.1.1 doctrine: 2.1.0 - eslint: 8.33.0 + eslint: 8.34.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.3 minimatch: 3.1.2 @@ -5636,14 +5650,14 @@ packages: string.prototype.matchall: 4.0.8 dev: true - /eslint-plugin-testing-library/5.5.1_4vsywjlpuriuw3tl5oq6zy5a64: + /eslint-plugin-testing-library/5.5.1_7kw3g6rralp5ps6mg3uyzz6azm: resolution: {integrity: sha512-plLEkkbAKBjPxsLj7x4jNapcHAg2ernkQlKKrN2I8NrQwPISZHyCUNvg5Hv3EDqOQReToQb5bnqXYbkijJPE/g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6'} peerDependencies: eslint: ^7.5.0 || ^8.0.0 dependencies: - '@typescript-eslint/utils': 5.50.0_4vsywjlpuriuw3tl5oq6zy5a64 - eslint: 8.33.0 + '@typescript-eslint/utils': 5.51.0_7kw3g6rralp5ps6mg3uyzz6azm + eslint: 8.34.0 transitivePeerDependencies: - supports-color - typescript @@ -5665,13 +5679,13 @@ packages: estraverse: 5.3.0 dev: true - /eslint-utils/3.0.0_eslint@8.33.0: + /eslint-utils/3.0.0_eslint@8.34.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.33.0 + eslint: 8.34.0 eslint-visitor-keys: 2.1.0 dev: true @@ -5685,8 +5699,8 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.33.0: - resolution: {integrity: sha512-WjOpFQgKK8VrCnAtl8We0SUOy/oVZ5NHykyMiagV1M9r8IFpIJX7DduK6n1mpfhlG7T1NLWm2SuD8QB7KFySaA==} + /eslint/8.34.0: + resolution: {integrity: sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: @@ -5701,7 +5715,7 @@ packages: doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.33.0 + eslint-utils: 3.0.0_eslint@8.34.0 eslint-visitor-keys: 3.3.0 espree: 9.4.0 esquery: 1.4.0 @@ -5848,15 +5862,15 @@ packages: jest-util: 29.4.1 dev: true - /expect/29.4.1: - resolution: {integrity: sha512-OKrGESHOaMxK3b6zxIq9SOW8kEXztKff/Dvg88j4xIJxur1hspEbedVkR3GpHe5LO+WB2Qw7OWN0RMTdp6as5A==} + /expect/29.4.2: + resolution: {integrity: sha512-+JHYg9O3hd3RlICG90OPVjRkPBoiUH7PxvDVMnRiaq1g6JUgZStX514erMl0v2Dc5SkfVbm7ztqbd6qHHPn+mQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/expect-utils': 29.4.1 - jest-get-type: 29.2.0 - jest-matcher-utils: 29.4.1 - jest-message-util: 29.4.1 - jest-util: 29.4.1 + '@jest/expect-utils': 29.4.2 + jest-get-type: 29.4.2 + jest-matcher-utils: 29.4.2 + jest-message-util: 29.4.2 + jest-util: 29.4.2 dev: true /extend-shallow/2.0.1: @@ -6816,43 +6830,43 @@ packages: istanbul-lib-report: 3.0.0 dev: true - /jest-changed-files/29.4.0: - resolution: {integrity: sha512-rnI1oPxgFghoz32Y8eZsGJMjW54UlqT17ycQeCEktcxxwqqKdlj9afl8LNeO0Pbu+h2JQHThQP0BzS67eTRx4w==} + /jest-changed-files/29.4.2: + resolution: {integrity: sha512-Qdd+AXdqD16PQa+VsWJpxR3kN0JyOCX1iugQfx5nUgAsI4gwsKviXkpclxOK9ZnwaY2IQVHz+771eAvqeOlfuw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: execa: 5.1.1 p-limit: 3.1.0 dev: true - /jest-circus/29.4.1: - resolution: {integrity: sha512-v02NuL5crMNY4CGPHBEflLzl4v91NFb85a+dH9a1pUNx6Xjggrd8l9pPy4LZ1VYNRXlb+f65+7O/MSIbLir6pA==} + /jest-circus/29.4.2: + resolution: {integrity: sha512-wW3ztp6a2P5c1yOc1Cfrt5ozJ7neWmqeXm/4SYiqcSriyisgq63bwFj1NuRdSR5iqS0CMEYwSZd89ZA47W9zUg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.4.1 - '@jest/expect': 29.4.1 - '@jest/test-result': 29.4.1 - '@jest/types': 29.4.1 - '@types/node': 18.11.18 + '@jest/environment': 29.4.2 + '@jest/expect': 29.4.2 + '@jest/test-result': 29.4.2 + '@jest/types': 29.4.2 + '@types/node': 18.13.0 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 is-generator-fn: 2.1.0 - jest-each: 29.4.1 - jest-matcher-utils: 29.4.1 - jest-message-util: 29.4.1 - jest-runtime: 29.4.1 - jest-snapshot: 29.4.1 - jest-util: 29.4.1 + jest-each: 29.4.2 + jest-matcher-utils: 29.4.2 + jest-message-util: 29.4.2 + jest-runtime: 29.4.2 + jest-snapshot: 29.4.2 + jest-util: 29.4.2 p-limit: 3.1.0 - pretty-format: 29.4.1 + pretty-format: 29.4.2 slash: 3.0.0 stack-utils: 2.0.5 transitivePeerDependencies: - supports-color dev: true - /jest-cli/29.4.1_@types+node@18.11.18: - resolution: {integrity: sha512-jz7GDIhtxQ37M+9dlbv5K+/FVcIo1O/b1sX3cJgzlQUf/3VG25nvuWzlDC4F1FLLzUThJeWLu8I7JF9eWpuURQ==} + /jest-cli/29.4.2_@types+node@18.13.0: + resolution: {integrity: sha512-b+eGUtXq/K2v7SH3QcJvFvaUaCDS1/YAZBYz0m28Q/Ppyr+1qNaHmVYikOrbHVbZqYQs2IeI3p76uy6BWbXq8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true peerDependencies: @@ -6861,16 +6875,16 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 29.4.1 - '@jest/test-result': 29.4.1 - '@jest/types': 29.4.1 + '@jest/core': 29.4.2 + '@jest/test-result': 29.4.2 + '@jest/types': 29.4.2 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 - jest-config: 29.4.1_@types+node@18.11.18 - jest-util: 29.4.1 - jest-validate: 29.4.1 + jest-config: 29.4.2_@types+node@18.13.0 + jest-util: 29.4.2 + jest-validate: 29.4.2 prompts: 2.4.2 yargs: 17.5.1 transitivePeerDependencies: @@ -6879,8 +6893,8 @@ packages: - ts-node dev: true - /jest-config/29.4.1_@types+node@18.11.18: - resolution: {integrity: sha512-g7p3q4NuXiM4hrS4XFATTkd+2z0Ml2RhFmFPM8c3WyKwVDNszbl4E7cV7WIx1YZeqqCtqbtTtZhGZWJlJqngzg==} + /jest-config/29.4.2_@types+node@18.13.0: + resolution: {integrity: sha512-919CtnXic52YM0zW4C1QxjG6aNueX1kBGthuMtvFtRTAxhKfJmiXC9qwHmi6o2josjbDz8QlWyY55F1SIVmCWA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@types/node': '*' @@ -6892,62 +6906,62 @@ packages: optional: true dependencies: '@babel/core': 7.20.12 - '@jest/test-sequencer': 29.4.1 - '@jest/types': 29.4.1 - '@types/node': 18.11.18 - babel-jest: 29.4.1_@babel+core@7.20.12 + '@jest/test-sequencer': 29.4.2 + '@jest/types': 29.4.2 + '@types/node': 18.13.0 + babel-jest: 29.4.2_@babel+core@7.20.12 chalk: 4.1.2 ci-info: 3.3.2 deepmerge: 4.2.2 glob: 7.2.3 graceful-fs: 4.2.10 - jest-circus: 29.4.1 - jest-environment-node: 29.4.1 - jest-get-type: 29.2.0 - jest-regex-util: 29.2.0 - jest-resolve: 29.4.1 - jest-runner: 29.4.1 - jest-util: 29.4.1 - jest-validate: 29.4.1 + jest-circus: 29.4.2 + jest-environment-node: 29.4.2 + jest-get-type: 29.4.2 + jest-regex-util: 29.4.2 + jest-resolve: 29.4.2 + jest-runner: 29.4.2 + jest-util: 29.4.2 + jest-validate: 29.4.2 micromatch: 4.0.5 parse-json: 5.2.0 - pretty-format: 29.4.1 + pretty-format: 29.4.2 slash: 3.0.0 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color dev: true - /jest-diff/29.4.1: - resolution: {integrity: sha512-uazdl2g331iY56CEyfbNA0Ut7Mn2ulAG5vUaEHXycf1L6IPyuImIxSz4F0VYBKi7LYIuxOwTZzK3wh5jHzASMw==} + /jest-diff/29.4.2: + resolution: {integrity: sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: chalk: 4.1.2 - diff-sequences: 29.3.1 - jest-get-type: 29.2.0 - pretty-format: 29.4.1 + diff-sequences: 29.4.2 + jest-get-type: 29.4.2 + pretty-format: 29.4.2 dev: true - /jest-docblock/29.2.0: - resolution: {integrity: sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==} + /jest-docblock/29.4.2: + resolution: {integrity: sha512-dV2JdahgClL34Y5vLrAHde3nF3yo2jKRH+GIYJuCpfqwEJZcikzeafVTGAjbOfKPG17ez9iWXwUYp7yefeCRag==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: detect-newline: 3.1.0 dev: true - /jest-each/29.4.1: - resolution: {integrity: sha512-QlYFiX3llJMWUV0BtWht/esGEz9w+0i7BHwODKCze7YzZzizgExB9MOfiivF/vVT0GSQ8wXLhvHXh3x2fVD4QQ==} + /jest-each/29.4.2: + resolution: {integrity: sha512-trvKZb0JYiCndc55V1Yh0Luqi7AsAdDWpV+mKT/5vkpnnFQfuQACV72IoRV161aAr6kAVIBpmYzwhBzm34vQkA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.4.1 + '@jest/types': 29.4.2 chalk: 4.1.2 - jest-get-type: 29.2.0 - jest-util: 29.4.1 - pretty-format: 29.4.1 + jest-get-type: 29.4.2 + jest-util: 29.4.2 + pretty-format: 29.4.2 dev: true - /jest-environment-jsdom/29.4.1: - resolution: {integrity: sha512-+KfYmRTl5CBHQst9hIz77TiiriHYvuWoLjMT855gx2AMxhHxpk1vtKvag1DQfyWCPVTWV/AG7SIqVh5WI1O/uw==} + /jest-environment-jsdom/29.4.2: + resolution: {integrity: sha512-v1sH4Q0JGM+LPEGqHNM+m+uTMf3vpXpKiuDYqWUAh+0c9+nc7scGE+qTR5JuE+OOTDnwfzPgcv9sMq6zWAOaVg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: canvas: ^2.5.0 @@ -6955,13 +6969,13 @@ packages: canvas: optional: true dependencies: - '@jest/environment': 29.4.1 - '@jest/fake-timers': 29.4.1 - '@jest/types': 29.4.1 + '@jest/environment': 29.4.2 + '@jest/fake-timers': 29.4.2 + '@jest/types': 29.4.2 '@types/jsdom': 20.0.0 - '@types/node': 18.11.18 - jest-mock: 29.4.1 - jest-util: 29.4.1 + '@types/node': 18.13.0 + jest-mock: 29.4.2 + jest-util: 29.4.2 jsdom: 20.0.0 transitivePeerDependencies: - bufferutil @@ -6969,16 +6983,16 @@ packages: - utf-8-validate dev: true - /jest-environment-node/29.4.1: - resolution: {integrity: sha512-x/H2kdVgxSkxWAIlIh9MfMuBa0hZySmfsC5lCsWmWr6tZySP44ediRKDUiNggX/eHLH7Cd5ZN10Rw+XF5tXsqg==} + /jest-environment-node/29.4.2: + resolution: {integrity: sha512-MLPrqUcOnNBc8zTOfqBbxtoa8/Ee8tZ7UFW7hRDQSUT+NGsvS96wlbHGTf+EFAT9KC3VNb7fWEM6oyvmxtE/9w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.4.1 - '@jest/fake-timers': 29.4.1 - '@jest/types': 29.4.1 - '@types/node': 18.11.18 - jest-mock: 29.4.1 - jest-util: 29.4.1 + '@jest/environment': 29.4.2 + '@jest/fake-timers': 29.4.2 + '@jest/types': 29.4.2 + '@types/node': 18.13.0 + jest-mock: 29.4.2 + jest-util: 29.4.2 dev: true /jest-get-type/29.2.0: @@ -6986,13 +7000,18 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true + /jest-get-type/29.4.2: + resolution: {integrity: sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + /jest-haste-map/26.6.2: resolution: {integrity: sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==} engines: {node: '>= 10.14.2'} dependencies: '@jest/types': 26.6.2 '@types/graceful-fs': 4.1.5 - '@types/node': 18.11.18 + '@types/node': 18.13.0 anymatch: 3.1.2 fb-watchman: 2.0.1 graceful-fs: 4.2.10 @@ -7009,31 +7028,31 @@ packages: - supports-color dev: true - /jest-haste-map/29.4.1: - resolution: {integrity: sha512-imTjcgfVVTvg02khXL11NNLTx9ZaofbAWhilrMg/G8dIkp+HYCswhxf0xxJwBkfhWb3e8dwbjuWburvxmcr58w==} + /jest-haste-map/29.4.2: + resolution: {integrity: sha512-WkUgo26LN5UHPknkezrBzr7lUtV1OpGsp+NfXbBwHztsFruS3gz+AMTTBcEklvi8uPzpISzYjdKXYZQJXBnfvw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.4.1 + '@jest/types': 29.4.2 '@types/graceful-fs': 4.1.5 - '@types/node': 18.11.18 + '@types/node': 18.13.0 anymatch: 3.1.2 fb-watchman: 2.0.1 graceful-fs: 4.2.10 - jest-regex-util: 29.2.0 - jest-util: 29.4.1 - jest-worker: 29.4.1 + jest-regex-util: 29.4.2 + jest-util: 29.4.2 + jest-worker: 29.4.2 micromatch: 4.0.5 walker: 1.0.8 optionalDependencies: fsevents: 2.3.2 dev: true - /jest-leak-detector/29.4.1: - resolution: {integrity: sha512-akpZv7TPyGMnH2RimOCgy+hPmWZf55EyFUvymQ4LMsQP8xSPlZumCPtXGoDhFNhUE2039RApZkTQDKU79p/FiQ==} + /jest-leak-detector/29.4.2: + resolution: {integrity: sha512-Wa62HuRJmWXtX9F00nUpWlrbaH5axeYCdyRsOs/+Rb1Vb6+qWTlB5rKwCCRKtorM7owNwKsyJ8NRDUcZ8ghYUA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - jest-get-type: 29.2.0 - pretty-format: 29.4.1 + jest-get-type: 29.4.2 + pretty-format: 29.4.2 dev: true /jest-matcher-utils/29.4.1: @@ -7041,9 +7060,19 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: chalk: 4.1.2 - jest-diff: 29.4.1 - jest-get-type: 29.2.0 - pretty-format: 29.4.1 + jest-diff: 29.4.2 + jest-get-type: 29.4.2 + pretty-format: 29.4.2 + dev: true + + /jest-matcher-utils/29.4.2: + resolution: {integrity: sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 29.4.2 + jest-get-type: 29.4.2 + pretty-format: 29.4.2 dev: true /jest-message-util/29.4.1: @@ -7051,26 +7080,41 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/code-frame': 7.18.6 - '@jest/types': 29.4.1 + '@jest/types': 29.4.2 '@types/stack-utils': 2.0.1 chalk: 4.1.2 graceful-fs: 4.2.10 micromatch: 4.0.5 - pretty-format: 29.4.1 + pretty-format: 29.4.2 slash: 3.0.0 stack-utils: 2.0.5 dev: true - /jest-mock/29.4.1: - resolution: {integrity: sha512-MwA4hQ7zBOcgVCVnsM8TzaFLVUD/pFWTfbkY953Y81L5ret3GFRZtmPmRFAjKQSdCKoJvvqOu6Bvfpqlwwb0dQ==} + /jest-message-util/29.4.2: + resolution: {integrity: sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.4.1 - '@types/node': 18.11.18 - jest-util: 29.4.1 + '@babel/code-frame': 7.18.6 + '@jest/types': 29.4.2 + '@types/stack-utils': 2.0.1 + chalk: 4.1.2 + graceful-fs: 4.2.10 + micromatch: 4.0.5 + pretty-format: 29.4.2 + slash: 3.0.0 + stack-utils: 2.0.5 dev: true - /jest-pnp-resolver/1.2.2_jest-resolve@29.4.1: + /jest-mock/29.4.2: + resolution: {integrity: sha512-x1FSd4Gvx2yIahdaIKoBjwji6XpboDunSJ95RpntGrYulI1ByuYQCKN/P7hvk09JB74IonU3IPLdkutEWYt++g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.4.2 + '@types/node': 18.13.0 + jest-util: 29.4.2 + dev: true + + /jest-pnp-resolver/1.2.2_jest-resolve@29.4.2: resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} engines: {node: '>=6'} peerDependencies: @@ -7079,7 +7123,7 @@ packages: jest-resolve: optional: true dependencies: - jest-resolve: 29.4.1 + jest-resolve: 29.4.2 dev: true /jest-regex-util/26.0.0: @@ -7092,84 +7136,89 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true - /jest-resolve-dependencies/29.4.1: - resolution: {integrity: sha512-Y3QG3M1ncAMxfjbYgtqNXC5B595zmB6e//p/qpA/58JkQXu/IpLDoLeOa8YoYfsSglBKQQzNUqtfGJJT/qLmJg==} + /jest-regex-util/29.4.2: + resolution: {integrity: sha512-XYZXOqUl1y31H6VLMrrUL1ZhXuiymLKPz0BO1kEeR5xER9Tv86RZrjTm74g5l9bPJQXA/hyLdaVPN/sdqfteig==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-resolve-dependencies/29.4.2: + resolution: {integrity: sha512-6pL4ptFw62rjdrPk7rRpzJYgcRqRZNsZTF1VxVTZMishbO6ObyWvX57yHOaNGgKoADtAHRFYdHQUEvYMJATbDg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - jest-regex-util: 29.2.0 - jest-snapshot: 29.4.1 + jest-regex-util: 29.4.2 + jest-snapshot: 29.4.2 transitivePeerDependencies: - supports-color dev: true - /jest-resolve/29.4.1: - resolution: {integrity: sha512-j/ZFNV2lm9IJ2wmlq1uYK0Y/1PiyDq9g4HEGsNTNr3viRbJdV+8Lf1SXIiLZXFvyiisu0qUyIXGBnw+OKWkJwQ==} + /jest-resolve/29.4.2: + resolution: {integrity: sha512-RtKWW0mbR3I4UdkOrW7552IFGLYQ5AF9YrzD0FnIOkDu0rAMlA5/Y1+r7lhCAP4nXSBTaE7ueeqj6IOwZpgoqw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: chalk: 4.1.2 graceful-fs: 4.2.10 - jest-haste-map: 29.4.1 - jest-pnp-resolver: 1.2.2_jest-resolve@29.4.1 - jest-util: 29.4.1 - jest-validate: 29.4.1 + jest-haste-map: 29.4.2 + jest-pnp-resolver: 1.2.2_jest-resolve@29.4.2 + jest-util: 29.4.2 + jest-validate: 29.4.2 resolve: 1.22.1 resolve.exports: 2.0.0 slash: 3.0.0 dev: true - /jest-runner/29.4.1: - resolution: {integrity: sha512-8d6XXXi7GtHmsHrnaqBKWxjKb166Eyj/ksSaUYdcBK09VbjPwIgWov1VwSmtupCIz8q1Xv4Qkzt/BTo3ZqiCeg==} + /jest-runner/29.4.2: + resolution: {integrity: sha512-wqwt0drm7JGjwdH+x1XgAl+TFPH7poowMguPQINYxaukCqlczAcNLJiK+OLxUxQAEWMdy+e6nHZlFHO5s7EuRg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/console': 29.4.1 - '@jest/environment': 29.4.1 - '@jest/test-result': 29.4.1 - '@jest/transform': 29.4.1 - '@jest/types': 29.4.1 - '@types/node': 18.11.18 + '@jest/console': 29.4.2 + '@jest/environment': 29.4.2 + '@jest/test-result': 29.4.2 + '@jest/transform': 29.4.2 + '@jest/types': 29.4.2 + '@types/node': 18.13.0 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.10 - jest-docblock: 29.2.0 - jest-environment-node: 29.4.1 - jest-haste-map: 29.4.1 - jest-leak-detector: 29.4.1 - jest-message-util: 29.4.1 - jest-resolve: 29.4.1 - jest-runtime: 29.4.1 - jest-util: 29.4.1 - jest-watcher: 29.4.1 - jest-worker: 29.4.1 + jest-docblock: 29.4.2 + jest-environment-node: 29.4.2 + jest-haste-map: 29.4.2 + jest-leak-detector: 29.4.2 + jest-message-util: 29.4.2 + jest-resolve: 29.4.2 + jest-runtime: 29.4.2 + jest-util: 29.4.2 + jest-watcher: 29.4.2 + jest-worker: 29.4.2 p-limit: 3.1.0 source-map-support: 0.5.13 transitivePeerDependencies: - supports-color dev: true - /jest-runtime/29.4.1: - resolution: {integrity: sha512-UXTMU9uKu2GjYwTtoAw5rn4STxWw/nadOfW7v1sx6LaJYa3V/iymdCLQM6xy3+7C6mY8GfX22vKpgxY171UIoA==} + /jest-runtime/29.4.2: + resolution: {integrity: sha512-3fque9vtpLzGuxT9eZqhxi+9EylKK/ESfhClv4P7Y9sqJPs58LjVhTt8jaMp/pRO38agll1CkSu9z9ieTQeRrw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.4.1 - '@jest/fake-timers': 29.4.1 - '@jest/globals': 29.4.1 - '@jest/source-map': 29.2.0 - '@jest/test-result': 29.4.1 - '@jest/transform': 29.4.1 - '@jest/types': 29.4.1 - '@types/node': 18.11.18 + '@jest/environment': 29.4.2 + '@jest/fake-timers': 29.4.2 + '@jest/globals': 29.4.2 + '@jest/source-map': 29.4.2 + '@jest/test-result': 29.4.2 + '@jest/transform': 29.4.2 + '@jest/types': 29.4.2 + '@types/node': 18.13.0 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 glob: 7.2.3 graceful-fs: 4.2.10 - jest-haste-map: 29.4.1 - jest-message-util: 29.4.1 - jest-mock: 29.4.1 - jest-regex-util: 29.2.0 - jest-resolve: 29.4.1 - jest-snapshot: 29.4.1 - jest-util: 29.4.1 + jest-haste-map: 29.4.2 + jest-message-util: 29.4.2 + jest-mock: 29.4.2 + jest-regex-util: 29.4.2 + jest-resolve: 29.4.2 + jest-snapshot: 29.4.2 + jest-util: 29.4.2 semver: 7.3.8 slash: 3.0.0 strip-bom: 4.0.0 @@ -7181,12 +7230,12 @@ packages: resolution: {integrity: sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==} engines: {node: '>= 10.14.2'} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 graceful-fs: 4.2.10 dev: true - /jest-snapshot/29.4.1: - resolution: {integrity: sha512-l4iV8EjGgQWVz3ee/LR9sULDk2pCkqb71bjvlqn+qp90lFwpnulHj4ZBT8nm1hA1C5wowXLc7MGnw321u0tsYA==} + /jest-snapshot/29.4.2: + resolution: {integrity: sha512-PdfubrSNN5KwroyMH158R23tWcAXJyx4pvSvWls1dHoLCaUhGul9rsL3uVjtqzRpkxlkMavQjGuWG1newPgmkw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/core': 7.20.12 @@ -7195,23 +7244,23 @@ packages: '@babel/plugin-syntax-typescript': 7.18.6_@babel+core@7.20.12 '@babel/traverse': 7.20.12 '@babel/types': 7.20.7 - '@jest/expect-utils': 29.4.1 - '@jest/transform': 29.4.1 - '@jest/types': 29.4.1 + '@jest/expect-utils': 29.4.2 + '@jest/transform': 29.4.2 + '@jest/types': 29.4.2 '@types/babel__traverse': 7.17.1 '@types/prettier': 2.6.3 babel-preset-current-node-syntax: 1.0.1_@babel+core@7.20.12 chalk: 4.1.2 - expect: 29.4.1 + expect: 29.4.2 graceful-fs: 4.2.10 - jest-diff: 29.4.1 - jest-get-type: 29.2.0 - jest-haste-map: 29.4.1 - jest-matcher-utils: 29.4.1 - jest-message-util: 29.4.1 - jest-util: 29.4.1 + jest-diff: 29.4.2 + jest-get-type: 29.4.2 + jest-haste-map: 29.4.2 + jest-matcher-utils: 29.4.2 + jest-message-util: 29.4.2 + jest-util: 29.4.2 natural-compare: 1.4.0 - pretty-format: 29.4.1 + pretty-format: 29.4.2 semver: 7.3.8 transitivePeerDependencies: - supports-color @@ -7226,7 +7275,7 @@ packages: engines: {node: '>= 10.14.2'} dependencies: '@jest/types': 26.6.2 - '@types/node': 18.11.18 + '@types/node': 18.13.0 chalk: 4.1.2 graceful-fs: 4.2.10 is-ci: 2.0.0 @@ -7237,27 +7286,39 @@ packages: resolution: {integrity: sha512-bQy9FPGxVutgpN4VRc0hk6w7Hx/m6L53QxpDreTZgJd9gfx/AV2MjyPde9tGyZRINAUrSv57p2inGBu2dRLmkQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.4.1 - '@types/node': 18.11.18 + '@jest/types': 29.4.2 + '@types/node': 18.13.0 chalk: 4.1.2 ci-info: 3.3.2 graceful-fs: 4.2.10 picomatch: 2.3.1 dev: true - /jest-validate/29.4.1: - resolution: {integrity: sha512-qNZXcZQdIQx4SfUB/atWnI4/I2HUvhz8ajOSYUu40CSmf9U5emil8EDHgE7M+3j9/pavtk3knlZBDsgFvv/SWw==} + /jest-util/29.4.2: + resolution: {integrity: sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.4.1 - camelcase: 6.3.0 + '@jest/types': 29.4.2 + '@types/node': 18.13.0 chalk: 4.1.2 - jest-get-type: 29.2.0 - leven: 3.1.0 - pretty-format: 29.4.1 + ci-info: 3.3.2 + graceful-fs: 4.2.10 + picomatch: 2.3.1 dev: true - /jest-watch-typeahead/2.2.2_jest@29.4.1: + /jest-validate/29.4.2: + resolution: {integrity: sha512-tto7YKGPJyFbhcKhIDFq8B5od+eVWD/ySZ9Tvcp/NGCvYA4RQbuzhbwYWtIjMT5W5zA2W0eBJwu4HVw34d5G6Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.4.2 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.4.2 + leven: 3.1.0 + pretty-format: 29.4.2 + dev: true + + /jest-watch-typeahead/2.2.2_jest@29.4.2: resolution: {integrity: sha512-+QgOFW4o5Xlgd6jGS5X37i08tuuXNW8X0CV9WNFi+3n8ExCIP+E1melYhvYLjv5fE6D0yyzk74vsSO8I6GqtvQ==} engines: {node: ^14.17.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -7265,7 +7326,7 @@ packages: dependencies: ansi-escapes: 6.0.0 chalk: 5.2.0 - jest: 29.4.1_@types+node@18.11.18 + jest: 29.4.2_@types+node@18.13.0 jest-regex-util: 29.2.0 jest-watcher: 29.4.0 slash: 5.0.0 @@ -7277,27 +7338,27 @@ packages: resolution: {integrity: sha512-PnnfLygNKelWOJwpAYlcsQjB+OxRRdckD0qiGmYng4Hkz1ZwK3jvCaJJYiywz2msQn4rBNLdriasJtv7YpWHpA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/test-result': 29.4.1 - '@jest/types': 29.4.1 - '@types/node': 18.11.18 + '@jest/test-result': 29.4.2 + '@jest/types': 29.4.2 + '@types/node': 18.13.0 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 - jest-util: 29.4.1 + jest-util: 29.4.2 string-length: 4.0.2 dev: true - /jest-watcher/29.4.1: - resolution: {integrity: sha512-vFOzflGFs27nU6h8dpnVRER3O2rFtL+VMEwnG0H3KLHcllLsU8y9DchSh0AL/Rg5nN1/wSiQ+P4ByMGpuybaVw==} + /jest-watcher/29.4.2: + resolution: {integrity: sha512-onddLujSoGiMJt+tKutehIidABa175i/Ays+QvKxCqBwp7fvxP3ZhKsrIdOodt71dKxqk4sc0LN41mWLGIK44w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/test-result': 29.4.1 - '@jest/types': 29.4.1 - '@types/node': 18.11.18 + '@jest/test-result': 29.4.2 + '@jest/types': 29.4.2 + '@types/node': 18.13.0 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 - jest-util: 29.4.1 + jest-util: 29.4.2 string-length: 4.0.2 dev: true @@ -7305,23 +7366,23 @@ packages: resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 merge-stream: 2.0.0 supports-color: 7.2.0 dev: true - /jest-worker/29.4.1: - resolution: {integrity: sha512-O9doU/S1EBe+yp/mstQ0VpPwpv0Clgn68TkNwGxL6/usX/KUW9Arnn4ag8C3jc6qHcXznhsT5Na1liYzAsuAbQ==} + /jest-worker/29.4.2: + resolution: {integrity: sha512-VIuZA2hZmFyRbchsUCHEehoSf2HEl0YVF8SDJqtPnKorAaBuh42V8QsLnde0XP5F6TyCynGPEGgBOn3Fc+wZGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 18.11.18 - jest-util: 29.4.1 + '@types/node': 18.13.0 + jest-util: 29.4.2 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest/29.4.1_@types+node@18.11.18: - resolution: {integrity: sha512-cknimw7gAXPDOmj0QqztlxVtBVCw2lYY9CeIE5N6kD+kET1H4H79HSNISJmijb1HF+qk+G+ploJgiDi5k/fRlg==} + /jest/29.4.2_@types+node@18.13.0: + resolution: {integrity: sha512-+5hLd260vNIHu+7ZgMIooSpKl7Jp5pHKb51e73AJU3owd5dEo/RfVwHbA/na3C/eozrt3hJOLGf96c7EWwIAzg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true peerDependencies: @@ -7330,10 +7391,10 @@ packages: node-notifier: optional: true dependencies: - '@jest/core': 29.4.1 - '@jest/types': 29.4.1 + '@jest/core': 29.4.2 + '@jest/types': 29.4.2 import-local: 3.1.0 - jest-cli: 29.4.1_@types+node@18.11.18 + jest-cli: 29.4.2_@types+node@18.13.0 transitivePeerDependencies: - '@types/node' - supports-color @@ -8207,8 +8268,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /postcss/8.4.20: - resolution: {integrity: sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==} + /postcss/8.4.21: + resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.4 @@ -8233,8 +8294,8 @@ packages: fast-diff: 1.2.0 dev: true - /prettier/2.8.3: - resolution: {integrity: sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==} + /prettier/2.8.4: + resolution: {integrity: sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==} engines: {node: '>=10.13.0'} hasBin: true dev: true @@ -8257,11 +8318,11 @@ packages: react-is: 18.2.0 dev: true - /pretty-format/29.4.1: - resolution: {integrity: sha512-dt/Z761JUVsrIKaY215o1xQJBGlSmTx/h4cSqXqjHLnU1+Kt+mavVE7UgqJJO5ukx5HjSswHfmXz4LjS2oIJfg==} + /pretty-format/29.4.2: + resolution: {integrity: sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/schemas': 29.4.0 + '@jest/schemas': 29.4.2 ansi-styles: 5.2.0 react-is: 18.2.0 dev: true @@ -8332,8 +8393,8 @@ packages: react: 18.2.0 scheduler: 0.23.0 - /react-i18next/12.1.4_iakk3dtjhjpukdoa4oua5khgci: - resolution: {integrity: sha512-XQND7jYtgM7ht5PH3yIZljCRpAMTlH/zmngM9ZjToqa+0BR6xuu8c7QF0WIIOEjcMTB2S3iOfpN/xG/ZrAnO6g==} + /react-i18next/12.1.5_iakk3dtjhjpukdoa4oua5khgci: + resolution: {integrity: sha512-7PQAv6DA0TcStG96fle+8RfTwxVbHVlZZJPoEszwUNvDuWpGldJmNWa3ZPesEsZQZGF6GkzwvEh6p57qpFD2gQ==} peerDependencies: i18next: '>= 19.0.0' react: '>= 16.8.0 || 18' @@ -8379,26 +8440,26 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-router-dom/6.8.0_biqbaboplfbrettd7655fr4n2y: - resolution: {integrity: sha512-hQouduSTywGJndE86CXJ2h7YEy4HYC6C/uh19etM+79FfQ6cFFFHnHyDlzO4Pq0eBUI96E4qVE5yUjA00yJZGQ==} + /react-router-dom/6.8.1_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-67EXNfkQgf34P7+PSb6VlBuaacGhkKn3kpE51+P6zYSG2kiRoumXEL6e27zTa9+PGF2MNXbgIUHTVlleLbIcHQ==} engines: {node: '>=14'} peerDependencies: react: '>=16.8 || 18' react-dom: '>=16.8 || 18' dependencies: - '@remix-run/router': 1.3.1 + '@remix-run/router': 1.3.2 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - react-router: 6.8.0_react@18.2.0 + react-router: 6.8.1_react@18.2.0 dev: false - /react-router/6.8.0_react@18.2.0: - resolution: {integrity: sha512-760bk7y3QwabduExtudhWbd88IBbuD1YfwzpuDUAlJUJ7laIIcqhMvdhSVh1Fur1PE8cGl84L0dxhR3/gvHF7A==} + /react-router/6.8.1_react@18.2.0: + resolution: {integrity: sha512-Jgi8BzAJQ8MkPt8ipXnR73rnD7EmZ0HFFb7jdQU24TynGW1Ooqin2KVDN9voSC+7xhqbbCd2cjGUepb6RObnyg==} engines: {node: '>=14'} peerDependencies: react: '>=16.8 || 18' dependencies: - '@remix-run/router': 1.3.1 + '@remix-run/router': 1.3.2 react: 18.2.0 dev: false @@ -8652,8 +8713,8 @@ packages: fsevents: 2.3.2 dev: true - /rollup/3.7.4: - resolution: {integrity: sha512-jN9rx3k5pfg9H9al0r0y1EYKSeiRANZRYX32SuNXAnKzh6cVyf4LZVto1KAuDnbHT03E1CpsgqDKaqQ8FZtgxw==} + /rollup/3.12.1: + resolution: {integrity: sha512-t9elERrz2i4UU9z7AwISj3CQcXP39cWxgRWLdf4Tm6aKm1eYrqHIgjzXBgb67GNY1sZckTFFi0oMozh3/S++Ig==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: @@ -9201,7 +9262,7 @@ packages: engines: {node: '>=8'} dev: true - /ts-node/10.9.0_bdgp3l2zgaopogaavxusmetvge: + /ts-node/10.9.0_4bewfcp2iebiwuold25d6rgcsy: resolution: {integrity: sha512-bunW18GUyaCSYRev4DPf4SQpom3pWH29wKl0sDk5zE7ze19RImEVhCW7K4v3hHKkUyfWotU08ToE2RS+Y49aug==} hasBin: true peerDependencies: @@ -9220,7 +9281,7 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.3 - '@types/node': 18.11.18 + '@types/node': 18.13.0 acorn: 8.8.0 acorn-walk: 8.2.0 arg: 4.1.3 @@ -9448,7 +9509,7 @@ packages: spdx-expression-parse: 3.0.1 dev: true - /vite-plugin-eslint/1.8.1_eslint@8.33.0+vite@4.0.4: + /vite-plugin-eslint/1.8.1_eslint@8.34.0+vite@4.1.1: resolution: {integrity: sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==} peerDependencies: eslint: '>=7' @@ -9456,12 +9517,12 @@ packages: dependencies: '@rollup/pluginutils': 4.2.1 '@types/eslint': 8.4.5 - eslint: 8.33.0 + eslint: 8.34.0 rollup: 2.78.0 - vite: 4.0.4_@types+node@18.11.18 + vite: 4.1.1_@types+node@18.13.0 dev: true - /vite-plugin-istanbul/4.0.0_vite@4.0.4: + /vite-plugin-istanbul/4.0.0_vite@4.1.1: resolution: {integrity: sha512-r5TUlEprFyp+L+by/waG1RsIMiqfy7LBAZvheFlXjxzm69146rHGW6bh9TDzXg7wJB6DsyjqKFtvAX50d/I/IQ==} peerDependencies: vite: '>=2.9.1 <= 5' @@ -9470,19 +9531,19 @@ packages: istanbul-lib-instrument: 5.2.0 picocolors: 1.0.0 test-exclude: 6.0.0 - vite: 4.0.4_@types+node@18.11.18 + vite: 4.1.1_@types+node@18.13.0 transitivePeerDependencies: - supports-color dev: true - /vite-plugin-svgr/2.4.0_vite@4.0.4: + /vite-plugin-svgr/2.4.0_vite@4.1.1: resolution: {integrity: sha512-q+mJJol6ThvqkkJvvVFEndI4EaKIjSI0I3jNFgSoC9fXAz1M7kYTVUin8fhUsFojFDKZ9VHKtX6NXNaOLpbsHA==} peerDependencies: vite: ^2.6.0 || 3 || 4 dependencies: '@rollup/pluginutils': 5.0.2 '@svgr/core': 6.5.1 - vite: 4.0.4_@types+node@18.11.18 + vite: 4.1.1_@types+node@18.13.0 transitivePeerDependencies: - rollup - supports-color @@ -9499,8 +9560,8 @@ packages: - typescript dev: true - /vite/4.0.4_@types+node@18.11.18: - resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==} + /vite/4.1.1_@types+node@18.13.0: + resolution: {integrity: sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true peerDependencies: @@ -9524,11 +9585,11 @@ packages: terser: optional: true dependencies: - '@types/node': 18.11.18 + '@types/node': 18.13.0 esbuild: 0.16.17 - postcss: 8.4.20 + postcss: 8.4.21 resolve: 1.22.1 - rollup: 3.7.4 + rollup: 3.12.1 optionalDependencies: fsevents: 2.3.2 dev: true @@ -9666,9 +9727,9 @@ packages: typedarray-to-buffer: 3.1.5 dev: true - /write-file-atomic/5.0.0: - resolution: {integrity: sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + /write-file-atomic/4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} dependencies: imurmurhash: 0.1.4 signal-exit: 3.0.7