feat: major documentation refresh (#3475)

This marks the launch of the new documentation website.
This commit is contained in:
James Elliott 2022-06-15 17:51:47 +10:00 committed by GitHub
parent c020697caa
commit b2c60ef898
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
580 changed files with 23726 additions and 7878 deletions

View File

@ -61,11 +61,4 @@ steps:
agents:
upload: "fast"
if: build.tag != null
- label: ":book: Deploy Documentation"
command: "syncdoc.sh"
depends_on: ~
agents:
upload: "fast"
if: build.branch == "master"
EOF
EOF

View File

@ -1,25 +0,0 @@
#!/usr/bin/env bash
set -e
rm -rf authelia
git clone git@github.com:authelia/authelia.git --single-branch --branch gh-pages
pushd docs
bundle install
bundle exec jekyll build -d ../authelia
popd
COMMIT=$(git show -s --format=%h)
pushd authelia
git config user.name "Authelia[bot]"
git config user.email "autheliabot@gmail.com"
git status | grep "nothing to commit" && exit
git add -A
git commit -m "Synchronize docs of commit: ${COMMIT}"
git push
popd
rm -rf authelia

View File

@ -2,7 +2,7 @@
blank_issues_enabled: false
contact_links:
- name: Documentation
url: https://www.authelia.com/docs/
url: https://www.authelia.com/
about: Read the Documentation
- name: Matrix
url: https://matrix.to/#/#community:authelia.com

View File

@ -4,6 +4,9 @@
":semanticCommitTypeAll(build)",
":separatePatchReleases"
],
"ignorePaths": [
"docs/**"
],
"ignorePresets": [
":combinePatchMinorReleases",
"helpers:disableTypesNodeMajor",
@ -58,4 +61,4 @@
"gomodTidy",
"gomodNoMassage"
]
}
}

View File

@ -2,6 +2,7 @@
extends: default
ignore: |
docs/pnpm-lock.yaml
internal/configuration/test_resources/config_bad_quoting.yml
web/pnpm-lock.yaml
web/node_modules/

View File

