From 7608fba2f579aac8ab8f991fe08a1910f5a03332 Mon Sep 17 00:00:00 2001 From: Alicia Sykes Date: Sat, 21 Aug 2021 20:38:58 +0100 Subject: [PATCH 01/12] :boom: Major structural modifications to Auth object --- docs/configuring.md | 11 ++++-- src/router.js | 6 ++-- src/utils/Auth.js | 26 ++++++++++++-- src/utils/ConfigSchema.json | 71 ++++++++++++++++++++----------------- src/views/Login.vue | 17 +++++---- 5 files changed, 86 insertions(+), 45 deletions(-) diff --git a/docs/configuring.md b/docs/configuring.md index a17d93b8b4..eb983966bc 100644 --- a/docs/configuring.md +++ b/docs/configuring.md @@ -64,8 +64,7 @@ To disallow any changes from being written to disk via the UI config editor, set **`enableFontAwesome`** | `boolean` | _Optional_ | Where `true` is enabled, if left blank font-awesome will be enabled only if required by 1 or more icons **`fontAwesomeKey`** | `string` | _Optional_ | If you have a font-awesome key, then you can use it here and make use of premium icons. It is a 10-digit alpha-numeric string from you're FA kit URL (e.g. `13014ae648`) **`faviconApi`** | `enum` | _Optional_ | Only applicable if you are using favicons for item icons. Specifies which service to use to resolve favicons. Set to `local` to do this locally, without using an API. Services running locally will use this option always. Available options are: `local`, `faviconkit`, `google`, `clearbit`, `webmasterapi` and `allesedv`. Defaults to `faviconkit`. See [Icons](/docs/icons.md#favicons) for more info -**`auth`** | `array` | _Optional_ | An array of objects containing usernames and hashed passwords. If this is not provided, then authentication will be off by default, and you will not need any credentials to access the app. Note authentication is done on the client side, and so if your instance of Dashy is exposed to the internet, it is recommend to configure your web server to handle this. See [`auth`](#appconfigauth-optional) -**`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` to be configured. Defaults to `false`. +**`auth`** | `object` | _Optional_ | All settings relating to user authentication. See [`auth`](#appconfigauth-optional) **`layout`** | `enum` | _Optional_ | App layout, either `horizontal`, `vertical`, `auto` or `sidebar`. Defaults to `auto`. This specifies the layout and direction of how sections are positioned on the home screen. This can also be modified from the UI. **`iconSize`** | `enum` | _Optional_ | The size of link items / icons. Can be either `small`, `medium,` or `large`. Defaults to `medium`. This can also be set directly from the UI. **`theme`** | `string` | _Optional_ | The default theme for first load (you can change this later from the UI) @@ -85,6 +84,14 @@ To disallow any changes from being written to disk via the UI config editor, set **[⬆️ Back to Top](#configuring)** ### `appConfig.auth` _(optional)_ +**Field** | **Type** | **Required**| **Description** +--- | --- | --- | --- +**`users`** | `array` | _Optional_ | An array of objects containing usernames and hashed passwords. If this is not provided, then authentication will be off by default, and you will not need any credentials to access the app. See [`appConfig.auth.users`](#appconfigauthusers-optional).
**Note** this method of authentication is handled on the client side, so for security critical situations, it is recommended to use an [alternate authentication method](/docs/authentication.md#alternative-authentication-methods). +**`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`. + +**[⬆️ Back to Top](#configuring)** + +### `appConfig.auth.users` _(optional)_ **Field** | **Type** | **Required**| **Description** --- | --- | --- | --- diff --git a/src/router.js b/src/router.js index 2800f8a5c4..07c192737e 100644 --- a/src/router.js +++ b/src/router.js @@ -25,12 +25,14 @@ Vue.use(Router); /* Checks if guest mode is enabled in appConfig */ const isGuestEnabled = () => { if (!config || !config.appConfig) return false; - return config.appConfig.enableGuestAccess || false; + if (config.appConfig.enableGuestAccess) return true; + return config.appConfig.auth.enableGuestAccess || false; }; /* Returns true if user is already authenticated, or if auth is not enabled */ const isAuthenticated = () => { - const users = config.appConfig.auth; + const auth = config.appConfig.auth || {}; + const users = Array.isArray(auth) ? auth : auth.users || []; return (!users || users.length === 0 || isLoggedIn() || isGuestEnabled()); }; diff --git a/src/utils/Auth.js b/src/utils/Auth.js index 3fd00d441d..9bcf3f4858 100644 --- a/src/utils/Auth.js +++ b/src/utils/Auth.js @@ -9,10 +9,28 @@ const getAppConfig = () => { return config.appConfig || {}; }; +/** + * Called when the user is still using array for users, prints warning + * This was a breaking change, implemented in V 1.6.5 + * Support for old user structure will be removed in V 1.7.0 + */ +const printWarning = () => { + const msg = 'From V 1.6.5 onwards, the structure of the users object has changed.'; + // eslint-disable-next-line no-console + console.warn(msg); +}; + /* Returns the users array from appConfig, if available, else an empty array */ const getUsers = () => { const appConfig = getAppConfig(); - return appConfig.auth || []; + const auth = appConfig.auth || {}; + // Check if the user is still using previous schema type + if (Array.isArray(auth)) { + printWarning(); // Print warning message + return auth; + } + // Otherwise, return the users array, if available + return auth.users || []; }; /** @@ -58,7 +76,11 @@ export const isAuthEnabled = () => { /* Returns true if guest access is enabled */ export const isGuestAccessEnabled = () => { const appConfig = getAppConfig(); - return appConfig.enableGuestAccess || false; + if (appConfig.enableGuestAccess) return true; + if (!Array.isArray(appConfig.auth)) { + return appConfig.auth.enableGuestAccess || false; + } + return false; }; /** diff --git a/src/utils/ConfigSchema.json b/src/utils/ConfigSchema.json index 73b7b68492..03f95253ff 100644 --- a/src/utils/ConfigSchema.json +++ b/src/utils/ConfigSchema.json @@ -43,7 +43,7 @@ "logo": { "type": "string", "description": "Path to an optional image asset, to be displayed in the header", - "pattern": "^(http|\/)", + "pattern": "^(http|/)", "examples": [ "/web-icons/dashy-logo.png", "https://i.ibb.co/yhbt6CY/dashy.png" @@ -217,42 +217,49 @@ "description": "How often to recheck statuses. If set to 0, status will only be checked on page load" }, "auth": { - "type": "array", - "description": "Usernames and hashed credentials for frontend authentication", - "items": { - "type": "object", - "additionalProperties": false, - "required": [ - "user", - "hash" - ], - "properties": { - "user": { - "type": "string", - "description": "The username for a user" - }, - "hash": { - "type": "string", - "description": "A SHA-256 hashed password for that user", - "minLength": 64, - "maxLength": 64 - }, - "type": { - "enum": [ - "admin", - "normal" + "type": "object", + "description": "Settings for enabling authentication", + "additionalProperties": false, + "properties": { + "enableGuestAccess": { + "type": "boolean", + "default": false, + "description": "If set to true, an unauthenticated user will be able to have read-only access to dashboard, without needing to login. Requires auth to be configured." + }, + "users": { + "type": "array", + "description": "Usernames and hashed credentials for frontend authentication", + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "user", + "hash" ], - "description": "User type, denoting privilege level, either admin or normal", - "default": "normal" + "properties": { + "user": { + "type": "string", + "description": "The username for a user" + }, + "hash": { + "type": "string", + "description": "A SHA-256 hashed password for that user", + "minLength": 64, + "maxLength": 64 + }, + "type": { + "enum": [ + "admin", + "normal" + ], + "description": "User type, denoting privilege level, either admin or normal", + "default": "normal" + } + } } } } }, - "enableGuestAccess": { - "type": "boolean", - "default": false, - "description": "If set to true, an unauthenticated user will be able to have read-only access to dashboard, without needing to login. Requires auth to be configured." - }, "enableMultiTasking": { "type": "boolean", "default": false, diff --git a/src/views/Login.vue b/src/views/Login.vue index a86908f315..fd9f6a170c 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -49,7 +49,7 @@
+ v-if="isGuestAccessEnabled && !isUserAlreadyLoggedIn && isAuthenticationEnabled">