📝 rollback doc file changes

This commit is contained in:
Leonardo Covarrubias 2022-01-01 20:17:00 -05:00
parent 8a5329d50c
commit 0c8a2c853d
2 changed files with 601 additions and 601 deletions

View File

@ -1,278 +1,278 @@
# Authentication # Authentication
- [Basic Auth](#built-in-auth) - [Basic Auth](#built-in-auth)
- [Setting Up Authentication](#setting-up-authentication) - [Setting Up Authentication](#setting-up-authentication)
- [Hash Password](#hash-password) - [Hash Password](#hash-password)
- [Logging In and Out](#logging-in-and-out) - [Logging In and Out](#logging-in-and-out)
- [Guest Access](#enabling-guest-access) - [Guest Access](#enabling-guest-access)
- [Per-User Access](#granular-access) - [Per-User Access](#granular-access)
- [Security Considerations](#security) - [Security Considerations](#security)
- [Keycloak Auth](#keycloak) - [Keycloak Auth](#keycloak)
- [Deploying Keycloak](#1-deploy-keycloak) - [Deploying Keycloak](#1-deploy-keycloak)
- [Setting up Keycloak](#2-setup-keycloak-users) - [Setting up Keycloak](#2-setup-keycloak-users)
- [Configuring Dashy for Keycloak](#3-enable-keycloak-in-dashy-config-file) - [Configuring Dashy for Keycloak](#3-enable-keycloak-in-dashy-config-file)
- [Alternative Authentication Methods](#alternative-authentication-methods) - [Alternative Authentication Methods](#alternative-authentication-methods)
- [VPN](#vpn) - [VPN](#vpn)
- [IP-Based Access](#ip-based-access) - [IP-Based Access](#ip-based-access)
- [Web Server Authentication](#web-server-authentication) - [Web Server Authentication](#web-server-authentication)
- [OAuth Services](#oauth-services) - [OAuth Services](#oauth-services)
- [Auth on Cloud Hosting Services](#static-site-hosting-providers) - [Auth on Cloud Hosting Services](#static-site-hosting-providers)
## Built-In Auth ## Built-In Auth
Dashy has a basic login page included, and frontend authentication. You can enable this by adding users to the `auth` section under `appConfig` in your `conf.yml`. If this section is not specified, then no authentication will be required to access the app, and it the homepage will resolve to your dashboard. Dashy has a basic login page included, and frontend authentication. You can enable this by adding users to the `auth` section under `appConfig` in your `conf.yml`. If this section is not specified, then no authentication will be required to access the app, and it the homepage will resolve to your dashboard.
### Setting Up Authentication ### Setting Up Authentication
The `auth` property takes an array of users. Each user needs to include a username, hash and optional user type (`admin` or `normal`). The hash property is a [SHA-256 Hash](https://en.wikipedia.org/wiki/SHA-2) of your desired password. The `auth` property takes an array of users. Each user needs to include a username, hash and optional user type (`admin` or `normal`). The hash property is a [SHA-256 Hash](https://en.wikipedia.org/wiki/SHA-2) of your desired password.
For example: For example:
```yaml ```yaml
appConfig: appConfig:
auth: auth:
users: users:
- user: alicia - user: alicia
hash: 4D1E58C90B3B94BCAD9848ECCACD6D2A8C9FBC5CA913304BBA5CDEAB36FEEFA3 hash: 4D1E58C90B3B94BCAD9848ECCACD6D2A8C9FBC5CA913304BBA5CDEAB36FEEFA3
type: admin type: admin
- user: bob - user: bob
hash: 5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8 hash: 5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8
``` ```
### Hash Password ### Hash Password
Dashy uses [SHA-256 Hash](https://en.wikipedia.org/wiki/Sha-256), a 64-character string, which you can generate using an online tool, such as [this one](https://passwordsgenerator.net/sha256-hash-generator/) or [CyberChef](https://gchq.github.io/CyberChef/) (which can be self-hosted/ ran locally). Dashy uses [SHA-256 Hash](https://en.wikipedia.org/wiki/Sha-256), a 64-character string, which you can generate using an online tool, such as [this one](https://passwordsgenerator.net/sha256-hash-generator/) or [CyberChef](https://gchq.github.io/CyberChef/) (which can be self-hosted/ ran locally).
A hash is a one-way cryptographic function, meaning that it is easy to generate a hash for a given password, but very hard to determine the original password for a given hash. This means, that so long as your password is long, strong and unique, it is safe to store it's hash in the clear. Having said that, you should never reuse passwords, hashes can be cracked by iterating over known password lists, generating a hash of each. A hash is a one-way cryptographic function, meaning that it is easy to generate a hash for a given password, but very hard to determine the original password for a given hash. This means, that so long as your password is long, strong and unique, it is safe to store it's hash in the clear. Having said that, you should never reuse passwords, hashes can be cracked by iterating over known password lists, generating a hash of each.
### Logging In and Out ### Logging In and Out
Once authentication is enabled, so long as there is no valid token in cookie storage, the application will redirect the user to the login page. When the user enters credentials in the login page, they will be checked, and if valid, then a token will be generated, and they can be redirected to the home page. If credentials are invalid, then an error message will be shown, and they will remain on the login page. Once in the application, to log out the user can click the logout button (in the top-right), which will clear cookie storage, causing them to be redirected back to the login page. Once authentication is enabled, so long as there is no valid token in cookie storage, the application will redirect the user to the login page. When the user enters credentials in the login page, they will be checked, and if valid, then a token will be generated, and they can be redirected to the home page. If credentials are invalid, then an error message will be shown, and they will remain on the login page. Once in the application, to log out the user can click the logout button (in the top-right), which will clear cookie storage, causing them to be redirected back to the login page.
### Enabling Guest Access ### Enabling Guest Access
With authentication setup, by default no access is allowed to your dashboard without first logging in with valid credentials. Guest mode can be enabled to allow for read-only access to a secured dashboard by any user, without the need to log in. A guest user cannot write any changes to the config file, but can apply modifications locally (stored in their browser). You can enable guest access, by setting `appConfig.enableGuestAccess: true`. With authentication setup, by default no access is allowed to your dashboard without first logging in with valid credentials. Guest mode can be enabled to allow for read-only access to a secured dashboard by any user, without the need to log in. A guest user cannot write any changes to the config file, but can apply modifications locally (stored in their browser). You can enable guest access, by setting `appConfig.enableGuestAccess: true`.
### Granular Access ### Granular Access
You can use the following properties to make certain sections only visible to some users, or hide sections from guests. You can use the following properties to make certain sections only visible to some users, or hide sections from guests.
- `hideForUsers` - Section will be visible to all users, except for those specified in this list - `hideForUsers` - Section will be visible to all users, except for those specified in this list
- `showForUsers` - Section will be hidden from all users, except for those specified in this list - `showForUsers` - Section will be hidden from all users, except for those specified in this list
- `hideForGuests` - Section will be visible for logged in users, but not for guests - `hideForGuests` - Section will be visible for logged in users, but not for guests
For Example: For Example:
```yaml ```yaml
- name: Code Analysis & Monitoring - name: Code Analysis & Monitoring
icon: fas fa-code icon: fas fa-code
displayData: displayData:
cols: 2 cols: 2
hideForUsers: [alicia, bob] hideForUsers: [alicia, bob]
items: items:
... ...
``` ```
```yaml ```yaml
- name: Deployment Pipelines - name: Deployment Pipelines
icon: fas fa-rocket icon: fas fa-rocket
displayData: displayData:
hideForGuests: true hideForGuests: true
items: items:
... ...
``` ```
### Security ### Security
Since all authentication is happening entirely on the client-side, it is vulnerable to manipulation by an adversary. An attacker could look at the source code, find the function used generate the auth token, then decode the minified JavaScript to find the hash, and manually generate a token using it, then just insert that value as a cookie using the console, and become a logged in user. Therefore, if you need secure authentication for your app, it is strongly recommended to implement this using your web server, or use a VPN to control access to Dashy. The purpose of the login page is merely to prevent immediate unauthorized access to your homepage. Since all authentication is happening entirely on the client-side, it is vulnerable to manipulation by an adversary. An attacker could look at the source code, find the function used generate the auth token, then decode the minified JavaScript to find the hash, and manually generate a token using it, then just insert that value as a cookie using the console, and become a logged in user. Therefore, if you need secure authentication for your app, it is strongly recommended to implement this using your web server, or use a VPN to control access to Dashy. The purpose of the login page is merely to prevent immediate unauthorized access to your homepage.
Addressing this is on the todo list, and there are several potential solutions: Addressing this is on the todo list, and there are several potential solutions:
1. Encrypt all site data against the users password, so that an attacker can not physically access any data without the correct decryption key 1. Encrypt all site data against the users password, so that an attacker can not physically access any data without the correct decryption key
2. Use a backend service to handle authentication and configuration, with no user data returned from the server until the correct credentials are provided. However, this would require either Dashy to be run using it's Node.js server, or the use of an external service 2. Use a backend service to handle authentication and configuration, with no user data returned from the server until the correct credentials are provided. However, this would require either Dashy to be run using it's Node.js server, or the use of an external service
3. ~~Implement authentication using a self-hosted identity management solution, such as [Keycloak for Vue](https://www.keycloak.org/securing-apps/vue)~~ **This is now implemented, and released in PR #174 of V 1.6.5!** 3. ~~Implement authentication using a self-hosted identity management solution, such as [Keycloak for Vue](https://www.keycloak.org/securing-apps/vue)~~ **This is now implemented, and released in PR #174 of V 1.6.5!**
**[⬆️ Back to Top](#authentication)** **[⬆️ Back to Top](#authentication)**
--- ---
## Keycloak ## Keycloak
Dashy also supports using a [Keycloack](https://www.keycloak.org/) authentication server. The setup for this is a bit more involved, but it gives you greater security overall, useful for if your instance is exposed to the internet. Dashy also supports using a [Keycloack](https://www.keycloak.org/) authentication server. The setup for this is a bit more involved, but it gives you greater security overall, useful for if your instance is exposed to the internet.
[Keycloak](https://www.keycloak.org/about.html) is a Java-based [open source](https://github.com/keycloak/keycloak), high-performance, secure authentication system, supported by [RedHad](https://www.redhat.com/en). It is easy to setup ([with Docker](https://quay.io/repository/keycloak/keycloak)), and enables you to secure multiple self-hosted applications with single-sign on using standard protocols (OpenID Connect, OAuth 2.0, SAML 2.0 and social login). It's also very customizable, you can write or use custom [themes](https://wjw465150.gitbooks.io/keycloak-documentation/content/server_development/topics/themes.html), [plugins](https://www.keycloak.org/extensions.html), [password policies](https://wjw465150.gitbooks.io/keycloak-documentation/content/server_admin/topics/authentication/password-policies.html) and more. [Keycloak](https://www.keycloak.org/about.html) is a Java-based [open source](https://github.com/keycloak/keycloak), high-performance, secure authentication system, supported by [RedHad](https://www.redhat.com/en). It is easy to setup ([with Docker](https://quay.io/repository/keycloak/keycloak)), and enables you to secure multiple self-hosted applications with single-sign on using standard protocols (OpenID Connect, OAuth 2.0, SAML 2.0 and social login). It's also very customizable, you can write or use custom [themes](https://wjw465150.gitbooks.io/keycloak-documentation/content/server_development/topics/themes.html), [plugins](https://www.keycloak.org/extensions.html), [password policies](https://wjw465150.gitbooks.io/keycloak-documentation/content/server_admin/topics/authentication/password-policies.html) and more.
The following guide will walk you through setting up Keycloak with Dashy. If you already have a Keycloak instance configured, then skip to Step 3. The following guide will walk you through setting up Keycloak with Dashy. If you already have a Keycloak instance configured, then skip to Step 3.
### 1. Deploy Keycloak ### 1. Deploy Keycloak
First thing to do is to spin up a new instance of Keycloak. You will need [Docker installed](https://docs.docker.com/engine/install/), and can then choose a tag, and pull the container from [quay.io/keycloak/keycloak](https://quay.io/repository/keycloak/keycloak) First thing to do is to spin up a new instance of Keycloak. You will need [Docker installed](https://docs.docker.com/engine/install/), and can then choose a tag, and pull the container from [quay.io/keycloak/keycloak](https://quay.io/repository/keycloak/keycloak)
Use the following run command, replacing the attributes (default credentials, port and name), or incorporate this into your docker-compose file. Use the following run command, replacing the attributes (default credentials, port and name), or incorporate this into your docker-compose file.
```bash ```bash
docker run -d \ docker run -d \
-p 8081:8080 \ -p 8081:8080 \
--name auth-server \ --name auth-server \
-e KEYCLOAK_USER=admin \ -e KEYCLOAK_USER=admin \
-e KEYCLOAK_PASSWORD=admin \ -e KEYCLOAK_PASSWORD=admin \
quay.io/keycloak/keycloak:15.0.2 quay.io/keycloak/keycloak:15.0.2
``` ```
If you need to pull from DockerHub, a non-official image is available [here](https://registry.hub.docker.com/r/jboss/keycloak). Or if you would prefer not to use Docker, you can also directly install Keycloak from source, following [this guide](https://www.keycloak.org/docs/latest/getting_started/index.html). If you need to pull from DockerHub, a non-official image is available [here](https://registry.hub.docker.com/r/jboss/keycloak). Or if you would prefer not to use Docker, you can also directly install Keycloak from source, following [this guide](https://www.keycloak.org/docs/latest/getting_started/index.html).
You should now be able to access the Keycloak web interface, using the port specified above (e.g. `http://127.0.0.1:8081`), login with the default credentials, and when prompted create a new password. You should now be able to access the Keycloak web interface, using the port specified above (e.g. `http://127.0.0.1:8081`), login with the default credentials, and when prompted create a new password.
### 2. Setup Keycloak Users ### 2. Setup Keycloak Users
Before we can use Keycloak, we must first set it up with some users. Keycloak uses Realms (similar to tenants) to create isolated groups of users. You must create a Realm before you will be able to add your first user. Before we can use Keycloak, we must first set it up with some users. Keycloak uses Realms (similar to tenants) to create isolated groups of users. You must create a Realm before you will be able to add your first user.
1. Head over to the admin console 1. Head over to the admin console
2. In the top-left corner there is a dropdown called 'Master', hover over it and then click 'Add Realm' 2. In the top-left corner there is a dropdown called 'Master', hover over it and then click 'Add Realm'
3. Give your realm a name, and hit 'Create' 3. Give your realm a name, and hit 'Create'
You can now create your first user. You can now create your first user.
1. In the left-hand menu, click 'Users', then 'Add User' 1. In the left-hand menu, click 'Users', then 'Add User'
2. Fill in the form, including username and hit 'Save' 2. Fill in the form, including username and hit 'Save'
3. Under the 'Credentials' tab, give the new user an initial password. They will be prompted to change this after first login 3. Under the 'Credentials' tab, give the new user an initial password. They will be prompted to change this after first login
The last thing we need to do in the Keycloak admin console is to create a new client The last thing we need to do in the Keycloak admin console is to create a new client
1. Within your new realm, navigate to 'Clients' on the left-hand side, then click 'Create' in the top-right 1. Within your new realm, navigate to 'Clients' on the left-hand side, then click 'Create' in the top-right
2. Choose a 'Client ID', set 'Client Protocol' to 'openid-connect', and for 'Valid Redirect URIs' put a URL pattern to where you're hosting Dashy (if you're just testing locally, then * is fine), and do the same for the 'Web Origins' field 2. Choose a 'Client ID', set 'Client Protocol' to 'openid-connect', and for 'Valid Redirect URIs' put a URL pattern to where you're hosting Dashy (if you're just testing locally, then * is fine), and do the same for the 'Web Origins' field
3. Make note of your client-id, and click 'Save' 3. Make note of your client-id, and click 'Save'
### 3. Enable Keycloak in Dashy Config File ### 3. Enable Keycloak in Dashy Config File
Now that your Keycloak instance is up and running, all that's left to do is to configure Dashy to use it. Under `appConfig`, set `auth.enableKeycloak: true`, then fill in the details in `auth.keycloak`, including: `serverUrl` - the URL where your Keycloak instance is hosted, `realm` - the name you gave your Realm, and `clientId` - the Client ID you chose. Now that your Keycloak instance is up and running, all that's left to do is to configure Dashy to use it. Under `appConfig`, set `auth.enableKeycloak: true`, then fill in the details in `auth.keycloak`, including: `serverUrl` - the URL where your Keycloak instance is hosted, `realm` - the name you gave your Realm, and `clientId` - the Client ID you chose.
For example: For example:
```yaml ```yaml
appConfig: appConfig:
... ...
auth: auth:
enableKeycloak: true enableKeycloak: true
keycloak: keycloak:
serverUrl: 'http://localhost:8081' serverUrl: 'http://localhost:8081'
realm: 'alicia-homelab' realm: 'alicia-homelab'
clientId: 'dashy' clientId: 'dashy'
``` ```
Your app is now secured :) When you load Dashy, it will redirect to your Keycloak login page, and any user without valid credentials will be prevented from accessing your dashboard. Your app is now secured :) When you load Dashy, it will redirect to your Keycloak login page, and any user without valid credentials will be prevented from accessing your dashboard.
From within the Keycloak console, you can then configure things like user permissions, time outs, password policies, access, etc. You can also backup your full Keycloak config, and it is recommended to do this, along with your Dashy config. You can spin up both Dashy and Keycloak simultaneously and restore both applications configs using a `docker-compose.yml` file, and this is recommended. From within the Keycloak console, you can then configure things like user permissions, time outs, password policies, access, etc. You can also backup your full Keycloak config, and it is recommended to do this, along with your Dashy config. You can spin up both Dashy and Keycloak simultaneously and restore both applications configs using a `docker-compose.yml` file, and this is recommended.
--- ---
## Alternative Authentication Methods ## 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: 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:
- [Authentication Server](#authentication-server) - Put Dashy behind a self-hosted auth server - [Authentication Server](#authentication-server) - Put Dashy behind a self-hosted auth server
- [VPN](#vpn) - Use a VPN to tunnel into the network where Dashy is running - [VPN](#vpn) - Use a VPN to tunnel into the network where Dashy is running
- [IP-Based Access](#ip-based-access) - Disallow access from all IP addresses, except your own - [IP-Based Access](#ip-based-access) - Disallow access from all IP addresses, except your own
- [Web Server Authentication](#web-server-authentication) - Enable user control within your web server or proxy - [Web Server Authentication](#web-server-authentication) - Enable user control within your web server or proxy
- [OAuth Services](#oauth-services) - Implement a user management system using a cloud provider - [OAuth Services](#oauth-services) - Implement a user management system using a cloud provider
- [Password Protection (for cloud providers)](#static-site-hosting-providers) - Enable password-protection on your site - [Password Protection (for cloud providers)](#static-site-hosting-providers) - Enable password-protection on your site
### Authentication Server ### Authentication Server
##### Authelia ##### Authelia
[Authelia](https://www.authelia.com/) is an open-source full-featured authentication server, which can be self-hosted and either on bare metal, in a Docker container or in a Kubernetes cluster. It allows for fine-grained access control rules based on IP, path, users etc, and supports 2FA, simple password access or bypass policies for your domains. [Authelia](https://www.authelia.com/) is an open-source full-featured authentication server, which can be self-hosted and either on bare metal, in a Docker container or in a Kubernetes cluster. It allows for fine-grained access control rules based on IP, path, users etc, and supports 2FA, simple password access or bypass policies for your domains.
- `git clone https://github.com/authelia/authelia.git` - `git clone https://github.com/authelia/authelia.git`
- `cd authelia/examples/compose/lite` - `cd authelia/examples/compose/lite`
- Modify the `users_database.yml` the default username and password is authelia - Modify the `users_database.yml` the default username and password is authelia
- Modify the `configuration.yml` and `docker-compose.yml` with your respective domains and secrets - Modify the `configuration.yml` and `docker-compose.yml` with your respective domains and secrets
- `docker-compose up -d` - `docker-compose up -d`
For more information, see the [Authelia docs](https://www.authelia.com/docs/) For more information, see the [Authelia docs](https://www.authelia.com/docs/)
### VPN ### VPN
A catch-all solution to accessing services running from your home network remotely is to use a VPN. It means you do not need to worry about implementing complex authentication rules, or trusting the login implementation of individual applications. However it can be inconvenient to use on a day-to-day basis, and some public and corporate WiFi block VPN connections. Two popular VPN protocols are [OpenVPN](https://openvpn.net/) and [WireGuard](https://www.wireguard.com/) A catch-all solution to accessing services running from your home network remotely is to use a VPN. It means you do not need to worry about implementing complex authentication rules, or trusting the login implementation of individual applications. However it can be inconvenient to use on a day-to-day basis, and some public and corporate WiFi block VPN connections. Two popular VPN protocols are [OpenVPN](https://openvpn.net/) and [WireGuard](https://www.wireguard.com/)
### IP-Based Access ### IP-Based Access
If you have a static IP or use a VPN to access your running services, then you can use conditional access to block access to Dashy from everyone except users of your pre-defined IP address. This feature is offered by most cloud providers, and supported by most web servers. If you have a static IP or use a VPN to access your running services, then you can use conditional access to block access to Dashy from everyone except users of your pre-defined IP address. This feature is offered by most cloud providers, and supported by most web servers.
##### Apache ##### Apache
In Apache, this is configured in your `.htaccess` file in Dashy's root folder, and should look something like: In Apache, this is configured in your `.htaccess` file in Dashy's root folder, and should look something like:
``` ```
Order Deny,Allow Order Deny,Allow
Deny from all Deny from all
Allow from [your-ip] Allow from [your-ip]
``` ```
##### NGINX ##### NGINX
In NGINX you can specify [control access](https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-http/) rules for a given site in your `nginx.conf` or hosts file. For example: In NGINX you can specify [control access](https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-http/) rules for a given site in your `nginx.conf` or hosts file. For example:
``` ```
server { server {
listen 80; listen 80;
server_name www.dashy.example.com; server_name www.dashy.example.com;
location / { location / {
root /path/to/dashy/; root /path/to/dashy/;
passenger_enabled on; passenger_enabled on;
allow [your-ip]; allow [your-ip];
deny all; deny all;
} }
} }
``` ```
##### Caddy ##### Caddy
In Caddy, [Request Matchers](https://caddyserver.com/docs/caddyfile/matchers) can be used to filter requests In Caddy, [Request Matchers](https://caddyserver.com/docs/caddyfile/matchers) can be used to filter requests
``` ```
dashy.site { dashy.site {
@public_networks not remote_ip [your-ip] @public_networks not remote_ip [your-ip]
respond @public_networks "Access denied" 403 respond @public_networks "Access denied" 403
} }
``` ```
### Web Server Authentication ### Web Server Authentication
Most web servers make password protecting certain apps very easy. Note that you should also set up HTTPS and have a valid certificate in order for this to be secure. Most web servers make password protecting certain apps very easy. Note that you should also set up HTTPS and have a valid certificate in order for this to be secure.
##### Apache ##### Apache
First crate a `.htaccess` file in Dashy's route directory. Specify the auth type and path to where you want to store the password file (usually the same folder). For example: First crate a `.htaccess` file in Dashy's route directory. Specify the auth type and path to where you want to store the password file (usually the same folder). For example:
``` ```
AuthType Basic AuthType Basic
AuthName "Please Sign into Dashy" AuthName "Please Sign into Dashy"
AuthUserFile /path/dashy/.htpasswd AuthUserFile /path/dashy/.htpasswd
require valid-user require valid-user
``` ```
Then create a `.htpasswd` file in the same directory. List users and their hashed passwords here, with one user on each line, and a colon between username and password (e.g. `[username]:[hashed-password]`). You will need to generate an MD5 hash of your desired password, this can be done with an [online tool](https://www.web2generators.com/apache-tools/htpasswd-generator). Your file will look something like: Then create a `.htpasswd` file in the same directory. List users and their hashed passwords here, with one user on each line, and a colon between username and password (e.g. `[username]:[hashed-password]`). You will need to generate an MD5 hash of your desired password, this can be done with an [online tool](https://www.web2generators.com/apache-tools/htpasswd-generator). Your file will look something like:
``` ```
alicia:$apr1$jv0spemw$RzOX5/GgY69JMkgV6u16l0 alicia:$apr1$jv0spemw$RzOX5/GgY69JMkgV6u16l0
``` ```
##### NGINX ##### NGINX
NGINX has an [authentication module](https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html) which can be used to add passwords to given sites, and is fairly simple to set up. Similar to above, you will need to create a `.htpasswd` file. Then just enable auth and specify the path to that file, for example: NGINX has an [authentication module](https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html) which can be used to add passwords to given sites, and is fairly simple to set up. Similar to above, you will need to create a `.htpasswd` file. Then just enable auth and specify the path to that file, for example:
``` ```
location / { location / {
auth_basic "closed site"; auth_basic "closed site";
auth_basic_user_file conf/htpasswd; auth_basic_user_file conf/htpasswd;
} }
``` ```
##### Caddy ##### Caddy
Caddy has a [basic-auth](https://caddyserver.com/docs/caddyfile/directives/basicauth) directive, where you specify a username and hash. The password hash needs to be base-64 encoded, the [`caddy hash-password`](https://caddyserver.com/docs/command-line#caddy-hash-password) command can help with this. For example: Caddy has a [basic-auth](https://caddyserver.com/docs/caddyfile/directives/basicauth) directive, where you specify a username and hash. The password hash needs to be base-64 encoded, the [`caddy hash-password`](https://caddyserver.com/docs/command-line#caddy-hash-password) command can help with this. For example:
``` ```
basicauth /secret/* { basicauth /secret/* {
alicia JDJhJDEwJEVCNmdaNEg2Ti5iejRMYkF3MFZhZ3VtV3E1SzBWZEZ5Q3VWc0tzOEJwZE9TaFlZdEVkZDhX alicia JDJhJDEwJEVCNmdaNEg2Ti5iejRMYkF3MFZhZ3VtV3E1SzBWZEZ5Q3VWc0tzOEJwZE9TaFlZdEVkZDhX
} }
``` ```
For more info about implementing a single sign on for all your apps with Caddy, see [this tutorial](https://joshstrange.com/securing-your-self-hosted-apps-with-single-signon/) For more info about implementing a single sign on for all your apps with Caddy, see [this tutorial](https://joshstrange.com/securing-your-self-hosted-apps-with-single-signon/)
##### Lighttpd ##### Lighttpd
You can use the [mod_auth](https://doc.lighttpd.net/lighttpd2/mod_auth.html) module to secure your site with Lighttpd. Like with Apache, you need to first create a password file listing your usersnames and hashed passwords, but in Lighttpd, it's usually called `.lighttpdpassword`. You can use the [mod_auth](https://doc.lighttpd.net/lighttpd2/mod_auth.html) module to secure your site with Lighttpd. Like with Apache, you need to first create a password file listing your usersnames and hashed passwords, but in Lighttpd, it's usually called `.lighttpdpassword`.
Then in your `lighttpd.conf` file (usually in the `/etc/lighttpd/` directory), load in the mod_auth module, and configure it's directives. For example: Then in your `lighttpd.conf` file (usually in the `/etc/lighttpd/` directory), load in the mod_auth module, and configure it's directives. For example:
``` ```
server.modules += ( "mod_auth" ) server.modules += ( "mod_auth" )
auth.debug = 2 auth.debug = 2
auth.backend = "plain" auth.backend = "plain"
auth.backend.plain.userfile = "/home/lighttpd/.lighttpdpassword" auth.backend.plain.userfile = "/home/lighttpd/.lighttpdpassword"
$HTTP["host"] == "dashy.my-domain.net" { $HTTP["host"] == "dashy.my-domain.net" {
server.document-root = "/home/lighttpd/dashy.my-domain.net/http" server.document-root = "/home/lighttpd/dashy.my-domain.net/http"
server.errorlog = "/var/log/lighttpd/dashy.my-domain.net/error.log" server.errorlog = "/var/log/lighttpd/dashy.my-domain.net/error.log"
accesslog.filename = "/var/log/lighttpd/dashy.my-domain.net/access.log" accesslog.filename = "/var/log/lighttpd/dashy.my-domain.net/access.log"
auth.require = ( auth.require = (
"/docs/" => ( "/docs/" => (
"method" => "basic", "method" => "basic",
"realm" => "Password protected area", "realm" => "Password protected area",
"require" => "user=alicia" "require" => "user=alicia"
) )
) )
} }
``` ```
Restart your web server for changes to take effect. Restart your web server for changes to take effect.
### OAuth Services ### OAuth Services
There are also authentication services, such as [Ory.sh](https://www.ory.sh/), [Okta](https://developer.okta.com/), [Auth0](https://auth0.com/), [Firebase](https://firebase.google.com/docs/auth/). Implementing one of these solutions would involve some changes to the [`Auth.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/Auth.js) file, but should be fairly straight forward. There are also authentication services, such as [Ory.sh](https://www.ory.sh/), [Okta](https://developer.okta.com/), [Auth0](https://auth0.com/), [Firebase](https://firebase.google.com/docs/auth/). Implementing one of these solutions would involve some changes to the [`Auth.js`](https://github.com/Lissy93/dashy/blob/master/src/utils/Auth.js) file, but should be fairly straight forward.
### Static Site Hosting Providers ### Static Site Hosting Providers
If you are hosting Dashy on a cloud platform, you will probably find that it has built-in support for password protected access to web apps. For more info, see the relevant docs for your provider, for example: [Netlify Password Protection](https://docs.netlify.com/visitor-access/password-protection/), [Cloudflare Access](https://www.cloudflare.com/teams/access/), [AWS Cognito](https://aws.amazon.com/cognito/), [Azure Authentication](https://docs.microsoft.com/en-us/azure/app-service/scenario-secure-app-authentication-app-service) and [Vercel Password Protection](https://vercel.com/docs/platform/projects#password-protection). If you are hosting Dashy on a cloud platform, you will probably find that it has built-in support for password protected access to web apps. For more info, see the relevant docs for your provider, for example: [Netlify Password Protection](https://docs.netlify.com/visitor-access/password-protection/), [Cloudflare Access](https://www.cloudflare.com/teams/access/), [AWS Cognito](https://aws.amazon.com/cognito/), [Azure Authentication](https://docs.microsoft.com/en-us/azure/app-service/scenario-secure-app-authentication-app-service) and [Vercel Password Protection](https://vercel.com/docs/platform/projects#password-protection).
**[⬆️ Back to Top](#authentication)** **[⬆️ Back to Top](#authentication)**

View File

@ -1,323 +1,323 @@
# Developing # Developing
This article outlines how to get Dashy running in a development environment, and outlines the basics of the architecture. This article outlines how to get Dashy running in a development environment, and outlines the basics of the architecture.
If you're adding new features, you may want to check out the [Development Guides](./docs/development-guides.md) docs, for tutorials covering basic tasks. If you're adding new features, you may want to check out the [Development Guides](./docs/development-guides.md) docs, for tutorials covering basic tasks.
- [Setting up the Development Environment](#setting-up-the-dev-environment) - [Setting up the Development Environment](#setting-up-the-dev-environment)
- [Prerequisites](#prerequisites) - [Prerequisites](#prerequisites)
- [Running the App](#running-the-project) - [Running the App](#running-the-project)
- [Project Commands](#project-commands) - [Project Commands](#project-commands)
- [Environmental Variables](#environmental-variables) - [Environmental Variables](#environmental-variables)
- [Git Strategy](#git-strategy) - [Git Strategy](#git-strategy)
- [Flow](#git-flow) - [Flow](#git-flow)
- [Branches](#git-branch-naming) - [Branches](#git-branch-naming)
- [Commit emojis](#commit-emojis) - [Commit emojis](#commit-emojis)
- [PR Guidelines](#pr-guidelines) - [PR Guidelines](#pr-guidelines)
- [Resources for Beginners](#resources-for-beginners) - [Resources for Beginners](#resources-for-beginners)
- [App Info](#app-info) - [App Info](#app-info)
- [Code Style Guide](#style-guide) - [Code Style Guide](#style-guide)
- [Application Structure](#application-structure) - [Application Structure](#application-structure)
- [Development Tools](#development-tools) - [Development Tools](#development-tools)
- [Misc / Notes](#notes) - [Misc / Notes](#notes)
## Setting up the Dev Environment ## Setting up the Dev Environment
### Prerequisites ### Prerequisites
You will need either the latest or LTS version of **[Node.js](https://nodejs.org/)** to build and serve the application and **[Git](https://git-scm.com/downloads)** to easily fetch the code, and push any changes. If you plan on running or deploying the container, you'll also need **[Docker](https://docs.docker.com/get-docker/)**. To avoid any unexpected issues, ensure you've got at least **[NPM](https://www.npmjs.com/get-npm)** V 7.5 or **[Yarn](https://classic.yarnpkg.com/en/docs/install/#windows-stable)** 1.22 (you may find [NVM](https://github.com/nvm-sh/nvm) helpful for switching/ managing versions). You will need either the latest or LTS version of **[Node.js](https://nodejs.org/)** to build and serve the application and **[Git](https://git-scm.com/downloads)** to easily fetch the code, and push any changes. If you plan on running or deploying the container, you'll also need **[Docker](https://docs.docker.com/get-docker/)**. To avoid any unexpected issues, ensure you've got at least **[NPM](https://www.npmjs.com/get-npm)** V 7.5 or **[Yarn](https://classic.yarnpkg.com/en/docs/install/#windows-stable)** 1.22 (you may find [NVM](https://github.com/nvm-sh/nvm) helpful for switching/ managing versions).
### Running the Project ### Running the Project
1. Get Code: `git clone https://github.com/Lissy93/dashy.git` 1. Get Code: `git clone https://github.com/Lissy93/dashy.git`
2. Navigate into the directory: `cd dashy` 2. Navigate into the directory: `cd dashy`
3. Install dependencies: `yarn` 3. Install dependencies: `yarn`
4. Start dev server: `yarn dev` 4. Start dev server: `yarn dev`
Dashy should now be being served on http://localhost:8080/. Hot reload is enabled, so making changes to any of the files will trigger them to be rebuilt and the page refreshed. Dashy should now be being served on http://localhost:8080/. Hot reload is enabled, so making changes to any of the files will trigger them to be rebuilt and the page refreshed.
### Project Commands ### Project Commands
#### Basics #### Basics
- **`yarn build`** - In the interest of speed, the application is pre-compiled, this means that the config file is read during build-time, and therefore the app needs to rebuilt for any new changes to take effect. Luckily this is very straight forward. Just run `yarn build` or `docker exec -it [container-id] yarn build` - **`yarn build`** - In the interest of speed, the application is pre-compiled, this means that the config file is read during build-time, and therefore the app needs to rebuilt for any new changes to take effect. Luckily this is very straight forward. Just run `yarn build` or `docker exec -it [container-id] yarn build`
- **`yarn start`** - Starts a web server, and serves up the production site from `./dist` (must run build command first) - **`yarn start`** - Starts a web server, and serves up the production site from `./dist` (must run build command first)
#### Development #### Development
- **`yarn dev`** - Starts the development server with hot reloading - **`yarn dev`** - Starts the development server with hot reloading
- **`yarn lint`** - Lints code to ensure it follows a consistent, neat style - **`yarn lint`** - Lints code to ensure it follows a consistent, neat style
- **`yarn test`** - Runs tests, and outputs results - **`yarn test`** - Runs tests, and outputs results
#### Utils and Checks #### Utils and Checks
- **`yarn validate-config`** - If you have quite a long configuration file, you may wish to check that it's all good to go, before deploying the app. This can be done with `yarn validate-config` or `docker exec -it [container-id] yarn validate-config`. Your config file needs to be in `/public/conf.yml` (or within your Docker container at `/app/public/conf.yml`). This will first check that your YAML is valid, and then validates it against Dashy's [schema](https://github.com/Lissy93/dashy/blob/master/src/utils/ConfigSchema.js). - **`yarn validate-config`** - If you have quite a long configuration file, you may wish to check that it's all good to go, before deploying the app. This can be done with `yarn validate-config` or `docker exec -it [container-id] yarn validate-config`. Your config file needs to be in `/public/conf.yml` (or within your Docker container at `/app/public/conf.yml`). This will first check that your YAML is valid, and then validates it against Dashy's [schema](https://github.com/Lissy93/dashy/blob/master/src/utils/ConfigSchema.js).
- **`yarn health-check`** - Checks that the application is up and running on it's specified port, and outputs current status and response times. Useful for integrating into your monitoring service, if you need to maintain high system availability - **`yarn health-check`** - Checks that the application is up and running on it's specified port, and outputs current status and response times. Useful for integrating into your monitoring service, if you need to maintain high system availability
#### Alternate Start Commands #### Alternate Start Commands
- **`yarn build-and-start`** - Builds the app, runs checks and starts the production server. Commands are run in parallel, and so is faster than running them in independently. Uses the `yarn build` and `yarn start` commands - **`yarn build-and-start`** - Builds the app, runs checks and starts the production server. Commands are run in parallel, and so is faster than running them in independently. Uses the `yarn build` and `yarn start` commands
- **`yarn build-watch`** - If you find yourself making frequent changes to your configuration, and do not want to have to keep manually rebuilding, then this option is for you. It will watch for changes to any files within the projects root, and then trigger a rebuild. Note that if you are developing new features, then `yarn dev` would be more appropriate, as it's significantly faster at recompiling (under 1 second), and has hot reloading, linting and testing integrated - **`yarn build-watch`** - If you find yourself making frequent changes to your configuration, and do not want to have to keep manually rebuilding, then this option is for you. It will watch for changes to any files within the projects root, and then trigger a rebuild. Note that if you are developing new features, then `yarn dev` would be more appropriate, as it's significantly faster at recompiling (under 1 second), and has hot reloading, linting and testing integrated
- **`yarn pm2-start`** - Starts the Node server using [PM2](https://pm2.keymetrics.io/), a process manager for Node.js applications, that helps them stay alive. PM2 has some built-in basic monitoring features, and an optional [management solution](https://pm2.io/). If you are running the app on bare metal, it is recommended to use this start command - **`yarn pm2-start`** - Starts the Node server using [PM2](https://pm2.keymetrics.io/), a process manager for Node.js applications, that helps them stay alive. PM2 has some built-in basic monitoring features, and an optional [management solution](https://pm2.io/). If you are running the app on bare metal, it is recommended to use this start command
#### Notes #### Notes
- If you are using NPM, replace `yarn` with `npm run` - If you are using NPM, replace `yarn` with `npm run`
- If you are using Docker, precede each command with `docker exec -it [container-id]`. Container ID can be found by running `docker ps` - If you are using Docker, precede each command with `docker exec -it [container-id]`. Container ID can be found by running `docker ps`
- You can manage the app using the [Vue-CLI Service](https://cli.vuejs.org/guide/cli-service.html), with `npx vue-cli-service [command]`. Or to start the Vue Management UI, run `npx vue ui`, and open `http://localhost:8000` - You can manage the app using the [Vue-CLI Service](https://cli.vuejs.org/guide/cli-service.html), with `npx vue-cli-service [command]`. Or to start the Vue Management UI, run `npx vue ui`, and open `http://localhost:8000`
### Environmental Variables ### Environmental Variables
All environmental variables are optional. Currently there are not many environmental variables used, as most of the user preferences are stored under `appConfig` in the `conf.yml` file. All environmental variables are optional. Currently there are not many environmental variables used, as most of the user preferences are stored under `appConfig` in the `conf.yml` file.
You can set variables either in your environment, or using the [`.env`](https://github.com/Lissy93/dashy/blob/master/.env) file. You can set variables either in your environment, or using the [`.env`](https://github.com/Lissy93/dashy/blob/master/.env) file.
- `NODE_ENV` - Current environment, can be either development, production or test - `NODE_ENV` - Current environment, can be either development, production or test
- `PORT` - The port to expose the running application on - `PORT` - The port to expose the running application on
- `HOST` - The host that Dashy is running on, domain or IP - `HOST` - The host that Dashy is running on, domain or IP
- `BASE_URL` - The default base path for serving up static assets - `BASE_URL` - The default base path for serving up static assets
- `VUE_APP_DOMAIN` - Usually the same as BASE_URL, but accessible in frontend - `VUE_APP_DOMAIN` - Usually the same as BASE_URL, but accessible in frontend
- `INTEGRITY` - Should enable SRI for build script and link resources - `INTEGRITY` - Should enable SRI for build script and link resources
- `IS_DOCKER` - Computed automatically on build. Indicates if running in container - `IS_DOCKER` - Computed automatically on build. Indicates if running in container
- `VUE_APP_VERSION` - Again, set automatically using package.json during build time - `VUE_APP_VERSION` - Again, set automatically using package.json during build time
### Environment Modes ### Environment Modes
You can set the environment using the `NODE_ENV` variable. By default, the correct environment should be selected based on the script you run to start the app. The following environments are supported: `production`, `development` and `test`. For more info, see [Vue CLI Environment Modes](https://cli.vuejs.org/guide/mode-and-env.html#modes). You can set the environment using the `NODE_ENV` variable. By default, the correct environment should be selected based on the script you run to start the app. The following environments are supported: `production`, `development` and `test`. For more info, see [Vue CLI Environment Modes](https://cli.vuejs.org/guide/mode-and-env.html#modes).
--- ---
## Git Strategy ## Git Strategy
### Git Flow ### Git Flow
Like most Git repos, we are following the [Github Flow](https://guides.github.com/introduction/flow) standard. Like most Git repos, we are following the [Github Flow](https://guides.github.com/introduction/flow) standard.
1. Create a branch (or fork if you don'd have write access) 1. Create a branch (or fork if you don'd have write access)
2. Code some awesome stuff 🧑‍💻 2. Code some awesome stuff 🧑‍💻
3. Add, commit and push your changes to your branch/ fork 3. Add, commit and push your changes to your branch/ fork
4. Head over to GitHub and create a Pull Request 4. Head over to GitHub and create a Pull Request
5. Fill in the required sections in the template, and hit submit 5. Fill in the required sections in the template, and hit submit
6. Follow up with any reviews on your code 6. Follow up with any reviews on your code
7. Merge 🎉 7. Merge 🎉
### Git Branch Naming ### Git Branch Naming
The format of your branch name should be something similar to: `[TYPE]/[TICKET]_[TITLE]` The format of your branch name should be something similar to: `[TYPE]/[TICKET]_[TITLE]`
For example, `FEATURE/420_Awesome-feature` or `FIX/690_login-server-error` For example, `FEATURE/420_Awesome-feature` or `FIX/690_login-server-error`
### Commit Emojis ### Commit Emojis
Using a single emoji at the start of each commit message, to indicate the type task, makes the commit ledger easier to understand, plus it looks cool. Using a single emoji at the start of each commit message, to indicate the type task, makes the commit ledger easier to understand, plus it looks cool.
- 🎨 `:art:` - Improve structure / format of the code. - 🎨 `:art:` - Improve structure / format of the code.
- ⚡️ `:zap:` - Improve performance. - ⚡️ `:zap:` - Improve performance.
- 🔥 `:fire:` - Remove code or files. - 🔥 `:fire:` - Remove code or files.
- 🐛 `:bug:` - Fix a bug. - 🐛 `:bug:` - Fix a bug.
- 🚑️ `:ambulance:` - Critical hotfix - 🚑️ `:ambulance:` - Critical hotfix
- ✨ `:sparkles:` - Introduce new features. - ✨ `:sparkles:` - Introduce new features.
- 📝 `:memo:` - Add or update documentation. - 📝 `:memo:` - Add or update documentation.
- 🚀 `:rocket:` - Deploy stuff. - 🚀 `:rocket:` - Deploy stuff.
- 💄 `:lipstick:` - Add or update the UI and style files. - 💄 `:lipstick:` - Add or update the UI and style files.
- 🎉 `:tada:` - Begin a project. - 🎉 `:tada:` - Begin a project.
- ✅ `:white_check_mark:` - Add, update, or pass tests. - ✅ `:white_check_mark:` - Add, update, or pass tests.
- 🔒️ `:lock:` - Fix security issues. - 🔒️ `:lock:` - Fix security issues.
- 🔖 `:bookmark:` - Make a Release or Version tag. - 🔖 `:bookmark:` - Make a Release or Version tag.
- 🚨 `:rotating_light:` - Fix compiler / linter warnings. - 🚨 `:rotating_light:` - Fix compiler / linter warnings.
- 🚧 `:construction:` - Work in progress. - 🚧 `:construction:` - Work in progress.
- ⬆️ `:arrow_up:` - Upgrade dependencies. - ⬆️ `:arrow_up:` - Upgrade dependencies.
- 👷 `:construction_worker:` - Add or update CI build system. - 👷 `:construction_worker:` - Add or update CI build system.
- ♻️ `:recycle:` - Refactor code. - ♻️ `:recycle:` - Refactor code.
- 🩹 `:adhesive_bandage:` - Simple fix for a non-critical issue. - 🩹 `:adhesive_bandage:` - Simple fix for a non-critical issue.
- 🔧 `:wrench:` - Add or update configuration files. - 🔧 `:wrench:` - Add or update configuration files.
- 🍱 `:bento:` - Add or update assets. - 🍱 `:bento:` - Add or update assets.
- 🗃️ `:card_file_box:` - Perform database schema related changes. - 🗃️ `:card_file_box:` - Perform database schema related changes.
- ✏️ `:pencil2:` - Fix typos. - ✏️ `:pencil2:` - Fix typos.
- 🌐 `:globe_with_meridians:` - Internationalization and translations. - 🌐 `:globe_with_meridians:` - Internationalization and translations.
For a full list of options, see [gitmoji.dev](https://gitmoji.dev/) For a full list of options, see [gitmoji.dev](https://gitmoji.dev/)
### PR Guidelines ### PR Guidelines
Once you've made your changes, and pushed them to your fork or branch, you're ready to open a pull request! Once you've made your changes, and pushed them to your fork or branch, you're ready to open a pull request!
For a pull request to be merged, it must: For a pull request to be merged, it must:
- Must be backwards compatible - Must be backwards compatible
- The build, lint and tests (run by GH actions) must pass - The build, lint and tests (run by GH actions) must pass
- There must not be any merge conflicts - There must not be any merge conflicts
When you submit your PR, include the required info, by filling out the PR template. Including: When you submit your PR, include the required info, by filling out the PR template. Including:
- A brief description of your changes - A brief description of your changes
- The issue, ticket or discussion number (if applicable) - The issue, ticket or discussion number (if applicable)
- For UI relate updates include a screenshot - For UI relate updates include a screenshot
- If any dependencies were added, explain why it was needed, state the cost associated, and confirm it does not introduce any security issues - If any dependencies were added, explain why it was needed, state the cost associated, and confirm it does not introduce any security issues
- Finally, check the checkboxes, to confirm that the standards are met, and hit submit! - Finally, check the checkboxes, to confirm that the standards are met, and hit submit!
--- ---
## Resources for Beginners ## Resources for Beginners
New to Web Development? Glad you're here! Dashy is a pretty simple app, so it should make a good candidate for your first PR. Presuming that you already have a basic knowledge of JavaScript, the following articles should point you in the right direction for getting up to speed with the technologies used in this project: New to Web Development? Glad you're here! Dashy is a pretty simple app, so it should make a good candidate for your first PR. Presuming that you already have a basic knowledge of JavaScript, the following articles should point you in the right direction for getting up to speed with the technologies used in this project:
- [Open Source for Beginners](https://opensource.guide/how-to-contribute/) - [Open Source for Beginners](https://opensource.guide/how-to-contribute/)
- [Introduction to Vue.js](https://v3.vuejs.org/guide/introduction.html) - [Introduction to Vue.js](https://v3.vuejs.org/guide/introduction.html)
- [Vue.js Walkthrough](https://www.taniarascia.com/getting-started-with-vue/) - [Vue.js Walkthrough](https://www.taniarascia.com/getting-started-with-vue/)
- [ES6 Features](https://github.com/lukehoban/es6features) - [ES6 Features](https://github.com/lukehoban/es6features)
- [Definitive guide to SCSS](https://blog.logrocket.com/the-definitive-guide-to-scss/) - [Definitive guide to SCSS](https://blog.logrocket.com/the-definitive-guide-to-scss/)
- [Complete beginners guide to Docker](https://docker-curriculum.com/) - [Complete beginners guide to Docker](https://docker-curriculum.com/)
- [Docker Classroom - Interactive Tutorials](https://training.play-with-docker.com/) - [Docker Classroom - Interactive Tutorials](https://training.play-with-docker.com/)
- [Quick start TypeScript guide](https://www.freecodecamp.org/news/learn-typescript-in-5-minutes-13eda868daeb/) - [Quick start TypeScript guide](https://www.freecodecamp.org/news/learn-typescript-in-5-minutes-13eda868daeb/)
- [Complete TypeScript tutorial series](https://www.typescripttutorial.net/) - [Complete TypeScript tutorial series](https://www.typescripttutorial.net/)
- [Using TypeScript with Vue.js](https://blog.logrocket.com/vue-typescript-tutorial-examples/) - [Using TypeScript with Vue.js](https://blog.logrocket.com/vue-typescript-tutorial-examples/)
- [Git cheat sheet](http://git-cheatsheet.com/) - [Git cheat sheet](http://git-cheatsheet.com/)
- [Basics of using NPM](https://www.freecodecamp.org/news/what-is-npm-a-node-package-manager-tutorial-for-beginners/) - [Basics of using NPM](https://www.freecodecamp.org/news/what-is-npm-a-node-package-manager-tutorial-for-beginners/)
As well as Node, Git and Docker- you'll also need an IDE (e.g. [VS Code](https://code.visualstudio.com/) or [Vim](https://www.vim.org/)) and a terminal (Windows users may find [WSL](https://docs.microsoft.com/en-us/windows/wsl/) more convenient). As well as Node, Git and Docker- you'll also need an IDE (e.g. [VS Code](https://code.visualstudio.com/) or [Vim](https://www.vim.org/)) and a terminal (Windows users may find [WSL](https://docs.microsoft.com/en-us/windows/wsl/) more convenient).
--- ---
## App Info ## App Info
## Style Guide ## Style Guide
Linting is done using [ESLint](https://eslint.org/), and using the [Vue.js Styleguide](https://github.com/vuejs/eslint-config-standard), which is very similar to the [AirBnB Stylguide](https://github.com/airbnb/javascript). You can run `yarn lint` to report and fix issues. While the dev server is running, issues will be reported to the console automatically, and any lint errors will trigger the build to fail. Note that all lint checks must pass before any PR can be merged. Linting is also run as a git pre-commit hook Linting is done using [ESLint](https://eslint.org/), and using the [Vue.js Styleguide](https://github.com/vuejs/eslint-config-standard), which is very similar to the [AirBnB Stylguide](https://github.com/airbnb/javascript). You can run `yarn lint` to report and fix issues. While the dev server is running, issues will be reported to the console automatically, and any lint errors will trigger the build to fail. Note that all lint checks must pass before any PR can be merged. Linting is also run as a git pre-commit hook
The most significant things to note are: The most significant things to note are:
- Indentation should be done with two spaces - Indentation should be done with two spaces
- Strings should use single quotes - Strings should use single quotes
- All statements must end in a semi-colon - All statements must end in a semi-colon
- The final element in all objects must be preceded with a comma - The final element in all objects must be preceded with a comma
- Maximum line length is 100 - Maximum line length is 100
- There must be exactly one blank line between sections, before function names, and at the end of the file - There must be exactly one blank line between sections, before function names, and at the end of the file
- With conditionals, put else on the same line as your if blocks closing brace - With conditionals, put else on the same line as your if blocks closing brace
- All multiline blocks must use braces - All multiline blocks must use braces
- Avoid console statements in the frontend - Avoid console statements in the frontend
Styleguides: Styleguides:
- Vue: [Vue styleguide](https://vuejs.org/v2/style-guide/) - Vue: [Vue styleguide](https://vuejs.org/v2/style-guide/)
- JavaScript: [github.com/airbnb/javascript](https://github.com/airbnb/javascript) - JavaScript: [github.com/airbnb/javascript](https://github.com/airbnb/javascript)
--- ---
## Application Structure ## Application Structure
#### Files in the Root: `./` #### Files in the Root: `./`
``` ```
├── package.json # Project meta-data, dependencies and paths to scripts ├── package.json # Project meta-data, dependencies and paths to scripts
├── src/ # Project front-end source code ├── src/ # Project front-end source code
├── server.js # A Node.js server to serve up the /dist directory ├── server.js # A Node.js server to serve up the /dist directory
├── vue.config.js # Vue.js configuration ├── vue.config.js # Vue.js configuration
├── Dockerfile # The blueprint for building the Docker container ├── Dockerfile # The blueprint for building the Docker container
├── docker-compose.yml # A Docker run command ├── docker-compose.yml # A Docker run command
├── .env # Location for any environmental variables ├── .env # Location for any environmental variables
├── yarn.lock # Auto-generated list of current packages and version numbers ├── yarn.lock # Auto-generated list of current packages and version numbers
├── docs/ # Markdown documentation ├── docs/ # Markdown documentation
├── README.md # Readme, basic info for getting started ├── README.md # Readme, basic info for getting started
├── LICENSE.md # License for use ├── LICENSE.md # License for use
``` ```
#### Frontend Source: `./src/` #### Frontend Source: `./src/`
``` ```
./src ./src
├── App.vue # Vue.js starting file ├── App.vue # Vue.js starting file
├── assets # Static non-compiled assets ├── assets # Static non-compiled assets
│ ├── fonts # .ttf font files │ ├── fonts # .ttf font files
│ ├── locales # All app text, each language in a separate JSON file │ ├── locales # All app text, each language in a separate JSON file
│ ╰── interface-icons # SVG icons used in the app │ ╰── interface-icons # SVG icons used in the app
├── components # All front-end Vue web components ├── components # All front-end Vue web components
│ ├── Configuration # Components relating to the user config pop-up │ ├── Configuration # Components relating to the user config pop-up
│ │ ├── AppInfoModal.vue # A modal showing core app info, like version, language, etc │ │ ├── AppInfoModal.vue # A modal showing core app info, like version, language, etc
│ │ ├── AppVersion.vue # Shows current version from package.json, compares with GitHub │ │ ├── AppVersion.vue # Shows current version from package.json, compares with GitHub
│ │ ├── CloudBackupRestore.vue # Form where the user manages cloud sync options │ │ ├── CloudBackupRestore.vue # Form where the user manages cloud sync options
│ │ ├── ConfigContainer.vue # Main container, wrapping all other config components │ │ ├── ConfigContainer.vue # Main container, wrapping all other config components
│ │ ├── CustomCss.vue # Form where the user can input custom CSS │ │ ├── CustomCss.vue # Form where the user can input custom CSS
│ │ ├── EditSiteMeta.vue # Form where the user can edit site meta data │ │ ├── EditSiteMeta.vue # Form where the user can edit site meta data
│ │ ├── JsonEditor.vue # JSON editor, where the user can modify the main config file │ │ ├── JsonEditor.vue # JSON editor, where the user can modify the main config file
│ │ ╰── RebuildApp.vue # A component allowing user to trigger a rebuild through the UI │ │ ╰── RebuildApp.vue # A component allowing user to trigger a rebuild through the UI
│ ├── FormElements # Basic form elements used throughout the app │ ├── FormElements # Basic form elements used throughout the app
│ │ ├── Button.vue # Standard button component │ │ ├── Button.vue # Standard button component
│ │ ╰── Input.vue # Standard text field input component │ │ ╰── Input.vue # Standard text field input component
│ ├── LinkItems # Components for Sections and Link Items │ ├── LinkItems # Components for Sections and Link Items
│ │ ├── Collapsable.vue # The collapsible functionality of sections │ │ ├── Collapsable.vue # The collapsible functionality of sections
│ │ ├── ContextMenu.vue # The right-click menu, for showing Item opening methods and info │ │ ├── ContextMenu.vue # The right-click menu, for showing Item opening methods and info
│ │ ├── IframeModal.vue # Pop-up iframe modal, for viewing websites within the app │ │ ├── IframeModal.vue # Pop-up iframe modal, for viewing websites within the app
│ │ ├── Item.vue # Main link item, which is displayed within an item group │ │ ├── Item.vue # Main link item, which is displayed within an item group
│ │ ├── ItemGroup.vue # Item group is a section containing icons │ │ ├── ItemGroup.vue # Item group is a section containing icons
│ │ ├── ItemIcon.vue # The icon used by both items and sections │ │ ├── ItemIcon.vue # The icon used by both items and sections
│ │ ├── ItemOpenMethodIcon.vue # A small icon, visible on hover, indicating opening method │ │ ├── ItemOpenMethodIcon.vue # A small icon, visible on hover, indicating opening method
│ │ ╰── StatusIndicator.vue # Traffic light dot, showing if app is online or down │ │ ╰── StatusIndicator.vue # Traffic light dot, showing if app is online or down
│ ├── Minimal View # Components used for the startpage / minimal alternative view │ ├── Minimal View # Components used for the startpage / minimal alternative view
│ │ ├── MinimalHeading.vue # Title part of minimal view │ │ ├── MinimalHeading.vue # Title part of minimal view
│ │ ├── MinimalSearch.vue # Search bar for minimal view │ │ ├── MinimalSearch.vue # Search bar for minimal view
│ │ ╰── MinimalSection.vue # Tabbed-Item section for minimal view │ │ ╰── MinimalSection.vue # Tabbed-Item section for minimal view
│ ├── PageStrcture # Components relating the main structure of the page │ ├── PageStrcture # Components relating the main structure of the page
│ │ ├── Footer.vue # Footer, visible at the bottom of all pages │ │ ├── Footer.vue # Footer, visible at the bottom of all pages
│ │ ├── Header.vue # Header, visible at the top of pages, and includes title and nav │ │ ├── Header.vue # Header, visible at the top of pages, and includes title and nav
│ │ ├── LoadingScreen.vue # Splash screen shown on first load │ │ ├── LoadingScreen.vue # Splash screen shown on first load
│ │ ├── Nav.vue # Navigation bar, includes a list of links │ │ ├── Nav.vue # Navigation bar, includes a list of links
│ │ ╰── PageTitle.vue # Page title and sub-title, visible within the Header │ │ ╰── PageTitle.vue # Page title and sub-title, visible within the Header
│ ├── Workspace # Components used for the multi-tasking/ Workspace view │ ├── Workspace # Components used for the multi-tasking/ Workspace view
│ │ ├── MultiTaskingWeb.vue # When multi-tasking enabled, generates new iframe │ │ ├── MultiTaskingWeb.vue # When multi-tasking enabled, generates new iframe
│ │ ├── SideBar.vue # The left sidebar for the workspace view │ │ ├── SideBar.vue # The left sidebar for the workspace view
│ │ ├── SideBarItem.vue # App item for the sidebar view │ │ ├── SideBarItem.vue # App item for the sidebar view
│ │ ├── SideBarSection.vue # Collapsible collection of items within workspace sidebar │ │ ├── SideBarSection.vue # Collapsible collection of items within workspace sidebar
│ │ ╰── WebContent.vue # Workspace iframe view, displays content of current app │ │ ╰── WebContent.vue # Workspace iframe view, displays content of current app
│ ╰── Settings # Components relating to the quick-settings, in the top-right │ ╰── Settings # Components relating to the quick-settings, in the top-right
│ ├── AuthButtons.vue # Logout button and other app info │ ├── AuthButtons.vue # Logout button and other app info
│ ├── ConfigLauncher.vue # Icon that when clicked will launch the Configuration component │ ├── ConfigLauncher.vue # Icon that when clicked will launch the Configuration component
│ ├── CustomThemeMaker.vue # Color pickers for letting user build their own theme │ ├── CustomThemeMaker.vue # Color pickers for letting user build their own theme
│ ├── ItemSizeSelector.vue # Set of buttons used to set and save item size │ ├── ItemSizeSelector.vue # Set of buttons used to set and save item size
│ ├── KeyboardShortcutInfo.vue# Small pop-up displaying the available keyboard shortcuts │ ├── KeyboardShortcutInfo.vue# Small pop-up displaying the available keyboard shortcuts
│ ├── LanguageSwitcher.vue # Dropdown in a modal for changing app language │ ├── LanguageSwitcher.vue # Dropdown in a modal for changing app language
│ ├── LayoutSelector.vue # Set of buttons, letting the user select their desired layout │ ├── LayoutSelector.vue # Set of buttons, letting the user select their desired layout
│ ├── SearchBar.vue # The input field in the header, used for searching the app │ ├── SearchBar.vue # The input field in the header, used for searching the app
│ ├── SettingsContainer.vue # Container that wraps all the quick-settings components │ ├── SettingsContainer.vue # Container that wraps all the quick-settings components
│ ╰── ThemeSelector.vue # Drop-down menu enabling the user to select and change themes │ ╰── ThemeSelector.vue # Drop-down menu enabling the user to select and change themes
├── main.js # Main front-end entry point ├── main.js # Main front-end entry point
├── registerServiceWorker.js # Registers and manages service workers, for PWA apps ├── registerServiceWorker.js # Registers and manages service workers, for PWA apps
├── router.js # Defines all available application routes ├── router.js # Defines all available application routes
├── styles # Directory of all globally used common SCSS styles ├── styles # Directory of all globally used common SCSS styles
├── utils # Directory of re-used helper functions ├── utils # Directory of re-used helper functions
│ ├── ArrowKeyNavigation.js # Functionality for arrow-key navigation │ ├── ArrowKeyNavigation.js # Functionality for arrow-key navigation
│ ├── Auth.js # Handles all authentication related actions │ ├── Auth.js # Handles all authentication related actions
│ ├── CheckSectionVisibility.js # Checks which parts of the page should be visible/ hidden based on config │ ├── CheckSectionVisibility.js # Checks which parts of the page should be visible/ hidden based on config
│ ├── ClickOutside.js # A directive for detecting click, used to hide dropdown, modal or context menu │ ├── ClickOutside.js # A directive for detecting click, used to hide dropdown, modal or context menu
│ ├── ConfigHelpers.js # Helper functions for managing configuration │ ├── ConfigHelpers.js # Helper functions for managing configuration
│ ├── CloudBackup.js # Functionality for encrypting, processing and network calls │ ├── CloudBackup.js # Functionality for encrypting, processing and network calls
│ ├── ConfigSchema.json # The schema, used to validate the users conf.yml file │ ├── ConfigSchema.json # The schema, used to validate the users conf.yml file
│ ├── ConfigAccumulator.js # Central place for managing and combining config │ ├── ConfigAccumulator.js # Central place for managing and combining config
│ ├── ConfigHelpers.json # Collection of helper functions to process config using accumulator │ ├── ConfigHelpers.json # Collection of helper functions to process config using accumulator
│ ├── ConfigValidator.js # A helper script that validates the config file against schema │ ├── ConfigValidator.js # A helper script that validates the config file against schema
│ ├── CoolConsole.js # Prints info, warning and error messages to browser console, with a cool style │ ├── CoolConsole.js # Prints info, warning and error messages to browser console, with a cool style
│ ├── defaults.js # Global constants and their default values │ ├── defaults.js # Global constants and their default values
│ ├── emojis.json # List of emojis with unicode and shortcode, used for emoji icon feature │ ├── emojis.json # List of emojis with unicode and shortcode, used for emoji icon feature
│ ├── EmojiUnicodeRegex.js # Regular expression to validate emoji unicode format, for emoji icons │ ├── EmojiUnicodeRegex.js # Regular expression to validate emoji unicode format, for emoji icons
│ ├── ErrorHandler.js # Helper function called when an error is returned │ ├── ErrorHandler.js # Helper function called when an error is returned
│ ├── InitServiceWorker.js # Initializes and manages service worker, if enabled │ ├── InitServiceWorker.js # Initializes and manages service worker, if enabled
│ ├── Search.js # Helper functions for searching/ filtering items in all views │ ├── Search.js # Helper functions for searching/ filtering items in all views
│ ├── JsonToYaml.js # Function that parses and converts raw JSON into valid YAML │ ├── JsonToYaml.js # Function that parses and converts raw JSON into valid YAML
│ ├── languages.js # Handles fetching, switching and validating languages │ ├── languages.js # Handles fetching, switching and validating languages
│ ╰── ThemeHelper.js # Function that handles the fetching and setting of user themes │ ╰── ThemeHelper.js # Function that handles the fetching and setting of user themes
╰── views # Directory of available pages, corresponding to available routes ╰── views # Directory of available pages, corresponding to available routes
├── Home.vue # The home page container ├── Home.vue # The home page container
├── About.vue # About page ├── About.vue # About page
├── Login.vue # TAuthentication page ├── Login.vue # TAuthentication page
├── Minimal.vue # The minimal view ├── Minimal.vue # The minimal view
╰── Workspace.vue # The workspace view with apps in sidebar ╰── Workspace.vue # The workspace view with apps in sidebar
``` ```
#### Visualisation of Source Directory #### Visualisation of Source Directory
![File Breakdown](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/assets/repo-visualization.svg) ![File Breakdown](https://raw.githubusercontent.com/Lissy93/dashy/master/docs/assets/repo-visualization.svg)
--- ---
## Development Tools ## Development Tools
### Performance - Lighthouse ### Performance - Lighthouse
The easiest method of checking performance is to use Chromium's build in auditing tool, Lighthouse. To run the test, open Developer Tools (usually F12) --> Lighthouse and click on the 'Generate Report' button at the bottom. The easiest method of checking performance is to use Chromium's build in auditing tool, Lighthouse. To run the test, open Developer Tools (usually F12) --> Lighthouse and click on the 'Generate Report' button at the bottom.
### Dependencies - BundlePhobia ### Dependencies - BundlePhobia
[BundlePhobia](https://bundlephobia.com/) is a really useful app that lets you analyze the cost of adding any particular dependency to an application [BundlePhobia](https://bundlephobia.com/) is a really useful app that lets you analyze the cost of adding any particular dependency to an application
--- ---
## Notes ## Notes
### Known Warnings ### Known Warnings
When running the build command, several warnings appear. These are not errors, and do not affect the security or performance of the application. They will be addressed in a future update When running the build command, several warnings appear. These are not errors, and do not affect the security or performance of the application. They will be addressed in a future update
`WARN A new version of sass-loader is available. Please upgrade for best experience.` - Currently we're using an older version of SASS loader, since the more recent releases do not seem to be compatible with the Vue CLI's webpack configuration. `WARN A new version of sass-loader is available. Please upgrade for best experience.` - Currently we're using an older version of SASS loader, since the more recent releases do not seem to be compatible with the Vue CLI's webpack configuration.
`WARN asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).` - For the PWA to support Windows 10, a splash screen asset is required, and is quite large. This throws a warning, however PWA assets are not loaded until needed, so shouldn't have any impact on application performance. A similar warning is thrown for the Raleway font, and that is looking to be addressed. `WARN asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).` - For the PWA to support Windows 10, a splash screen asset is required, and is quite large. This throws a warning, however PWA assets are not loaded until needed, so shouldn't have any impact on application performance. A similar warning is thrown for the Raleway font, and that is looking to be addressed.