💥 Major structural modifications to Auth object

This commit is contained in:
Alicia Sykes 2021-08-21 20:38:58 +01:00
parent 053c55c8e3
commit 7608fba2f5
5 changed files with 86 additions and 45 deletions

View File

@ -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). <br>**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**
--- | --- | --- | ---

View File

@ -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());
};

View File

@ -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;
};
/**

View File

@ -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,

View File

@ -49,7 +49,7 @@
</form>
<!-- Guest login form -->
<form class="guest-form"
v-if="appConfig.enableGuestAccess && !isUserAlreadyLoggedIn && isAuthenticationEnabled">
v-if="isGuestAccessEnabled && !isUserAlreadyLoggedIn && isAuthenticationEnabled">
<h2 class="login-title">Guest Access</h2>
<Button class="login-button" :click="guestLogin">
{{ $t('login.proceed-guest-button') }}
@ -81,6 +81,7 @@ import {
login,
isLoggedIn,
logout,
isGuestAccessEnabled,
} from '@/utils/Auth';
export default {
@ -124,17 +125,19 @@ export default {
existingUsername() {
return localStorage[localStorageKeys.USERNAME];
},
users() {
const auth = this.appConfig.auth || {};
return Array.isArray(auth) ? auth : auth.users || [];
},
isUserAlreadyLoggedIn() {
const users = this.appConfig.auth;
const loggedIn = (!users || users.length === 0 || isLoggedIn());
const loggedIn = (!this.users || this.users.length === 0 || isLoggedIn());
return (loggedIn && this.existingUsername);
},
isGuestAccessEnabled() {
if (!this.appConfig || !this.appConfig.enableGuestAccess) return false;
return this.appConfig.enableGuestAccess;
return isGuestAccessEnabled();
},
isAuthenticationEnabled() {
return (this.appConfig && this.appConfig.auth && this.appConfig.auth.length > 0);
return (this.appConfig && this.appConfig.auth && this.users.length > 0);
},
},
methods: {
@ -146,7 +149,7 @@ export default {
const response = checkCredentials(
this.username,
this.password,
this.appConfig.auth || [], // All users
this.users, // All users
this.responseMessages, // Translated response messages
);
this.message = response.msg; // Show error or success message to the user