@ -1,7 +1,7 @@
# Contributing
Anybody willing to contribute to the project either with code, documentation, security reviews or whatever, are very
welcome to create or review pull requests and take part in discussions in any of our public
Anybody willing to contribute to the project either with code, documentation, security reviews or whatever, are very
welcome to create or review pull requests and take part in discussions in any of our public
[chat rooms](./README.md#contact-options).
It's also possible to contribute financially in order to support the community.
@ -15,11 +15,13 @@ If you've found a **bug** or have a **feature request** then please create an is
## Code
If you would like to fix a bug or implement a feature, please fork the repository and create a Pull Request.
More information on getting set up locally can be found [here](https://www.authelia.com/docs/contributing/).
More information on getting set up locally can be found in the
[Development Contribution](https://www.authelia.com/contributing/development/introduction/) documentation.
Before you start any Pull Request, it's recommended that you create an issue to discuss first if you have any doubts about requirement or implementation.
That way you can be sure that the maintainer(s) agree on what to change and how, and you can hopefully get a quick merge afterwards.
Also, let the maintainers know that you plan to work on a particular issue so that no one else starts any duplicate work.
Before you start any Pull Request, it's recommended that you create an issue to discuss first if you have any doubts
about requirement or implementation. That way you can be sure that the maintainer(s) agree on what to change and how,
and you can hopefully get a quick merge afterwards. Also, let the maintainers know that you plan to work on a particular
issue so that no one else starts any duplicate work.
Pull Requests can only be merged once all status checks are green, which means `authelia-scripts --log-level debug ci` passes, and coverage does not regress.
@ -37,7 +39,7 @@ Read more about this in the [GitHub docs, Re-requesting a review](https://docs.g
## Collaboration with maintainers
Sometimes the codebase can be a challenge to navigate, especially for a first-time contributor. We don't want you
Sometimes the codebase can be a challenge to navigate, especially for a first-time contributor. We don't want you
spending an hour trying to work out something that would take us only a minute to explain.
If you'd like some help getting started we have several [contact options](./README.md#contact-options) available.

View File

@ -1,5 +1,5 @@
<p align="center">
<img src="./docs/images/authelia-title.png" width="350" title="Authelia">
<img src="./docs/static/images/authelia-title.png" width="350" title="Authelia">
</p>
[![Build](https://img.shields.io/buildkite/d6543d3ece3433f46dbe5fd9fcfaf1f68a6dbc48eb1048bc22/master?logo=buildkite&style=flat-square&color=brightgreen)](https://buildkite.com/authelia/authelia)
@ -20,12 +20,12 @@ sign-on (SSO) for your applications via a web portal. It acts as a companion for
[Traefik], [caddy] or [HAProxy] to let them know whether requests should either be allowed or redirected to Authelia's
portal for authentication.
Documentation is available at https://www.authelia.com/docs.
Documentation is available at [https://www.authelia.com/](https://www.authelia.com/).
The following is a simple diagram of the architecture:
<p align="center" style="margin:50px">
<img src="./docs/images/archi.png"/>
<img src="./docs/static/images/archi.png"/>
</p>
**Authelia** can be installed as a standalone service from the [AUR](https://aur.archlinux.org/packages/authelia/),
@ -36,15 +36,15 @@ The following is a simple diagram of the architecture:
the Helm [Chart](https://charts.authelia.com) (beta) leveraging ingress controllers and ingress configurations.
<p align="center">
<img src="./docs/images/logos/kubernetes.png" height="100"/>
<img src="./docs/images/logos/docker.logo.png" width="100">
<img src="./docs/static/images/logos/kubernetes.png" height="100"/>
<img src="./docs/static/images/logos/docker.logo.png" width="100">
</p>
Here is what Authelia's portal looks like:
<p align="center">
<img src="./docs/images/1FA.png" width="400" />
<img src="./docs/images/2FA-METHODS.png" width="400" />
<img src="./docs/static/images/1FA.png" width="400" />
<img src="./docs/static/images/2FA-METHODS.png" width="400" />
</p>
## Features summary
@ -52,11 +52,11 @@ Here is what Authelia's portal looks like:
This is a list of the key features of Authelia:
* Several second factor methods:
* **[Security Keys](https://www.authelia.com/docs/features/2fa/security-key)** that support [FIDO2]&nbsp;[Webauthn]
with devices like a [YubiKey].
* **[Time-based One-Time password](https://www.authelia.com/docs/features/2fa/one-time-password)**
* **[Security Keys](https://www.authelia.com/overview/authentication/webauthn-security-key/)** that support
[FIDO2]&nbsp;[Webauthn] with devices like a [YubiKey].
* **[Time-based One-Time password](https://www.authelia.com/overview/authentication/one-time-password/)**
with compatible authenticator applications.
* **[Mobile Push Notifications](https://www.authelia.com/docs/features/2fa/push-notifications)**
* **[Mobile Push Notifications](https://www.authelia.com/overview/authentication/push-notification/)**
with [Duo](https://duo.com/).
* Password reset with identity verification using email confirmation.
* Access restriction after too many invalid authentication attempts.
@ -78,11 +78,11 @@ This is a list of the key features of Authelia:
[Traefik Kubernetes Ingress](https://doc.traefik.io/traefik/providers/kubernetes-crd/) Kubernetes ingress
controllers out of the box.
* Beta support for installing via Helm using our [Charts](https://charts.authelia.com).
* Beta support for [OpenID Connect](https://www.authelia.com/docs/configuration/identity-providers/oidc.html).
* Beta support for [OpenID Connect](https://www.authelia.com/roadmap/active/openid-connect/).
For more details about the features, follow [Features](https://www.authelia.com/docs/features/).
For more details take a look at the [Overview](https://www.authelia.com/overview/prologue/introduction/).
If you want to know more about the roadmap, follow [Roadmap](https://www.authelia.com/docs/roadmap).
If you want to know more about the roadmap, follow [Roadmap](https://www.authelia.com/roadmap).
## Proxy support
@ -90,33 +90,36 @@ Authelia works in combination with [nginx], [Traefik], [caddy] or [HAProxy]. It
Docker or on top of [Kubernetes].
<p align="center">
<img src="./docs/images/logos/nginx.png" height="50"/>
<img src="./docs/images/logos/traefik.png" height="50"/>
<img src="./docs/images/logos/caddy.png" height="50"/>
<img src="./docs/images/logos/haproxy.png" height="50"/>
<img src="./docs/images/logos/kubernetes.png" height="50"/>
<img src="./docs/static/images/logos/nginx.png" height="50"/>
<img src="./docs/static/images/logos/traefik.png" height="50"/>
<img src="./docs/static/images/logos/caddy.png" height="50"/>
<img src="./docs/static/images/logos/haproxy.png" height="50"/>
<img src="./docs/static/images/logos/kubernetes.png" height="50"/>
</p>
***Help Wanted:*** Assistance would be appreciated in getting Authelia working with
[Envoy](https://www.envoyproxy.io/).
<p align="center">
<img src="./docs/images/logos/envoy.png" height="50"/>
<img src="./docs/static/images/logos/envoy.png" height="50"/>
</p>
## Getting Started
See the [Get Started Guide](https://www.authelia.com/integration/prologue/get-started/) or one of the curated examples
below.
### docker-compose
The `docker-compose` bundles act as a starting point for anyone wanting to see Authelia in action. You will have to
customize them to your needs as they come with self-signed certificates.
#### [Local](https://www.authelia.com/docs/getting-started)
#### [Local](https://www.authelia.com/integration/deployment/docker/#local)
The Local compose bundle is intended to test Authelia without worrying about configuration.
It's meant to be used for scenarios where the server is not be exposed to the internet.
Domains will be defined in the local hosts file and self-signed certificates will be utilised.
#### [Lite](https://www.authelia.com/docs/deployment/deployment-lite)
#### [Lite](https://www.authelia.com/integration/deployment/docker/#lite)
The Lite compose bundle is intended for scenarios where the server will be exposed to the internet, domains and DNS will
need to be setup accordingly and certificates will be generated through LetsEncrypt. The Lite element refers to minimal
external dependencies; File based user storage, SQLite based configuration storage. In this configuration, the service
@ -140,8 +143,8 @@ This guide will show you how to deploy it on bare metal as well as on
Authelia takes security very seriously. If you discover a vulnerability in Authelia, please see our
[Security Policy](https://github.com/authelia/authelia/security/policy).
For more information about [security](https://www.authelia.com/docs/security/) related matters, please read
[the documentation](https://www.authelia.com/docs/security/).
For more information about [security](https://www.authelia.com/information/security/) related matters, please read
[the documentation](https://www.authelia.com/information/security/).
## Contact Options
@ -345,22 +348,17 @@ Companies contributing to Authelia will have a specical mention below. [[Become
#### Balto
Thank you to [<img src="./docs/images/logos/balto.svg" alt="Balto" width="32"> Balto](https://www.getbalto.com/) for
hosting our apt repository.
#### Digital Ocean
Thank you to [<img src="./docs/images/logos/digitalocean.svg" alt="Digital Ocean" width="32"> DigitalOcean](https://www.digitalocean.com/?from=Authelia) for
contributing on OpenCollective.
Thank you to [<img src="./docs/static/images/logos/balto.svg" alt="Balto" width="32"> Balto](https://www.getbalto.com/)
for hosting our apt repository.
#### JetBrains
Thank you to [<img src="./docs/images/logos/jetbrains.svg" alt="JetBrains" width="32"> JetBrains](https://www.jetbrains.com/?from=Authelia)
Thank you to [<img src="./docs/static/images/logos/jetbrains.svg" alt="JetBrains" width="32"> JetBrains](https://www.jetbrains.com/?from=Authelia)
for providing us with free licenses to their great tools.
* [<img src="./docs/images/logos/intellij-idea.svg" alt="IDEA" width="32"> IDEA](http://www.jetbrains.com/idea/)
* [<img src="./docs/images/logos/goland.svg" alt="GoLand" width="32"> GoLand](http://www.jetbrains.com/go/)
* [<img src="./docs/images/logos/webstorm.svg" alt="WebStorm" width="32"> WebStorm](http://www.jetbrains.com/webstorm/)
* [<img src="./docs/static/images/logos/intellij-idea.svg" alt="IDEA" width="32"> IDEA](http://www.jetbrains.com/idea/)
* [<img src="./docs/static/images/logos/goland.svg" alt="GoLand" width="32"> GoLand](http://www.jetbrains.com/go/)
* [<img src="./docs/static/images/logos/webstorm.svg" alt="WebStorm" width="32"> WebStorm](http://www.jetbrains.com/webstorm/)
## License

View File

@ -2,20 +2,20 @@
## Prologue
Authelia takes security very seriously. We follow the rule of
Authelia takes security very seriously. We follow the rule of
[responsible disclosure](https://en.wikipedia.org/wiki/Responsible_disclosure), and we urge our community to do so as
well instead of making the vulnerability public. This allows time for the security issue to be patched quickly.
If you discover a vulnerability in Authelia, please first contact one of the maintainers privately as described in the
[contact options](#contact-options) below.
If you discover a vulnerability in Authelia, please first contact one of the maintainers privately as described in the
[contact options](#contact-options) below.
We urge you not to disclose the bug publicly at least until we've had a
reasonable chance to fix it, and to clearly communicate any public disclosure timeline in your initial contact with us.
reasonable chance to fix it, and to clearly communicate any public disclosure timeline in your initial contact with us.
If you do not have a particular public disclosure timeline, we will clearly communicate ours as we publish security
advisories.
advisories.
For more information about [security](https://www.authelia.com/docs/security/) related matters, please read
[the documentation](https://www.authelia.com/docs/security/).
For more information about [security](https://www.authelia.com/information/security/) related matters, please read
[the documentation](https://www.authelia.com/information/security/).
## Contact Options
@ -25,7 +25,7 @@ privately which is described in each available contact method. The methods inclu
## Credit
Users who report bugs will optionally be creditted for the discovery. Both in the [security advisory] and in our
Users who report bugs will optionally be credited for the discovery. Both in the [security advisory] and in our
[all contributors](./README.md#contribute) configuration/documentation.
## Process
@ -40,8 +40,8 @@ Users who report bugs will optionally be creditted for the discovery. Both in th
## Help Wanted
We are actively looking for sponsorship to obtain either a code security audit, penetration testing, or other audits
We are actively looking for sponsorship to obtain either a code security audit, penetration testing, or other audits
related to improving the security of Authelia. If your company or you personally are willing to offer discounts, pro
bono, or funding towards services like these please feel free to contact us on *any* of the methods above.
[security advisory]: https://github.com/authelia/authelia/security/advisories
[security advisory]: https://github.com/authelia/authelia/security/advisories

View File

@ -15,7 +15,7 @@
theme: light
## The secret used to generate JWT tokens when validating user identity by email confirmation. JWT Secret can also be
## set using a secret: https://www.authelia.com/docs/configuration/secrets.html
## set using a secret: https://www.authelia.com/c/secrets
jwt_secret: a_very_important_secret
## Default redirection URL
@ -52,7 +52,7 @@ server:
# asset_path: /config/assets/
## Buffers usually should be configured to be the same value.
## Explanation at https://www.authelia.com/docs/configuration/server.html
## Explanation at https://www.authelia.com/c/server#buffer-sizes
## Read buffer size adjusts the server's max incoming request size in bytes.
## Write buffer size does the same for outgoing responses.
read_buffer_size: 4096
@ -129,13 +129,13 @@ totp:
## The TOTP algorithm to use.
## It is CRITICAL you read the documentation before changing this option:
## https://www.authelia.com/docs/configuration/one-time-password.html#algorithm
## https://www.authelia.com/c/totp#algorithm
algorithm: sha1
## The number of digits a user has to input. Must either be 6 or 8.
## Changing this option only affects newly generated TOTP configurations.
## It is CRITICAL you read the documentation before changing this option:
## https://www.authelia.com/docs/configuration/one-time-password.html#digits
## https://www.authelia.com/c/totp#digits
digits: 6
## The period in seconds a one-time password is valid for.
@ -145,7 +145,8 @@ totp:
## The skew controls number of one-time passwords either side of the current one that are valid.
## Warning: before changing skew read the docs link below.
skew: 1
## See: https://www.authelia.com/docs/configuration/one-time-password.html#input-validation to read the documentation.
## See: https://www.authelia.com/c/totp#input-validation to read
## the documentation.
## The size of the generated shared secrets. Default is 32 and is sufficient in most use cases, minimum is 20.
secret_size: 32
@ -181,7 +182,7 @@ duo_api:
disable: false
hostname: api-123456789.example.com
integration_key: ABCDEF
## Secret can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
## Secret can also be set using a secret: https://www.authelia.com/c/secrets
secret_key: 1234567890abcdefghifjkl
enable_self_enrollment: false
@ -230,8 +231,8 @@ authentication_backend:
## always belong to groups they belonged to at the time of login even if they have been removed from them in LDAP.
## To force update on every request you can set this to '0' or 'always', this will increase processor demand.
## See the below documentation for more information.
## Duration Notation docs: https://www.authelia.com/docs/configuration/index.html#duration-notation-format
## Refresh Interval docs: https://www.authelia.com/docs/configuration/authentication/ldap.html#refresh-interval
## Duration Notation docs: https://www.authelia.com/c/common#duration-notation-format
## Refresh Interval docs: https://www.authelia.com/c/1fa#refresh-interval
refresh_interval: 5m
##
@ -249,7 +250,7 @@ authentication_backend:
##
## Depending on the option here certain other values in this section have a default value, notably all of the
## attribute mappings have a default value that this config overrides, you can read more about these default values
## at https://www.authelia.com/docs/configuration/authentication/ldap.html#defaults
## at https://www.authelia.com/c/ldap#defaults
implementation: custom
## The url to the ldap server. Format: <scheme>://<address>[:<port>].
@ -294,7 +295,7 @@ authentication_backend:
## The users filter used in search queries to find the user profile based on input filled in login form.
## Various placeholders are available in the user filter which you can read about in the documentation which can
## be found at: https://www.authelia.com/docs/configuration/authentication/ldap.html#users-filter-replacements
## be found at: https://www.authelia.com/c/ldap#users-filter-replacements
##
## Recommended settings are as follows:
## - Microsoft Active Directory: (&({username_attribute}={input})(objectCategory=person)(objectClass=user))
@ -312,7 +313,7 @@ authentication_backend:
## The groups filter used in search queries to find the groups based on relevant authenticated user.
## Various placeholders are available in the groups filter which you can read about in the documentation which can
## be found at: https://www.authelia.com/docs/configuration/authentication/ldap.html#groups-filter-replacements
## be found at: https://www.authelia.com/c/ldap#groups-filter-replacements
##
## If your groups use the `groupOfUniqueNames` structure use this instead:
## (&(uniqueMember={dn})(objectClass=groupOfUniqueNames))
@ -334,7 +335,7 @@ authentication_backend:
## The username and password of the admin user.
user: cn=admin,dc=example,dc=com
## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
## Password can also be set using a secret: https://www.authelia.com/c/secrets
password: password
##
@ -345,9 +346,9 @@ authentication_backend:
## to be scaled to more than one instance. The options under 'password' have sane defaults, and as it has security
## implications it is highly recommended you leave the default values. Before considering changing these settings
## please read the docs page below:
## https://www.authelia.com/docs/configuration/authentication/file.html#password-hash-algorithm-tuning
## https://www.authelia.com/r/passwords#tuning
##
## Important: Kubernetes (or HA) users must read https://www.authelia.com/docs/features/statelessness.html
## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
##
# file:
# path: /config/users_database.yml
@ -524,15 +525,15 @@ session:
domain: example.com
## Sets the Cookie SameSite value. Possible options are none, lax, or strict.
## Please read https://www.authelia.com/docs/configuration/session/#same_site
## Please read https://www.authelia.com/c/session#same_site
same_site: lax
## The secret to encrypt the session data. This is only used with Redis / Redis Sentinel.
## Secret can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
## Secret can also be set using a secret: https://www.authelia.com/c/secrets
secret: insecure_session_secret
## The value for expiration, inactivity, and remember_me_duration are in seconds or the duration notation format.
## See: https://www.authelia.com/docs/configuration/index.html#duration-notation-format
## See: https://www.authelia.com/c/common#duration-notation-format
## All three of these values affect the cookie/session validity period. Longer periods are considered less secure
## because a stolen cookie will last longer giving attackers more time to spy or attack.
@ -551,7 +552,7 @@ session:
##
## Redis Provider
##
## Important: Kubernetes (or HA) users must read https://www.authelia.com/docs/features/statelessness.html
## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
##
redis:
host: 127.0.0.1
@ -562,7 +563,7 @@ session:
## Username used for redis authentication. This is optional and a new feature in redis 6.0.
# username: authelia
## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
## Password can also be set using a secret: https://www.authelia.com/c/secrets
password: authelia
## This is the Redis DB Index https://redis.io/commands/select (sometimes referred to as database number, DB, etc).
@ -625,11 +626,11 @@ regulation:
## The time range during which the user can attempt login before being banned. The user is banned if the
## authentication failed 'max_retries' times in a 'find_time' seconds window. Find Time accepts duration notation.
## See: https://www.authelia.com/docs/configuration/index.html#duration-notation-format
## See: https://www.authelia.com/c/common#duration-notation-format
find_time: 2m
## The length of time before a banned user can login again. Ban Time accepts duration notation.
## See: https://www.authelia.com/docs/configuration/index.html#duration-notation-format
## See: https://www.authelia.com/c/common#duration-notation-format
ban_time: 5m
##
@ -647,7 +648,7 @@ storage:
## This stores the data in a SQLite3 Database.
## This is only recommended for lightweight non-stateful installations.
##
## Important: Kubernetes (or HA) users must read https://www.authelia.com/docs/features/statelessness.html
## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
##
# local:
# path: /config/db.sqlite3
@ -660,7 +661,7 @@ storage:
port: 3306
database: authelia
username: authelia
## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
## Password can also be set using a secret: https://www.authelia.com/c/secrets
password: mypassword
timeout: 5s
@ -673,7 +674,7 @@ storage:
# database: authelia
# schema: public
# username: authelia
# ## Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
# ## Password can also be set using a secret: https://www.authelia.com/c/secrets
# password: mypassword
# timeout: 5s
# ssl:
@ -694,7 +695,7 @@ notifier:
##
## File System (Notification Provider)
##
## Important: Kubernetes (or HA) users must read https://www.authelia.com/docs/features/statelessness.html
## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
##
# filesystem:
# filename: /config/notification.txt
@ -723,7 +724,7 @@ notifier:
username: test
## The password used for SMTP authentication.
## Can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
## Can also be set using a secret: https://www.authelia.com/c/secrets
password: password
## The sender is used to is used for the MAIL FROM command and the FROM header.
@ -768,14 +769,14 @@ notifier:
## OpenID Connect (Identity Provider)
##
## It's recommended you read the documentation before configuration of this section:
## https://www.authelia.com/docs/configuration/identity-providers/oidc.html
## https://www.authelia.com/c/oidc
# oidc:
## The hmac_secret is used to sign OAuth2 tokens (authorization code, access tokens and refresh tokens).
## HMAC Secret can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
## HMAC Secret can also be set using a secret: https://www.authelia.com/c/secrets
# hmac_secret: this_is_a_secret_abc123abc123abc
## The issuer_private_key is used to sign the JWT forged by OpenID Connect.
## Issuer Private Key can also be set using a secret: https://docs.authelia.com/configuration/secrets.html
## Issuer Private Key can also be set using a secret: https://www.authelia.com/c/secrets
# issuer_private_key: |
# --- KEY START
# --- KEY END

11
docs/.editorconfig Normal file
View File

@ -0,0 +1,11 @@
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

4
docs/.eslintignore Normal file
View File

@ -0,0 +1,4 @@
assets/js/index.js
assets/js/katex.js
assets/js/vendor
node_modules

31
docs/.eslintrc.json Normal file
View File

@ -0,0 +1,31 @@
{
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
"no-console": 0,
"quotes": ["error", "single"],
"comma-dangle": [
"error",
{
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "ignore"
}
]
}
}

10
docs/.gitignore vendored
View File

@ -1,4 +1,6 @@
_site
.sass-cache
.jekyll-metadata
.jekyll-cache
node_modules
public
resources
.netlify
.hugo_build.lock
!content/*/reference/cli/authelia

View File

@ -0,0 +1,20 @@
{
"config": {
"default": true,
"MD013": false,
"MD024": false,
"MD026": false,
"MD033": false,
"MD034": false,
"emphasis-style": {
"style": "asterisk"
},
"strong-style": {
"style": "underscore"
},
"ul-style": {
"style": "asterisk"
}
},
"ignores": ["node_modules", "CHANGELOG.md", "README.md", "content/*/reference/cli"]
}

3
docs/.stylelintignore Normal file
View File

@ -0,0 +1,3 @@
assets/scss/components/_syntax.scss
assets/scss/vendor
node_modules

48
docs/.stylelintrc.json Normal file
View File

@ -0,0 +1,48 @@
{
"extends": "stylelint-config-standard-scss",
"rules": {
"no-empty-source": null,
"string-quotes": "double",
"scss/comment-no-empty": null,
"max-line-length": null,
"scss/at-extend-no-missing-placeholder": null,
"scss/dollar-variable-colon-space-after": null,
"scss/dollar-variable-empty-line-before": null,
"color-function-notation": null,
"alpha-value-notation": null,
"selector-id-pattern": null,
"selector-class-pattern": null,
"scss/no-global-function-names": null,
"number-max-precision": null,
"hue-degree-notation": null,
"value-no-vendor-prefix": null,
"property-no-vendor-prefix": null,
"at-rule-no-unknown": [
true,
{
"ignoreAtRules": [
"extend",
"at-root",
"debug",
"warn",
"error",
"if",
"else",
"for",
"each",
"while",
"mixin",
"include",
"content",
"return",
"function",
"tailwind",
"apply",
"responsive",
"variants",
"screen"
]
}
]
}
}

View File

@ -1,30 +0,0 @@
source "https://rubygems.org"
# Hello! This is where you manage which Jekyll version is used to run.
# When you want to use a different version, change it below, save the
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
#
# bundle exec jekyll serve
#
# This will help ensure the proper Jekyll version is running.
# Happy Jekylling!
gem "jekyll", "~> 3.9.0"
# This is the default theme for new Jekyll sites. You may change this to anything you like.
#gem "minima", "~> 2.0"
gem "just-the-docs"
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
# uncomment the line below. To upgrade, run `bundle update github-pages`.
gem "github-pages", group: :jekyll_plugins
# If you have any plugins, put them here!
group :jekyll_plugins do
# gem "jekyll-feed", "~> 0.6"
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
# Performance-booster for watching directories on Windows
gem "wdm", "~> 0.1.0" if Gem.win_platform?

View File

@ -1,273 +0,0 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (6.0.3.6)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2)
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.11.1)
colorator (1.1.0)
commonmarker (0.17.13)
ruby-enum (~> 0.5)
concurrent-ruby (1.1.8)
dnsruby (1.61.5)
simpleidn (~> 0.1)
em-websocket (0.5.2)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
ethon (0.12.0)
ffi (>= 1.3.0)
eventmachine (1.2.7)
execjs (2.7.0)
faraday (1.3.0)
faraday-net_http (~> 1.0)
multipart-post (>= 1.2, < 3)
ruby2_keywords
faraday-net_http (1.0.1)
ffi (1.15.0)
forwardable-extended (2.6.0)
gemoji (3.0.1)
github-pages (214)
github-pages-health-check (= 1.17.0)
jekyll (= 3.9.0)
jekyll-avatar (= 0.7.0)
jekyll-coffeescript (= 1.1.1)
jekyll-commonmark-ghpages (= 0.1.6)
jekyll-default-layout (= 0.1.4)
jekyll-feed (= 0.15.1)
jekyll-gist (= 1.5.0)
jekyll-github-metadata (= 2.13.0)
jekyll-mentions (= 1.6.0)
jekyll-optional-front-matter (= 0.3.2)
jekyll-paginate (= 1.1.0)
jekyll-readme-index (= 0.3.0)
jekyll-redirect-from (= 0.16.0)
jekyll-relative-links (= 0.6.1)
jekyll-remote-theme (= 0.4.3)
jekyll-sass-converter (= 1.5.2)
jekyll-seo-tag (= 2.7.1)
jekyll-sitemap (= 1.4.0)
jekyll-swiss (= 1.0.0)
jekyll-theme-architect (= 0.1.1)
jekyll-theme-cayman (= 0.1.1)
jekyll-theme-dinky (= 0.1.1)
jekyll-theme-hacker (= 0.1.2)
jekyll-theme-leap-day (= 0.1.1)
jekyll-theme-merlot (= 0.1.1)
jekyll-theme-midnight (= 0.1.1)
jekyll-theme-minimal (= 0.1.1)
jekyll-theme-modernist (= 0.1.1)
jekyll-theme-primer (= 0.5.4)
jekyll-theme-slate (= 0.1.1)
jekyll-theme-tactile (= 0.1.1)
jekyll-theme-time-machine (= 0.1.1)
jekyll-titles-from-headings (= 0.5.3)
jemoji (= 0.12.0)
kramdown (= 2.3.1)
kramdown-parser-gfm (= 1.1.0)
liquid (= 4.0.3)
mercenary (~> 0.3)
minima (= 2.5.1)
nokogiri (>= 1.10.4, < 2.0)
rouge (= 3.26.0)
terminal-table (~> 1.4)
github-pages-health-check (1.17.0)
addressable (~> 2.3)
dnsruby (~> 1.60)
octokit (~> 4.0)
public_suffix (>= 2.0.2, < 5.0)
typhoeus (~> 1.3)
html-pipeline (2.14.0)
activesupport (>= 2)
nokogiri (>= 1.4)
http_parser.rb (0.6.0)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
jekyll (3.9.0)
addressable (~> 2.4)
colorator (~> 1.0)
em-websocket (~> 0.5)
i18n (~> 0.7)
jekyll-sass-converter (~> 1.0)
jekyll-watch (~> 2.0)
kramdown (>= 1.17, < 3)
liquid (~> 4.0)
mercenary (~> 0.3.3)
pathutil (~> 0.9)
rouge (>= 1.7, < 4)
safe_yaml (~> 1.0)
jekyll-avatar (0.7.0)
jekyll (>= 3.0, < 5.0)
jekyll-coffeescript (1.1.1)
coffee-script (~> 2.2)
coffee-script-source (~> 1.11.1)
jekyll-commonmark (1.3.1)
commonmarker (~> 0.14)
jekyll (>= 3.7, < 5.0)
jekyll-commonmark-ghpages (0.1.6)
commonmarker (~> 0.17.6)
jekyll-commonmark (~> 1.2)
rouge (>= 2.0, < 4.0)
jekyll-default-layout (0.1.4)
jekyll (~> 3.0)
jekyll-feed (0.15.1)
jekyll (>= 3.7, < 5.0)
jekyll-gist (1.5.0)
octokit (~> 4.2)
jekyll-github-metadata (2.13.0)
jekyll (>= 3.4, < 5.0)
octokit (~> 4.0, != 4.4.0)
jekyll-mentions (1.6.0)
html-pipeline (~> 2.3)
jekyll (>= 3.7, < 5.0)
jekyll-optional-front-matter (0.3.2)
jekyll (>= 3.0, < 5.0)
jekyll-paginate (1.1.0)
jekyll-readme-index (0.3.0)
jekyll (>= 3.0, < 5.0)
jekyll-redirect-from (0.16.0)
jekyll (>= 3.3, < 5.0)
jekyll-relative-links (0.6.1)
jekyll (>= 3.3, < 5.0)
jekyll-remote-theme (0.4.3)
addressable (~> 2.0)
jekyll (>= 3.5, < 5.0)
jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
rubyzip (>= 1.3.0, < 3.0)
jekyll-sass-converter (1.5.2)
sass (~> 3.4)
jekyll-seo-tag (2.7.1)
jekyll (>= 3.8, < 5.0)
jekyll-sitemap (1.4.0)
jekyll (>= 3.7, < 5.0)
jekyll-swiss (1.0.0)
jekyll-theme-architect (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-cayman (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-dinky (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-hacker (0.1.2)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-leap-day (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-merlot (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-midnight (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-minimal (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-modernist (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-primer (0.5.4)
jekyll (> 3.5, < 5.0)
jekyll-github-metadata (~> 2.9)
jekyll-seo-tag (~> 2.0)
jekyll-theme-slate (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-tactile (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-time-machine (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-titles-from-headings (0.5.3)
jekyll (>= 3.3, < 5.0)
jekyll-watch (2.2.1)
listen (~> 3.0)
jemoji (0.12.0)
gemoji (~> 3.0)
html-pipeline (~> 2.2)
jekyll (>= 3.0, < 5.0)
just-the-docs (0.3.3)
jekyll (>= 3.8.5)
jekyll-seo-tag (~> 2.0)
rake (>= 12.3.1, < 13.1.0)
kramdown (2.3.1)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (4.0.3)
listen (3.5.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
mini_portile2 (2.8.0)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.14.4)
multipart-post (2.1.1)
nokogiri (1.13.6)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
octokit (4.20.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (4.0.6)
racc (1.6.0)
rake (13.0.3)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
rexml (3.2.5)
rouge (3.26.0)
ruby-enum (0.9.0)
i18n
ruby2_keywords (0.0.4)
rubyzip (2.3.0)
safe_yaml (1.0.5)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sawyer (0.8.2)
addressable (>= 2.3.5)
faraday (> 0.8, < 2.0)
simpleidn (0.2.1)
unf (~> 0.1.4)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (1.2.9)
thread_safe (~> 0.1)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
zeitwerk (2.4.2)
PLATFORMS
ruby
DEPENDENCIES
github-pages
jekyll (~> 3.9.0)
just-the-docs
tzinfo-data
BUNDLED WITH
2.2.3

22
docs/LICENSE Normal file
View File

@ -0,0 +1,22 @@
MIT License
Copyright (c) 2018-present, Gridsome
Copyright (c) 2020-present, Henk Verlinde
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

9
docs/README.md Normal file
View File

@ -0,0 +1,9 @@
The **Authelia** website / documentation source.
Please:
- Only edit the `/content` folder via the main Authelia [monorepo](https://github.com/authelia/authelia/tree/master/docs)
- Edit everything else via the Authelia [website repo](https://github.com/authelia/website)
See the [Documentation Contributing Guide](https://www.authelia.com/contributing/prologue/documentation/) for more
information.

View File

@ -1,19 +0,0 @@
---
title: Authelia
email: team@authelia.com
description: Authelia is an open source multi-factor single sign-on portal for web applications
# We need this base URL to serve the docs under https://www.authelia.com/docs/
baseurl: "/docs/"
# url: "https://www.authelia.com"
repository: https://github.com/authelia/authelia
logo: ./images/authelia-title.png
footer_content: >
Copyright &copy; 2022 Authelia. Distributed by an
<a href="https://github.com/authelia/authelia/blob/master/LICENSE">Apache 2.0 license.</a>
markdown: kramdown
theme: just-the-docs
keep_files:
- .git
- CNAME
ga_tracking: UA-124926127-1
...

View File

@ -1,4 +0,0 @@
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/github-fork-ribbon-css/0.2.3/gh-fork-ribbon.min.css" />
<link rel="stylesheet"
href="https://fonts.googleapis.com/icon?family=Material+Icons" />

View File

@ -1,262 +0,0 @@
---
layout: table_wrappers
---
<!DOCTYPE html>
<html lang="{{ site.lang | default: 'en-US' }}">
{% include head.html %}
<body>
<a class="github-fork-ribbon" href="https://github.com/authelia/authelia" data-ribbon="Fork me on GitHub"
title="Fork me on GitHub">Fork me on GitHub</a>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-link" viewBox="0 0 24 24">
<title>Link</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link">
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
</svg>
</symbol>
<symbol id="svg-search" viewBox="0 0 24 24">
<title>Search</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search">
<circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>
</symbol>
<symbol id="svg-menu" viewBox="0 0 24 24">
<title>Menu</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu">
<line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</symbol>
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
<title>Expand</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</symbol>
<symbol id="svg-doc" viewBox="0 0 24 24">
<title>Document</title>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file">
<path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline>
</svg>
</symbol>
<symbol id="svg-contrib" viewBox="0 0 24 24">
<title>Survey contribution</title>
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<path style="fill:#FEC9A3;" d="M507.661,503.322V399.907c0-11.325-5.528-21.938-14.805-28.438l-65.25-45.681
c-4.374-3.063-9.589-4.703-14.935-4.703h-52.536l0.868,148.48c0.321,15.473,10.431,29.028,25.166,33.757H507.661z"/>
<path style="fill:#FABD91;" d="M455.593,503.322h-60.746c-19.17,0-34.712-15.542-34.712-34.712v-34.712h60.746L455.593,503.322z"/>
<path style="fill:#88B337;" d="M229.966,60.746c-5.979,0.009-11.889,1.258-17.356,3.662V0H56.407
C27.648,0,4.339,23.309,4.339,52.068v156.203h64.408c-9.633-21.938,0.338-47.538,22.285-57.17
c21.938-9.633,47.538,0.338,57.17,22.285c4.886,11.116,4.886,23.778,0,34.894h64.408v-64.408
c21.938,9.633,47.538-0.338,57.17-22.285s-0.338-47.538-22.285-57.17C241.976,61.978,236.006,60.737,229.966,60.746z"/>
<path style="fill:#E8594A;" d="M420.881,52.068C420.881,23.309,397.572,0,368.814,0H212.61v64.408
c21.938-9.633,47.538,0.338,57.17,22.285c9.633,21.938-0.338,47.538-22.285,57.17c-11.116,4.886-23.778,4.886-34.894,0v64.408
h64.408c-9.633,21.938,0.338,47.538,22.285,57.17c21.938,9.633,47.538-0.338,57.17-22.285c4.886-11.116,4.886-23.778,0-34.894
h64.417V52.068z"/>
<path style="fill:#D65245;" d="M420.881,57.023C371.278,126.03,281.73,165.228,212.61,186.325v21.947h64.408
c-9.633,21.938,0.338,47.538,22.285,57.17c21.938,9.633,47.538-0.338,57.17-22.285c4.886-11.116,4.886-23.778,0-34.894h64.408
V57.023z"/>
<path style="fill:#FDB62F;" d="M195.254,277.695c5.979,0.009,11.889,1.258,17.356,3.662v-73.086h-64.408
c9.633-21.938-0.338-47.538-22.285-57.17c-21.947-9.633-47.538,0.338-57.17,22.285c-4.886,11.116-4.886,23.778,0,34.894H4.339
v156.203c0,28.759,23.309,52.068,52.068,52.068H212.61v-55.73c-21.938,9.633-47.538-0.338-57.17-22.285
c-9.633-21.938,0.338-47.538,22.285-57.17C183.244,278.927,189.214,277.686,195.254,277.695z"/>
<path style="fill:#FFA719;" d="M4.339,364.475c0,28.759,23.309,52.068,52.068,52.068H212.61v-55.73
c-21.834,9.615-47.33-0.286-56.945-22.12c-2.23-5.068-3.471-10.526-3.645-16.063c-46.523,20.749-96.751,31.918-147.682,32.846
V364.475z"/>
<path style="fill:#4398D1;" d="M443.574,389.641l-54.906-146.658l-60.303,22.71c16.809,17.122,16.549,44.631-0.573,61.431
c-17.122,16.801-44.631,16.549-61.431-0.573c-8.556-8.721-13.052-20.636-12.375-32.837l-60.295,22.71l25.687,68.634
c-5.962-0.338-11.932,0.573-17.529,2.673c-22.407,8.695-33.514,33.905-24.819,56.311c8.548,22.016,33.098,33.202,55.322,25.183
c5.597-2.109,10.7-5.372,14.969-9.563L266.9,512l146.241-55.079C440.094,446.716,453.71,416.62,443.574,389.641z"/>
<path style="fill:#3E8FC9;" d="M415.258,314.012c-59.878,89.557-172.127,120.832-237.872,131.601
c9.225,21.947,34.495,32.256,56.441,23.031c5.025-2.109,9.607-5.163,13.494-8.982L266.9,512l146.241-55.079
c26.945-10.205,40.552-40.283,30.434-67.254L415.258,314.012z"/>
<path style="fill:#80A834;" d="M229.966,60.746c-5.979,0.009-11.889,1.258-17.356,3.662V51.816
C147.63,111.633,59.592,144.67,4.339,160.768v47.503h64.408c-9.633-21.938,0.338-47.538,22.285-57.17
c21.938-9.633,47.538,0.338,57.17,22.285c4.886,11.116,4.886,23.778,0,34.894h64.408v-64.408
c21.938,9.633,47.538-0.338,57.17-22.285s-0.338-47.538-22.285-57.17C241.976,61.978,236.006,60.737,229.966,60.746z"/>
<path style="fill:#FEC9A3;" d="M403.682,390.665c-8.305-8.47-21.903-8.609-30.373-0.304c-8.47,8.305-8.609,21.903-0.304,30.373
c0.104,0.104,0.2,0.208,0.304,0.304l30.217,30.217c0,28.759,23.309,52.068,52.068,52.068l0,0h52.068v-8.678L403.682,390.665z"/>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>
</symbol>
</svg>
<div class="side-bar">
<div class="site-header">
<a href="{{ '/' | absolute_url }}" class="site-title lh-tight">{% include title.html %}</a>
<a href="#" id="menu-button" class="site-button">
<svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-menu"></use></svg>
</a>
</div>
<nav role="navigation" aria-label="Main" id="site-nav" class="site-nav">
{% if site.just_the_docs.collections %}
{% assign collections_size = site.just_the_docs.collections | size %}
{% for collection_entry in site.just_the_docs.collections %}
{% assign collection_key = collection_entry[0] %}
{% assign collection_value = collection_entry[1] %}
{% assign collection = site[collection_key] %}
{% if collection_value.nav_exclude != true %}
{% if collections_size > 1 %}
<div class="nav-category">{{ collection_value.name }}</div>
{% endif %}
{% include nav.html pages=collection %}
{% endif %}
{% endfor %}
{% else %}
{% include nav.html pages=site.html_pages %}
{% endif %}
</nav>
<footer class="site-footer">
This site uses <a href="https://github.com/pmarsceill/just-the-docs">Just the Docs</a>, a documentation theme for Jekyll.
</footer>
</div>
<div class="main" id="top">
<div id="main-header" class="main-header">
{% if site.search_enabled != false %}
<div class="search">
<div class="search-input-wrap">
<input type="text" id="search-input" class="search-input" tabindex="0" placeholder="Search {{ site.title }}" aria-label="Search {{ site.title }}" autocomplete="off">
<label for="search-input" class="search-label"><svg viewBox="0 0 24 24" class="search-icon"><use xlink:href="#svg-search"></use></svg></label>
</div>
<div id="search-results" class="search-results"></div>
</div>
{% endif %}
{% if site.aux_links %}
<nav aria-label="Auxiliary" class="aux-nav">
<ul class="aux-nav-list">
{% for link in site.aux_links %}
<li class="aux-nav-list-item">
<a href="{{ link.last }}" class="site-button"
{% if site.aux_links_new_tab %}
target="_blank" rel="noopener noreferrer"
{% endif %}
>
{{ link.first }}
</a>
</li>
{% endfor %}
</ul>
</nav>
{% endif %}
</div>
<div id="main-content-wrap" class="main-content-wrap">
{% unless page.url == "/" %}
{% if page.parent %}
<nav aria-label="Breadcrumb" class="breadcrumb-nav">
<ol class="breadcrumb-nav-list">
{% if page.grand_parent %}
<li class="breadcrumb-nav-list-item"><a href="{{ first_level_url }}">{{ page.grand_parent }}</a></li>
<li class="breadcrumb-nav-list-item"><a href="{{ second_level_url }}">{{ page.parent }}</a></li>
{% else %}
<li class="breadcrumb-nav-list-item"><a href="{{ first_level_url }}">{{ page.parent }}</a></li>
{% endif %}
<li class="breadcrumb-nav-list-item"><span>{{ page.title }}</span></li>
</ol>
</nav>
{% endif %}
{% endunless %}
<div id="survey-wrapper" style="border: 1px solid #d6d6d6; border-radius: 5px; background-color: #f1f1f1; padding: 20px; display: flex; flex-direction: row; align-items: center;">
<svg viewBox="0 0 24 24" width="32px" height="32px" class="contrib-icon" style="display: inline-block"><use xlink:href="#svg-contrib"></use></svg>
<span style="margin-left: 10px">Help the team improve <b>Authelia</b> by taking this <a href="https://forms.gle/aVw6J9jcez97EAhD6" target="_blank">10-second survey</a>.</span>
</div>
<div id="main-content" class="main-content" role="main">
{% if site.heading_anchors != false %}
{% include vendor/anchor_headings.html html=content beforeHeading="true" anchorBody="<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><use xlink:href=\"#svg-link\"></use></svg>" anchorClass="anchor-heading" anchorAttrs="aria-labelledby=\"%html_id%\"" %}
{% else %}
{{ content }}
{% endif %}
{% if page.has_children == true and page.has_toc != false %}
<hr>
<h2 class="text-delta">Table of contents</h2>
<ul>
{%- assign children_list = pages_list | where: "parent", page.title | where: "grand_parent", page.parent -%}
{% for child in children_list %}
<li>
<a href="{{ child.url | absolute_url }}">{{ child.title }}</a>{% if child.summary %} - {{ child.summary }}{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
{% if site.footer_content != nil or site.last_edit_timestamp or site.gh_edit_link %}
<hr>
<footer>
{% if site.back_to_top %}
<p><a href="#top" id="back-to-top">{{ site.back_to_top_text }}</a></p>
{% endif %}
{% if site.footer_content != nil %}
<p class="text-small text-grey-dk-000 mb-0">{{ site.footer_content }}</p>
{% endif %}
{% if site.last_edit_timestamp or site.gh_edit_link %}
<div class="d-flex mt-2">
{% if site.last_edit_timestamp and site.last_edit_time_format and page.last_modified_date %}
<p class="text-small text-grey-dk-000 mb-0 mr-2">
Page last modified: <span class="d-inline-block">{{ page.last_modified_date | date: site.last_edit_time_format }}</span>.
</p>
{% endif %}
{% if
site.gh_edit_link and
site.gh_edit_link_text and
site.gh_edit_repository and
site.gh_edit_branch and
site.gh_edit_view_mode
%}
<p class="text-small text-grey-dk-000 mb-0">
<a href="{{ site.gh_edit_repository }}/{{ site.gh_edit_view_mode }}/{{ site.gh_edit_branch }}{% if site.gh_edit_source %}/{{ site.gh_edit_source }}{% endif %}/{{ page.path }}" id="edit-this-page">{{ site.gh_edit_link_text }}</a>
</p>
{% endif %}
</div>
{% endif %}
</footer>
{% endif %}
</div>
</div>
{% if site.search_enabled != false %}
{% if site.search.button %}
<a href="#" id="search-button" class="search-button">
<svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-search"></use></svg>
</a>
{% endif %}
<div class="search-overlay"></div>
{% endif %}
</div>
</body>
</html>

View File

@ -1,19 +0,0 @@
.label.label-config {
text-transform: none;
}
.tbl-header {
font-weight: bold;
text-align: center;
}
.tbl-beta-stage {
border-bottom-width: 3px !important;
}
.material-icons.green {
color: #56D364;
}
.material-icons.red {
color: #F85149;
}
.material-icons.orange {
color: #E3B341;
}

View File

@ -1,10 +0,0 @@
img {
border: 1px solid #e6e6e6;
border-radius: 5px;
padding: 10px;
}
.no-border {
border: 0px;
}

View File

@ -1,69 +0,0 @@
---
layout: default
title: About Us
nav_order: 10
---
## Core Team
<table>
<td align="center">
<a href="https://github.com/clems4ever">
<img src="https://avatars.githubusercontent.com/u/3193257?v=4?s=100" width="100px;" alt=""/>
<br />
<sub>
<b>Clément Michaud</b>
</sub>
</a>
</td>
<td align="center">
<a href="https://github.com/nightah">
<img src="https://avatars.githubusercontent.com/u/3339418?v=4?s=100" width="100px;" alt=""/>
<br />
<sub>
<b>Amir Zarrinkafsh</b>
</sub>
</a>
</td>
<td align="center">
<a href="https://github.com/james-d-elliott">
<img src="https://avatars.githubusercontent.com/u/3903683?v=4?s=100" width="100px;" alt=""/>
<br />
<sub>
<b>James Elliott</b>
</sub>
</a>
</td>
</table>
## Contact Options
Several contact options exist for our community, the primary one being [Matrix](#matrix). These are in addition to
[GitHub issues](https://github.com/authelia/authelia/issues) for creating a [new issue](https://github.com/authelia/authelia/issues/new/choose).
### Matrix
Community members are invited to join the [Matrix Space](https://matrix.to/#/#community:authelia.com) which includes both
the [Support Room](https://matrix.to/#/#support:authelia.com) and the [Contributing Room](https://matrix.to/#/#contributing:authelia.com).
- The core team members are identified as administrators in the Space and individual Rooms.
- All channels are linked to [Discord](#discord).
### Discord
Community members are invited to join the [Discord Server](https://discord.authelia.com).
- The core team members are identified by the <span style="color:#BA55D3;">**CORE TEAM**</span> role in Discord.
- The [#support] and [#contributing] channels are linked to [Matrix](#matrix).
### Email
You can contact the core team by email via [team@authelia.com](mailto:team@authelia.com). Please note the
[security@authelia.com](mailto:security@authelia.com) is also available but is strictly reserved for [security] related
matters.
[security]: https://github.com/authelia/authelia/security/policy
[#support]: https://discord.com/channels/707844280412012608/707844280412012612
[#contributing]: https://discord.com/channels/707844280412012608/804943261265297408

11
docs/archetypes/blog.md Normal file
View File

@ -0,0 +1,11 @@
---
title: "{{ replace .Name "-" " " | title }}"
description: ""
lead: ""
date: {{ .Date }}
lastmod: {{ .Date }}
draft: true
weight: 50
images: ["{{ .Name | urlize }}.jpg"]
contributors: []
---

View File

@ -0,0 +1,14 @@
---
title: "{{ replace .Name "-" " " | title }}"
description: ""
lead: ""
date: {{ .Date }}
lastmod: {{ .Date }}
draft: true
images: []
menu:
configuration:
parent: ""
weight: 999
toc: true
---

View File

@ -0,0 +1,8 @@
---
title: "{{ replace .Name "-" " " | title }}"
description: ""
date: {{ .Date }}
lastmod: {{ .Date }}
draft: true
images: []
---

14
docs/archetypes/docs.md Normal file
View File

@ -0,0 +1,14 @@
---
title: "{{ replace .Name "-" " " | title }}"
description: ""
lead: ""
date: {{ .Date }}
lastmod: {{ .Date }}
draft: true
images: []
menu:
docs:
parent: ""
weight: 999
toc: true
---

View File

View File

View File

@ -0,0 +1,5 @@
Object.keys(localStorage).forEach(function(key) {
if (/^global-alert-/.test(key)) {
document.documentElement.setAttribute('data-global-alert', 'closed');
}
});

20
docs/assets/js/alert.js Normal file
View File

@ -0,0 +1,20 @@
var announcement = document.getElementById('announcement');
if (announcement !== null) {
var id = announcement.dataset.id;
Object.keys(localStorage).forEach(function(key) {
if (/^global-alert-/.test(key)) {
if (key !== id ) {
localStorage.removeItem(key);
document.documentElement.removeAttribute('data-global-alert');
}
}
});
announcement.addEventListener('closed.bs.alert', () => {
localStorage.setItem(id, 'closed');
});
}

0
docs/assets/js/app.js Normal file
View File

1
docs/assets/js/bootstrap.js vendored Normal file
View File

@ -0,0 +1 @@
import 'bootstrap/dist/js/bootstrap.bundle.min.js'

View File

@ -0,0 +1,37 @@
import Clipboard from 'clipboard';
var pre = document.getElementsByTagName('pre');
for (var i = 0; i < pre.length; ++ i)
{
var element = pre[i];
var mermaid = element.getElementsByClassName('language-mermaid')[0];
if (mermaid == null) {
element.insertAdjacentHTML('afterbegin', '<button class="btn btn-copy"></button>');
}
}
var clipboard = new Clipboard('.btn-copy', {
target: function(trigger) {
return trigger.nextElementSibling;
},
});
clipboard.on('success', function(e) {
/*
console.info('Action:', e.action);
console.info('Text:', e.text);
console.info('Trigger:', e.trigger);
*/
e.clearSelection();
});
clipboard.on('error', function(e) {
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
});

View File

@ -0,0 +1,21 @@
const globalDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
const localMode = localStorage.getItem('theme');
if (globalDark && (localMode === null)) {
localStorage.setItem('theme', 'dark');
document.documentElement.setAttribute('data-dark-mode', '');
}
if (globalDark && (localMode === 'dark')) {
document.documentElement.setAttribute('data-dark-mode', '');
}
if (localMode === 'dark') {
document.documentElement.setAttribute('data-dark-mode', '');
}

View File

@ -0,0 +1,38 @@
const mode = document.getElementById('mode');
if (mode !== null) {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
if (event.matches) {
localStorage.setItem('theme', 'dark');
document.documentElement.setAttribute('data-dark-mode', '');
} else {
localStorage.setItem('theme', 'light');
document.documentElement.removeAttribute('data-dark-mode');
}
})
mode.addEventListener('click', () => {
document.documentElement.toggleAttribute('data-dark-mode');
localStorage.setItem('theme', document.documentElement.hasAttribute('data-dark-mode') ? 'dark' : 'light');
});
if (localStorage.getItem('theme') === 'dark') {
document.documentElement.setAttribute('data-dark-mode', '');
} else {
document.documentElement.removeAttribute('data-dark-mode');
}
}

View File

@ -0,0 +1,44 @@
import hljs from 'highlight.js/lib/core';
import go from 'highlight.js/lib/languages/go';
import json from 'highlight.js/lib/languages/json';
import bash from 'highlight.js/lib/languages/bash';
import xml from 'highlight.js/lib/languages/xml';
import yaml from 'highlight.js/lib/languages/yaml';
import dockerfile from 'highlight.js/lib/languages/dockerfile';
import nginx from 'highlight.js/lib/languages/nginx';
import ruby from 'highlight.js/lib/languages/ruby';
import plaintext from 'highlight.js/lib/languages/plaintext';
import php from 'highlight.js/lib/languages/php';
import python from 'highlight.js/lib/languages/python';
import ldif from 'highlight.js/lib/languages/ldif';
import ini from 'highlight.js/lib/languages/ini';
hljs.registerLanguage('go', go);
hljs.registerLanguage('json', json);
hljs.registerLanguage('bash', bash);
hljs.registerLanguage('console', bash);
hljs.registerLanguage('sh', bash);
hljs.registerLanguage('shell', bash);
hljs.registerLanguage('html', xml);
hljs.registerLanguage('yaml', yaml);
hljs.registerLanguage('yml', yaml);
hljs.registerLanguage('dockerfile', dockerfile);
hljs.registerLanguage('nginx', nginx);
hljs.registerLanguage('ruby', ruby);
hljs.registerLanguage('rb', ruby);
hljs.registerLanguage('plaintext', plaintext);
hljs.registerLanguage('php', php);
hljs.registerLanguage('text', plaintext);
hljs.registerLanguage('txt', plaintext);
hljs.registerLanguage('python', python);
hljs.registerLanguage('py', python);
hljs.registerLanguage('ldif', ldif);
hljs.registerLanguage('ini', ini);
hljs.registerLanguage('cnf', ini);
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('pre code:not(.language-mermaid)').forEach((block) => {
hljs.highlightElement(block);
});
});

169
docs/assets/js/index.js Normal file
View File

@ -0,0 +1,169 @@
var suggestions = document.getElementById('suggestions');
var search = document.getElementById('search');
if (search !== null) {
document.addEventListener('keydown', inputFocus);
}
function inputFocus(e) {
if (e.ctrlKey && e.key === '/' ) {
e.preventDefault();
search.focus();
}
if (e.key === 'Escape' ) {
search.blur();
suggestions.classList.add('d-none');
}
}
document.addEventListener('click', function(event) {
var isClickInsideElement = suggestions.contains(event.target);
if (!isClickInsideElement) {
suggestions.classList.add('d-none');
}
});
/*
Source:
- https://dev.to/shubhamprakash/trap-focus-using-javascript-6a3
*/
document.addEventListener('keydown',suggestionFocus);
function suggestionFocus(e) {
const suggestionsHidden = suggestions.classList.contains('d-none');
if (suggestionsHidden) return;
const focusableSuggestions= [...suggestions.querySelectorAll('a')];
if (focusableSuggestions.length === 0) return;
const index = focusableSuggestions.indexOf(document.activeElement);
if (e.key === "ArrowUp") {
e.preventDefault();
const nextIndex = index > 0 ? index - 1 : 0;
focusableSuggestions[nextIndex].focus();
}
else if (e.key === "ArrowDown") {
e.preventDefault();
const nextIndex= index + 1 < focusableSuggestions.length ? index + 1 : index;
focusableSuggestions[nextIndex].focus();
}
}
/*
Source:
- https://github.com/nextapps-de/flexsearch#index-documents-field-search
- https://raw.githack.com/nextapps-de/flexsearch/master/demo/autocomplete.html
*/
(function(){
var index = new FlexSearch.Document({
tokenize: "forward",
cache: 100,
document: {
id: 'id',
store: [
"href", "title", "description"
],
index: ["title", "description", "content"]
}
});
// Not yet supported: https://github.com/nextapps-de/flexsearch#complex-documents
/*
var docs = [
{{ range $index, $page := (where .Site.Pages "Section" "docs") -}}
{
id: {{ $index }},
href: "{{ .Permalink }}",
title: {{ .Title | jsonify }},
description: {{ .Params.description | jsonify }},
content: {{ .Content | jsonify }}
},
{{ end -}}
];
*/
// https://discourse.gohugo.io/t/range-length-or-last-element/3803/2
{{ $list := (where .Site.RegularPages "Type" "in" (union .Site.Params.Sections.Search .Site.Params.Sections.Searchable)) -}}
{{ $len := (len $list) -}}
index.add(
{{ range $index, $element := $list -}}
{
id: {{ $index }},
href: "{{ .RelPermalink }}",
title: {{ .Title | jsonify }},
{{ with .Description -}}
description: {{ . | jsonify }},
{{ else -}}
description: {{ .Summary | plainify | jsonify }},
{{ end -}}
content: {{ .Plain | jsonify }}
})
{{ if ne (add $index 1) $len -}}
.add(
{{ end -}}
{{ end -}}
;
search.addEventListener('input', show_results, true);
function show_results(){
const maxResult = 5;
var searchQuery = this.value;
var results = index.search(searchQuery, {limit: maxResult, enrich: true});
// flatten results since index.search() returns results for each indexed field
const flatResults = new Map(); // keyed by href to dedupe results
for (const result of results.flatMap(r => r.result)) {
if (flatResults.has(result.doc.href)) continue;
flatResults.set(result.doc.href, result.doc);
}
suggestions.innerHTML = "";
suggestions.classList.remove('d-none');
// inform user that no results were found
if (flatResults.size === 0 && searchQuery) {
const noResultsMessage = document.createElement('div')
noResultsMessage.innerHTML = `No results for "<strong>${searchQuery}</strong>"`
noResultsMessage.classList.add("suggestion__no-results");
suggestions.appendChild(noResultsMessage);
return;
}
// construct a list of suggestions
for(const [href, doc] of flatResults) {
const entry = document.createElement('div');
suggestions.appendChild(entry);
const a = document.createElement('a');
a.href = href;
entry.appendChild(a);
const title = document.createElement('span');
title.textContent = doc.title;
title.classList.add("suggestion__title");
a.appendChild(title);
const description = document.createElement('span');
description.textContent = doc.description;
description.classList.add("suggestion__description");
a.appendChild(description);
suggestions.appendChild(entry);
if(suggestions.childElementCount == maxResult) break;
}
}
}());

View File

@ -0,0 +1 @@
import 'instant.page';

10
docs/assets/js/katex.js Normal file
View File

@ -0,0 +1,10 @@
document.addEventListener('DOMContentLoaded', function() {
renderMathInElement(document.body, {
delimiters: [
{left: '$$', right: '$$', display: true},
{left: '$', right: '$', display: false},
{left: '\\(', right: '\\)', display: false},
{left: '\\[', right: '\\]', display: true},
],
});
});

View File

@ -0,0 +1 @@
import 'lazysizes';

11
docs/assets/js/mermaid.js Normal file
View File

@ -0,0 +1,11 @@
import mermaid from 'mermaid';
var config = {
theme: 'default',
fontFamily: '"Jost", -apple-system, blinkmacsystemfont, "Segoe UI", roboto, "Helvetica Neue", arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";',
};
document.addEventListener('DOMContentLoaded', () => {
mermaid.initialize(config);
mermaid.init(undefined, '.language-mermaid');
});

View File

@ -0,0 +1,14 @@
// Adds scroll position lock for default docs sidebar
if (document.querySelector('#sidebar-default') !== null) {
let sidebar = document.getElementById('sidebar-default');
let pos = sessionStorage.getItem('sidebar-scroll');
if (pos !== null) {
sidebar.scrollTop = parseInt(pos, 10);
}
window.addEventListener('beforeunload', () => {
sessionStorage.setItem('sidebar-scroll', sidebar.scrollTop);
});
}

0
docs/assets/js/vendor/.gitkeep vendored Normal file
View File

37
docs/assets/scss/app.scss Normal file
View File

@ -0,0 +1,37 @@
/** Import Bootstrap functions */
@import "bootstrap/scss/functions";
/** Import theme variables */
@import "common/variables";
/** Import Bootstrap */
@import "bootstrap/scss/bootstrap";
@import "bootstrap-icons/font/bootstrap-icons.scss";
/** Import highlight.js */
@import "highlight.js/scss/github-dark-dimmed";
/** Import KaTeX */
@import "katex/dist/katex";
/** Import theme styles */
@import "common/fonts";
@import "common/global";
@import "common/dark";
@import "components/alerts";
@import "components/buttons";
@import "components/code";
@import "components/details";
@import "components/syntax";
@import "components/comments";
@import "components/forms";
@import "components/images";
@import "components/mermaid";
@import "components/search";
@import "components/tables";
@import "layouts/footer";
@import "layouts/header";
@import "layouts/pages";
@import "layouts/posts";
@import "layouts/sidebar";
@import "custom";

View File

@ -0,0 +1,572 @@
/** Theme variables */
// Source: https://material.io/design/color/dark-theme.html
$body-bg-dark: $gray-900;
$body-overlay-dark: darken($body-bg-dark, 2.5%);
/*
$border-dark: darken($body-bg-dark, 2.5%);
*/
$border-dark: $gray-800;
$body-color-dark: $gray-300;
$dots-dark: darken($body-color-dark, 50%);
$link-color-dark: $blue-300;
$button-color-dark: $link-color-dark;
$focus-color-dark: lighten($link-color-dark, 2.5%);
$navbar-dark-color: $body-color-dark;
$navbar-dark-hover-color: $link-color-dark;
$navbar-dark-active-color: $link-color-dark;
/** Theme styles */
[data-dark-mode] body {
background: $body-bg-dark;
color: $body-color-dark;
}
[data-dark-mode] body a {
color: $link-color-dark;
}
[data-dark-mode] body a.text-body {
color: $body-color-dark !important;
}
[data-dark-mode] body .btn-primary {
@include button-variant($button-color-dark, $button-color-dark);
color: $body-bg-dark !important;
}
[data-dark-mode] body .btn-outline-primary {
@include button-outline-variant($button-color-dark, $button-color-dark);
color: $link-color-dark;
}
[data-dark-mode] body .btn-outline-primary:hover {
color: $body-bg-dark;
}
[data-dark-mode] body .btn-doks-light {
color: $navbar-dark-color;
}
[data-dark-mode] body .show > .btn-doks-light,
[data-dark-mode] body .btn-doks-light:hover,
[data-dark-mode] body .btn-doks-light:active {
color: $link-color-dark;
}
[data-dark-mode] body .btn-menu svg {
color: $body-color-dark;
}
[data-dark-mode] body .doks-sidebar-toggle {
color: $navbar-dark-color;
}
[data-dark-mode] body .btn-menu:hover,
[data-dark-mode] body .btn-doks-light:hover,
[data-dark-mode] body .doks-sidebar-toggle:hover {
background: $body-overlay-dark;
}
/*
[data-dark-mode] body .dropdown-menu {
@extend .dropdown-menu-dark;
}
*/
[data-dark-mode] body .navbar,
[data-dark-mode] body .doks-subnavbar {
background-color: rgba(33, 37, 41, 0.95);
border-bottom: 1px solid $border-dark;
}
[data-dark-mode] body.home .navbar {
border-bottom: 0;
}
[data-dark-mode] body .offcanvas-header {
border-bottom: 1px solid $gray-800;
}
[data-dark-mode] body .offcanvas .nav-link {
color: $body-color-dark;
}
[data-dark-mode] body .offcanvas .nav-link:hover,
[data-dark-mode] body .offcanvas .nav-link:focus {
color: $link-color-dark;
}
[data-dark-mode] body .offcanvas .nav-link.active {
color: $link-color-dark;
}
[data-dark-mode] body .navbar-light .navbar-brand {
color: $navbar-dark-color !important;
}
[data-dark-mode] body .navbar-light .navbar-nav .nav-link {
color: $navbar-dark-color;
}
[data-dark-mode] body .navbar-light .navbar-nav .nav-link:hover,
[data-dark-mode] body .navbar-light .navbar-nav .nav-link:focus {
color: $navbar-dark-hover-color;
}
[data-dark-mode] body .navbar-light .navbar-nav .nav-link.disabled {
color: $navbar-dark-disabled-color;
}
[data-dark-mode] body .navbar-light .navbar-nav .show > .nav-link,
[data-dark-mode] body .navbar-light .navbar-nav .active > .nav-link,
[data-dark-mode] body .navbar-light .navbar-nav .nav-link.show,
[data-dark-mode] body .navbar-light .navbar-nav .nav-link.active {
color: $navbar-dark-active-color;
}
[data-dark-mode] body .navbar-light .navbar-text {
color: $navbar-dark-color;
}
[data-dark-mode] body .alert-primary a {
color: $body-bg-dark;
}
[data-dark-mode] body .alert-doks {
background: $body-overlay-dark;
color: $body-color-dark;
}
[data-dark-mode] body .alert-doks a {
color: $link-color-dark;
}
[data-dark-mode] body .page-links a {
color: $body-color-dark;
}
[data-dark-mode] body .btn-toggle-nav a {
color: $body-color-dark;
}
[data-dark-mode] body .showcase-meta a {
color: $body-color-dark;
}
[data-dark-mode] body .showcase-meta a:hover,
[data-dark-mode] body .showcase-meta a:focus {
color: $link-color-dark;
}
[data-dark-mode] body .docs-link:hover,
[data-dark-mode] body .docs-link.active,
[data-dark-mode] body .page-links a:hover {
text-decoration: none;
color: $link-color-dark;
}
[data-dark-mode] body .btn-toggle {
color: $body-color-dark;
background-color: transparent;
border: 0;
}
[data-dark-mode] body .btn-toggle:hover,
[data-dark-mode] body .btn-toggle:focus {
color: $body-color-dark;
}
[data-dark-mode] body .btn-toggle::before {
width: 1.25em;
line-height: 0;
content: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%28222, 226, 230, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e");
transition: transform 0.35s ease;
transform-origin: 0.5em 50%;
margin-bottom: 0.125rem;
}
[data-dark-mode] body .btn-toggle[aria-expanded="true"] {
color: $body-color-dark;
}
[data-dark-mode] body .btn-toggle[aria-expanded="true"]::before {
transform: rotate(90deg);
}
[data-dark-mode] body .btn-toggle-nav a:hover,
[data-dark-mode] body .btn-toggle-nav a:focus {
color: $link-color-dark;
}
[data-dark-mode] body .btn-toggle-nav a.active {
color: $link-color-dark;
}
[data-dark-mode] body .navbar-light .navbar-text a {
color: $navbar-dark-active-color;
}
[data-dark-mode] body .docs-links h3.sidebar-link a,
[data-dark-mode] body .page-links h3.sidebar-link a {
color: $body-color-dark;
}
[data-dark-mode] body .navbar-light .navbar-text a:hover,
[data-dark-mode] body .navbar-light .navbar-text a:focus {
color: $navbar-dark-active-color;
}
[data-dark-mode] body .navbar .btn-link {
color: $navbar-dark-color;
}
[data-dark-mode] body .content .btn-link {
color: $link-color-dark;
}
[data-dark-mode] body .content .btn-link:hover {
color: $link-color-dark;
}
[data-dark-mode] body .content img[src^="https://latex.codecogs.com/svg.latex"] {
filter: invert(1);
}
[data-dark-mode] body .navbar .btn-link:hover {
color: $navbar-dark-hover-color;
}
[data-dark-mode] body .navbar .btn-link:active {
color: $navbar-dark-active-color;
}
[data-dark-mode] body .form-control.is-search {
background: $body-overlay-dark;
border: 1px solid transparent;
color: $gray-300;
/*
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%236c757d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-search'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right calc(0.375em + 0.1875rem) center;
background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
*/
}
[data-dark-mode] body .form-control.is-search:focus {
border: 1px solid $link-color-dark;
}
[data-dark-mode] body .doks-search::after {
color: $gray-300;
border: 1px solid $gray-700;
}
[data-dark-mode] body .text-dark {
color: $body-color-dark !important;
}
/*
[data-dark-mode] body .navbar-form::after {
color: $gray-600;
border: 1px solid $gray-800;
}
*/
[data-dark-mode] body .form-control {
color: $gray-300;
}
[data-dark-mode] body .form-control::placeholder {
color: $gray-400;
opacity: 1;
}
[data-dark-mode] body .border-top {
border-top: 1px solid $border-dark !important;
}
@include media-breakpoint-up(lg) {
[data-dark-mode] body .docs-sidebar {
order: 0;
border-right: 1px solid $border-dark;
}
}
[data-dark-mode] body .docs-navigation {
border-top: 1px solid $border-dark;
}
[data-dark-mode] body pre code::-webkit-scrollbar-thumb {
background: $gray-400;
}
[data-dark-mode] body code:not(.hljs) {
background: $body-overlay-dark;
color: $body-color-dark;
}
[data-dark-mode] body pre code:hover {
scrollbar-width: thin;
scrollbar-color: $border-dark transparent;
}
[data-dark-mode] body pre code::-webkit-scrollbar-thumb:hover {
background: $gray-500;
}
[data-dark-mode] body blockquote {
border-left: 3px solid $border-dark;
}
[data-dark-mode] body .footer {
border-top: 1px solid $border-dark;
}
[data-dark-mode] body .docs-links,
[data-dark-mode] body .docs-toc {
scrollbar-width: thin;
scrollbar-color: $body-bg-dark $body-bg-dark;
}
[data-dark-mode] body .docs-links::-webkit-scrollbar,
[data-dark-mode] body .docs-toc::-webkit-scrollbar {
width: 5px;
}
[data-dark-mode] body .docs-links::-webkit-scrollbar-track,
[data-dark-mode] body .docs-toc::-webkit-scrollbar-track {
background: $body-bg-dark;
}
[data-dark-mode] body .docs-links::-webkit-scrollbar-thumb,
[data-dark-mode] body .docs-toc::-webkit-scrollbar-thumb {
background: $body-bg-dark;
}
[data-dark-mode] body .docs-links:hover,
[data-dark-mode] body .docs-toc:hover {
scrollbar-width: thin;
scrollbar-color: $border-dark $body-bg-dark;
}
[data-dark-mode] body .docs-links:hover::-webkit-scrollbar-thumb,
[data-dark-mode] body .docs-toc:hover::-webkit-scrollbar-thumb {
background: $border-dark;
}
[data-dark-mode] body .docs-links::-webkit-scrollbar-thumb:hover,
[data-dark-mode] body .docs-toc::-webkit-scrollbar-thumb:hover {
background: $border-dark;
}
[data-dark-mode] body .docs-links h3:not(:first-child) {
border-top: 1px solid $border-dark;
}
[data-dark-mode] body a.docs-link {
color: $body-color-dark;
}
[data-dark-mode] body .page-links li:not(:first-child) {
border-top: 1px dashed $border-dark;
}
[data-dark-mode] body .card {
background: $body-bg-dark;
border: 1px solid $border-dark;
}
[data-dark-mode] body .card.bg-light {
background: $body-overlay-dark !important;
}
[data-dark-mode] body .navbar .menu-icon .navicon {
background: $navbar-dark-color;
}
[data-dark-mode] body .navbar .menu-icon .navicon::before,
[data-dark-mode] body .navbar .menu-icon .navicon::after {
background: $navbar-dark-color;
}
[data-dark-mode] body .logo-light {
display: none !important;
}
[data-dark-mode] body .logo-dark {
display: inline-block !important;
}
[data-dark-mode] body .bg-light {
background: darken($body-bg-dark, 1.5%) !important;
}
[data-dark-mode] body .bg-dots {
background-image: radial-gradient($dots-dark 15%, transparent 15%);
}
[data-dark-mode] body .text-muted {
color: darken($body-color-dark, 7.5%) !important;
}
[data-dark-mode] body .alert-primary {
background: $link-color-dark;
color: $body-bg-dark;
}
[data-dark-mode] body .figure-caption {
color: $body-color-dark;
}
[data-dark-mode] body table {
@extend .table-dark;
}
[data-dark-mode] body .copy-status::after {
content: "Copy";
display: block;
color: $body-color-dark;
}
[data-dark-mode] body .copy-status:hover::after {
content: "Copy";
display: block;
color: $link-color-dark;
}
[data-dark-mode] body .copy-status:focus::after,
[data-dark-mode] body .copy-status:active::after {
content: "Copied";
display: block;
color: $link-color-dark;
}
/*
[data-dark-mode] body .dropdown-toggle:focus,
[data-dark-mode] body .doks-sidebar-toggle:focus {
box-shadow: 0 0 0 0.2rem $focus-color-dark;
}
*/
[data-dark-mode] body .offcanvas {
background-color: $body-bg-dark;
}
[data-dark-mode] body .btn-close {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiNkZWUyZTYiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0iZmVhdGhlciBmZWF0aGVyLXgiPjxsaW5lIHgxPSIxOCIgeTE9IjYiIHgyPSI2IiB5Mj0iMTgiPjwvbGluZT48bGluZSB4MT0iNiIgeTE9IjYiIHgyPSIxOCIgeTI9IjE4Ij48L2xpbmU+PC9zdmc+");
background-size: 1.5rem;
}
@include media-breakpoint-up(md) {
[data-dark-mode] body .alert-dismissible .btn-close {
background-size: 1.25rem;
}
}
/*
[data-dark-mode] body .btn-close:focus {
box-shadow: 0 0 0 0.2rem $focus-color-dark;
}
*/
[data-dark-mode] .dropdown-item {
color: $body-bg-dark;
}
[data-dark-mode] body hr.text-black-50 {
color: $gray-600 !important;
}
[data-dark-mode] body .email-form .form-control {
background: $body-overlay-dark;
border: 1px solid transparent;
}
[data-dark-mode] body .email-form .form-control:focus {
border: 1px solid $link-color-dark;
}
[data-dark-mode] .page-link {
color: $link-color-dark;
background-color: transparent;
border: $pagination-border-width solid $border-dark;
&:hover {
color: $body-bg-dark;
background-color: $body-color-dark;
border-color: $body-color-dark;
}
&:focus {
color: $body-bg-dark;
background-color: $body-color-dark;
}
}
[data-dark-mode] .page-item {
&.active .page-link {
color: $body-bg-dark;
@include gradient-bg($link-color-dark);
border-color: $link-color-dark;
}
&.disabled .page-link {
color: $pagination-disabled-color;
background-color: $body-overlay-dark;
border-color: $border-dark;
}
}
[data-dark-mode] .dropdown-menu {
background: $body-overlay-dark;
}
[data-dark-mode] .dropdown-menu .dropdown-item {
color: $body-color-dark;
}
[data-dark-mode] .dropdown-menu .dropdown-item:hover {
color: $link-color-dark;
background: $body-bg-dark;
}
[data-dark-mode] .dropdown-menu .dropdown-item.active,
[data-dark-mode] .dropdown-menu .dropdown-item:focus {
color: $link-color-dark;
background: $body-bg-dark;
}
[data-dark-mode] .doks-navbar .dropdown-item.current,
[data-dark-mode] .doks-subnavbar .dropdown-item.current {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23dee2e6' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 1rem top 0.6rem;
background-size: 0.75rem 0.75rem;
}
[data-dark-mode] details {
border: 1px solid $border-dark;
}
[data-dark-mode] summary:hover {
background: $body-overlay-dark;
}
[data-dark-mode] details[open] > summary {
border-bottom: 1px solid $border-dark;
}
[data-dark-mode] details summary::before {
content: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%28222, 226, 230, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e");
}

View File

@ -0,0 +1,101 @@
/* jost-regular - latin */
@font-face {
font-family: Jost;
font-style: normal;
font-weight: 400;
font-display: swap;
src:
// Google Fonts Jost
local("Jost Regular Regular"), // Full Name
local("Jost-Regular"), // PostScript name
// indestructible Jost*
local("Jost* Book"),
local("Jost-Book"),
url("fonts/vendor/jost/jost-v4-latin-regular.woff2") format("woff2"),
url("fonts/vendor/jost/jost-v4-latin-regular.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* jost-500 - latin */
@font-face {
font-family: Jost;
font-style: normal;
font-weight: 500;
font-display: swap;
src:
// Google Fonts Jost
local("Jost Regular Medium"),
local("JostRoman-Medium"),
// indestructible Jost*
local("Jost* Medium"),
local("Jost-Medium"),
url("fonts/vendor/jost/jost-v4-latin-500.woff2") format("woff2"),
url("fonts/vendor/jost/jost-v4-latin-500.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* jost-700 - latin */
@font-face {
font-family: Jost;
font-style: normal;
font-weight: 700;
font-display: swap;
src:
// Google Fonts Jost
local("Jost Regular Bold"),
local("JostRoman-Bold"),
// indestructible Jost*
local("Jost* Bold"),
local("Jost-Bold"),
url("fonts/vendor/jost/jost-v4-latin-700.woff2") format("woff2"),
url("fonts/vendor/jost/jost-v4-latin-700.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* jost-italic - latin */
@font-face {
font-family: Jost;
font-style: italic;
font-weight: 400;
font-display: swap;
src:
// Google Fonts Jost
local("Jost Italic Italic"),
local("Jost-Italic"),
// indestructible Jost*
local("Jost* BookItalic"),
local("Jost-BookItalic"),
url("fonts/vendor/jost/jost-v4-latin-italic.woff2") format("woff2"),
url("fonts/vendor/jost/jost-v4-latin-italic.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* jost-500italic - latin */
@font-face {
font-family: Jost;
font-style: italic;
font-weight: 500;
font-display: swap;
src:
// Google Fonts Jost
local("Jost Italic Medium Italic"),
local("JostItalic-Medium"),
// indestructible Jost*
local("Jost* Medium Italic"),
local("Jost-MediumItalic"),
url("fonts/vendor/jost/jost-v4-latin-500italic.woff2") format("woff2"),
url("fonts/vendor/jost/jost-v4-latin-500italic.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* jost-700italic - latin */
@font-face {
font-family: Jost;
font-style: italic;
font-weight: 700;
font-display: swap;
src:
// Google Fonts Jost
local("Jost Italic Bold Italic"),
local("JostItalic-Bold"),
// indestructible Jost*
local("Jost* Bold Italic"),
local("Jost-BoldItalic"),
url("fonts/vendor/jost/jost-v4-latin-700italic.woff2") format("woff2"),
url("fonts/vendor/jost/jost-v4-latin-700italic.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}

View File

@ -0,0 +1,312 @@
.contributors .content,
.blog .content,
.page .content,
.error404 .content,
.docs.list .content,
.tutorial.list .content,
.showcase.list .content {
padding-top: 1rem;
padding-bottom: 3rem;
}
.content img {
max-width: 100%;
}
h1,
h2,
h3,
h4,
h5,
h6,
.h1,
.h2,
.h3,
.h4,
.h5,
.h6 {
margin: 2rem 0 1rem;
}
.offcanvas-header {
border-bottom: 1px solid $gray-300;
padding-top: 1.0625rem;
padding-bottom: 0.8125rem;
}
h5.offcanvas-title {
margin: 0;
}
body.docs {
padding-top: 0 !important;
}
@include media-breakpoint-up(md) {
body {
font-size: $font-size-md;
/*
padding-top: 4rem !important;
*/
}
h1,
h2,
h3,
h4,
h5,
h6,
.h1,
.h2,
.h3,
.h4,
.h5,
.h6 {
margin-bottom: 1.125rem;
}
}
.home h1 {
/* font-size: calc(1.375rem + 1.5vw); */
font-size: calc(1.875rem + 1.5vw);
}
a:hover,
a:focus {
text-decoration: underline;
}
a.btn:hover,
a.btn:focus {
text-decoration: none;
}
.section {
padding-top: 5rem;
padding-bottom: 5rem;
}
.section-md {
padding-top: 3rem;
padding-bottom: 3rem;
}
.section-sm {
padding-top: 1rem;
padding-bottom: 1rem;
}
/*
.section svg {
display: inline-block;
width: 2rem;
height: 2rem;
vertical-align: text-top;
}
*/
/*
body {
padding-top: 3.5625rem;
}
*/
.docs-sidebar {
order: 2;
}
@include media-breakpoint-up(lg) {
.docs-sidebar {
order: 0;
border-right: 1px solid $gray-200;
}
@supports ((position:-webkit-sticky) or (position:sticky)) {
.docs-sidebar {
position: -webkit-sticky;
position: sticky;
top: 4rem;
z-index: 1000;
height: calc(100vh - 4rem);
}
}
}
@include media-breakpoint-up(xl) {
.docs-sidebar {
flex: 0 1 320px;
}
}
.docs-links {
padding-bottom: 5rem;
}
@include media-breakpoint-up(lg) {
@supports ((position: -webkit-sticky) or (position: sticky)) {
.docs-links {
max-height: calc(100vh - 4rem);
overflow-y: scroll;
}
}
}
@include media-breakpoint-up(lg) {
.docs-links {
display: block;
width: auto;
margin-right: -1.5rem;
padding-bottom: 4rem;
}
}
.docs-toc {
order: 2;
}
@supports ((position:-webkit-sticky) or (position:sticky)) {
.docs-toc {
position: -webkit-sticky;
position: sticky;
top: 4rem;
height: calc(100vh - 4rem);
overflow-y: auto;
}
}
.docs-content {
padding-bottom: 3rem;
order: 1;
}
.docs-navigation {
border-top: 1px solid $gray-200;
margin-top: 2rem;
margin-bottom: 0;
padding-top: 2rem;
}
.docs-navigation a {
font-size: $font-size-base * 0.9;
}
@include media-breakpoint-up(lg) {
.docs-navigation {
margin-bottom: -1rem;
}
.docs-navigation a {
font-size: $font-size-base;
}
}
.navbar a:hover,
.navbar a:focus {
text-decoration: none;
}
#TableOfContents ul {
padding-left: 0;
list-style: none;
}
::selection {
background: rgba(212, 53, 159, 0.2);
}
.bg-dots {
background-image: radial-gradient($gray-300 15%, transparent 15%);
background-position: 0 0;
background-size: 1rem 1rem;
-webkit-mask: linear-gradient(to top, #fff, transparent);
mask: linear-gradient(to top, #fff, transparent);
width: 100%;
height: 9rem;
margin-top: -10rem;
z-index: -1;
}
.bg-dots-md {
margin-top: -11rem;
}
.bg-dots-lg {
margin-top: -12rem;
}
.confkey-type {
background-color: $purple;
}
.confkey-default {
background-color: $blue;
}
.confkey-required {
background-color: $red;
}
.confkey-notrequired {
background-color: $green;
}
.confkey-situational {
background-color: $orange;
}
.rs-not-started {
background-color: $red;
}
.rs-complete {
background-color: $green;
}
.rs-started {
background-color: $blue;
}
.rs-waiting {
background-color: $yellow;
}
.rs-version {
background-color: $purple;
}
// https://fossheim.io/writing/posts/css-text-gradient/
.gradient-text {
background-color: $primary;
background-image: linear-gradient(90deg, $primary, $blue-300 50%, $pink-500);
background-size: 100%;
background-repeat: repeat;
-webkit-background-clip: text;
-moz-background-clip: text;
-webkit-text-fill-color: transparent;
-moz-text-fill-color: transparent;
}
.katex {
font-size: $font-size-md;
}
.card-bar {
border-top: 4px solid;
border-image-source: linear-gradient(90deg, $primary, #8ed6fb 50%, #d32e9d);
border-image-slice: 1;
}
.modal-backdrop {
background-color: #fff;
}
.modal-backdrop.show {
opacity: 0.7;
}
@include media-breakpoint-up(md) {
.modal-backdrop.show {
opacity: 0;
}
}

View File

@ -0,0 +1,200 @@
// Color system
$white: #fff;
$gray-100: #f8f9fa;
$gray-200: #e9ecef;
$gray-300: #dee2e6;
$gray-400: #ced4da;
$gray-500: #adb5bd;
$gray-600: #6c757d;
$gray-700: #495057;
$gray-800: #343a40;
$gray-900: #212529;
$black: #000;
$yellow: #ffe000;
$black: #1d2d35;
$beige: #fbf7f0;
// $red: #e55235;
$purple: #5d2f86;
$brown: #aa9c84;
$blue-300: #8ed6fb;
$pink-100: #fcfaff;
$pink-500: #d32e9d;
$primary: $purple;
$color-btn-bg: $pink-500;
$color-btn-border: darken($pink-500, 5%);
$color-btn-text: $white;
// Options
//
// Quickly modify global styling by enabling or disabling optional features.
$enable-caret: true;
$enable-rounded: true;
$enable-shadows: false;
$enable-gradients: false;
$enable-transitions: true;
$enable-reduced-motion: true;
$enable-smooth-scroll: true;
$enable-grid-classes: true;
$enable-button-pointers: true;
$enable-rfs: true;
$enable-validation-icons: true;
$enable-negative-margins: true;
$enable-deprecation-messages: true;
$enable-important-utilities: true;
/** Bootstrap navbar fix (https://git.io/fADqW) */
$navbar-dark-toggler-icon-bg: none;
$navbar-light-toggler-icon-bg: none;
// Options
//
// Quickly modify global styling by enabling or disabling optional features.
// $enable-responsive-font-sizes: true;
// Body
//
// Settings for the `<body>` element.
$body-bg: $white;
$body-color: $black;
// Links
//
// Style anchor elements.
$link-color: $primary;
$link-decoration: none;
// Grid containers
//
// Define the breakpoints for different screen sizes.
$grid-breakpoints: (
xs: 0,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px,
xxl: 2380px
);
// Define the maximum width of `.container` for different screen sizes.
$container-max-widths: (
sm: 540px,
md: 720px,
lg: 960px,
xl: 1240px,
xxl: 2240px
);
@include _assert-ascending($container-max-widths, "$container-max-widths");
// Grid columns
//
// Set the number of columns and specify the width of the gutters.
$grid-columns: 16;
$grid-gutter-width: 48px;
$grid-row-columns: 6;
// Components
//
// Define common padding and border radius sizes and more.
$border-color: $gray-200;
// Typography
//
// Font, line-height, and color for body text, headings, and more.
// stylelint-disable value-keyword-case
$font-family-sans-serif: "Jost", -apple-system, blinkmacsystemfont, "Segoe UI", roboto, "Helvetica Neue", arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
$font-family-monospace: sfmono-regular, menlo, monaco, consolas, "Liberation Mono", "Courier New", monospace;
$font-family-base: $font-family-sans-serif;
// stylelint-enable value-keyword-case
$font-size-base: 1rem; // Assumes the browser default, typically `16px`
$font-size-xl: $font-size-base * 1.375;
$font-size-lg: $font-size-base * 1.25;
$font-size-md: $font-size-base * 1.125;
$font-size-sm: $font-size-base * 0.875;
// $line-height-base: 1.5;
$headings-font-family: null;
$headings-font-weight: 700;
$lead-font-weight: 400;
// Spacing
//
// Control the default styling of most Bootstrap elements by modifying these
// variables. Mostly focused on spacing.
// You can add more entries to the $spacers map, should you need more variation.
$spacer: 1rem;
// Navbar
$navbar-padding-y: $spacer / 2;
$navbar-padding-x: null;
$navbar-nav-link-padding-x: 0.5rem;
$navbar-light-color: $black;
$navbar-light-hover-color: $primary;
$navbar-light-active-color: $primary;
// Cards
$card-border-color: $gray-200;
// Alerts
//
// Define alert colors, border radius, and padding.
$alert-padding-y: $spacer;
$alert-padding-x: $spacer * 1.5;
$alert-margin-bottom: 0;
$alert-border-radius: 0;
$alert-link-font-weight: $headings-font-weight;
$alert-border-width: 0;
$alert-bg-scale: 0;
$alert-border-scale: 0;
$alert-color-scale: 0;
// docsearch
$dropdown-config: (
main-color: $purple,
layout-type: normal,
layout-width: normal,
layout-alignment: align,
background-color: $white,
border-radius: 4,
border-width: 1,
border-color: $gray-200,
box-shadow: none,
branding-position: bottom,
spacing: normal,
include-desc: yes,
background-category-header: $white,
font-size: normal,
header-color: $black,
title-color: $black,
subtitle-color: $black,
text-color: $black,
highlight-color: $purple,
highlight-opacity: 0.1,
highlight-type: underline
);
$input-btn-focus-width: 0;

View File

@ -0,0 +1,164 @@
.alert {
font-family: $font-family-monospace;
font-size: $font-size-sm;
}
.alert-icon {
margin-right: 0.75rem;
}
.docs main .alert {
margin: 2rem -1.5rem;
}
.alert .alert-link {
text-decoration: underline;
}
.alert-doks {
background: $beige;
color: $black;
}
/*
.alert-light {
color: #215888;
background: linear-gradient(-45deg, rgb(212, 245, 255), rgb(234, 250, 255), rgb(234, 250, 255), #d3f6ef);
}
.alert-light .alert-link {
color: #215888;
}
*/
.alert-white {
background-color: rgba(255, 255, 255, 0.95);
}
.alert-primary {
color: $white;
background-color: $primary;
}
.alert a {
text-decoration: underline;
}
.alert-primary .alert-link {
color: $white;
}
/*
.alert-primary {
color: #084298;
background-color: #cfe2ff;
border-color: #b6d4fe;
}
.alert-primary .alert-link {
color: #06357a;
}
*/
.alert-secondary {
color: #41464b;
background-color: #e2e3e5;
border-color: #d3d6d8;
}
.alert-secondary .alert-link {
color: #34383c;
}
.alert-success {
color: #0f5132;
background-color: #d1e7dd;
border-color: #badbcc;
}
.alert-success .alert-link {
color: #0c4128;
}
.alert-info {
color: #055160;
background-color: #cff4fc;
border-color: #b6effb;
}
.alert-info .alert-link {
color: #04414d;
}
.alert-warning {
color: #664d03;
background-color: #fff3cd;
border-color: #ffecb5;
}
.alert-warning .alert-link {
color: #523e02;
}
.alert-danger {
color: #842029;
background-color: #f8d7da;
border-color: #f5c2c7;
}
.alert-danger .alert-link {
color: #6a1a21;
}
.alert-light {
color: #636464;
background-color: #fefefe;
border-color: #fdfdfe;
}
.alert-light .alert-link {
color: #4f5050;
}
.alert-dark {
color: #141619;
background-color: #d3d3d4;
border-color: #bcbebf;
}
.alert-dark .alert-link {
color: #101214;
}
.alert .alert-link:hover,
.alert .alert-link:focus {
text-decoration: none;
}
.alert-dismissible .btn-close {
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 1rem;
z-index: 2;
padding: 0.5rem;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-x'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E");
background-size: 1.5rem;
filter: invert(1) grayscale(100%) brightness(200%);
}
@include media-breakpoint-up(md) {
.alert-dismissible .btn-close {
background-size: 1.25rem;
}
}
[data-global-alert="closed"] #announcement {
display: none;
}
.alert code {
background: darken($beige, 5%);
color: $black;
padding: 0.25rem 0.5rem;
}

View File

@ -0,0 +1,253 @@
.navbar .btn-link {
color: $navbar-light-color;
padding: 0.4375rem 0;
}
#mode {
padding-right: 0.25rem;
padding-left: 0.25rem;
margin-right: -0.25rem;
}
.btn-link:focus {
outline: 0;
box-shadow: none;
}
#navigation {
margin-left: 1.25rem;
}
@include media-breakpoint-up(md) {
#mode {
margin-left: 1.125rem;
margin-right: -0.375rem;
}
.navbar .btn-link {
padding: 0.5625em 0.25rem 0.5rem 0.125rem;
}
}
.navbar .btn-link:hover {
color: $navbar-light-hover-color;
}
.navbar .btn-link:active {
color: $navbar-light-active-color;
}
body .toggle-dark {
display: block;
}
body .toggle-light {
display: none;
}
[data-dark-mode] body .toggle-light {
display: block;
}
[data-dark-mode] body .toggle-dark {
display: none;
}
pre {
position: relative;
}
@include media-breakpoint-down(md) {
.btn-copy {
display: none;
}
}
.btn-copy {
transition: opacity 0.3s ease-in-out;
visibility: hidden !important;
position: absolute;
right: 0.25rem;
top: 0.25rem;
z-index: 10;
font-family: $font-family-sans-serif;
font-size: $font-size-sm;
padding: 0.25rem 0.5rem;
color: $color-btn-text;
background-color: $color-btn-bg;
border-color: $color-btn-border;
}
.btn-copy:hover {
color: $color-btn-text;
background-color: lighten($color-btn-bg, 5%);
border-color: lighten($color-btn-border, 15%);
}
.btn-copy:focus {
color: $color-btn-text;
background-color: $color-btn-bg;
border-color: lighten($color-btn-border, 15%);
box-shadow: none;
}
.btn-copy:active,
.btn-copy.active {
color: $color-btn-text;
background-color: $color-btn-bg;
border-color: lighten($color-btn-border, 15%);
}
.btn-copy:active:focus,
.btn-copy.active:focus {
box-shadow: none;
}
@include media-breakpoint-up(md) {
pre:hover .btn-copy {
visibility: visible !important;
}
}
.btn-copy::after {
content: "Copy";
display: block;
color: $color-btn-text;
}
.btn-copy:hover::after {
content: "Copy";
display: block;
color: $color-btn-text;
}
.btn-copy:focus::after,
.btn-copy:active::after {
content: "Copied";
display: block;
color: $color-btn-text;
}
.collapsible-sidebar {
margin: 2.125rem 0;
}
.btn-toggle {
display: inline-flex;
align-items: center;
padding: 0.25rem 0.5rem 0.25rem 0;
font-weight: $headings-font-weight;
font-size: $font-size-base;
text-transform: uppercase;
color: $body-color;
background-color: transparent;
border: 0;
}
.btn-toggle:hover,
.btn-toggle:focus {
color: $body-color;
background-color: transparent;
outline: 0;
box-shadow: none;
}
.btn-toggle::before {
width: 1.25em;
line-height: 0;
content: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%2829, 45, 53, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e");
transition: transform 0.35s ease;
transform-origin: 0.5em 50%;
margin-bottom: 0.125rem;
}
.btn-toggle[aria-expanded="true"] {
color: $body-color;
}
.btn-toggle[aria-expanded="true"]::before {
transform: rotate(90deg);
}
.btn-toggle-nav a {
display: inline-flex;
padding: 0.1875rem 0.5rem;
margin-top: 0.125rem;
margin-left: 1.25rem;
text-decoration: none;
}
.btn-toggle-nav a:hover,
.btn-toggle-nav a:focus {
background-color: transparent;
color: $link-color;
}
.btn-toggle-nav a.active {
color: $link-color;
}
.doks-navbar .dropdown-menu,
.doks-subnavbar .dropdown-menu {
font-size: 0.875rem;
}
.doks-navbar .dropdown-item.current,
.doks-subnavbar .dropdown-item.current {
font-weight: 600;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 1rem top 0.6rem;
background-size: 0.75rem 0.75rem;
}
.btn-close {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-x'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E");
background-size: 1.5rem;
}
.offcanvas-header .btn-close {
margin-right: 0 !important;
}
.dropdown-toggle::after {
display: none;
}
.dropdown-caret {
margin-left: -0.1875rem;
margin-right: -0.3125rem;
}
.dropdown-menu.dropdown-menu-main {
width: 100%;
}
@include media-breakpoint-up(md) {
.dropdown-menu.dropdown-menu-main {
width: auto;
}
}
.dropdown-menu-main .dropdown-item {
color: inherit;
font-size: $font-size-base;
font-weight: 400;
text-decoration: none;
}
.dropdown-menu-main .dropdown-item:hover {
background-color: transparent;
color: $primary;
}
.dropdown-menu-main .dropdown-item.active {
color: $primary;
font-weight: 400;
text-decoration: none;
background-color: inherit;
}
.dropdown-menu-main .dropdown-item.active:hover {
background-color: transparent;
}

View File

@ -0,0 +1,66 @@
pre,
code,
kbd,
samp {
font-family: $font-family-monospace;
font-size: $font-size-sm;
border-radius: $border-radius;
}
code {
background: $beige;
color: $black;
padding: 0.25rem 0.5rem;
}
pre {
margin: 2rem 0;
}
pre code {
display: block;
overflow-x: auto;
line-height: $line-height-base;
padding: 1.25rem 1.5rem;
tab-size: 4;
scrollbar-width: thin;
scrollbar-color: transparent transparent;
}
.hljs {
padding: 1.5rem !important;
}
@include media-breakpoint-down(sm) {
pre,
code,
kbd,
samp {
border-radius: 0;
}
pre {
margin: 2rem -1.5rem;
}
}
pre code::-webkit-scrollbar {
height: 5px;
}
pre code::-webkit-scrollbar-thumb {
background: $gray-400;
}
pre code:hover {
scrollbar-width: thin;
scrollbar-color: $gray-500 transparent;
}
pre code::-webkit-scrollbar-thumb:hover {
background: $gray-500;
}
code.language-mermaid {
background: none;
}

View File

@ -0,0 +1,30 @@
.comment-list {
@extend .list-unstyled;
}
.comment-list ol {
list-style: none;
}
.comment-form p {
@extend .form-group !optional;
}
.comment-form input[type="text"],
.comment-form input[type="email"],
.comment-form input[type="url"],
.comment-form textarea {
@extend .form-control;
}
.comment-form input[type="submit"] {
@extend .btn;
@extend .btn-secondary;
}
blockquote {
margin-bottom: 1rem;
font-size: 1.25rem;
border-left: 3px solid $gray-300;
padding-left: 1rem;
}

View File

@ -0,0 +1,77 @@
details {
display: block;
border: 1px solid $gray-200;
border-radius: 0.25rem;
padding: 0.5rem 1rem 0;
margin: 0.5rem 0;
}
/*
details summary {
&::marker {
content: "";
}
}
*/
summary {
list-style: none;
display: inline-block;
width: calc(100% + 2rem);
margin: -0.5rem -1rem 0;
padding: 0.5rem 0.75rem;
}
summary::-webkit-details-marker {
display: none;
}
summary:hover {
background: $gray-100;
}
details summary::before {
display: inline-block;
content: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='rgba%2829, 45, 53, 0.75%29' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e");
transition: transform 0.35s ease;
transform-origin: center center;
margin-right: 0.375rem;
}
details[open] > summary::before {
transform: rotate(90deg);
}
/*
details summary > * {
display: inline-block;
}
*/
details[open] {
padding: 0.5rem 1rem;
}
details[open] > summary {
border-bottom: 1px solid $gray-300;
margin-bottom: 0.5rem;
}
details h2,
details h3,
details h4 {
margin: 1rem 0 0.5rem;
}
details p:last-child {
margin-bottom: 0;
}
details ul,
details ol {
margin-bottom: 0;
}
details pre {
margin: 0 0 1rem;
}

View File

@ -0,0 +1,19 @@
/** Search form */
.search-form {
@extend .form-inline !optional;
}
.search-form label {
@extend .form-group;
font-weight: normal;
}
.search-form .search-field {
@extend .form-control;
}
.search-form .search-submit {
@extend .btn;
@extend .btn-secondary;
}

View File

@ -0,0 +1,48 @@
figure {
margin: 2rem 0;
}
.figure-caption {
margin: 0.25rem 0 0.75rem;
}
figure.wide {
margin: 2rem -1.5rem;
}
figure.wide .figure-caption {
margin: 0.25rem 1.5rem 0.75rem;
}
@include media-breakpoint-up(md) {
figure.wide {
margin: 2rem -2.5rem;
}
figure.wide .figure-caption {
margin: 0.25rem 2.5rem 0.75rem;
}
}
@include media-breakpoint-up(lg) {
figure.wide {
margin: 2rem -5rem;
}
figure.wide .figure-caption {
margin: 0.25rem 5rem 0.75rem;
}
}
.blur-up {
filter: blur(5px);
}
.blur-up.lazyloaded {
filter: unset;
}
.img-simple {
margin-top: 0.375rem;
margin-bottom: 1.25rem;
}

View File

@ -0,0 +1,8 @@
.mermaid {
margin: 1.5rem 0;
padding: 1.5rem;
}
.mermaid svg {
height: auto;
}

View File

@ -0,0 +1,81 @@
.navbar-form {
position: relative;
}
#suggestions {
position: absolute;
left: 0;
margin-top: 0.5rem;
width: calc(100vw - 3rem);
z-index: $zindex-dropdown;
}
#suggestions a,
.suggestion__no-results {
padding: 0.75rem;
margin: 0 0.5rem;
}
#suggestions a {
display: block;
text-decoration: none;
}
#suggestions a:focus {
background: $gray-100;
outline: 0;
}
#suggestions div:not(:first-child) {
border-top: 1px dashed $gray-200;
}
#suggestions div:first-child {
margin-top: 0.5rem;
}
#suggestions div:last-child {
margin-bottom: 0.5rem;
}
#suggestions a:hover {
background: $gray-100;
}
#suggestions span {
display: flex;
font-size: $font-size-base;
}
.suggestion__title {
font-weight: $headings-font-weight;
color: $black;
}
.suggestion__description,
.suggestion__no-results {
color: $gray-700;
}
@include media-breakpoint-up(sm) {
#suggestions {
width: 31.125rem;
}
#suggestions a {
display: flex;
}
.suggestion__title {
width: 9rem;
padding-right: 1rem;
border-right: 1px solid $gray-200;
display: inline-block;
text-align: right;
}
.suggestion__description {
width: 19rem;
padding-left: 1rem;
}
}

View File

@ -0,0 +1,62 @@
/*
Based on Ascetic by (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 1.25rem 1.5rem;
background: $beige;
color: $body-color;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-symbol,
.hljs-bullet,
.hljs-section,
.hljs-addition,
.hljs-attribute,
.hljs-link {
color: $pink-500;
}
.hljs-comment,
.hljs-quote,
.hljs-meta,
.hljs-deletion {
color: #888;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-section,
.hljs-name,
.hljs-type,
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}
[data-dark-mode] body .hljs {
background: $body-overlay-dark;
color: $body-color-dark;
}
[data-dark-mode] body .hljs-string,
[data-dark-mode] body .hljs-variable,
[data-dark-mode] body .hljs-template-variable,
[data-dark-mode] body .hljs-symbol,
[data-dark-mode] body .hljs-bullet,
[data-dark-mode] body .hljs-section,
[data-dark-mode] body .hljs-addition,
[data-dark-mode] body .hljs-attribute,
[data-dark-mode] body .hljs-link {
color: $blue-300;
}

View File

@ -0,0 +1,5 @@
table {
@extend .table;
margin: 3rem 0;
}

View File

@ -0,0 +1,65 @@
.text-orange {
--bs-text-opacity: 1;
color: $orange;
}
.icon-support-full {
@extend .bi;
@extend .bi-check-circle-fill;
@extend .text-success;
}
[data-dark-mode] .icon-support-full {
@extend .bi;
@extend .bi-check-circle;
@extend .text-success;
}
.icon-support-unknown {
@extend .bi;
@extend .bi-dash-circle-fill;
@extend .text-warning;
}
[data-dark-mode] .icon-support-unknown {
@extend .bi;
@extend .bi-dash-circle;
@extend .text-warning;
}
.icon-support-partial {
@extend .bi;
@extend .bi-exclamation-circle-fill;
@extend .text-orange;
}
[data-dark-mode] .icon-support-partial {
@extend .bi;
@extend .bi-exclamation-circle;
@extend .text-orange;
}
.icon-support-none {
@extend .bi;
@extend .bi-x-circle-fill;
@extend .text-danger;
}
[data-dark-mode] .icon-support-none {
@extend .bi;
@extend .bi-x-circle;
@extend .text-danger;
}
body code span.line.hl {
background: $orange;
display: block;
width: 100%;
}
[data-dark-mode] body code span.line.hl {
background: $orange;
display: block;
width: 100%;
}

View File

@ -0,0 +1,20 @@
.footer {
border-top: 1px solid $gray-200;
padding-top: 1.125rem;
padding-bottom: 1.125rem;
}
.footer ul {
margin-bottom: 0;
}
.footer li {
font-size: $font-size-sm;
margin-bottom: 0;
}
@include media-breakpoint-up(md) {
.footer li {
font-size: $font-size-base;
}
}

View File

@ -0,0 +1,445 @@
.banner .nav li {
@extend .nav-item;
}
.banner .nav a {
@extend .nav-link;
}
.navbar-text {
margin-left: 1rem;
}
.navbar-brand {
font-weight: $headings-font-weight;
}
/*
.navbar-light .navbar-brand,
.navbar-light .navbar-brand:hover,
.navbar-light .navbar-brand:active {
color: $body-color;
}
.navbar-light .navbar-nav .active .nav-link {
color: $primary;
}
*/
.navbar {
z-index: 1000;
background-color: rgba(255, 255, 255, 0.95);
border-bottom: 1px solid $gray-200;
/*
margin-top: 4px;
*/
}
@include media-breakpoint-up(lg) {
.navbar {
z-index: 1025;
}
}
@include media-breakpoint-up(md) {
.navbar-brand {
font-size: $font-size-xl;
}
.navbar-text {
margin-left: 1.25rem;
}
}
.navbar-nav {
flex-direction: row;
}
.nav-item {
margin-left: 0;
}
@include media-breakpoint-up(md) {
.nav-item {
margin-left: 0.5rem;
}
}
/*
@include media-breakpoint-down(sm) {
.nav-item:first-child {
margin-left: 0;
}
}
*/
@include media-breakpoint-down(md) {
.navbar .container {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
}
.break {
flex-basis: 100%;
height: 0;
}
button#doks-languages {
margin-right: -0.5625rem;
margin-left: 0.75rem;
}
button#doks-versions {
margin-right: -0.5625rem;
margin-left: 0;
}
.offcanvas .nav-link {
color: $body-color;
}
.doks-subnavbar {
background-color: rgba(255, 255, 255, 0.95);
border-bottom: 1px solid $gray-200;
}
.doks-subnavbar .nav-link {
padding: 0.5rem 1.5rem 0.5rem 0;
}
.doks-subnavbar .nav-link:first-child {
padding: 0.5rem 1.5rem 0.5rem 0;
}
.offcanvas .nav-link:hover,
.offcanvas .nav-link:focus {
color: $link-color;
}
.offcanvas .nav-link.active {
color: $link-color;
}
/*
.navbar {
background-color: rgba(255, 255, 255, 0.95);
border-bottom: 1px solid $gray-200;
margin-top: 4px;
}
*/
.header-bar {
border-top: 4px solid;
border-image-source: linear-gradient(90deg, $primary, #8ed6fb 50%, #d32e9d);
border-image-slice: 1;
}
.offcanvas .header-bar {
margin-bottom: -4px;
}
.home .navbar {
border-bottom: 0;
}
/*
.navbar-form {
position: relative;
margin-top: 0.25rem;
}
*/
@include media-breakpoint-up(md) {
.navbar-brand {
margin-right: 0.75rem !important;
}
.main-nav .nav-item:first-child .nav-link,
.social-nav .nav-item:first-child .nav-link {
padding-left: 0;
}
.main-nav .nav-item:last-child .nav-link,
.social-nav .nav-item:last-child .nav-link {
padding-right: 0;
}
.doks-search {
max-width: 20rem;
margin-top: 0.125rem;
margin-bottom: 0.125rem;
}
/*
.navbar-form {
margin-top: 0;
margin-left: 6rem;
margin-right: 1.5rem;
}
*/
}
.form-control.is-search {
padding-right: 4rem;
border: 1px solid transparent;
background: $gray-100;
}
.form-control.is-search:focus {
border: 1px solid $primary;
}
.doks-search::after {
position: absolute;
top: 0.4625rem;
right: 0.5375rem;
display: flex;
align-items: center;
justify-content: center;
height: 1.5rem;
padding-right: 0.3125rem;
padding-left: 0.3125rem;
font-size: $font-size-base * 0.75;
color: $gray-700;
content: "Ctrl + /";
border: 1px solid $gray-300;
border-radius: 0.25rem;
}
/*
@include media-breakpoint-up(lg) {
.navbar-form {
margin-left: 15rem;
}
}
@include media-breakpoint-up(xl) {
.navbar-form {
margin-left: 30rem;
}
}
*/
/*
.form-control.is-search {
*/
/*
padding-right: calc(1.5em + 0.75rem);
*/
/*
padding-right: 2.5rem;
background: $gray-100;
border: 0;
*/
/*
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%236c757d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-search'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right calc(0.375em + 0.1875rem) center;
background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
*/
/*
}
*/
/*
.navbar-form::after {
position: absolute;
top: 0.4625rem;
right: 0.5375rem;
display: flex;
align-items: center;
justify-content: center;
height: 1.5rem;
padding-right: 0.4375rem;
padding-left: 0.4375rem;
font-size: $font-size-base * 0.75;
color: $gray-700;
content: "/";
border: 1px solid $gray-300;
border-radius: 0.25rem;
}
*/
/*! purgecss start ignore */
.algolia-autocomplete {
display: flex !important;
}
.algolia-autocomplete .ds-dropdown-menu {
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;
}
@include media-breakpoint-down(sm) {
.algolia-autocomplete .ds-dropdown-menu {
max-width: 512px !important;
min-width: 312px !important;
width: auto !important;
}
.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column {
font-weight: normal;
}
.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column::after {
content: "/";
margin-right: 0.25rem;
}
}
.algolia-autocomplete .algolia-docsearch-suggestion--category-header {
color: $black;
}
.algolia-autocomplete .algolia-docsearch-suggestion--title {
margin-bottom: 0;
}
.algolia-autocomplete .algolia-docsearch-suggestion--highlight {
padding: 0 0.05em;
}
.algolia-autocomplete .algolia-docsearch-footer {
margin-top: 1rem;
margin-right: 0.5rem;
margin-bottom: 0.5rem;
}
/*! purgecss end ignore */
/*
* Source: https://medium.com/creative-technology-concepts-code/responsive-mobile-dropdown-navigation-using-css-only-7218e4498a99
*/
/* Style the menu icon for the dropdown */
.navbar .menu-icon {
cursor: pointer;
/* display: inline-block; */
/* float: right; */
padding: 1.125rem 0.625rem;
margin: 0 0 0 -0.625rem;
/* position: relative; */
user-select: none;
}
.navbar .menu-icon .navicon {
background: $navbar-light-color;
display: block;
height: 2px;
position: relative;
transition: background 0.2s ease-out;
width: 18px;
}
.navbar .menu-icon .navicon::before,
.navbar .menu-icon .navicon::after {
background: $navbar-light-color;
content: "";
display: block;
height: 100%;
position: absolute;
transition: all 0.2s ease-out;
width: 100%;
}
.navbar .menu-icon .navicon::before {
top: 5px;
}
.navbar .menu-icon .navicon::after {
top: -5px;
}
/* Add the icon and menu animations when the checkbox is clicked */
.navbar .menu-btn {
display: none;
}
.navbar .menu-btn:checked ~ .navbar-collapse {
display: block;
max-height: 100vh;
}
.navbar .menu-btn:checked ~ .menu-icon .navicon {
background: transparent;
}
.navbar .menu-btn:checked ~ .menu-icon .navicon::before {
transform: rotate(-45deg);
}
.navbar .menu-btn:checked ~ .menu-icon .navicon::after {
transform: rotate(45deg);
}
.navbar .menu-btn:checked ~ .menu-icon:not(.steps) .navicon::before,
.navbar .menu-btn:checked ~ .menu-icon:not(.steps) .navicon::after {
top: 0;
}
.btn-menu {
margin-left: 1rem;
}
.btn-menu,
.doks-sidebar-toggle {
padding-right: 0.25rem;
padding-left: 0.25rem;
margin-right: -0.5rem;
}
.btn-menu:hover,
.btn-doks-light:hover,
.doks-sidebar-toggle:hover {
background: $pink-100;
}
.btn-menu:focus,
.doks-sidebar-toggle:focus,
.doks-mode-toggle:focus {
outline: 0;
}
.doks-sidebar-toggle .doks-collapse {
display: none;
}
.doks-sidebar-toggle:not(.collapsed) .doks-expand {
display: none;
}
.doks-sidebar-toggle:not(.collapsed) .doks-collapse {
display: inline-block;
}
.navbar-light .navbar-brand,
.navbar-light .navbar-brand:hover,
.navbar-light .navbar-brand:active {
color: $body-color;
}
.navbar-light .navbar-nav .active .nav-link {
color: $primary;
}
.dropdown-divider {
border-top: 1px dashed $gray-200;
}
.dropdown-item:hover {
background: $gray-100;
}
.dropdown-item:active {
color: inherit;
}

View File

@ -0,0 +1,64 @@
.docs-content > h2[id]::before,
.docs-content > h3[id]::before,
.docs-content > h4[id]::before {
display: block;
height: 6rem;
margin-top: -6rem;
content: "";
}
.anchor {
visibility: hidden;
}
h1:hover a,
h2:hover a,
h3:hover a,
h4:hover a {
visibility: visible;
text-decoration: none;
}
.card-list {
margin-top: 2.25rem;
}
.page-footer-meta {
margin-top: 3rem;
}
.edit-page,
.last-modified {
font-size: $font-size-sm;
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
@include media-breakpoint-up(md) {
.edit-page,
.last-modified {
font-size: $font-size-base;
margin-top: 0.75rem;
margin-bottom: 0.25rem;
}
}
.edit-page svg,
.last-modified svg {
margin-right: 0.25rem;
margin-bottom: 0.25rem;
}
p.meta {
margin-top: 0.5rem;
font-size: $font-size-base;
}
.breadcrumb {
margin-top: 2.25rem;
font-size: $font-size-base;
}
.page-link:hover {
text-decoration: none;
}

View File

@ -0,0 +1,28 @@
.home .card,
.contributors.list .card,
.blog.list .card {
margin-top: 2rem;
margin-bottom: 2rem;
transition: transform 0.3s;
}
.home .card:hover,
.contributors.list .card:hover,
.blog.list .card:hover {
transform: scale(1.025);
}
.home .card-body,
.contributors.list .card-body,
.blog.list .card-body {
padding: 0 2rem 1rem;
}
.blog-header {
text-align: center;
margin-bottom: 2rem;
}
.blog-footer {
text-align: center;
}

View File

@ -0,0 +1,116 @@
.docs-links,
.docs-toc {
scrollbar-width: thin;
scrollbar-color: $white $white;
}
.docs-links::-webkit-scrollbar,
.docs-toc::-webkit-scrollbar {
width: 5px;
}
.docs-links::-webkit-scrollbar-track,
.docs-toc::-webkit-scrollbar-track {
background: $white;
}
.docs-links::-webkit-scrollbar-thumb,
.docs-toc::-webkit-scrollbar-thumb {
background: $white;
}
.docs-links:hover,
.docs-toc:hover {
scrollbar-width: thin;
scrollbar-color: $gray-200 $white;
}
.docs-links:hover::-webkit-scrollbar-thumb,
.docs-toc:hover::-webkit-scrollbar-thumb {
background: $gray-200;
}
.docs-links::-webkit-scrollbar-thumb:hover,
.docs-toc::-webkit-scrollbar-thumb:hover {
background: $gray-200;
}
.docs-links h3,
.page-links h3 {
text-transform: uppercase;
font-size: $font-size-base;
margin: 1.25rem 0 0.5rem;
padding: 1.5rem 0 0;
}
@include media-breakpoint-up(lg) {
.docs-links h3,
.page-links h3 {
margin: 1.125rem 1.5rem 0.75rem 0;
padding: 1.375rem 0 0;
}
}
.docs-links h3:not(:first-child) {
border-top: 1px solid $gray-200;
}
a.docs-link {
color: $body-color;
display: block;
padding: 0.125rem 0;
font-size: $font-size-base;
}
.page-links li {
margin-top: 0.375rem;
padding-top: 0.375rem;
}
.page-links li ul li {
border-top: none;
padding-left: 1rem;
margin-top: 0.125rem;
padding-top: 0.125rem;
}
.page-links li:not(:first-child) {
border-top: 1px dashed $gray-200;
}
.page-links a {
color: $body-color;
display: block;
padding: 0.125rem 0;
font-size: $font-size-base * 0.9375;
}
.docs-link:hover,
.docs-link.active,
.page-links a:hover {
text-decoration: none;
color: $link-color;
}
.nav-link.active,
.dropdown-menu-main .dropdown-item.active,
.docs-link.active {
font-weight: 500;
}
.docs-links h3.sidebar-link,
.page-links h3.sidebar-link {
text-transform: none;
font-size: $font-size-md;
font-weight: normal;
}
.docs-links h3.sidebar-link a,
.page-links h3.sidebar-link a {
color: $body-color;
}
.docs-links h3.sidebar-link a:hover,
.page-links h3.sidebar-link a:hover {
text-decoration: underline;
}

0
docs/assets/scss/vendor/.gitkeep vendored Normal file
View File

17
docs/babel.config.js Normal file
View File

@ -0,0 +1,17 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: [
// Best practice: https://github.com/babel/babel/issues/7789
'>=1%',
'not ie 11',
'not op_mini all'
]
}
}
]
]
};

View File

@ -1,18 +0,0 @@
---
layout: default
title: Miscellaneous Additional Resources
parent: Community
nav_order: 3
---
In this document you will find miscellaneous resources that could give you more
information on Authelia or help you set it up.
# Articles
[Setting Up Authelia With SWAG](https://blog.linuxserver.io/2020/08/26/setting-up-authelia/)
[Authelia Tutorial Protect your Docker Traefik stack with Private MFA](https://www.smarthomebeginner.com/docker-authelia-tutorial/)
# Youtube Videos
[Authelia: Install Guide on Unraid + NGINX (Deep Dive)](https://www.youtube.com/watch?v=kw_pohbKE3Y)

View File

@ -1,212 +0,0 @@
---
layout: default
title: Integrate Authelia with Django
parent: Community
nav_order: 6
---
# Integrate Authelia with Django
Django, the Python web framework, can be configured to delegate authentication to external services
using HTTP request headers. This is well documented on [Django documentation](https://docs.djangoproject.com/en/3.2/howto/auth-remote-user/)
Therefore, it is possible to integrate Django with Authelia following the documentation about
[Proxy integration](https://www.authelia.com/docs/deployment/supported-proxies/#how-can-the-backend-be-aware-of-the-authenticated-users)
and adding a few lines of code on your Django application.
## Basic integration
Django uses `REMOTE_USER` header by default. But WSGI servers transform the headers received from
proxy servers adding `HTTP_` as prefix. So we need to add a custom middleware in order to use `HTTP_REMOTE_USER`.
This basic configuration enables authentication using Authelia. If the user does not exists on Django database,
it will be automatically created.
### Configuration
```python
# file: settings.py
MIDDLEWARE = [
'...',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'your_app.auth.middleware.RemoteUserMiddleware',
# or 'your_app.auth.middleware.PersistentRemoteUserMiddleware',
'...',
]
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.RemoteUserBackend',
]
# Logout from authelia after logout on the Django application
LOGOUT_REDIRECT_URL = 'https://auth.your_domain.com/logout'
```
### New authentication middleware
```python
# new file: your_app/auth/middleware.py
from django.contrib.auth.middleware import RemoteUserMiddleware, PersistentRemoteUserMiddleware
class HttpRemoteUserMiddleware(RemoteUserMiddleware):
header = 'HTTP_REMOTE_USER'
# uncomment the line below to disable authentication to users that not exists on Django database
# create_unknown_user = False
class PersistentHttpRemoteUserMiddleware(PersistentRemoteUserMiddleware):
"""
The RemoteUserMiddleware authentication middleware assumes that the HTTP request header
REMOTE_USER is present with all authenticated requests.
With PersistentRemoteUserMiddleware, it is possible to receive this header only on a few
pages (as login page) and maintain the authenticated session until explicit
logout by the user.
"""
header = 'HTTP_REMOTE_USER'
```
**Security Warning:**
The proxy server **must** set `Remote-User` header **every time** it hits the Django application. If you only
protect the login URL with Authelia and use the Persistent class, you have to set this header to `''`
on the other locations.
## Advanced integration
While the basic integration only uses the HTTP header `Remote-User` set by Authelia, this advanced integration
uses also the HTTP headers `Remote-Name`, `Remote-Email` and `Remote-Groups`.
In this example, we create a new authentication backend on Django that will synchronize user data with Authelia
backend, storing the name, the email and the groups of the user on the Django database.
### Configuration
```python
# file: settings.py
MIDDLEWARE = [
'...',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'your_app.auth.middleware.RemoteUserMiddleware',
# or 'your_app.auth.middleware.PersistentRemoteUserMiddleware',
'...',
]
AUTHENTICATION_BACKENDS = [
'your_app.auth.backends.RemoteExtendedUserBackend',
]
# Logout from authelia after logout on the Django application
LOGOUT_REDIRECT_URL = 'https://auth.your_domain.com/logout'
```
### New authentication backend
```python
# new file: your_app/auth/backends.py
from django.conf import settings
from django.contrib.auth.models import Group
from django.contrib.auth.backends import RemoteUserBackend
class RemoteExtendedUserBackend(RemoteUserBackend):
"""
This backend can be used in conjunction with the ``RemoteUserMiddleware``
to handle authentication outside Django and update local user with external information
(name, email and groups).
Extends RemoteUserBackend (it creates the Django user if it does not exist,
as explained here: https://github.com/django/django/blob/main/django/contrib/auth/backends.py#L167),
updating the user with the information received from the remote headers.
Django user is only added to groups that already exist on the database (no groups are created).
A settings variable can be used to exclude some groups when updating the user.
"""
excluded_groups = set()
if hasattr(settings, 'REMOTE_AUTH_BACKEND_EXCLUDED_GROUPS'):
excluded_groups = set(settings.REMOTE_AUTH_BACKEND_EXCLUDED_GROUPS)
# Warning: possible security breach if reverse proxy does not set
# these variables EVERY TIME it hits this Django application (and REMOTE_USER variable).
# See https://docs.djangoproject.com/en/4.0/howto/auth-remote-user/#configuration
header_name = 'HTTP_REMOTE_NAME'
header_groups = 'HTTP_REMOTE_GROUPS'
header_email = 'HTTP_REMOTE_EMAIL'
def authenticate(self, request, remote_user):
user = super().authenticate(request, remote_user)
# original authenticate calls configure_user only
# when user is created. We need to call this method every time
# the user is authenticated in order to update its data.
if user:
self.configure_user(request, user)
return user
def configure_user(self, request, user):
"""
Complete the user from extra request.META information.
"""
if self.header_name in request.META:
user.last_name = request.META[self.header_name]
if self.header_email in request.META:
user.email = request.META[self.header_email]
if self.header_groups in request.META:
self.update_groups(user, request.META[self.header_groups])
if self.user_has_to_be_staff(user):
user.is_staff = True
user.save()
return user
def user_has_to_be_staff(self, user):
return True
def update_groups(self, user, remote_groups):
"""
Synchronizes groups the user belongs to with remote information.
Groups (existing django groups or remote groups) on excluded_groups are completely ignored.
No group will be created on the django database.
Disclaimer: this method is strongly inspired by the LDAPBackend from django-auth-ldap.
"""
current_group_names = frozenset(
user.groups.values_list("name", flat=True).iterator()
)
preserved_group_names = current_group_names.intersection(self.excluded_groups)
current_group_names = current_group_names - self.excluded_groups
target_group_names = frozenset(
[x for x in map(self.clean_groupname, remote_groups.split(',')) if x is not None]
)
target_group_names = target_group_names - self.excluded_groups
if target_group_names != current_group_names:
target_group_names = target_group_names.union(preserved_group_names)
existing_groups = list(
Group.objects.filter(name__in=target_group_names).iterator()
)
user.groups.set(existing_groups)
return
def clean_groupname(self, groupname):
"""
Perform any cleaning on the "groupname" prior to using it.
Return the cleaned groupname.
"""
return groupname
```

View File

@ -1,181 +0,0 @@
---
layout: default
title: Example of authelia lite on docker swarm
parent: Community
nav_order: 4
---
The overlay network for docker swarm can be initialized with:
```
$ docker swarm init
$ docker swarm init && docker network create --driver=overlay traefik-public
$ mkdir ./redis ./letsencrypt
```
The structure of the folder should be like this:
```
├── authelia/
│   ├── configuration.yml
│   └── users_database.yml
├── redis/
├── letsencrypt/
│   └── acme.json
└── traefik-compose.yml
```
The following configuration allows you to deploy authelia to docker swarm with traefik 2.x. Please replace the **example.com** and **your@email.com** with your domain and email respectively. Then save it as **traefik-compose.yml**.
```
version: '3.3'
services:
authelia:
image: authelia/authelia:4
volumes:
- ./authelia:/config
networks:
- traefik-public
deploy:
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.authelia.rule=Host(`auth.example.com`)'
- 'traefik.http.routers.authelia.entrypoints=web'
- "traefik.http.services.authelia.loadbalancer.server.port=9091"
# TLS
- "traefik.http.routers.authelias.rule=Host(`auth.example.com`)"
- "traefik.http.routers.authelias.entrypoints=websecure"
- "traefik.http.routers.authelias.tls.certresolver=letsencrypt"
# Redirect
- "traefik.http.routers.authelia.middlewares=https_redirect"
- "traefik.http.middlewares.https_redirect.redirectscheme.scheme=https"
# Authelia
- 'traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://auth.example.com'
- 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true'
- 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User, Remote-Groups'
- "traefik.http.routers.authelia.service=authelia"
redis:
image: redis:6-alpine
volumes:
- ./redis:/data
networks:
- traefik-public
traefik:
# The official v2.0 Traefik docker image
image: traefik:v2.2
deploy:
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.api.rule=Host(`traefik.example.com`)'
- 'traefik.http.routers.api.entrypoints=web'
- 'traefik.http.routers.api.service=api@internal'
- 'traefik.http.services.traefik.loadbalancer.server.port=80'
# TLS
- "traefik.http.routers.apis.rule=Host(`traefik.example.com`)"
- "traefik.http.routers.apis.entrypoints=websecure"
- "traefik.http.routers.apis.tls.certresolver=letsencrypt"
# Redirect
- "traefik.http.routers.api.middlewares=https_redirect"
- "traefik.http.middlewares.https_redirect.redirectscheme.scheme=https"
# Authelia
- 'traefik.http.routers.apis.service=api@internal'
- 'traefik.http.routers.apis.middlewares=authelia@docker'
placement:
constraints:
- node.role == manager
command:
- "--api"
- "--providers.docker=true"
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entryPoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.letsencrypt.acme.email=your@email.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
# Listen on port 80, default for HTTP, necessary to redirect to HTTPS
- target: 80
published: 80
mode: host
# Listen on port 443, default for HTTPS
- target: 443
published: 443
mode: host
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
- ./letsencrypt:/letsencrypt
networks:
- traefik-public
secure:
image: containous/whoami
networks:
- traefik-public
deploy:
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.secure.rule=Host(`secure.example.com`)'
- 'traefik.http.routers.secure.entrypoints=web'
- 'traefik.http.services.secure.loadbalancer.server.port=80'
# TLS
- "traefik.http.routers.secures.rule=Host(`secure.example.com`)"
- "traefik.http.routers.secures.entrypoints=websecure"
- "traefik.http.routers.secures.tls.certresolver=letsencrypt"
# Redirect
- "traefik.http.routers.secure.middlewares=https_redirect"
- "traefik.http.middlewares.https_redirect.redirectscheme.scheme=https"
# Authelia
- 'traefik.http.routers.secures.middlewares=authelia@docker'
public:
image: containous/whoami
networks:
- traefik-public
deploy:
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.public.rule=Host(`public.example.com`)'
- 'traefik.http.routers.public.entrypoints=web'
- 'traefik.http.services.public.loadbalancer.server.port=80'
# TLS
- "traefik.http.routers.publics.rule=Host(`public.example.com`)"
- "traefik.http.routers.publics.entrypoints=websecure"
- "traefik.http.routers.publics.tls.certresolver=letsencrypt"
# Redirect
- "traefik.http.routers.public.middlewares=https_redirect"
- "traefik.http.middlewares.https_redirect.redirectscheme.scheme=https"
# Authelia
- 'traefik.http.routers.publics.middlewares=authelia@docker'
networks:
traefik-public:
external: true
```
Finally, the stack is ready to be deployed.
```
$ docker stack deploy -c traefik-compose.yml traefik
```
Full configuration files can be found here https://github.com/wuhanstudio/authelia-docker-swarm
```
$ docker swarm init && docker network create --driver=overlay traefik-public
$ git clone https://github.com/wuhanstudio/authelia-docker-swarm && cd authelia-docker-swarm
# Replace wuhanstudio.cc with your domain
$ find . -type f -name "*.yml" -exec sed -i'' -e 's/example.com/wuhanstudio.cc/g' {} +
# Replace wuhanstudio@qq.com with your email
$ find . -type f -name "*.yml" -exec sed -i'' -e 's/your@email.com/wuhanstudio@qq.com/g' {} +
$ docker stack deploy -c traefik-compose.yml traefik
```

View File

@ -1,13 +0,0 @@
---
layout: default
title: Community
nav_order: 11
has_children: true
---
# Community documentation
This section is meant to advertise and organize documentation produced
by the community. This documentation is considered non-official and we
will not guarantee that this documentation is up-to-date. If you think
some of it should be considered official, please file an issue on GitHub.

View File

@ -1,51 +0,0 @@
---
layout: default
title: Community-Tested OIDC Integrations
parent: Community
nav_order: 5
has_children: true
has_toc: false
---
# OIDC Integrations
**Note** This is community-based content for which the core-maintainers cannot guarantee correctness. The parameters may change over time. If a parameter does not work as documented, please submit a PR to update the list.
## Currently Tested Applications
| Application | Minimal Version | Notes |
|:----------------:|:------------------------------:|:-------------------------------------------------------------------------------------------------------------:|
| Bookstack | `21.10` | |
| Gitea | `1.14.6` | |
| GitLab | `13.0.0` | |
| Grafana | `8.0.5` | |
| Harbor | `1.10` | It works on >v2.1 also, but not sure if there is OIDC support on v2.0 |
| Hashicorp Vault | `1.8.1` | |
| Miniflux | `2.0.21` | |
| MinIO | `RELEASE.2021-11-09T03-21-45Z` | must set `MINIO_IDENTITY_OPENID_CLAIM_NAME: groups` in MinIO and set [MinIO policies](https://docs.min.io/minio/baremetal/security/minio-identity-management/policy-based-access-control.html#minio-policy) as groups in Authelia |
| Nextcloud | `22.1.0` | Tested using the `nextcloud-oidc-login` app - [Link](https://github.com/pulsejet/nextcloud-oidc-login) |
| Portainer CE | `2.6.1` | Settings to use username as ID: set `Scopes` to `openid` and `User Identifier` to `preferred_username` |
| Seafile | `9.0.4` | Requires `OAUTH_ATTRIBUTE_MAP` to contain the mapping of the `id` field even if not present in Authelia, e.g. `'id': (False, "unused")` (see [seahub#5162](https://github.com/haiwen/seahub/issues/5162)) |
| Verdaccio | `5` | Depends on this fork of verdaccio-github-oauth-ui: [Link](https://github.com/OnekO/verdaccio-github-oauth-ui) |
| Wekan | `5.41` | |
## Known Callback URLs
If you do not find the application in the list below, you will need to search for yourself - and maybe come back to open a PR to add your application to this list so others won't have to search for them.
`<DOMAIN>` needs to be substituted with the full URL on which the application runs on. If GitLab, as an example, was reachable under `https://gitlab.example.com`, `<DOMAIN>` would be exactly the same.
| Application | Version | Callback URL | Notes |
|:---------------:|:-------------------------------------:|:------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
| Bookstack | `21.10` | `<DOMAIN>/oidc/callback` | |
| Gitea | `1.14.6` | `<DOMAIN>/user/oauth2/authelia/callback` | `ROOT_URL` in `[server]` section of `app.ini` must be configured correctly. Typically it is `<DOMAIN>/`. The string `authelia` in the callback url is the `Authentication Name` of the configured Authentication Source in Gitea (Authentication Type: OAuth2, OAuth2 Provider: OpenID Connect). |
| GitLab | `14.0.1` | `<DOMAIN>/users/auth/openid_connect/callback` | |
| Harbor | `1.10` | `<DOMAIN>/-/oauth/callback` | |
| Hashicorp Vault | `14.0.1` | `<DOMAIN>/oidc/callback` and `<DOMAIN>/ui/vault/auth/oidc/oidc/callback` | |
| Miniflux | `2.0.21` | `<DOMAIN>/oauth2/oidc/callback` | Set via Miniflux `OAUTH2_REDIRECT_URL` [configuration parameter](https://miniflux.app/docs/configuration.html#oauth2-redirect-url). Example value follows this format |
| MinIO | `RELEASE.2021-07-12T02-44-53Z` | `<DOMAIN>/oauth_callback` | |
| Nextcloud | `22.1.0` + `nextcloud-oidc-login` app | `<DOMAIN>/apps/oidc_login/oidc` | |
| Portainer CE | `2.6.1` | `<DOMAIN>` | |
| Seafile | `9.0.4` | `<DOMAIN>/oauth/callback/` | Must exactly match `OAUTH_REDIRECT_URL` value as set in `seahub_settings.py` |
| Verdaccio | `5` | `<DOMAIN>/oidc/callback` | |
| Wekan | `5.41` | `<DOMAIN>/_oauth_oidc` | |

View File

@ -1,47 +0,0 @@
---
layout: default
title: Portainer
parent: Community-Tested OIDC Integrations
grand_parent: Community
nav_order: 1
---
# OIDC Integrations: Portainer
{{ page.path }}
**Note** these setting have been tested with authelia `v4.34.6` and Portainer (CE and EE) `2.12.2`
## Authelia config
The specific client config for portainer.
```yaml
identity_providers:
oidc:
clients:
- id: portainer_client_id
description: Some description you want to shown on the Authelia consent page
secret: some secret string which should also be entered in the portainer config
public: false
authorization_policy: two_factor
audience: []
scopes:
- openid
- profile
- groups
- email
redirect_uris:
- https://portainer.example.com
userinfo_signing_algorithm: none
```
## Portainer config
To setup Authelia as SSO provider in portainer go to **Settings > Authentication** and select **Authentication method** OAuth and **Provider** Custom and make sure automatic user provision is turned so users get automatically created.
**Note** make sure that Redirect URL matches exacty the redirect_uris in authelia config. Use `preferred_username` as the User identifier which makes sure the portianer user and authelia user have the same username. Scopes should be `openid profile groups email` **do not use commas**
<p align="center">
<a href="../../images/portainer.gif" target="_blank"><img src="../../images/portainer.gif" width="736"></a>
</p>

View File

@ -1,42 +0,0 @@
---
layout: default
title: Proxmox
parent: Community-Tested OIDC Integrations
grand_parent: Community
nav_order: 2
---
# OIDC Integrations: Proxmox
{{ page.path }}
## Authelia config
**Note** these setting have been tested with authelia `v4.33.2` and Proxmox `7.1-10`
The specific client config for proxmox.
```yaml
identity_providers:
oidc:
clients:
- id: some id you want to use on the client
description: Some description you want to shown on the Authelia consent page
secret: some secret string which should also be entered in the proxmox config
public: false
authorization_policy: two_factor
audience: []
scopes:
- openid
redirect_uris:
- https://proxmox.example.com
userinfo_signing_algorithm: none
```
## Proxmox config
Under Datacenter go to **Persmission > Realms** and add the an OpenID Connect Server
<p align="center">
<a href="../../images/portainer.gif" target="_blank"><img src="../../images/proxmox.gif" width="736"></a>
</p>

View File

@ -1,15 +0,0 @@
---
layout: default
title: 2FA through basic auth
parent: Community
nav_order: 1
---
The following project allows you to use Authelia's one-time password (OTP) 2-factor authentication (2FA) through only
[basic auth](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication)
and a custom credentials format described below.
This allows you to use 2FA on clients and scenarios
that demand basic auth, e.g. [webdav](https://en.wikipedia.org/wiki/WebDAV) network streaming.
More information:
## [authelia-basic-2fa](https://github.com/ViRb3/authelia-basic-2fa)

View File

@ -1,34 +0,0 @@
---
layout: default
title: Using Remote-User header for SSO with Jira
parent: Community
nav_order: 2
---
# Using Remote-User header for SSO with Jira
You can make Jira auto-login to the user that is currently logged in to authelia.
I say "auto-login" as I couldn't find any plugin to actually be authentication
provider through HTTP headers only - LDAP though seems to have support.
So this guide is targeted to authelia users that don't use any other authentication
backend.
I'm using traefik with docker as an example, but any proxy that can forward
authelia `Remote-User` header is fine.
First of all, users should exist on both Authelia and Jira, and have the same
username for this to work. Also you will have to
[pay for a plugin](https://marketplace.atlassian.com/apps/1212581/easy-sso-jira-kerberos-ntlm-saml?hosting=server&tab=overview).
After both steps are done:
- Add `traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User` in the labels of authelia
- Add `traefik.http.routers.jira.middlewares=authelia@docker` in the labels of Jira (to actually enable Authelia for
the Jira instance)
- Install EasySSO in Jira
- Go to EasySSO preferences and add the "Remote-User" header under HTTP and tick the "Username" checkbox.
- Save
## Other Systems
While this guide is tailored for Jira, you can use a similar method with many other services like Jenkins and Grafana.

View File

@ -0,0 +1,89 @@
baseurl = "https://www.authelia.com/"
canonifyURLs = false
disableAliases = true
disableHugoGeneratorInject = true
enableEmoji = true
enableGitInfo = true
enableRobotsTXT = true
languageCode = "en-US"
paginate = 7
rssLimit = 10
title = "Authelia"
# Multilingual
defaultContentLanguage = "en"
disableLanguages = []
# defaultContentLanguageInSubdir = true
# add redirects/headers
[outputs]
home = ["HTML", "RSS", "REDIRECTS", "HEADERS"]
section = ["HTML", "RSS", "SITEMAP"]
# remove .{ext} from text/netlify
[mediaTypes."text/netlify"]
suffixes = [""]
delimiter = ""
# add output format for netlify _redirects
[outputFormats.REDIRECTS]
mediaType = "text/netlify"
baseName = "_redirects"
isPlainText = true
notAlternative = true
# add output format for netlify _headers
[outputFormats.HEADERS]
mediaType = "text/netlify"
baseName = "_headers"
isPlainText = true
notAlternative = true
# add output format for section sitemap.xml
[outputFormats.SITEMAP]
mediaType = "application/xml"
baseName = "sitemap"
isHTML = false
isPlainText = true
noUgly = true
rel = "sitemap"
[caches]
[caches.getjson]
dir = ":cacheDir/:project"
maxAge = "10s"
[sitemap]
changefreq = "weekly"
filename = "sitemap.xml"
priority = 0.5
[taxonomies]
contributor = "contributors"
[permalinks]
blog = "/blog/:title/"
[minify.tdewolff.html]
keepWhitespace = false
[module]
[module.hugoVersion]
extended = true
min = "0.80.0"
max = ""
[[module.mounts]]
source = "assets"
target = "assets"
[[module.mounts]]
source = "static"
target = "static"
[[module.mounts]]
source = "node_modules/flexsearch"
target = "assets/js/vendor/flexsearch"
[[module.mounts]]
source = "node_modules/katex"
target = "assets/js/vendor/katex"
[[module.mounts]]
source = "node_modules/mermaid"
target = "assets/js/vendor/mermaid"

View File

@ -0,0 +1,6 @@
[en]
languageName = "English"
contentDir = "content/en"
weight = 10
[en.params]
languageISO = "EN"

View File

@ -0,0 +1,29 @@
defaultMarkdownHandler = "goldmark"
[goldmark]
[goldmark.extensions]
linkify = true
[goldmark.parser]
autoHeadingID = true
autoHeadingIDType = "github"
[goldmark.parser.attribute]
block = true
title = true
[goldmark.renderer]
unsafe = true
[highlight]
codeFences = false
guessSyntax = false
hl_Lines = ""
lineNoStart = 1
lineNos = false
lineNumbersInTable = true
noClasses = false
style = "dracula"
tabWidth = 4
[tableOfContents]
endLevel = 4
ordered = false
startLevel = 2

View File

@ -0,0 +1,68 @@
[[main]]
name = "Overview"
identifier = "overview"
url = "/overview/prologue/introduction/"
weight = 10
[[main]]
name = "Configuration"
identifier = "configuration"
url = "/configuration/prologue/introduction/"
weight = 20
[[main]]
name = "Integration"
identifier = "integration"
url = "/integration/prologue/introduction/"
weight = 30
[[main]]
name = "Contributing"
identifier = "contributing"
url = "/contributing/prologue/introduction"
weight = 40
[[main]]
name = "Blog"
identifier = "blog"
url = "/blog/"
weight = 50
[[main]]
name = "Roadmap"
identifier = "roadmap"
url = "/roadmap/prologue/introduction/"
weight = 80
[[main]]
name = "Reference"
identifier = "reference"
url = "/reference/prologue/introduction/"
weight = 90
[[social]]
name = "GitHub"
pre = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-github\"><path d=\"M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22\"></path></svg>"
url = "https://github.com/authelia/authelia"
post = "v0.1.0"
weight = 10
[[footer]]
name = "Privacy"
url = "/information/privacy-policy"
weight = 10
[[footer]]
name = "Code of Conduct"
url = "/information/code-of-conduct"
weight = 20
[[footer]]
name = "Security"
url = "/information/security"
weight = 30
[[footer]]
name = "Contact"
url = "/information/contact"
weight = 40

View File

@ -0,0 +1,95 @@
# Meta Data for SEO
## Homepage
title = "Authelia"
titleSeparator = "-"
titleAddition = "The Single Sign-On Multi-Factor portal for web apps"
description = "Authelia is an open-source authentication and authorization server and portal fulfilling the identity and access management (IAM) role of information security in providing multi-factor authentication and single sign-on (SSO) for your applications via a web portal. It acts as a companion for common reverse proxies."
## Documentation
# docsVersion = "0.3"
## Open Graph
images = ["authelia.png"]
ogLocale = "en_US"
domainTLD = "authelia.com"
titleHome = "Authelia"
## Twitter Cards
# twitterSite = ""
# twitterCreator = ""
## JSON-LD
schemaType = "Organization"
schemaName = "Authelia"
schemaAuthor = "Authelia"
# schemaAuthorTwitter = ""
# schemaAuthorLinkedIn = ""
schemaAuthorGitHub = "https://github.com/authelia"
schemaLocale = "en-US"
schemaLogo = "logo-doks.png"
schemaLogoWidth = 512
schemaLogoHeight = 512
schemaImage = "doks.png"
schemaImageWidth = 1280
schemaImageHeight = 640
# schemaTwitter = ""
# schemaLinkedIn = ""
schemaGitHub = "https://github.com/authelia/authelia"
schemaSection = "blog"
## Sitelinks Search Box
siteLinksSearchBox = false
## Chrome Browser
themeColor = "#fff"
# Images
quality = 85
bgColor = "#fff"
landscapePhotoWidths = [900, 800, 700, 600, 500]
portraitPhotoWidths = [800, 700, 600, 500]
lqipWidth = "20x"
smallLimit = "300"
# Footer
footer = "Powered by <a class=\"text-muted\" href=\"https://www.netlify.com/\">Netlify</a>, <a class=\"text-muted\" href=\"https://gohugo.io/\">Hugo</a>, and <a class=\"text-muted\" href=\"https://getdoks.org/\">Doks</a>"
# Feed
copyRight = "Copyright © 2016-%s Authelia"
# Alert
alert = true
alertDismissable = true
alertText = "Help us improve Authelia by taking this <a class=\"alert-link stretched-link\" href=\"https://forms.gle/aVw6J9jcez97EAhD6\">10 second survey.</a>"
# Edit Page
repoHost = "GitHub"
docsRepo = "https://github.com/authelia/authelia"
docsRepoBranch = "master"
docsRepoSubPath = "docs"
editPage = true
lastMod = true
[options]
lazySizes = true
clipBoard = true
instantPage = true
flexSearch = true
darkMode = true
bootStrapJs = true
breadCrumb = true
highLight = true
kaTex = false
multilingualMode = false
docsVersioning = false
fullWidth = false
[menu]
[menu.section]
auto = true
collapsibleSidebar = true
[Sections]
Search = ["overview", "configuration", "integration", "contributing", "reference"]
Searchable = ["blog"]

View File

@ -0,0 +1 @@
canonifyURLs = false

View File

@ -0,0 +1,39 @@
const autoprefixer = require('autoprefixer');
const purgecss = require('@fullhuman/postcss-purgecss');
const whitelister = require('purgecss-whitelister');
module.exports = {
plugins: [
autoprefixer(),
purgecss({
content: [
'./layouts/**/*.html',
'./content/**/*.md',
],
safelist: [
'lazyloaded',
'table',
'thead',
'tbody',
'tr',
'th',
'td',
'h5',
'alert-link',
'container-xxl',
'container-fluid',
...whitelister([
'./assets/scss/components/_alerts.scss',
'./assets/scss/components/_buttons.scss',
'./assets/scss/components/_code.scss',
'./assets/scss/components/_diagrams.scss',
'./assets/scss/components/_syntax.scss',
'./assets/scss/components/_search.scss',
'./assets/scss/common/_dark.scss',
'./node_modules/bootstrap/scss/_dropdown.scss',
'./node_modules/katex/dist/katex.css',
]),
],
}),
],
}

View File

@ -0,0 +1 @@
canonifyURLs = false

View File

@ -0,0 +1,2 @@
canonifyURLs = false
baseurl = "https://authelia-staging.netlify.app/"

View File

@ -1,247 +0,0 @@
---
layout: default
title: File
parent: Authentication Backends
grand_parent: Configuration
nav_order: 1
---
# File
**Authelia** supports a file as a users database.
## Configuration
Configuring Authelia to use a file is done by specifying the path to the
file in the configuration file.
```yaml
authentication_backend:
disable_reset_password: false
file:
path: /config/users.yml
password:
algorithm: argon2id
iterations: 3
salt_length: 16
key_length: 32
parallelism: 4
memory: 64
```
## Format
The format of the users file is as follows.
```yaml
users:
john:
displayname: "John Doe"
password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM"
email: john.doe@authelia.com
groups:
- admins
- dev
harry:
displayname: "Harry Potter"
password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM"
email: harry.potter@authelia.com
groups: []
bob:
displayname: "Bob Dylan"
password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM"
email: bob.dylan@authelia.com
groups:
- dev
james:
displayname: "James Dean"
password: "$argon2id$v=19$m=65536,t=3,p=2$BpLnfgDsc2WD8F2q$o/vzA4myCqZZ36bUGsDY//8mKUYNZZaR0t4MFFSs+iM"
email: james.dean@authelia.com
```
This file should be set with read/write permissions as it could be updated by users
resetting their passwords.
## Options
### path
<div markdown="1">
type: string (path)
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
### password
#### algorithm
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: argon2id
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Controls the hashing algorithm used for hashing new passwords. Value must be one of `argon2id` or `sha512`.
#### iterations
<div markdown="1">
type: integer
{: .label .label-config .label-purple }
required: no
{: .label .label-config .label-green }
</div>
Controls the number of hashing iterations done by the other hashing settings.
When using `argon2id` the minimum is 3, which is also the recommended and default value.
When using `sha512` the minimum is 1000, and 50000 is the recommended and default value.
#### salt_length
<div markdown="1">
type: integer
{: .label .label-config .label-purple }
default: 16
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Controls the length of the random salt added to each password before hashing. It's recommended this value is set to 16,
and there is no documented reason why you'd set it to anything other than this, however the minimum is 8.
#### parallelism
<div markdown="1">
type: integer
{: .label .label-config .label-purple }
default: 4
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
This setting is specific to `argon2id` and unused with `sha512`. Sets the number of threads used when hashing passwords,
which affects the effective cost of hashing.
#### memory
<div markdown="1">
type: integer
{: .label .label-config .label-purple }
default: 64
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
This setting is specific to `argon2id` and unused with `sha512`. Sets the amount of memory allocated to a single
password hashing action. This memory is released by go after the hashing process completes, however the operating system
may not reclaim it until it needs the memory which may make Authelia appear to be using more memory than it technically
is.
## Passwords
The file contains hashed passwords instead of plain text passwords for security reasons.
You can use Authelia binary or docker image to generate the hash of any password. The
hash-password command has many tunable options, you can view them with the
`authelia hash-password --help` command. For example if you wanted to improve the entropy
you could generate a 16 byte salt and provide it with the `--salt` flag.
Example: `authelia hash-password --salt abcdefghijklhijl -- 'yourpassword'`. For argon2id the salt must
always be valid for base64 decoding (characters a through z, A through Z, 0 through 9, and +/).
Passwords passed to `hash-password` should be single quoted if using special characters to prevent parameter substitution.
For instance to generate a hash with the docker image just run:
$ docker run authelia/authelia:latest authelia hash-password -- 'yourpassword'
Password hash: $argon2id$v=19$m=65536$3oc26byQuSkQqksq$zM1QiTvVPrMfV6BVLs2t4gM+af5IN7euO0VB6+Q8ZFs
You may also use the `--config` flag to point to your existing configuration. When used, the values defined in the config will be used instead.
Full CLI Help Documentation:
```
Hash a password to be used in file-based users database. Default algorithm is argon2id.
Usage:
authelia hash-password [flags] -- <password>
Flags:
-c, --config strings Configuration files
-h, --help help for hash-password
-i, --iterations int set the number of hashing iterations (default 3)
-k, --key-length int [argon2id] set the key length param (default 32)
-m, --memory int [argon2id] set the amount of memory param (in MB) (default 64)
-p, --parallelism int [argon2id] set the parallelism param (default 4)
-s, --salt string set the salt string
-l, --salt-length int set the auto-generated salt length (default 16)
-z, --sha512 use sha512 as the algorithm (changes iterations to 50000, change with -i)
```
### Password hash algorithm
The default hash algorithm is Argon2id version 19 with a salt. Argon2id is currently considered
the best hashing algorithm, and in 2015 won the
[Password Hashing Competition](https://en.wikipedia.org/wiki/Password_Hashing_Competition).
It benefits from customizable parameters allowing the cost of computing a hash to scale
into the future which makes it harder to brute-force. Argon2id was implemented due to community
feedback as you can see in this closed [issue](https://github.com/authelia/authelia/issues/577).
For backwards compatibility and user choice support for the SHA512 algorithm is still available.
While it's a reasonable hashing function given high enough iterations, as hardware improves it
has a higher chance of being brute-forced.
Hashes are identifiable as argon2id or SHA512 by their prefix of either `$argon2id$` and `$6$`
respectively, as described in this [wiki page](https://en.wikipedia.org/wiki/Crypt_(C)).
**Important Note:** When using argon2id Authelia will appear to remain using the memory allocated
to creating the hash. This is due to how [Go](https://golang.org/) allocates memory to the heap when
generating an argon2id hash. Go periodically garbage collects the heap, however this doesn't remove
the memory allocation, it keeps it allocated even though it's technically unused. Under memory
pressure the unused allocated memory will be reclaimed by the operating system, you can test
this on linux with:
$ stress-ng --vm-bytes $(awk '/MemFree/{printf "%d\n", $2 * 0.9;}' < /proc/meminfo)k --vm-keep -m 1
If this is not desirable we recommend investigating the following options in order of most to least secure:
1. using the [LDAP authentication provider](./ldap.md)
2. adjusting the [memory](#memory) parameter
3. changing the [algorithm](#algorithm)
### Password hash algorithm tuning
All algorithm tuning for Argon2id is supported. The only configuration variables that affect
SHA512 are iterations and salt length. The configuration variables are unique to the file
authentication provider, thus they all exist in a key under the file authentication configuration
key called `password`. We have set what are considered as sane and recommended defaults
to cater for a reasonable system, if you're unsure about which settings to tune, please see the
parameters below, or for a more in depth understanding see the referenced documentation in
[Argon2 links](./file.md#argon2-links).
#### Recommended Parameters: Argon2id
This table is adapted from [RFC9106 Parameter Choice]:
| Situation | Iterations (t) | Parallelism (p) | Memory (m) | Salt Size | Key Size |
|:-----------:|:--------------:|:---------------:|:----------:|:---------:|:--------:|
| Low Memory | 3 | 4 | 64 | 16 | 32 |
| Recommended | 1 | 4 | 2048 | 16 | 32 |
## Argon2 Links
- [Go Documentation](https://godoc.org/golang.org/x/crypto/argon2)
- Argon2 Specification [RFC9106]
- [OWASP Password Storage Cheatsheet]
[RFC9106]: https://www.rfc-editor.org/rfc/rfc9106.html
[RFC9106 Parameter Choice]: https://www.rfc-editor.org/rfc/rfc9106.html#section-4
[OWASP Password Storage Cheatsheet]: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html

View File

@ -1,62 +0,0 @@
---
layout: default
title: Authentication Backends
parent: Configuration
nav_order: 2
has_children: true
---
# Authentication Backends
There are two ways to store the users along with their password:
* LDAP: users are stored in remote servers like OpenLDAP, OpenAM or Microsoft Active Directory.
* File: users are stored in YAML file with a hashed version of their password.
## Configuration
```yaml
authentication_backend:
disable_reset_password: false
password_reset:
custom_url: ""
file: {}
ldap: {}
```
## Options
### disable_reset_password
<div markdown="1">
type: boolean
{: .label .label-config .label-purple }
default: false
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
This setting controls if users can reset their password from the web frontend or not.
### password_reset
#### custom_url
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: ""
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
The custom password reset URL. This replaces the inbuilt password reset functionality and disables the endpoints if
this is configured to anything other than nothing or an empty string.
### file
The [file](file.md) authentication provider.
### ldap
The [LDAP](ldap.md) authentication provider.

View File

@ -1,336 +0,0 @@
---
layout: default
title: LDAP
parent: Authentication Backends
grand_parent: Configuration
nav_order: 2
---
# LDAP
**Authelia** supports using a LDAP server as the users database.
## Configuration
```yaml
authentication_backend:
disable_reset_password: false
refresh_interval: 5m
ldap:
implementation: custom
url: ldap://127.0.0.1
timeout: 5s
start_tls: false
tls:
server_name: ldap.example.com
skip_verify: false
minimum_version: TLS1.2
base_dn: DC=example,DC=com
username_attribute: uid
additional_users_dn: ou=users
users_filter: (&({username_attribute}={input})(objectClass=person))
additional_groups_dn: ou=groups
groups_filter: (&(member={dn})(objectClass=groupOfNames))
group_name_attribute: cn
mail_attribute: mail
display_name_attribute: displayName
permit_referrals: false
user: CN=admin,DC=example,DC=com
password: password
```
## Options
### implementation
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: custom
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Configures the LDAP implementation used by Authelia.
See the [Implementation Guide](#implementation-guide) for information.
### url
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
The LDAP URL which consists of a scheme, address, and port. Format is `<scheme>://<address>:<port>` or
`<scheme>://<address>` where scheme is either `ldap` or `ldaps`.
If utilising an IPv6 literal address it must be enclosed by square brackets:
```yaml
url: ldap://[fd00:1111:2222:3333::1]
```
### timeout
<div markdown="1">
type: duration
{: .label .label-config .label-purple }
default: 5s
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
The timeout for dialing an LDAP connection.
### start_tls
<div markdown="1">
type: boolean
{: .label .label-config .label-purple }
default: false
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Enables use of the LDAP StartTLS process which is not commonly used. You should only configure this if you know you need
it. The initial connection will be over plain text, and Authelia will try to upgrade it with the LDAP server. LDAPS
URL's are slightly more secure.
### tls
Controls the TLS connection validation process. You can see how to configure the tls
section [here](../index.md#tls-configuration).
### base_dn
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
Sets the base distinguished name container for all LDAP queries. If your LDAP domain is example.com this is usually
`dc=example,dc=com`, however you can fine tune this to be more specific for example to only include objects inside the
authelia OU: `ou=authelia,dc=example,dc=com`. This is prefixed with the [additional_users_dn](#additional_users_dn) for
user searches and [additional_groups_dn](#additional_groups_dn) for groups searches.
### username_attribute
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
_**Note:** While this option is required, an [implementation](#implementation) may set a default value implicitly
negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information._
The LDAP attribute that maps to the username in Authelia.
### additional_users_dn
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: no
{: .label .label-config .label-green }
</div>
Additional LDAP path to append to the [base_dn](#base_dn) when searching for users. Useful if you want to restrict
exactly which OU to get users from for either security or performance reasons. For example setting it to
`ou=users,ou=people` with a base_dn set to `dc=example,dc=com` will mean user searches will occur in
`ou=users,ou=people,dc=example,dc=com`. The default value is dependent on the [implementation](#implementation), refer
to the [attribute defaults](#attribute-defaults) for more information.
### users_filter
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
_**Note:** While this option is required, an [implementation](#implementation) may set a default value implicitly
negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information._
The LDAP filter to narrow down which users are valid. This is important to set correctly as to exclude disabled users.
### group_name_attribute
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
_**Note:** While this option is required, an [implementation](#implementation) may set a default value implicitly
negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information._
The LDAP attribute that is used by Authelia to determine the group name.
### additional_groups_dn
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: no
{: .label .label-config .label-green }
</div>
Similar to [additional_users_dn](#additional_users_dn) but it applies to group searches.
### groups_filter
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
_**Note:** While this option is required, an [implementation](#implementation) may set a default value implicitly
negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information._
Similar to [users_filter](#users_filter) but it applies to group searches. In order to include groups the member is not
a direct member of, but is a member of another group that is a member of those (i.e. recursive groups), you may try
using the following filter which is currently only tested against Microsoft Active Directory:
`(&(member:1.2.840.113556.1.4.1941:={dn})(objectClass=group)(objectCategory=group))`
### mail_attribute
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
_**Note:** While this option is required, an [implementation](#implementation) may set a default value implicitly
negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information._
The attribute to retrieve which contains the users email addresses. This is important for the device registration and
password reset processes.
The user must have an email address in order for Authelia to perform identity verification when a user attempts to reset
their password or register a second factor device.
### display_name_attribute
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
_**Note:** While this option is required, an [implementation](#implementation) may set a default value implicitly
negating this requirement. Refer to the [attribute defaults](#attribute-defaults) for more information._
The attribute to retrieve which is shown on the Web UI to the user when they log in.
### permit_referrals
<div markdown="1">
type: boolean
{: .label .label-config .label-purple }
default: false
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-red }
</div>
Permits following referrals. This is useful if you have read-only servers in your architecture and thus require
referrals to be followed when performing write operations. This is only implemented for password modifications, if you
need this for searches please open a GitHub issue or contact us.
### user
The distinguished name of the user paired with the password to bind with for lookup and password change operations.
### password
The password of the user paired with the user to bind with for lookup and password change operations.
Can also be defined using a [secret](../secrets.md) which is the recommended for containerized deployments.
## Implementation Guide
There are currently two implementations, `custom` and `activedirectory`. The `activedirectory` implementation
must be used if you wish to allow users to change or reset their password as Active Directory
uses a custom attribute for this, and an input format other implementations do not use. The long term
intention of this is to have logical defaults for various RFC implementations of LDAP.
### Filter replacements
Various replacements occur in the user and groups filter. The replacements either occur at startup or upon an LDAP
search.
#### Users filter replacements
| Placeholder | Phase | Replacement |
|:------------------------:|:-------:|:-------------------------------------:|
| {username_attribute} | startup | The configured username attribute |
| {mail_attribute} | startup | The configured mail attribute |
| {display_name_attribute} | startup | The configured display name attribute |
| {input} | search | The input into the username field |
#### Groups filter replacements
| Placeholder | Phase | Replacement |
|:-----------:|:------:|:-------------------------------------------------------------------------:|
| {input} | search | The input into the username field |
| {username} | search | The username from the profile lookup obtained from the username attribute |
| {dn} | search | The distinguished name from the profile lookup |
### Defaults
The below tables describes the current attribute defaults for each implementation.
#### Attribute defaults
This table describes the attribute defaults for each implementation. i.e. the username_attribute is
described by the Username column.
| Implementation | Username | Display Name | Mail | Group Name |
|:---------------:|:--------------:|:------------:|:----:|:----------:|
| custom | n/a | displayName | mail | cn |
| activedirectory | sAMAccountName | displayName | mail | cn |
#### Filter defaults
The filters are probably the most important part to get correct when setting up LDAP.
You want to exclude disabled accounts. The active directory example has two attribute
filters that accomplish this as an example (more examples would be appreciated). The
userAccountControl filter checks that the account is not disabled and the pwdLastSet
makes sure that value is not 0 which means the password requires changing at the next login.
| Implementation | Users Filter | Groups Filter |
|:---------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------:|:---------------------------------------------------------:|
| custom | n/a | n/a |
| activedirectory | (&(&#124;({username_attribute}={input})({mail_attribute}={input}))(sAMAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(!(pwdLastSet=0))) | (&(member={dn})(objectClass=group)(objectCategory=group)) |
_**Note:**_ The Active Directory filter `(sAMAccountType=805306368)` is exactly the same as
`(&(objectCategory=person)(objectClass=user))` except that the former is more performant, you can read more about this
and other Active Directory filters on the
[TechNet wiki](https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx).
## Refresh Interval
This setting takes a [duration notation](../index.md#duration-notation-format) that sets the max frequency
for how often Authelia contacts the backend to verify the user still exists and that the groups stored
in the session are up to date. This allows us to destroy sessions when the user no longer matches the
user_filter, or deny access to resources as they are removed from groups.
In addition to the duration notation, you may provide the value `always` or `disable`. Setting to `always`
is the same as setting it to 0 which will refresh on every request, `disable` turns the feature off, which is
not recommended. This completely prevents Authelia from refreshing this information, and it would only be
refreshed when the user session gets destroyed by other means like inactivity, session expiration or logging
out and in.
This value can be any value including 0, setting it to 0 would automatically refresh the session on
every single request. This means Authelia will have to contact the LDAP backend every time an element
on a page loads which could be substantially costly. It's a trade-off between load and security that
you should adapt according to your own security policy.
## Important notes
Users must be uniquely identified by an attribute, this attribute must obviously contain a single value and
be guaranteed by the administrator to be unique. If multiple users have the same value, Authelia will simply
fail authenticating the user and display an error message in the logs.
In order to avoid such problems, we highly recommended you follow https://www.ietf.org/rfc/rfc2307.txt by using
`sAMAccountName` for Active Directory and `uid` for other implementations as the attribute holding the
unique identifier for your users.
As of versions > `4.24.0` the `users_filter` must include the `username_attribute` placeholder, not including this will
result in Authelia throwing an error.
In versions <= `4.24.0` not including the `username_attribute` placeholder will cause issues with the session refresh
and will result in session resets when the refresh interval has expired, default of 5 minutes.
[LDAP GeneralizedTime]: https://ldapwiki.com/wiki/GeneralizedTime
[username attribute]: #username_attribute
[TechNet wiki]: https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx

View File

@ -1,97 +0,0 @@
---
layout: default
title: Duo Push Notifications
parent: Configuration
nav_order: 3
---
# Duo Push Notifications
Authelia supports mobile push notifications relying on [Duo].
Follow the instructions in the dedicated [documentation](../features/2fa/push-notifications.md)
to know how to set up push notifications in Authelia.
**Note:** The configuration options in the following sections are noted as required. They are however only required when
you have this section defined. i.e. if you don't wish to use the [Duo] push notifications you can just not define this
section of the configuration.
## Configuration
The configuration is as follows:
```yaml
duo_api:
disable: false
hostname: api-123456789.example.com
integration_key: ABCDEF
secret_key: 1234567890abcdefghifjkl
enable_self_enrollment: false
```
The secret key is shown as an example, you also have the option to set it using an environment
variable as described [here](./secrets.md).
## Options
### disable:
<div markdown="1">
type: boolean
{: .label .label-config .label-purple }
default: false
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Disables Duo. If the hostname, integration_key, and secret_key are all empty strings or undefined this is automatically
true.
### hostname
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: ""
{: .label .label-config .label-blue }
required: yes
{: .label .label-config .label-red }
</div>
The [Duo] API hostname supplied by [Duo].
### integration_key
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: ""
{: .label .label-config .label-blue }
required: yes
{: .label .label-config .label-red }
</div>
The non-secret [Duo] integration key. Similar to a client identifier.
### secret_key
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: ""
{: .label .label-config .label-blue }
required: yes
{: .label .label-config .label-red }
</div>
The secret [Duo] key used to verify your application is valid.
### enable_self_enrollment
<div markdown="1">
type: boolean
{: .label .label-config .label-purple }
default: false
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Enables [Duo] device self-enrollment from within the Authelia portal.
[Duo]: https://duo.com/

View File

@ -1,12 +0,0 @@
---
layout: default
title: Identity Providers
parent: Configuration
nav_order: 4
has_children: true
---
# Identity Providers
This section covers configuration of the identity server characteristics of Authelia. Currently the only identity server
supported is OpenID Connect.

View File

@ -1,656 +0,0 @@
---
layout: default
title: OpenID Connect
parent: Identity Providers
grand_parent: Configuration
nav_order: 2
---
# OpenID Connect
**Authelia** currently supports the [OpenID Connect] OP role as a [**beta**](../../roadmap/oidc.md) feature. The OP role
is the [OpenID Connect] Provider role, not the Relying Party or RP role. This means other applications that implement the
[OpenID Connect] RP role can use Authelia as an authentication and authorization backend similar to how you may use
social media or development platforms for login.
The Relying Party role is the role which allows an application to use GitHub, Google, or other [OpenID Connect]
providers for authentication and authorization. We do not intend to support this functionality at this moment in time.
More information about the beta can be found in the [roadmap](../../roadmap/oidc.md).
## Configuration
The following snippet provides a sample-configuration for the OIDC identity provider explaining each field in detail.
```yaml
identity_providers:
oidc:
hmac_secret: this_is_a_secret_abc123abc123abc
issuer_private_key: |
--- KEY START
--- KEY END
access_token_lifespan: 1h
authorize_code_lifespan: 1m
id_token_lifespan: 1h
refresh_token_lifespan: 90m
enable_client_debug_messages: false
enforce_pkce: public_clients_only
cors:
endpoints:
- authorization
- token
- revocation
- introspection
allowed_origins:
- https://example.com
allowed_origins_from_client_redirect_uris: false
clients:
- id: myapp
description: My Application
secret: this_is_a_secret
sector_identifier: ''
public: false
authorization_policy: two_factor
pre_configured_consent_duration: ''
audience: []
scopes:
- openid
- groups
- email
- profile
redirect_uris:
- https://oidc.example.com:8080/oauth2/callback
grant_types:
- refresh_token
- authorization_code
response_types:
- code
response_modes:
- form_post
- query
- fragment
userinfo_signing_algorithm: none
```
## Options
### hmac_secret
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
The HMAC secret used to sign the [OpenID Connect] JWT's. The provided string is hashed to a SHA256
byte string for the purpose of meeting the required format. You must [generate this option yourself](#generating-a-random-secret).
Should be defined using a [secret](../secrets.md) which is the recommended for containerized deployments.
### issuer_private_key
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
The private key in DER base64 encoded PEM format used to encrypt the [OpenID Connect] JWT's.[¹](../../faq.md#why-only-use-a-private-issuer-key-and-no-public-key-with-oidc)
You must [generate this option yourself](#generating-a-random-secret). To create this option, use
`docker run -u "$(id -u):$(id -g)" -v "$(pwd)":/keys authelia/authelia:latest authelia rsa generate --dir /keys`
to generate both the private and public key in the current directory. You can then paste the
private key into your configuration.
Should be defined using a [secret](../secrets.md) which is the recommended for containerized deployments.
### access_token_lifespan
<div markdown="1">
type: duration
{: .label .label-config .label-purple }
default: 1h
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
The maximum lifetime of an access token. It's generally recommended keeping this short similar to the default.
For more information read these docs about [token lifespan].
### authorize_code_lifespan
<div markdown="1">
type: duration
{: .label .label-config .label-purple }
default: 1m
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
The maximum lifetime of an authorize code. This can be rather short, as the authorize code should only be needed to
obtain the other token types. For more information read these docs about [token lifespan].
### id_token_lifespan
<div markdown="1">
type: duration
{: .label .label-config .label-purple }
default: 1h
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
The maximum lifetime of an ID token. For more information read these docs about [token lifespan].
### refresh_token_lifespan
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: 90m
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
The maximum lifetime of a refresh token. The
refresh token can be used to obtain new refresh tokens as well as access tokens or id tokens with an
up-to-date expiration. For more information read these docs about [token lifespan].
A good starting point is 50% more or 30 minutes more (which ever is less) time than the highest lifespan out of the
[access token lifespan](#access_token_lifespan), the [authorize code lifespan](#authorize_code_lifespan), and the
[id token lifespan](#id_token_lifespan). For instance the default for all of these is 60 minutes, so the default refresh
token lifespan is 90 minutes.
### enable_client_debug_messages
<div markdown="1">
type: boolean
{: .label .label-config .label-purple }
default: false
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Allows additional debug messages to be sent to the clients.
### minimum_parameter_entropy
<div markdown="1">
type: integer
{: .label .label-config .label-purple }
default: 8
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
This controls the minimum length of the `nonce` and `state` parameters.
***Security Notice:*** Changing this value is generally discouraged, reducing it from the default can theoretically
make certain scenarios less secure. It is highly encouraged that if your OpenID Connect RP does not send these parameters
or sends parameters with a lower length than the default that they implement a change rather than changing this value.
### enforce_pkce
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: public_clients_only
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
[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 Authorization Code flow.
When set to `always`, PKCE will be required for all clients using the Authorization Code flow.
***Security Notice:*** Changing this value to `never` is generally discouraged, reducing it from the default can theoretically
make certain client-side applications (mobile applications, SPA) vulnerable to CSRF and authorization code interception attacks.
### enable_pkce_plain_challenge
<div markdown="1">
type: boolean
{: .label .label-config .label-purple }
default: false
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Allows PKCE `plain` challenges when set to `true`.
***Security Notice:*** Changing this value is generally discouraged. Applications should use the `S256` PKCE challenge method instead.
### cors
Some OpenID Connect Endpoints need to allow cross-origin resource sharing, however some are optional. This section allows
you to configure the optional parts. We reply with CORS headers when the request includes the Origin header.
#### endpoints
<div markdown="1">
type: list(string)
{: .label .label-config .label-purple }
default: empty
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
A list of endpoints to configure with cross-origin resource sharing headers. It is recommended that the `userinfo`
option is at least in this list. The potential endpoints which this can be enabled on are as follows:
* authorization
* token
* revocation
* introspection
* userinfo
#### allowed_origins
<div markdown="1">
type: list(string)
{: .label .label-config .label-purple }
default: empty
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
A list of permitted origins.
Any origin with https is permitted unless this option is configured or the allowed_origins_from_client_redirect_uris
option is enabled. This means you must configure this option manually if you want http endpoints to be permitted to
make cross-origin requests to the OpenID Connect endpoints, however this is not recommended.
Origins must only have the scheme, hostname and port, they may not have a trailing slash or path.
In addition to an Origin URI, you may specify the wildcard origin in the allowed_origins. It MUST be specified by itself
and the allowed_origins_from_client_redirect_uris MUST NOT be enabled. The wildcard origin is denoted as `*`. Examples:
```yaml
identity_providers:
oidc:
cors:
allowed_origins: "*"
```
```yaml
identity_providers:
oidc:
cors:
allowed_origins:
- "*"
```
#### allowed_origins_from_client_redirect_uris
<div markdown="1">
type: boolean
{: .label .label-config .label-purple }
default: false
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Automatically adds the origin portion of all redirect URI's on all clients to the list of allowed_origins, provided they
have the scheme http or https and do not have the hostname of localhost.
### clients
A list of clients to configure. The options for each client are described below.
#### id
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
The Client ID for this client. It must exactly match the Client ID configured in the application
consuming this client.
#### description
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: *same as id*
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
A friendly description for this client shown in the UI. This defaults to the same as the ID.
#### secret
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: situational
{: .label .label-config .label-yellow }
</div>
The shared secret between Authelia and the application consuming this client. This secret must
match the secret configured in the application. Currently this is stored in plain text.
You must [generate this option yourself](#generating-a-random-secret).
This must be provided when the client is a confidential client type, and must be blank when using the public client
type. To set the client type to public see the [public](#public) configuration option.
#### sector_identifier
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: ''
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-red }
</div>
_**Important Note:** because adjusting this option will inevitably change the `sub` claim of all tokens generated for
the specified client, changing this should cause the relying party to detect all future authorizations as completely new
users._
Must be an empty string or the host component of a URL. This is commonly just the domain name, but may also include a
port.
Authelia utilizes UUID version 4 subject identifiers. By default the public subject identifier type is utilized for all
clients. This means the subject identifiers will be the same for all clients. This configuration option enables pairwise
for this client, and configures the sector identifier utilized for both the storage and the lookup of the subject
identifier.
1. All clients who do not have this configured will generate the same subject identifier for a particular user regardless
of which client obtains the ID token.
2. All clients which have the same sector identifier will:
1. have the same subject identifier for a particular user when compared to clients with the same sector identifier.
2. have a completely different subject identifier for a particular user whe compared to:
1. any client with the public subject identifier type.
2. any client with a differing sector identifier.
In specific but limited scenarios this option is beneficial for privacy reasons. In particular this is useful when the
party utilizing the _Authelia_ [OpenID Connect] Authorization Server is foreign and not controlled by the user. It would
prevent the third party utilizing the subject identifier with another third party in order to track the user.
Keep in mind depending on the other claims they may still be able to perform this tracking and it is not a silver bullet.
There are very few benefits when utilizing this in a homelab or business where no third party is utilizing
the server.
#### public
<div markdown="1">
type: bool
{: .label .label-config .label-purple }
default: false
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
This enables the public client type for this client. This is for clients that are not capable of maintaining
confidentiality of credentials, you can read more about client types in [RFC6749](https://datatracker.ietf.org/doc/html/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.
#### authorization_policy
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: two_factor
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
The authorization policy for this client: either `one_factor` or `two_factor`.
#### pre_configured_consent_duration
<div markdown="1">
type: string (duration)
{: .label .label-config .label-purple }
required: no
{: .label .label-config .label-green }
</div>
Configuring this enables users of this client to remember their consent as a pre-configured consent. The value is period
of time is in [duration notation format](../index.md#duration-notation-format). The period of time dictates how long a
users choice to remember the pre-configured consent lasts.
Pre-configured consents are only valid if the subject, client id are exactly the same and the requested scopes/audience
match exactly with the granted scopes/audience.
#### audience
<div markdown="1">
type: list(string)
{: .label .label-config .label-purple }
required: no
{: .label .label-config .label-green }
</div>
A list of audiences this client is allowed to request.
#### scopes
<div markdown="1">
type: list(string)
{: .label .label-config .label-purple }
default: openid, groups, profile, email
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
A list of scopes to allow this client to consume. See [scope definitions](#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.
#### redirect_uris
<div markdown="1">
type: list(string)
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
A list of valid callback URIs this client will redirect to. All other callbacks will be considered
unsafe. The URIs are case-sensitive and they differ from application to application - the community has
provided [a list of URL´s for common applications](../../community/oidc-integrations.md).
Some restrictions that have been placed on clients and
their redirect URIs are as follows:
1. If a client attempts to authorize with Authelia and its redirect URI is not listed in the client configuration the
attempt to authorize wil 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.
#### grant_types
<div markdown="1">
type: list(string)
{: .label .label-config .label-purple }
default: refresh_token, authorization_code
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
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`.
#### response_types
<div markdown="1">
type: list(string)
{: .label .label-config .label-purple }
default: code
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
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`.
#### response_modes
<div markdown="1">
type: list(string)
{: .label .label-config .label-purple }
default: form_post, query, fragment
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
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`.
#### userinfo_signing_algorithm
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: none
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
The algorithm used to sign the userinfo endpoint responses. This can either be `none` or `RS256`.
## Generating a random secret
If you must provide a random secret in configuration, you can generate a random string of sufficient length. The command
```sh
LENGTH=64
tr -cd '[:alnum:]' < /dev/urandom | fold -w "${LENGTH}" | head -n 1 | tr -d '\n' ; echo
```
prints such a string with a length in characters of `${LENGTH}` on `stdout`. The string will only contain alphanumeric
characters. For Kubernetes, see [this section too](../secrets.md#Kubernetes).
## Scope Definitions
### openid
This is the default scope for openid. This field is forced on every client by the configuration validation that Authelia
does.
_**Important Note:** The subject identifiers or `sub` claim has been changed to a [RFC4122] UUID V4 to identify the
individual user as per the [Subject Identifier Types] specification. Please use the claim `preferred_username` instead._
| Claim | JWT Type | Authelia Attribute | Description |
|:---------:|:-------------:|:------------------:|:-----------------------------------------------------------:|
| sub | string | username | A [RFC4122] UUID V4 linked to the user who logged in |
| scope | string | scopes | Granted scopes (space delimited) |
| scp | array[string] | scopes | Granted scopes |
| iss | string | hostname | The issuer name, determined by URL |
| at_hash | string | _N/A_ | Access Token Hash |
| aud | array[string] | _N/A_ | Audience |
| exp | number | _N/A_ | Expires |
| auth_time | number | _N/A_ | The time the user authenticated with Authelia |
| rat | number | _N/A_ | The time when the token was requested |
| iat | number | _N/A_ | The time when the token was issued |
| jti | string(uuid) | _N/A_ | A JWT Identifier in the form of a [RFC4122] UUID V4 |
| amr | array[string] | _N/A_ | An [RFC8176] list of authentication method reference values |
| azp | string | id (client) | The authorized party |
| client_id | string | id (client) | The client id |
### groups
This scope includes the groups the authentication backend reports the user is a member of in the token.
| Claim | JWT Type | Authelia Attribute | Description |
|:------:|:-------------:|:------------------:|:------------------------------------------------------------------------------------------------------------------:|
| groups | array[string] | groups | List of user's groups discovered via [authentication](https://www.authelia.com/docs/configuration/authentication/) |
### email
This scope includes the email information the authentication backend reports about the user in the token.
| Claim | JWT Type | Authelia Attribute | Description |
|:--------------:|:-------------:|:------------------:|:---------------------------------------------------------:|
| email | string | email[0] | The first email address in the list of emails |
| email_verified | bool | _N/A_ | If the email is verified, assumed true for the time being |
| alt_emails | array[string] | email[1:] | All email addresses that are not in the email JWT field |
### profile
This scope includes the profile information the authentication backend reports about the user in the token.
| Claim | JWT Type | Authelia Attribute | Description |
|:------------------:|:--------:|:------------------:|:----------------------------------------:|
| preferred_username | string | username | The username the user used to login with |
| name | string | display_name | The users display name |
## Authentication Method References
Authelia currently supports adding the `amr` claim to the [ID Token](https://openid.net/specs/openid-connect-core-1_0.html#IDToken)
utilizing the [RFC8176] Authentication Method Reference values.
The values this claim has are not strictly defined by the [OpenID Connect] specification. As such, some backends may
expect a specification other than [RFC8176] for this purpose. If you have such an application and wish for us to support
it then you're encouraged to create an issue.
Below is a list of the potential values we place in the claim and their meaning:
| Value | Description | Factor | Channel |
|:-----:|:----------------------------------------------------------------:|:------:|:--------:|
| mfa | User used multiple factors to login (see factor column) | N/A | N/A |
| mca | User used multiple channels to login (see channel column) | N/A | N/A |
| user | User confirmed they were present when using their hardware key | N/A | N/A |
| pin | User confirmed they are the owner of the hardware key with a pin | N/A | N/A |
| pwd | User used a username and password to login | Know | Browser |
| otp | User used TOTP to login | Have | Browser |
| hwk | User used a hardware key to login | Have | Browser |
| sms | User used Duo to login | Have | External |
## Endpoint Implementations
The following section documents the endpoints we implement and their respective paths. This information can traditionally
be discovered by relying parties that utilize [discovery](https://openid.net/specs/openid-connect-discovery-1_0.html),
however this information may be useful for clients which do not implement this.
The endpoints can be discovered easily by visiting the Discovery and Metadata endpoints. It is recommended regardless
of your version of Authelia that you utilize this version as it will always produce the correct endpoint URLs. The paths
for the Discovery/Metadata endpoints are part of IANA's well known registration but are also documented in a table below.
These tables document the endpoints we currently support and their paths in the most recent version of Authelia. The paths
are appended to the end of the primary URL used to access Authelia. The tables use the url https://auth.example.com as
an example of the Authelia root URL which is also the OpenID Connect issuer.
### Well Known Discovery Endpoints
These endpoints can be utilized to discover other endpoints and metadata about the Authelia OP.
| Endpoint | Path |
|:-----------------------------------------:|:---------------------------------------------------------------:|
| [OpenID Connect Discovery] | https://auth.example.com/.well-known/openid-configuration |
| [OAuth 2.0 Authorization Server Metadata] | https://auth.example.com/.well-known/oauth-authorization-server |
### Discoverable Endpoints
These endpoints implement OpenID Connect elements.
| Endpoint | Path | Discovery Attribute |
|:-------------------:|:-----------------------------------------------:|:----------------------:|
| [JSON Web Key Sets] | https://auth.example.com/jwks.json | jwks_uri |
| [Authorization] | https://auth.example.com/api/oidc/authorization | authorization_endpoint |
| [Token] | https://auth.example.com/api/oidc/token | token_endpoint |
| [Userinfo] | https://auth.example.com/api/oidc/userinfo | userinfo_endpoint |
| [Introspection] | https://auth.example.com/api/oidc/introspection | introspection_endpoint |
| [Revocation] | https://auth.example.com/api/oidc/revocation | revocation_endpoint |
[JSON Web Key Sets]: https://datatracker.ietf.org/doc/html/rfc7517#section-5
[OpenID Connect]: https://openid.net/connect/
[Subject Identifier Types]:https://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
[OpenID Connect Discovery]: https://openid.net/specs/openid-connect-discovery-1_0.html
[OAuth 2.0 Authorization Server Metadata]: https://datatracker.ietf.org/doc/html/rfc8414
[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://datatracker.ietf.org/doc/html/rfc7662
[Revocation]: https://datatracker.ietf.org/doc/html/rfc7009
[RFC8176]: https://datatracker.ietf.org/doc/html/rfc8176
[RFC4122]: https://datatracker.ietf.org/doc/html/rfc4122
[token lifespan]: https://docs.apigee.com/api-platform/antipatterns/oauth-long-expiration

View File

@ -1,209 +0,0 @@
---
layout: default
title: Configuration
nav_order: 4
has_children: true
---
# Configuration
Authelia has several methods of configuration available to it. The order of precedence is as follows:
1. [Secrets](./secrets.md)
2. [Environment Variables](#environment)
3. [Files](#files) (in order of them being specified)
This order of precedence puts higher weight on things higher in the list. This means anything specified in the
[files](#files) is overridden by [environment variables](#environment) if specified, and anything specified by
[environment variables](#environment) is overridden by [secrets](./secrets.md) if specified.
## Files
When running **Authelia**, you can specify your configuration by passing the file path as shown below.
```console
$ authelia --config config.custom.yml
```
You can have multiple configuration files which will be merged in the order specified. If duplicate keys are specified
the last one to be specified is the one that takes precedence. Example:
```console
$ authelia --config configuration.yml --config config-acl.yml --config config-other.yml
$ authelia --config configuration.yml,config-acl.yml,config-other.yml
```
Authelia's configuration files use the YAML format. A template with all possible options can be found at the root of the
repository [here](https://github.com/authelia/authelia/blob/master/config.template.yml).
### Docker
By default, the container looks for a configuration file at `/config/configuration.yml`. This can be changed using the `command` setting.
## Environment
You may also provide the configuration by using environment variables. Environment variables are applied after the
configuration file meaning anything specified as part of the environment overrides the configuration files. The
environment variables must be prefixed with `AUTHELIA_`.
_**Please Note:** It is not possible to configure_ the _access control rules section or OpenID Connect identity provider
section using environment variables at this time._
_**Please Note:** There are compatability issues with Kubernetes and this particular configuration option. You must
ensure you have the `enableServiceLinks: false` setting in your pod spec. You can read more about this in the
[migration documentation](./migration.md#kubernetes-4300)._
Underscores replace indented configuration sections or subkeys. For example the following environment variables replace
the configuration snippet that follows it:
```
AUTHELIA_LOG_LEVEL=info
AUTHELIA_SERVER_READ_BUFFER_SIZE=4096
```
```yaml
log:
level: info
server:
read_buffer_size: 4096
```
# Documentation
We document the configuration in two ways:
1. The configuration yaml default has comments documenting it. All documentation lines start with `##`. Lines starting
with a single `#` are yaml configuration options which are commented to disable them or as examples.
2. This documentation site. Generally each section of the configuration is in its own section of the documentation
site. Each configuration option is listed in its relevant section as a heading, under that heading generally are two
or three colored labels.
- The `type` label is purple and indicates the yaml value type of the variable. It optionally includes some
additional information in parentheses.
- The `default` label is blue and indicates the default value if you don't define the option at all. This is not the
same value as you will see in the examples in all instances, it is the value set when blank or undefined.
- The `required` label changes color. When required it will be red, when not required it will be green, when the
required state depends on another configuration value it is yellow.
# Validation
Authelia validates the configuration when it starts. This process checks multiple factors including configuration keys
that don't exist, configuration keys that have changed, the values of the keys are valid, and that a configuration
key isn't supplied at the same time as a secret for the same configuration option.
You may also optionally validate your configuration against this validation process manually by using the validate-config
option with the Authelia binary as shown below. Keep in mind if you're using [secrets](./secrets.md) you will have to
manually provide these if you don't want to get certain validation errors (specifically requesting you provide one of
the secret values). You can choose to ignore them if you know what you're doing. This command is useful prior to
upgrading to prevent configuration changes from impacting downtime in an upgrade. This process does not validate
integrations, it only checks that your configuration syntax is valid.
```console
$ authelia validate-config --config configuration.yml
```
# Regex
We have several sections of configuration that utilize regular expressions. It's recommended to validate your regex
manually either via tools like [Rego](https://regoio.herokuapp.com/) or some other means.
It's important when attempting to utilize a backslash that it's utilized correctly. The YAML parser is likely to parse
this as you trying to use YAML escape syntax instead of regex escape syntax. To avoid this use single quotes instead of
no quotes or double quotes.
Good Example:
```yaml
domain_regex: '^(admin|secure)\.example\.com$'
```
Bad Example:
```yaml
domain_regex: "^(admin|secure)\.example\.com$"
```
# Duration Notation Format
We have implemented a string/integer based notation for configuration options that take a duration of time. This section
describes the implementation of this. You can use this implementation in various areas of configuration such as:
- session:
- expiration
- inactivity
- remember_me_duration
- regulation:
- ban_time
- find_time
- ntp:
- max_desync
- webauthn:
- timeout
The way this format works is you can either configure an integer or a string in the specific configuration areas. If you
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`.
While you can use multiple of these blocks in combination, ee suggest keeping it simple and use a single value.
## Duration Notation Format Unit Legend
| Unit | Associated Letter |
|:-------:|:-----------------:|
| Years | y |
| Months | M |
| Weeks | w |
| Days | d |
| Hours | h |
| Minutes | m |
| Seconds | s |
## Duration Notation Format Examples
| Desired Value | Configuration Examples |
|:---------------------:|:-------------------------------------:|
| 1 hour and 30 minutes | `90m` or `1h30m` or `5400` or `5400s` |
| 1 day | `1d` or `24h` or `86400` or `86400s` |
| 10 hours | `10h` or `600m` or `9h60m` or `36000` |
# TLS Configuration
Various sections of the configuration use a uniform configuration section called TLS. Notably LDAP and SMTP.
This section documents the usage.
## Server Name
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: ""
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
The key `server_name` overrides the name checked against the certificate in the verification process. Useful if you
require to use a direct IP address for the address of the backend service but want to verify a specific SNI.
## Skip Verify
<div markdown="1">
type: boolean
{: .label .label-config .label-purple }
default: false
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
The key `skip_verify` completely negates validating the certificate of the backend service. This is not recommended,
instead you should tweak the `server_name` option, and the global option [certificates directory](./miscellaneous.md#certificates_directory).
## Minimum Version
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: TLS1.2
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
The key `minimum_version` controls the minimum TLS version Authelia will use when opening TLS connections.
The possible values are `TLS1.3`, `TLS1.2`, `TLS1.1`, `TLS1.0`. Anything other than `TLS1.3` or `TLS1.2`
are very old and deprecated. You should avoid using these and upgrade your backend service instead of decreasing
this value.

View File

@ -1,95 +0,0 @@
---
layout: default
title: Migration
parent: Configuration
nav_order: 6
---
This section documents changes in the configuration which may require manual migration by the administrator. Typically
this only occurs when a configuration key is renamed or moved to a more appropriate location.
## Format
The migrations are formatted in a table with the old key and the new key. Periods indicate a different section which can
be represented in YAML as a dictionary i.e. it's indented.
In our table `server.host` with a value of `0.0.0.0` is represented in YAML like this:
```yaml
server:
host: 0.0.0.0
```
## Policy
Our deprecation policy for configuration keys is 3 minor versions. For example if a configuration option is deprecated
in version 4.30.0, it will remain as a warning for 4.30.x, 4.31.x, and 4.32.x; then it will become a fatal error in
4.33.0+.
## Migrations
### 4.33.0
The options deprecated in version [4.30.0](#4300) have been fully removed as per our deprecation policy and warnings
logged for users.
### 4.30.0
The following changes occurred in 4.30.0:
| Previous Key | New Key |
|:-------------:|:----------------------:|
| host | server.host |
| port | server.port |
| tls_key | server.tls.key |
| tls_cert | server.tls.certificate |
| log_level | log.level |
| log_file_path | log.file_path |
| log_format | log.format |
_**Please Note:** you can no longer define secrets for providers that you are not using. For example if you're using the
[filesystem notifier](./notifier/filesystem.md) you must ensure that the `AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE`
environment variable or other environment variables set. This also applies to other providers like
[storage](./storage/index.md) and [authentication backend](./authentication/index.md)._
#### Kubernetes 4.30.0
_**Please Note:** if you're using Authelia with Kubernetes and are not using the provided [helm chart](https://charts.authelia.com)
you will be required to set the following option in your PodSpec. Keeping in mind this example is for a Pod, not for
a Deployment, StatefulSet, or DaemonSet; you will need to adapt the `enableServiceLinks` option to fit into the relevant
location depending on your needs._
```yaml
---
apiVersion: v1
kind: Pod
metadata:
name: authelia
spec:
enableServiceLinks: false
...
```
### 4.25.0
The following changes occurred in 4.25.0:
|Previous Key |New Key |
|:---------------------------------------------:|:---------------------------------------------:|
|authentication_backend.ldap.tls.skip_verify |authentication_backend.ldap.tls.skip_verify |
|authentication_backend.ldap.minimum_tls_version|authentication_backend.ldap.tls.minimum_version|
|notifier.smtp.disable_verify_cert |notifier.smtp.tls.skip_verify |
|notifier.smtp.trusted_cert |certificates_directory |
_**Please Note:** `certificates_directory` is not a direct replacement for the `notifier.smtp.trusted_cert`, instead
of being the path to a specific file it is a path to a directory containing certificates trusted by Authelia. This
affects other services like LDAP as well._
### 4.7.0
The following changes occurred in 4.7.0:
|Previous Key|New Key |
|:----------:|:-------:|
|logs_level |log_level|
|logs_file |log_file |
_**Please Note:** The new keys also changed in [4.30.0](#4.30.0) so you will need to update them to the new values if you
are using [4.30.0](#4.30.0) or newer instead of the new keys listed here._

View File

@ -1,33 +0,0 @@
---
layout: default
title: Filesystem
parent: Notifier
grand_parent: Configuration
nav_order: 1
---
# Filesystem
With this configuration, the message will be sent to a file. This option should only be used for testing purposes.
This method will use the plain text email template for readability purposes.
## Configuration
```yaml
notifier:
disable_startup_check: false
filesystem:
filename: /config/notification.txt
```
## Options
### filename
<div markdown="1">
type: string
{: .label .label-config .label-purple }
required: yes
{: .label .label-config .label-red }
</div>
The file to add email text to. If it doesn't exist it will be created.

View File

@ -1,97 +0,0 @@
---
layout: default
title: Notifier
parent: Configuration
nav_order: 8
has_children: true
---
# Notifier
**Authelia** sometimes needs to send messages to users in order to
verify their identity.
## Configuration
```yaml
notifier:
disable_startup_check: false
template_path: /path/to/templates/folder
filesystem: {}
smtp: {}
```
## Options
### disable_startup_check
<div markdown="1">
type: boolean
{: .label .label-config .label-purple }
default: false
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
The notifier has a startup check which validates the specified provider
configuration is correct and will be able to send emails. This can be
disabled with the `disable_startup_check` option:
### template_path
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: ""
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
This option allows the administrator to set a path where custom templates for notifications can be found. Each template
has two extensions; `.html` for HTML templates, and `.txt` for plaintext templates.
| Template | Description |
|:--------------------:|:-----------------------------------------------------------------------------------------------:|
| IdentityVerification | Template used when registering devices or resetting passwords |
| PasswordReset | Template used to send the notification to users when their password has successfully been reset |
For example, to modify the `IdentityVerification` HTML template, if your `template_path` was `/config/email_templates`,
you would create the `/config/email_templates/IdentityVerification.html` file.
_**Note:** you may configure this directory and add only add the templates you wish to override, any templates not
supplied in this folder will utilize the default templates._
In template files, you can use the following variables:
| Placeholder | Templates | Description |
|:-----------------------------------------:|:--------------------:|:---------------------------------------------------------------------------------------------------------------------------------------------:|
| `{% raw %}{{ .LinkURL }}{% endraw %}` | IdentityVerification | The URL of the used with the IdentityVerification template. |
| `{% raw %}{{ .LinkText }}{% endraw %}` | IdentityVerification | The display value for the IdentityVerification button intended for the link. |
| `{% raw %}{{ .Title }}{% endraw %}` | All | A predefined title for the email. <br> It will be `"Reset your password"` or `"Password changed successfully"`, depending on the current step |
| `{% raw %}{{ .DisplayName }}{% endraw %}` | All | The name of the user, i.e. `John Doe` |
| `{% raw %}{{ .RemoteIP }}{% endraw %}` | All | The remote IP address that initiated the request or event |
#### Examples
This is a basic example:
```html
<body>
<h1>{{ .Title }}</h1>
Hi {{ .DisplayName }}<br/>
This email has been sent to you in order to validate your identity.
Click <a href="{{ .LinkURL }}">here</a> to change your password.
</body>
```
Some Additional examples for specific purposes can be found in the
[examples directory on GitHub](https://github.com/authelia/authelia/tree/master/examples/templates/notifications).
### filesystem
The [filesystem](filesystem.md) provider.
### smtp
The [smtp](smtp.md) provider.

View File

@ -1,91 +0,0 @@
---
layout: default
title: NTP
parent: Configuration
nav_order: 9
---
# NTP
Authelia has the ability to check the system time against an NTP server. Currently this only occurs at startup. This
section configures and tunes the settings for this check which is primarily used to ensure [TOTP](./one-time-password.md)
can be accurately validated.
In the instance of inability to contact the NTP server Authelia will just log an error and will continue to run.
## Configuration
```yaml
ntp:
address: "time.cloudflare.com:123"
version: 3
max_desync: 3s
disable_startup_check: false
disable_failure: false
```
## Options
### address
<div markdown="1">
type: string
{: .label .label-config .label-purple }
default: time.cloudflare.com:123
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Determines the address of the NTP server to retrieve the time from. The format is `<host>:<port>`, and both of these are
required.
### version
<div markdown="1">
type: integer
{: .label .label-config .label-purple }
default: 4
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Determines the NTP verion supported. Valid values are 3 or 4.
### max_desync
<div markdown="1">
type: duration
{: .label .label-config .label-purple }
default: 3s
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
This is used to tune the acceptable desync from the time reported from the NTP server. This uses our
[duration notation](./index.md#duration-notation-format) format.
### disable_startup_check
<div markdown="1">
type: boolean
{: .label .label-config .label-purple }
default: false
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Setting this to true will disable the startup check entirely.
### disable_failure
<div markdown="1">
type: boolean
{: .label .label-config .label-purple }
default: false
{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
</div>
Setting this to true will allow Authelia to start and just log an error instead of exiting. The default is that if
Authelia can contact the NTP server successfully, and the time reported by the server is greater than what is configured
in [max_desync](#max_desync) that Authelia fails to start and logs a fatal error.

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