mirror of https://github.com/Lissy93/dashy.git
Merge branch 'master' of github.com:lissy93/dashy
This commit is contained in:
commit
c92340649e
28
README.md
28
README.md
|
@ -553,28 +553,21 @@ Huge thanks to the sponsors helping to support Dashy's development!
|
|||
<sub><b>Torgny Bjers</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/emlazzarin">
|
||||
<img src="https://avatars.githubusercontent.com/u/1141361?u=714e3487a3f2e0df721b01a0133945f075d3ff68&v=4" width="80;" alt="emlazzarin"/>
|
||||
<br />
|
||||
<sub><b>Eddy Lazzarin</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/AnandChowdhary">
|
||||
<img src="https://avatars.githubusercontent.com/u/2841780?u=747e554b3a7f12eb20b7910e1c87d817844f714f&v=4" width="80;" alt="AnandChowdhary"/>
|
||||
<br />
|
||||
<sub><b>Anand Chowdhary</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/shrippen">
|
||||
<img src="https://avatars.githubusercontent.com/u/2873570?v=4" width="80;" alt="shrippen"/>
|
||||
<br />
|
||||
<sub><b>Shrippen</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bile0026">
|
||||
<img src="https://avatars.githubusercontent.com/u/5022496?u=aec96ad173c0ea9baaba93807efa8a848af6595c&v=4" width="80;" alt="bile0026"/>
|
||||
|
@ -609,15 +602,15 @@ Huge thanks to the sponsors helping to support Dashy's development!
|
|||
<br />
|
||||
<sub><b>Araguaci</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bmcgonag">
|
||||
<img src="https://avatars.githubusercontent.com/u/7346620?u=2a0f9284f3e12ac1cc15288c254d1ec68a5081e8&v=4" width="80;" alt="bmcgonag"/>
|
||||
<br />
|
||||
<sub><b>Brian McGonagill</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/vlad-timofeev">
|
||||
<img src="https://avatars.githubusercontent.com/u/11474041?u=eee43705b54d2ec9f51fc4fcce5ad18dd17c87e4&v=4" width="80;" alt="vlad-timofeev"/>
|
||||
|
@ -652,15 +645,15 @@ Huge thanks to the sponsors helping to support Dashy's development!
|
|||
<br />
|
||||
<sub><b>Göksel Yeşiller</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/allesauseinerhand">
|
||||
<img src="https://avatars.githubusercontent.com/u/32039836?v=4" width="80;" alt="allesauseinerhand"/>
|
||||
<br />
|
||||
<sub><b>Allesauseinerhand</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/lamtrinhdev">
|
||||
<img src="https://avatars.githubusercontent.com/u/49742151?u=c5eaca5aa6841a80605cf4f7d0e861a9e6339ef3&v=4" width="80;" alt="lamtrinhdev"/>
|
||||
|
@ -695,8 +688,7 @@ Huge thanks to the sponsors helping to support Dashy's development!
|
|||
<br />
|
||||
<sub><b>Nixy</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/nrvo">
|
||||
<img src="https://avatars.githubusercontent.com/u/151435968?u=e1dcb307fd0efdc45cddbe9490a7b956e4da6835&v=4" width="80;" alt="nrvo"/>
|
||||
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 30 MiB After Width: | Height: | Size: 30 MiB |
|
@ -14,6 +14,7 @@
|
|||
- [Deploying Keycloak](#1-deploy-keycloak)
|
||||
- [Setting up Keycloak](#2-setup-keycloak-users)
|
||||
- [Configuring Dashy for Keycloak](#3-enable-keycloak-in-dashy-config-file)
|
||||
- [Toubleshooting Keycloak](#troubleshooting-keycloak)
|
||||
- [Alternative Authentication Methods](#alternative-authentication-methods)
|
||||
- [VPN](#vpn)
|
||||
- [IP-Based Access](#ip-based-access)
|
||||
|
@ -253,6 +254,67 @@ From within the Keycloak console, you can then configure things like time-outs,
|
|||
|
||||
---
|
||||
|
||||
### Troubleshooting Keycloak
|
||||
|
||||
If you encounter issues with your Keycloak setup, follow these steps to troubleshoot and resolve common problems.
|
||||
|
||||
1. Client Authentication Issue
|
||||
Problem: Redirect loop, if client authentication is enabled.
|
||||
Solution: Switch off "client authentication" in "TC clients" -> "Advanced" settings.
|
||||
|
||||
2. Double URL
|
||||
Problem: If you get redirected to "https://dashy.my.domain/#iss=https://keycloak.my.domain/realms/my-realm"
|
||||
Solution: Make sure to turn on "Exclude Issuer From Authentication Response" in "TC clients" -> "Advanced" -> "OpenID Connect Compatibility Modes"
|
||||
|
||||
3. Problems with mutiple Dashy Pages
|
||||
Problem: Refreshing or logging out of dashy results in an "invalid_redirect_uri" error.
|
||||
Solution: In "TC clients" -> "Access settings" -> "Root URL" https://dashy.my.domain/, valid redirect URIs must be /*
|
||||
|
||||
---
|
||||
|
||||
## OIDC
|
||||
|
||||
Dashy also supports using a general [OIDC compatible](https://openid.net/connect/) authentication server. In order to use it, the authentication section needs to be configured:
|
||||
|
||||
```yaml
|
||||
appConfig:
|
||||
auth:
|
||||
enableOidc: true
|
||||
oidc:
|
||||
clientId: [registered client id]
|
||||
endpoint: [OIDC endpoint]
|
||||
```
|
||||
|
||||
Because Dashy is a SPA, a [public client](https://datatracker.ietf.org/doc/html/rfc6749#section-2.1) registration with PKCE is needed.
|
||||
|
||||
An example for Authelia is shared below, but other OIDC systems can be used:
|
||||
|
||||
```yaml
|
||||
identity_providers:
|
||||
oidc:
|
||||
clients:
|
||||
- client_id: dashy
|
||||
client_name: dashy
|
||||
public: true
|
||||
authorization_policy: 'one_factor'
|
||||
require_pkce: true
|
||||
pkce_challenge_method: 'S256'
|
||||
redirect_uris:
|
||||
- https://dashy.local # should point to your dashy endpoint
|
||||
grant_types:
|
||||
- authorization_code
|
||||
scopes:
|
||||
- 'openid'
|
||||
- 'profile'
|
||||
- 'roles'
|
||||
- 'email'
|
||||
- 'groups'
|
||||
```
|
||||
|
||||
Groups and roles will be populated and available for controlling display similar to [Keycloak](#Keycloak) abvoe.
|
||||
|
||||
---
|
||||
|
||||
## Alternative Authentication Methods
|
||||
|
||||
If you are self-hosting Dashy, and require secure authentication to prevent unauthorized access, then you can either use Keycloak, or one of the following options:
|
||||
|
|
|
@ -158,6 +158,8 @@ The following file provides a reference of all supported configuration options.
|
|||
**`keycloak`** | `object` | _Optional_ | Config options to point Dashy to your Keycloak server. Requires `enableKeycloak: true`. See [`auth.keycloak`](#appconfigauthkeycloak-optional) for more info
|
||||
**`enableHeaderAuth`** | `boolean` | _Optional_ | If set to `true`, then authentication using HeaderAuth will be enabled. Note that you need to have your web server/reverse proxy running, and have also configured `auth.headerAuth`. Defaults to `false`
|
||||
**`headerAuth`** | `object` | _Optional_ | Config options to point Dashy to your headers for authentication. Requires `enableHeaderAuth: true`. See [`auth.headerAuth`](#appconfigauthheaderauth-optional) for more info
|
||||
**`enableOidc`** | `boolean` | _Optional_ | If set to `true`, then authentication using OIDC will be enabled. Note that you need to have a configured OIDC server and configure it with `auth.oidc`. Defaults to `false`
|
||||
**`oidc`** | `object` | _Optional_ | Config options to point Dash to your OIDC configuration. Request `enableOidc: true`. See [`auth.oidc`](#appconfigauthoidc-optional) for more info
|
||||
**`enableGuestAccess`** | `boolean` | _Optional_ | When set to `true`, an unauthenticated user will be able to access the dashboard, with read-only access, without having to login. Requires `auth.users` to be configured. Defaults to `false`.
|
||||
|
||||
For more info, see the **[Authentication Docs](/docs/authentication.md)**
|
||||
|
@ -194,6 +196,15 @@ For more info, see the **[Authentication Docs](/docs/authentication.md)**
|
|||
|
||||
**[⬆️ Back to Top](#configuring)**
|
||||
|
||||
## `appConfig.auth.oidc` _(optional)_
|
||||
|
||||
**Field** | **Type** | **Required**| **Description**
|
||||
--- | --- | --- | ---
|
||||
**`clientId`** | `string` | Required | The client id registered in the OIDC server
|
||||
**`endpoint`** | `string` | Required | The URL of the OIDC server that should be used.
|
||||
|
||||
**[⬆️ Back to Top](#configuring)**
|
||||
|
||||
## `appConfig.webSearch` _(optional)_
|
||||
|
||||
**Field** | **Type** | **Required**| **Description**
|
||||
|
|
118
docs/credits.md
118
docs/credits.md
|
@ -32,28 +32,21 @@
|
|||
<sub><b>Torgny Bjers</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/emlazzarin">
|
||||
<img src="https://avatars.githubusercontent.com/u/1141361?u=714e3487a3f2e0df721b01a0133945f075d3ff68&v=4" width="80;" alt="emlazzarin"/>
|
||||
<br />
|
||||
<sub><b>Eddy Lazzarin</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/AnandChowdhary">
|
||||
<img src="https://avatars.githubusercontent.com/u/2841780?u=747e554b3a7f12eb20b7910e1c87d817844f714f&v=4" width="80;" alt="AnandChowdhary"/>
|
||||
<br />
|
||||
<sub><b>Anand Chowdhary</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/shrippen">
|
||||
<img src="https://avatars.githubusercontent.com/u/2873570?v=4" width="80;" alt="shrippen"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bile0026">
|
||||
<img src="https://avatars.githubusercontent.com/u/5022496?u=aec96ad173c0ea9baaba93807efa8a848af6595c&v=4" width="80;" alt="bile0026"/>
|
||||
|
@ -88,15 +81,15 @@
|
|||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bmcgonag">
|
||||
<img src="https://avatars.githubusercontent.com/u/7346620?u=2a0f9284f3e12ac1cc15288c254d1ec68a5081e8&v=4" width="80;" alt="bmcgonag"/>
|
||||
<br />
|
||||
<sub><b>Brian McGonagill</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/vlad-timofeev">
|
||||
<img src="https://avatars.githubusercontent.com/u/11474041?u=eee43705b54d2ec9f51fc4fcce5ad18dd17c87e4&v=4" width="80;" alt="vlad-timofeev"/>
|
||||
|
@ -131,15 +124,15 @@
|
|||
<br />
|
||||
<sub><b>Göksel Yeşiller</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/allesauseinerhand">
|
||||
<img src="https://avatars.githubusercontent.com/u/32039836?v=4" width="80;" alt="allesauseinerhand"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/forwardemail">
|
||||
<img src="https://avatars.githubusercontent.com/u/32481436?v=4" width="80;" alt="forwardemail"/>
|
||||
|
@ -174,15 +167,15 @@
|
|||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/frankdez93">
|
||||
<img src="https://avatars.githubusercontent.com/u/87549420?v=4" width="80;" alt="frankdez93"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/terminaltrove">
|
||||
<img src="https://avatars.githubusercontent.com/u/121595180?v=4" width="80;" alt="terminaltrove"/>
|
||||
|
@ -612,13 +605,6 @@
|
|||
<sub><b>Alessandro Del Prete</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/turnrye">
|
||||
<img src="https://avatars.githubusercontent.com/u/701035?v=4" width="80;" alt="turnrye"/>
|
||||
<br />
|
||||
<sub><b>Ryan Turner</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/sachahjkl">
|
||||
<img src="https://avatars.githubusercontent.com/u/32895534?v=4" width="80;" alt="sachahjkl"/>
|
||||
|
@ -639,15 +625,15 @@
|
|||
<br />
|
||||
<sub><b>Shawn Salat</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/royshreyaa">
|
||||
<img src="https://avatars.githubusercontent.com/u/139828242?v=4" width="80;" alt="royshreyaa"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Smexhy">
|
||||
<img src="https://avatars.githubusercontent.com/u/4880625?v=4" width="80;" alt="Smexhy"/>
|
||||
|
@ -676,14 +662,28 @@
|
|||
<sub><b>Steven Kast</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/twsouthwick">
|
||||
<img src="https://avatars.githubusercontent.com/u/583206?v=4" width="80;" alt="twsouthwick"/>
|
||||
<br />
|
||||
<sub><b>Taylor Southwick</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/turnrye">
|
||||
<img src="https://avatars.githubusercontent.com/u/701035?v=4" width="80;" alt="turnrye"/>
|
||||
<br />
|
||||
<sub><b>Ryan Turner</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/rubjo">
|
||||
<img src="https://avatars.githubusercontent.com/u/42270947?v=4" width="80;" alt="rubjo"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/PrynsTag">
|
||||
<img src="https://avatars.githubusercontent.com/u/56314705?v=4" width="80;" alt="PrynsTag"/>
|
||||
|
@ -718,15 +718,15 @@
|
|||
<br />
|
||||
<sub><b>Michael D</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/miclav">
|
||||
<img src="https://avatars.githubusercontent.com/u/11891522?v=4" width="80;" alt="miclav"/>
|
||||
<br />
|
||||
<sub><b>Michael Lavaire</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/imsakg">
|
||||
<img src="https://avatars.githubusercontent.com/u/62212589?v=4" width="80;" alt="imsakg"/>
|
||||
|
@ -734,13 +734,6 @@
|
|||
<sub><b>Mert Sefa AKGUN</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/maximemoreillon">
|
||||
<img src="https://avatars.githubusercontent.com/u/29086128?v=4" width="80;" alt="maximemoreillon"/>
|
||||
<br />
|
||||
<sub><b>Maxime Moreillon</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/AmadeusGraves">
|
||||
<img src="https://avatars.githubusercontent.com/u/18572939?v=4" width="80;" alt="AmadeusGraves"/>
|
||||
|
@ -870,6 +863,13 @@
|
|||
<sub><b>Xert</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/maximemoreillon">
|
||||
<img src="https://avatars.githubusercontent.com/u/29086128?v=4" width="80;" alt="maximemoreillon"/>
|
||||
<br />
|
||||
<sub><b>Maxime Moreillon</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/emiran-orange">
|
||||
<img src="https://avatars.githubusercontent.com/u/71817149?v=4" width="80;" alt="emiran-orange"/>
|
||||
|
@ -890,15 +890,15 @@
|
|||
<br />
|
||||
<sub><b>Dylan Bersans</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/dyauss">
|
||||
<img src="https://avatars.githubusercontent.com/u/50002238?v=4" width="80;" alt="dyauss"/>
|
||||
<br />
|
||||
<sub><b>Thandy Norberto</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/dougaldhub">
|
||||
<img src="https://avatars.githubusercontent.com/u/25713235?v=4" width="80;" alt="dougaldhub"/>
|
||||
|
@ -933,15 +933,15 @@
|
|||
<br />
|
||||
<sub><b>David</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/clsty">
|
||||
<img src="https://avatars.githubusercontent.com/u/129247596?v=4" width="80;" alt="clsty"/>
|
||||
<br />
|
||||
<sub><b>Celestial.y</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bskim45">
|
||||
<img src="https://avatars.githubusercontent.com/u/5674934?v=4" width="80;" alt="bskim45"/>
|
||||
|
@ -976,15 +976,15 @@
|
|||
<br />
|
||||
<sub><b>Artyom</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/alydemah">
|
||||
<img src="https://avatars.githubusercontent.com/u/652035?v=4" width="80;" alt="alydemah"/>
|
||||
<br />
|
||||
<sub><b>Aly Mohamed</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/5idereal">
|
||||
<img src="https://avatars.githubusercontent.com/u/30827929?v=4" width="80;" alt="5idereal"/>
|
||||
|
@ -1019,15 +1019,15 @@
|
|||
<br />
|
||||
<sub><b>Мирослав Асенов</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/luispabon">
|
||||
<img src="https://avatars.githubusercontent.com/u/6388823?v=4" width="80;" alt="luispabon"/>
|
||||
<br />
|
||||
<sub><b>Luis Pabon</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/LeoColman">
|
||||
<img src="https://avatars.githubusercontent.com/u/1577251?v=4" width="80;" alt="LeoColman"/>
|
||||
|
@ -1062,15 +1062,15 @@
|
|||
<br />
|
||||
<sub><b>Jemy SCHNEPP</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/jjmung">
|
||||
<img src="https://avatars.githubusercontent.com/u/6049600?v=4" width="80;" alt="jjmung"/>
|
||||
<br />
|
||||
<sub><b>JJ Munguia</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/b1thunt3r">
|
||||
<img src="https://avatars.githubusercontent.com/u/791091?v=4" width="80;" alt="b1thunt3r"/>
|
||||
|
@ -1105,15 +1105,15 @@
|
|||
<br />
|
||||
<sub><b>Harald Töpfer</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gbrown09">
|
||||
<img src="https://avatars.githubusercontent.com/u/3360055?v=4" width="80;" alt="gbrown09"/>
|
||||
<br />
|
||||
<sub><b>Garrett Brown</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/FormatToday">
|
||||
<img src="https://avatars.githubusercontent.com/u/20515769?v=4" width="80;" alt="FormatToday"/>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "dashy",
|
||||
"version": "3.0.1",
|
||||
"version": "3.1.0",
|
||||
"license": "MIT",
|
||||
"main": "server",
|
||||
"author": "Alicia Sykes <alicia@omg.lol> (https://aliciasykes.com)",
|
||||
|
@ -30,6 +30,7 @@
|
|||
"frappe-charts": "^1.6.2",
|
||||
"js-yaml": "^4.1.0",
|
||||
"keycloak-js": "^20.0.3",
|
||||
"oidc-client-ts": "^3.0.1",
|
||||
"register-service-worker": "^1.7.2",
|
||||
"remedial": "^1.0.8",
|
||||
"rss-parser": "3.13.0",
|
||||
|
|
|
@ -24,6 +24,13 @@
|
|||
v-tooltip="tooltip($t('settings.sign-out-tooltip'))"
|
||||
class="layout-icon" tabindex="-2"
|
||||
/>
|
||||
<!-- If user logged in via oidc, show oidc logout button -->
|
||||
<IconLogout
|
||||
v-if="userType == userStateEnum.oidcEnabled"
|
||||
@click="oidcLogout()"
|
||||
v-tooltip="tooltip($t('settings.sign-out-tooltip'))"
|
||||
class="layout-icon" tabindex="-2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -32,6 +39,7 @@
|
|||
import router from '@/router';
|
||||
import { logout as registerLogout } from '@/utils/Auth';
|
||||
import { getKeycloakAuth } from '@/utils/KeycloakAuth';
|
||||
import { getOidcAuth } from '@/utils/OidcAuth';
|
||||
import { localStorageKeys, userStateEnum } from '@/utils/defaults';
|
||||
import IconLogout from '@/assets/interface-icons/user-logout.svg';
|
||||
|
||||
|
@ -56,6 +64,13 @@ export default {
|
|||
router.push({ path: '/login' });
|
||||
}, 500);
|
||||
},
|
||||
oidcLogout() {
|
||||
const oidc = getOidcAuth();
|
||||
this.$toasted.show(this.$t('login.logout-message'));
|
||||
setTimeout(() => {
|
||||
oidc.logout();
|
||||
}, 500);
|
||||
},
|
||||
keycloakLogout() {
|
||||
const keycloak = getKeycloakAuth();
|
||||
this.$toasted.show(this.$t('login.logout-message'));
|
||||
|
|
|
@ -22,6 +22,7 @@ import clickOutside from '@/directives/ClickOutside'; // Directive for closing p
|
|||
import { toastedOptions, tooltipOptions, language as defaultLanguage } from '@/utils/defaults';
|
||||
import { initKeycloakAuth, isKeycloakEnabled } from '@/utils/KeycloakAuth';
|
||||
import { initHeaderAuth, isHeaderAuthEnabled } from '@/utils/HeaderAuth';
|
||||
import { initOidcAuth, isOidcEnabled } from '@/utils/OidcAuth';
|
||||
import Keys from '@/utils/StoreMutations';
|
||||
import ErrorHandler from '@/utils/ErrorHandler';
|
||||
|
||||
|
@ -62,7 +63,13 @@ const mount = () => new Vue({
|
|||
}).$mount('#app');
|
||||
|
||||
store.dispatch(Keys.INITIALIZE_CONFIG).then(() => {
|
||||
if (isKeycloakEnabled()) { // If Keycloak is enabled, initialize auth
|
||||
if (isOidcEnabled()) {
|
||||
initOidcAuth()
|
||||
.then(() => mount())
|
||||
.catch((e) => {
|
||||
ErrorHandler('Failed to authenticate with OIDC', e);
|
||||
});
|
||||
} else if (isKeycloakEnabled()) { // If Keycloak is enabled, initialize auth
|
||||
initKeycloakAuth()
|
||||
.then(() => mount())
|
||||
.catch((e) => {
|
||||
|
|
|
@ -3,6 +3,7 @@ import ConfigAccumulator from '@/utils/ConfigAccumalator';
|
|||
import ErrorHandler from '@/utils/ErrorHandler';
|
||||
import { cookieKeys, localStorageKeys, userStateEnum } from '@/utils/defaults';
|
||||
import { isKeycloakEnabled } from '@/utils/KeycloakAuth';
|
||||
import { isOidcEnabled } from '@/utils/OidcAuth';
|
||||
|
||||
/* Uses config accumulator to get and return app config */
|
||||
const getAppConfig = () => {
|
||||
|
@ -96,7 +97,7 @@ export const isAuthEnabled = () => {
|
|||
/* Returns true if guest access is enabled */
|
||||
export const isGuestAccessEnabled = () => {
|
||||
const appConfig = getAppConfig();
|
||||
if (appConfig.auth && typeof appConfig.auth === 'object' && !isKeycloakEnabled()) {
|
||||
if (appConfig.auth && typeof appConfig.auth === 'object' && !isKeycloakEnabled() && !isOidcEnabled()) {
|
||||
return appConfig.auth.enableGuestAccess || false;
|
||||
}
|
||||
return false;
|
||||
|
@ -229,8 +230,10 @@ export const getUserState = () => {
|
|||
loggedIn,
|
||||
guestAccess,
|
||||
keycloakEnabled,
|
||||
oidcEnabled,
|
||||
} = userStateEnum; // Numeric enum options
|
||||
if (isKeycloakEnabled()) return keycloakEnabled; // Keycloak auth configured
|
||||
if (isOidcEnabled()) return oidcEnabled;
|
||||
if (!isAuthEnabled()) return notConfigured; // No auth enabled
|
||||
if (isLoggedIn()) return loggedIn; // User is logged in
|
||||
if (isGuestAccessEnabled()) return guestAccess; // Guest is viewing
|
||||
|
|
|
@ -541,6 +541,33 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"enableOidc": {
|
||||
"title": "Enable OIDC?",
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "If set to true, enable OIDC. See appConfig.auth.oidc"
|
||||
},
|
||||
"oidc": {
|
||||
"type": "object",
|
||||
"description": "Configuration for OIDC",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"clientId",
|
||||
"endpoint"
|
||||
],
|
||||
"properties": {
|
||||
"endpoint": {
|
||||
"title": "OIDC Endpoint",
|
||||
"type": "string",
|
||||
"description": "Endpoint of OIDC provider"
|
||||
},
|
||||
"clientId": {
|
||||
"title": "OIDC Client Id",
|
||||
"type": "string",
|
||||
"description": "ClientId from OIDC provider"
|
||||
}
|
||||
}
|
||||
},
|
||||
"enableHeaderAuth": {
|
||||
"title": "Enable HeaderAuth?",
|
||||
"type": "boolean",
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
import { UserManager, WebStorageStateStore } from 'oidc-client-ts';
|
||||
import ConfigAccumulator from '@/utils/ConfigAccumalator';
|
||||
import { localStorageKeys } from '@/utils/defaults';
|
||||
import ErrorHandler from '@/utils/ErrorHandler';
|
||||
import { statusMsg, statusErrorMsg } from '@/utils/CoolConsole';
|
||||
|
||||
const getAppConfig = () => {
|
||||
const Accumulator = new ConfigAccumulator();
|
||||
const config = Accumulator.config();
|
||||
return config.appConfig || {};
|
||||
};
|
||||
|
||||
class OidcAuth {
|
||||
constructor() {
|
||||
const { auth } = getAppConfig();
|
||||
const { clientId, endpoint } = auth.oidc;
|
||||
const settings = {
|
||||
userStore: new WebStorageStateStore({ store: window.localStorage }),
|
||||
authority: endpoint,
|
||||
client_id: clientId,
|
||||
redirect_uri: `${window.location.origin}`,
|
||||
response_type: 'code',
|
||||
scope: 'openid profile email roles groups',
|
||||
response_mode: 'query',
|
||||
filterProtocolClaims: true,
|
||||
};
|
||||
|
||||
this.userManager = new UserManager(settings);
|
||||
}
|
||||
|
||||
async login() {
|
||||
const url = new URL(window.location.href);
|
||||
const code = url.searchParams.get('code');
|
||||
|
||||
if (code) {
|
||||
await this.userManager.signinCallback(window.location.href);
|
||||
window.location.href = '/';
|
||||
return;
|
||||
}
|
||||
|
||||
const user = await this.userManager.getUser();
|
||||
|
||||
if (user === null) {
|
||||
await this.userManager.signinRedirect();
|
||||
} else {
|
||||
const { roles, groups } = user.profile;
|
||||
const info = {
|
||||
groups,
|
||||
roles,
|
||||
};
|
||||
|
||||
statusMsg(`user: ${user.profile.preferred_username}`, JSON.stringify(info));
|
||||
|
||||
localStorage.setItem(localStorageKeys.KEYCLOAK_INFO, JSON.stringify(info));
|
||||
localStorage.setItem(localStorageKeys.USERNAME, user.profile.preferred_username);
|
||||
}
|
||||
}
|
||||
|
||||
async logout() {
|
||||
localStorage.removeItem(localStorageKeys.USERNAME);
|
||||
localStorage.removeItem(localStorageKeys.KEYCLOAK_INFO);
|
||||
|
||||
try {
|
||||
await this.userManager.signoutRedirect();
|
||||
} catch (reason) {
|
||||
statusErrorMsg('logout', 'could not log out. Redirecting to OIDC instead', reason);
|
||||
window.location.href = this.userManager.settings.authority;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const isOidcEnabled = () => {
|
||||
const { auth } = getAppConfig();
|
||||
if (!auth) return false;
|
||||
return auth.enableOidc || false;
|
||||
};
|
||||
|
||||
let oidc;
|
||||
|
||||
export const initOidcAuth = () => {
|
||||
oidc = new OidcAuth();
|
||||
return oidc.login();
|
||||
};
|
||||
|
||||
export const getOidcAuth = () => {
|
||||
if (!oidc) {
|
||||
ErrorHandler("OIDC not initialized, can't get instance of class");
|
||||
}
|
||||
return oidc;
|
||||
};
|
|
@ -305,6 +305,7 @@ module.exports = {
|
|||
guestAccess: 2,
|
||||
notLoggedIn: 3,
|
||||
keycloakEnabled: 4,
|
||||
oidcEnabled: 5,
|
||||
},
|
||||
/* Progressive Web App settings, used by Vue Config */
|
||||
pwa: {
|
||||
|
|
Loading…
Reference in New Issue