mirror of https://github.com/Lissy93/dashy.git
🔀 Merge pull request #326 from Lissy93/PERFORMANCE/server-speed-improvments
[ARCHITECTURE] Performance and Speed Improvements
This commit is contained in:
commit
a88e899f53
9
.env
9
.env
|
@ -7,12 +7,19 @@
|
|||
# The port to expose the running application on
|
||||
# PORT=4000
|
||||
|
||||
# If you've proved SSL certs, then can set HTTPS port
|
||||
# SSL_PORT=4001
|
||||
|
||||
# The host that Dashy is running on, domain or IP
|
||||
# HOST=localhost
|
||||
|
||||
# The default base path for serving up static assets
|
||||
# BASE_URL=./
|
||||
|
||||
# Optionally, specify the path of SSL private + public keys
|
||||
# SSL_PRIV_KEY_PATH=/etc/ssl/certs/dashy-priv.key
|
||||
# SSL_PUB_KEY_PATH=/etc/ssl/certs/dashy-pub.pem
|
||||
|
||||
# Usually the same as BASE_URL, but accessible in frontend
|
||||
# VUE_APP_DOMAIN=https://dashy.to
|
||||
|
||||
|
@ -23,4 +30,4 @@
|
|||
# IS_DOCKER=true
|
||||
|
||||
# Again, set automatically using package.json during build time
|
||||
# VUE_APP_VERSION=1.7.0
|
||||
# VUE_APP_VERSION=2.0.0
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
# Changelog
|
||||
|
||||
## ⚡️ 1.9.2 - Native SSL Support + Performance Improvements [PR #326](https://github.com/Lissy93/dashy/pull/326)
|
||||
- Updates the server to use Express, removing serve-static, connect and body-parser
|
||||
- Adds native support for passing in self-signed SSL certificates and updates docs
|
||||
- Updates router to lazy-load additional pages (minimal, workspace, etc)
|
||||
- Changes default favicon API to allesedv, since faviconkit is down, and adds basic fallback
|
||||
- Updates GH action build scripts to fallback on context token when running on fork
|
||||
|
||||
## 💄 1.9.1 - Editor and Theming Fixes and Improvements [PR #319](https://github.com/Lissy93/dashy/pull/319)
|
||||
- Bug fixes for interactive editor: #310, #311, #312
|
||||
- Adds option to modify text font through the UI
|
||||
|
|
|
@ -10,4 +10,4 @@ jobs:
|
|||
steps:
|
||||
- uses: logerfo/close-label@0.0.4
|
||||
with:
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
|
|
|
@ -12,4 +12,4 @@ jobs:
|
|||
- name: Assign author
|
||||
uses: technote-space/assign-author@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
|
|
|
@ -15,9 +15,9 @@ jobs:
|
|||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
fetch-depth: 0
|
||||
- name: Rebase
|
||||
uses: cirrus-actions/rebase@1.4
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- uses: butlerlogic/action-autotag@stable
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
strategy: package
|
||||
commit_message_template: "🔖 {{number}} {{message}} (by {{author}})\nSHA: {{sha}}\n."
|
||||
mark-issue-fixed:
|
||||
|
@ -22,5 +22,5 @@ jobs:
|
|||
- name: Label Fixed Issues
|
||||
uses: gh-bot/fix-labeler@master
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
label: '✅ Fixed'
|
||||
|
|
|
@ -11,4 +11,4 @@ jobs:
|
|||
steps:
|
||||
- uses: jenschelkopf/broadcast-action@master
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
@ -18,6 +18,7 @@ jobs:
|
|||
npm run build
|
||||
- name: Deploy 🚀
|
||||
uses: JamesIves/github-pages-deploy-action@4.1.4
|
||||
if: ${{ github.repository_owner === 'lissy93' }}
|
||||
with:
|
||||
branch: dev-demo
|
||||
folder: dist
|
||||
|
|
|
@ -9,7 +9,7 @@ jobs:
|
|||
steps:
|
||||
- uses: wow-actions/potential-duplicates@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
filter: ''
|
||||
exclude: '[BUG] [QUESTION] [FEEDBACK] [SHOWCASE]'
|
||||
label: '🕸️ Potential Duplicate'
|
||||
|
|
|
@ -11,6 +11,6 @@ jobs:
|
|||
- uses: mschilde/auto-label-merge-conflicts@master
|
||||
with:
|
||||
CONFLICT_LABEL_NAME: "🚫 Merge Conflicts"
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
MAX_RETRIES: 5
|
||||
WAIT_MS: 5000
|
||||
|
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
- name: Automatically close issues that don't follow the issue template
|
||||
uses: lucasbento/auto-close-issues@v1.0.2
|
||||
with:
|
||||
github-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
github-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
closed-issues-label: '🙁 Auto-Closed'
|
||||
issue-close-message: |
|
||||
Hello @${issue.user.login} 👋
|
||||
|
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
- name: Close Stale Issues
|
||||
uses: actions/stale@v4
|
||||
with:
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 30
|
||||
days-before-close: 5
|
||||
operations-per-run: 30
|
||||
|
@ -40,7 +40,7 @@ jobs:
|
|||
- name: Close Issues without Response
|
||||
uses: actions/stale@v4
|
||||
with:
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 5
|
||||
days-before-close: 3
|
||||
operations-per-run: 30
|
||||
|
@ -60,7 +60,7 @@ jobs:
|
|||
- name: Notify Repo Owner to Respond
|
||||
uses: actions/stale@v4
|
||||
with:
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 7
|
||||
days-before-close: 365
|
||||
operations-per-run: 30
|
||||
|
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
uses: peter-evans/create-pull-request@v3.10.1
|
||||
if: startsWith(github.head_ref, 'AUTO/') == false
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
base: master
|
||||
commit-message: ':pencil2: Auto-fix typos in text'
|
||||
title: '[AUTO] Fix spelling and language'
|
||||
|
|
|
@ -21,7 +21,7 @@ jobs:
|
|||
if: ${{ steps.check-domain.outputs.paid-till-days-left && steps.check-domain.outputs.paid-till-days-left < 30 }}
|
||||
uses: rishabhgupta/git-action-issue@v2
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
assignees: Lissy93
|
||||
title: '[WEBSITE] Domain Expiring Soon'
|
||||
body: >
|
||||
|
@ -33,7 +33,7 @@ jobs:
|
|||
if: ${{ steps.check-domain.outputs.ssl-expire-days-left && steps.check-domain.outputs.ssl-expire-days-left < 14 }}
|
||||
uses: rishabhgupta/git-action-issue@v2
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
assignees: Lissy93
|
||||
title: '[WEBSITE] SSL Cert Expiring Soon'
|
||||
body: >
|
||||
|
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
steps:
|
||||
- uses: bubkoo/contributors-list@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
svgPath: docs/assets/CONTRIBUTORS.svg
|
||||
affiliation: all
|
||||
includeBots: false
|
||||
|
@ -30,12 +30,12 @@ jobs:
|
|||
- name: Generate Sponsors in Readme 💖
|
||||
uses: JamesIves/github-sponsors-readme-action@1.0.5
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
file: 'README.md'
|
||||
- name: Generate Sponsors in Credits 💖
|
||||
uses: JamesIves/github-sponsors-readme-action@1.0.5
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
file: 'docs/credits.md'
|
||||
# Job #3 - Update the Credits page
|
||||
insert-credits:
|
||||
|
@ -45,7 +45,7 @@ jobs:
|
|||
- name: Contribute List - Credits Page
|
||||
uses: akhilmhdh/contributors-readme-action@v2.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
image_size: 80
|
||||
readme_path: docs/credits.md
|
||||
|
@ -56,7 +56,7 @@ jobs:
|
|||
- name: Sponsors List - Readme
|
||||
uses: akhilmhdh/contributors-readme-action@v2.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
image_size: 80
|
||||
readme_path: README.md
|
||||
|
@ -74,7 +74,7 @@ jobs:
|
|||
fetch-depth: 0
|
||||
- uses: wow-actions/update-authors@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
sort: commits
|
||||
bots: true
|
||||
path: .github/AUTHORS.txt
|
||||
|
|
|
@ -19,7 +19,7 @@ jobs:
|
|||
- name: close
|
||||
uses: uhyo/please-star-first@v1
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
message: |
|
||||
Welcome to Dashy 👋
|
||||
It's great to have you here, but unfortunately your ticket has been closed to prevent spam. Before reopening this issue, please ensure the following criteria are met.
|
||||
|
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
steps:
|
||||
- uses: tomsun28/issues-translate-action@v2.5
|
||||
with:
|
||||
BOT_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
BOT_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
BOT_LOGIN_NAME: liss-bot
|
||||
IS_MODIFY_TITLE: true
|
||||
CUSTOM_BOT_NOTE: It looks like this issue isn't in English - not a problem, here's the translation! 🇬🇧
|
||||
|
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
- name: Label Issues
|
||||
uses: adamzolyak/top-issues-action@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
TOP_NUMBER_OF_ISSUES: 10
|
||||
TOP_LABEL_NAME: "👍 Top 10 Issue!"
|
||||
TOP_LABEL_COLOR: FBCA04
|
||||
|
|
|
@ -12,6 +12,6 @@ jobs:
|
|||
uses: actions-cool/issues-helper@v2
|
||||
with:
|
||||
actions: remove-labels
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: '🚏 Awaiting User Response,⚰️ Stale,👤 Awaiting Maintainer Response'
|
||||
|
|
|
@ -13,7 +13,7 @@ jobs:
|
|||
uses: actions-cool/issues-helper@v2
|
||||
with:
|
||||
actions: remove-labels
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: '🚏 Awaiting User Response,⚰️ Stale'
|
||||
|
||||
|
@ -31,7 +31,7 @@ jobs:
|
|||
uses: actions-cool/issues-helper@v2
|
||||
with:
|
||||
actions: add-labels
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: '👤 Awaiting Maintainer Response'
|
||||
|
||||
|
@ -43,6 +43,6 @@ jobs:
|
|||
uses: actions-cool/issues-helper@v2
|
||||
with:
|
||||
actions: remove-labels
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
labels: '👤 Awaiting Maintainer Response'
|
||||
|
|
|
@ -17,4 +17,4 @@ jobs:
|
|||
- name: Profanity check step
|
||||
uses: tailaiw/mind-your-language-action@v1.0.3
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
@ -9,4 +9,4 @@ jobs:
|
|||
if: github.event.action == 'opened'
|
||||
uses: ffittschen/pr-branch-labeler@v1
|
||||
with:
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
@ -10,4 +10,4 @@ jobs:
|
|||
uses: "alstr/todo-to-issue-action@v4.2"
|
||||
id: "todo"
|
||||
with:
|
||||
TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
@ -9,7 +9,7 @@ jobs:
|
|||
steps:
|
||||
- uses: apexskier/github-release-commenter@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
label-template: 🛩️ Released {release_tag}, 🔨 Fixed
|
||||
comment-template: |
|
||||
**The fix for this issue has now been released in {release_name} ✨**
|
||||
|
|
|
@ -46,7 +46,7 @@ jobs:
|
|||
uses: lowlighter/metrics@latest
|
||||
with:
|
||||
token: ${{ secrets.LISSY93_PAT }}
|
||||
committer_token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
committer_token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
committer_branch: master
|
||||
committer_message: ':purple_heart: Adds repo metrics'
|
||||
filename: docs/assets/repo-metrics.*
|
||||
|
@ -59,7 +59,7 @@ jobs:
|
|||
uses: lowlighter/metrics@latest
|
||||
with:
|
||||
token: ${{ secrets.LISSY93_PAT }}
|
||||
committer_token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
committer_token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
committer_branch: master
|
||||
committer_message: ':purple_heart: Adds license metrics'
|
||||
filename: docs/assets/license-metrics.*
|
||||
|
@ -76,7 +76,7 @@ jobs:
|
|||
uses: lowlighter/metrics@latest
|
||||
with:
|
||||
token: ${{ secrets.LISSY93_PAT }}
|
||||
committer_token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
committer_token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
committer_branch: master
|
||||
committer_message: ':purple_heart: Adds contributor metrics'
|
||||
filename: docs/assets/controbutor-metrics.*
|
||||
|
|
|
@ -12,4 +12,4 @@ jobs:
|
|||
with:
|
||||
repository: lissy93/dashy
|
||||
databranch: DATA/repo-stats
|
||||
ghtoken: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
ghtoken: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
|
@ -13,7 +13,7 @@ jobs:
|
|||
- name: Upload Docs to GH Wiki
|
||||
uses: docker://decathlon/wiki-page-creator-action:latest
|
||||
env:
|
||||
GH_PAT: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
GH_PAT: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
ACTION_MAIL: alicia-gh-bot@mail.as93.net
|
||||
ACTION_NAME: liss-bot
|
||||
OWNER: Lissy93
|
||||
|
|
|
@ -28,13 +28,13 @@ Dashy can auto-fetch an icon for a given service, using it's favicon. Just set `
|
|||
|
||||
If the service is hosted under a local IP, then Dashy will attempt to find the favicon from `http://[ip]/favicon.ico`. This has two issues, favicons are not always hosted at the same location for every service, and often the default favicon is sometimes low resolution. Therefore for remote services, by default an API is used to return a high-quality icon for almost any online service.
|
||||
|
||||
The default favicon API is [Favicon Kit](https://faviconkit.com/), a free and reliable service for returning images from any given URL. However several other API's are supported. To change the API used, under `appConfig`, set `faviconApi` to one of the following values:
|
||||
The default favicon API is [allesedv.com](https://favicon.allesedv.com/), but several other API's are supported. To change the API used, under `appConfig`, set `faviconApi` to one of the following values:
|
||||
|
||||
- `faviconkit` - [faviconkit.com](https://faviconkit.com/) (Recommend)
|
||||
- `google` - Official Google favicon API service, good support for all sites, but poor quality
|
||||
- `clearbit` - [Clearbit](https://clearbit.com/logo) returns high-quality logos from mainstream websites
|
||||
- `webmasterapi` - [WebMasterAPI](https://www.webmasterapi.com/get-favicons)
|
||||
- `allesedv` - [allesedv.com](https://favicon.allesedv.com/) is a highly efficient IPv6-enabled service
|
||||
- `faviconkit` - [faviconkit.com](https://faviconkit.com/) (Note: currently down, as of Nov 2021)
|
||||
- `clearbit` - [Clearbit](https://clearbit.com/logo) returns high-quality logos from mainstream websites
|
||||
- `google` - Official Google favicon API service, good support for all sites, but poor quality
|
||||
- `webmasterapi` - [WebMasterAPI](https://www.webmasterapi.com/get-favicons)
|
||||
|
||||
You can also force Dashy to always get favicons from the root of the domain, and not use an external service, by setting `appConfig.faviconApi` to `local`, although you may face the issue explained above.
|
||||
|
||||
|
@ -80,7 +80,7 @@ sections:
|
|||
---
|
||||
|
||||
## Generative Icons
|
||||
To uses a unique and programmatically generated icon for a given service just set `icon: generative`. This is particularly useful when you have a lot of similar services with a different IP or port, and no specific icon. These icons are generated with [DiceBear](https://avatars.dicebear.com/), and use a hash of the services domain/ ip for entropy, so each domain will always have the same icon.
|
||||
To uses a unique and programmatically generated icon for a given service just set `icon: generative`. This is particularly useful when you have a lot of similar services with a different IP or port, and no specific icon. These icons are generated with [DiceBear](https://avatars.dicebear.com/) (or [Evatar](https://evatar.io/) for fallback), and use a hash of the services domain/ ip for entropy, so each domain will have a unique icon.
|
||||
|
||||
<p align="center">
|
||||
<img width="500" src="https://i.ibb.co/b2pC2CL/generative-icons-2.png" />
|
||||
|
|
|
@ -195,17 +195,34 @@ I recommend combining this with [healthchecks](https://github.com/healthchecks/h
|
|||
|
||||
## SSL Certificates
|
||||
|
||||
Enabling HTTPS with an SSL certificate is recommended if you hare hosting Dashy anywhere other than your home. This will ensure that all traffic is encrypted in transit.
|
||||
Enabling HTTPS with an SSL certificate is recommended, especially if you hare hosting Dashy anywhere other than your home. This will ensure that all traffic is encrypted in transit.
|
||||
|
||||
[Let's Encrypt](https://letsencrypt.org/docs/) is a global Certificate Authority, providing free SSL/TLS Domain Validation certificates in order to enable secure HTTPS access to your website. They have good browser/ OS [compatibility](https://letsencrypt.org/docs/certificate-compatibility/) with their ISRG X1 and DST CA X3 root certificates, support [Wildcard issuance](https://community.letsencrypt.org/t/acme-v2-production-environment-wildcards/55578) done via ACMEv2 using the DNS-01 and have [Multi-Perspective Validation](https://letsencrypt.org/2020/02/19/multi-perspective-validation.html). Let's Encrypt provide [CertBot](https://certbot.eff.org/) an easy app for generating and setting up an SSL certificate
|
||||
### Auto-SSL
|
||||
If you are using [NGINX Proxy Manager](https://nginxproxymanager.com/), then SSL is supported out of the box. Once you've added your proxy host and web address, then set the scheme to HTTPS, then under the SSL Tab select "Request a new SSL certificate" and follow the on-screen instructions.
|
||||
|
||||
[ZeroSSL](https://zerossl.com/) is another popular certificate issuer, they are free for personal use, and also provide easy-to-use tools for getting things setup.
|
||||
If you're hosting Dashy behind Cloudflare, then they offer [free and easy SSL](https://www.cloudflare.com/en-gb/learning/ssl/what-is-an-ssl-certificate/)- all you need to do is enable it under the SSL/TLS tab. Or if you are using shared hosting, you may find [this tutorial](https://www.sitepoint.com/a-guide-to-setting-up-lets-encrypt-ssl-on-shared-hosting/) helpful.
|
||||
|
||||
### Getting a Self-Signed SSL Certificate
|
||||
[Let's Encrypt](https://letsencrypt.org/docs/) is a global Certificate Authority, providing free SSL/TLS Domain Validation certificates in order to enable secure HTTPS access to your website. They have good browser/ OS [compatibility](https://letsencrypt.org/docs/certificate-compatibility/) with their ISRG X1 and DST CA X3 root certificates, support [Wildcard issuance](https://community.letsencrypt.org/t/acme-v2-production-environment-wildcards/55578) done via ACMEv2 using the DNS-01 and have [Multi-Perspective Validation](https://letsencrypt.org/2020/02/19/multi-perspective-validation.html). Let's Encrypt provide [CertBot](https://certbot.eff.org/) an easy app for generating and setting up an SSL certificate.
|
||||
|
||||
If you're hosting Dashy behind Cloudflare, then they offer [free and easy SSL](https://www.cloudflare.com/en-gb/learning/ssl/what-is-an-ssl-certificate/).
|
||||
This process can be automated, using something like the [Docker-NGINX-Auto-SSL Container](https://github.com/Valian/docker-nginx-auto-ssl) to generate and renew certificates when needed.
|
||||
|
||||
If you're not so comfortable on the command line, then you can use a tool like [SSL For Free](https://www.sslforfree.com/) to generate your Let's Encrypt or ZeroSSL certificate, and support shared hosting servers. They also provide step-by-step tutorials on setting up your certificate on most common platforms. If you are using shared hosting, you may find [this tutorial](https://www.sitepoint.com/a-guide-to-setting-up-lets-encrypt-ssl-on-shared-hosting/) helpful.
|
||||
If you're not so comfortable on the command line, then you can use a tool like [SSL For Free](https://www.sslforfree.com/) or [ZeroSSL](https://zerossl.com/) to generate your cert. They also provide step-by-step setup instructions for most platforms.
|
||||
|
||||
### Passing a Self-Signed Certificate to Dashy
|
||||
Once you've generated your SSL cert, you'll need to pass it to Dashy. This can be done by specifying the paths to your public and private keys using the `SSL_PRIV_KEY_PATH` and `SSL_PUB_KEY_PATH` environmental variables. Or if you're using Docker, then just pass public + private SSL keys in under `/etc/ssl/certs/dashy-pub.pem` and `/etc/ssl/certs/dashy-priv.key` respectively, e.g:
|
||||
|
||||
```
|
||||
docker run -d \
|
||||
-p 8080:80 \
|
||||
-v ~/my-private-key.key:/etc/ssl/certs/dashy-priv.key:ro \
|
||||
-v ~/my-public-key.pem:/etc/ssl/certs/dashy-pub.pem:ro \
|
||||
lissy93/dashy:latest
|
||||
```
|
||||
|
||||
By default the SSL port is `443` within a Docker container, or `4001` if running on bare metal, but you can override this with the `SSL_PORT` environmental variable.
|
||||
|
||||
Once everything is setup, you can verify your site is secured using a tool like [SSL Checker](https://www.sslchecker.com/sslchecker).
|
||||
|
||||
**[⬆️ Back to Top](#management)**
|
||||
|
||||
|
@ -213,8 +230,7 @@ If you're not so comfortable on the command line, then you can use a tool like [
|
|||
|
||||
## Authentication
|
||||
|
||||
Dashy natively supports secure authentication using KeyCloak. There is also a Simple Auth feature that doesn't require any additional setup. Setup instructions for which, and alternative auth methods, has now moved to the **[Authentication Docs](/docs/authentication.md)** page.
|
||||
|
||||
Dashy natively supports secure authentication using KeyCloak. There is also a Simple Auth feature that doesn't require any additional setup. Usage instructions for both, as well as alternative auth methods, has now moved to the **[Authentication Docs](/docs/authentication.md)** page.
|
||||
|
||||
**[⬆️ Back to Top](#management)**
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "Dashy",
|
||||
"version": "1.9.1",
|
||||
"version": "1.9.2",
|
||||
"license": "MIT",
|
||||
"main": "server",
|
||||
"author": "Alicia Sykes <alicia@omg.lol> (https://aliciasykes.com)",
|
||||
|
@ -22,16 +22,14 @@
|
|||
"@sentry/vue": "^6.13.1",
|
||||
"ajv": "^8.6.3",
|
||||
"axios": "^0.23.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"connect": "^3.7.0",
|
||||
"connect-history-api-fallback": "^1.6.0",
|
||||
"crypto-js": "^4.1.1",
|
||||
"express": "^4.17.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"keycloak-js": "^15.0.2",
|
||||
"register-service-worker": "^1.6.2",
|
||||
"remedial": "^1.0.8",
|
||||
"rsup-progress": "^2.0.4",
|
||||
"serve-static": "^1.14.1",
|
||||
"simple-icons": "^5.14.0",
|
||||
"v-jsoneditor": "^1.4.2",
|
||||
"v-tooltip": "^2.1.3",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!doctype html>
|
||||
<!-- Dashy: Licensed under MIT, (C) 2021 Alicia Sykes <https://aliciasykes.com> -->
|
||||
<!-- This is the default page, displayed while the app is still building -->
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Dashy</title>
|
||||
<meta name="description" content="Welcome to Dashy">
|
88
server.js
88
server.js
|
@ -5,13 +5,15 @@
|
|||
* Also includes some routes for status checks/ ping and config saving
|
||||
* */
|
||||
|
||||
/* Include required node dependencies */
|
||||
const serveStatic = require('serve-static');
|
||||
const connect = require('connect');
|
||||
/* Import built-in Node server modules */
|
||||
const http = require('http');
|
||||
const path = require('path');
|
||||
const util = require('util');
|
||||
const dns = require('dns');
|
||||
const os = require('os');
|
||||
const bodyParser = require('body-parser');
|
||||
|
||||
/* Import Express + middleware functions */
|
||||
const express = require('express');
|
||||
const history = require('connect-history-api-fallback');
|
||||
|
||||
/* Kick of some basic checks */
|
||||
|
@ -22,6 +24,7 @@ require('./services/config-validator'); // Include and kicks off the config file
|
|||
const statusCheck = require('./services/status-check'); // Used by the status check feature, uses GET
|
||||
const saveConfig = require('./services/save-config'); // Saves users new conf.yml to file-system
|
||||
const rebuild = require('./services/rebuild-app'); // A script to programmatically trigger a build
|
||||
const sslServer = require('./services/ssl-server');
|
||||
|
||||
/* Helper functions, and default config */
|
||||
const printMessage = require('./services/print-message'); // Function to print welcome msg on start
|
||||
|
@ -55,44 +58,43 @@ const printWarning = (msg, error) => {
|
|||
/* A middleware function for Connect, that filters requests based on method type */
|
||||
const method = (m, mw) => (req, res, next) => (req.method === m ? mw(req, res, next) : next());
|
||||
|
||||
try {
|
||||
connect()
|
||||
.use(history())
|
||||
.use(bodyParser.json())
|
||||
// Serves up the main built application to the root
|
||||
.use(serveStatic(`${__dirname}/dist`))
|
||||
// During build, a custom page will be served before the app is available
|
||||
.use(serveStatic(`${__dirname}/public`, { index: 'default.html' }))
|
||||
// GET endpoint to run status of a given URL with GET request
|
||||
.use(ENDPOINTS.statusCheck, (req, res) => {
|
||||
try {
|
||||
statusCheck(req.url, async (results) => {
|
||||
await res.end(results);
|
||||
});
|
||||
} catch (e) {
|
||||
printWarning(`Error running status check for ${req.url}\n`, e);
|
||||
}
|
||||
})
|
||||
// POST Endpoint used to save config, by writing conf.yml to disk
|
||||
.use(ENDPOINTS.save, method('POST', (req, res) => {
|
||||
try {
|
||||
saveConfig(req.body, (results) => { res.end(results); });
|
||||
} catch (e) {
|
||||
res.end(JSON.stringify({ success: false, message: e }));
|
||||
}
|
||||
}))
|
||||
// GET endpoint to trigger a build, and respond with success status and output
|
||||
.use(ENDPOINTS.rebuild, (req, res) => {
|
||||
rebuild().then((response) => {
|
||||
res.end(JSON.stringify(response));
|
||||
}).catch((response) => {
|
||||
res.end(JSON.stringify(response));
|
||||
const app = express()
|
||||
// Serves up static files
|
||||
.use(express.static(path.join(__dirname, 'dist')))
|
||||
.use(express.static(path.join(__dirname, 'public'), { index: 'initialization.html' }))
|
||||
// Load middlewares for parsing JSON, and supporting HTML5 history routing
|
||||
.use(express.json())
|
||||
.use(history())
|
||||
// GET endpoint to run status of a given URL with GET request
|
||||
.use(ENDPOINTS.statusCheck, (req, res) => {
|
||||
try {
|
||||
statusCheck(req.url, async (results) => {
|
||||
await res.end(results);
|
||||
});
|
||||
})
|
||||
// Finally, initialize the server then print welcome message
|
||||
.listen(port, () => {
|
||||
try { printWelcomeMessage(); } catch (e) { printWarning('Dashy is Starting...'); }
|
||||
} catch (e) {
|
||||
printWarning(`Error running status check for ${req.url}\n`, e);
|
||||
}
|
||||
})
|
||||
// POST Endpoint used to save config, by writing conf.yml to disk
|
||||
.use(ENDPOINTS.save, method('POST', (req, res) => {
|
||||
try {
|
||||
saveConfig(req.body, (results) => { res.end(results); });
|
||||
} catch (e) {
|
||||
printWarning('Error writing config file to disk', e);
|
||||
res.end(JSON.stringify({ success: false, message: e }));
|
||||
}
|
||||
}))
|
||||
// GET endpoint to trigger a build, and respond with success status and output
|
||||
.use(ENDPOINTS.rebuild, (req, res) => {
|
||||
rebuild().then((response) => {
|
||||
res.end(JSON.stringify(response));
|
||||
}).catch((response) => {
|
||||
res.end(JSON.stringify(response));
|
||||
});
|
||||
} catch (error) {
|
||||
printWarning('Sorry, a critical error occurred ', error);
|
||||
}
|
||||
});
|
||||
|
||||
/* Create HTTP server from app on port, and print welcome message */
|
||||
http.createServer(app).listen(port, () => { printWelcomeMessage(); });
|
||||
|
||||
/* Check, and if possible start SSL server too */
|
||||
sslServer(app);
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
const fs = require('fs');
|
||||
const util = require('util');
|
||||
const https = require('https');
|
||||
|
||||
const promise = util.promisify;
|
||||
const stat = promise(fs.stat);
|
||||
|
||||
module.exports = (app) => {
|
||||
const httpsCerts = {
|
||||
private: process.env.SSL_PRIV_KEY_PATH || '/etc/ssl/certs/dashy-priv.key',
|
||||
public: process.env.SSL_PUB_KEY_PATH || '/etc/ssl/certs/dashy-pub.pem',
|
||||
};
|
||||
|
||||
const isDocker = !!process.env.IS_DOCKER;
|
||||
const SSLPort = process.env.SSL_PORT || (isDocker ? 443 : 4001);
|
||||
|
||||
const printSuccess = () => {
|
||||
console.log(`🔐 HTTPS server successfully started (port: ${SSLPort} ${isDocker ? 'of container' : ''})`);
|
||||
};
|
||||
|
||||
const printNotSoGood = (msg) => {
|
||||
console.log(`SSL Not Enabled: ${msg}`);
|
||||
};
|
||||
|
||||
/* Starts SSL-secured node server */
|
||||
const startSSLServer = () => {
|
||||
const httpsServer = https.createServer({
|
||||
key: fs.readFileSync(httpsCerts.private),
|
||||
cert: fs.readFileSync(httpsCerts.public),
|
||||
}, app);
|
||||
httpsServer.listen(SSLPort, () => { printSuccess(); });
|
||||
};
|
||||
|
||||
/* Check if SSL certs present, if so also start the HTTPS server */
|
||||
stat(httpsCerts.public).then(() => {
|
||||
stat(httpsCerts.private).then(() => {
|
||||
startSSLServer();
|
||||
}).catch(() => { printNotSoGood('Private key not present'); });
|
||||
}).catch(() => { printNotSoGood('Public key not present'); });
|
||||
};
|
|
@ -49,12 +49,14 @@ export default {
|
|||
},
|
||||
/* Gets the icon path, dependent on icon type */
|
||||
iconPath: function iconPath() {
|
||||
if (this.broken) return this.getFallbackIcon();
|
||||
return this.getIconPath(this.icon, this.url);
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
broken: false, // If true, was unable to resolve icon
|
||||
attemptedFallback: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -94,12 +96,12 @@ export default {
|
|||
},
|
||||
/* Get favicon URL, for items which use the favicon as their icon */
|
||||
getFavicon(fullUrl, specificApi) {
|
||||
if (this.shouldUseDefaultFavicon(fullUrl)) { // Check if we should use local icon
|
||||
const faviconApi = specificApi || this.appConfig.faviconApi || defaultFaviconApi;
|
||||
if (this.shouldUseDefaultFavicon(fullUrl) || faviconApi === 'local') { // Check if we should use local icon
|
||||
const urlParts = fullUrl.split('/');
|
||||
if (urlParts.length >= 2) return `${urlParts[0]}/${urlParts[1]}/${urlParts[2]}/${iconCdns.faviconName}`;
|
||||
} else if (fullUrl.includes('http')) { // Service is running publicly
|
||||
const host = this.getHostName(fullUrl);
|
||||
const faviconApi = specificApi || this.appConfig.faviconApi || defaultFaviconApi;
|
||||
const endpoint = faviconApiEndpoints[faviconApi];
|
||||
return endpoint.replace('$URL', host);
|
||||
}
|
||||
|
@ -130,9 +132,9 @@ export default {
|
|||
return `${iconCdns.localPath}/${img}`;
|
||||
},
|
||||
/* Formats the URL for fetching the generative icons */
|
||||
getGenerativeIcon(url) {
|
||||
getGenerativeIcon(url, cdn) {
|
||||
const host = encodeURI(url) || Math.random().toString();
|
||||
return iconCdns.generative.replace('{icon}', asciiHash(host));
|
||||
return (cdn || iconCdns.generative).replace('{icon}', asciiHash(host));
|
||||
},
|
||||
/* Returns the SVG path content */
|
||||
getSimpleIcon(img) {
|
||||
|
@ -187,6 +189,23 @@ export default {
|
|||
this.broken = true;
|
||||
ErrorHandler(`The path to '${this.icon}' could not be resolved`);
|
||||
},
|
||||
/* Called when initial icon has resulted in 404. Attempts to find new icon */
|
||||
getFallbackIcon() {
|
||||
if (this.attemptedFallback) return undefined; // If this is second attempt, then give up
|
||||
const { iconType } = this;
|
||||
const markAsSttempted = () => {
|
||||
this.broken = false;
|
||||
this.attemptedFallback = true;
|
||||
};
|
||||
if (iconType.includes('favicon')) { // Specify fallback for favicon-based icons
|
||||
markAsSttempted();
|
||||
return this.getFavicon(this.url, 'local');
|
||||
} else if (iconType === 'generative') {
|
||||
markAsSttempted();
|
||||
return this.getGenerativeIcon(this.url, iconCdns.generativeFallback);
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -11,9 +11,6 @@ import ProgressBar from 'rsup-progress';
|
|||
|
||||
// Import views, that are not lazy-loaded
|
||||
import Home from '@/views/Home.vue';
|
||||
import Login from '@/views/Login.vue';
|
||||
import Workspace from '@/views/Workspace.vue';
|
||||
import Minimal from '@/views/Minimal.vue';
|
||||
import ConfigAccumulator from '@/utils/ConfigAccumalator';
|
||||
|
||||
// Import helper functions, config data and defaults
|
||||
|
@ -52,9 +49,8 @@ const getStartingView = () => appConfig.startingView || startingView;
|
|||
const getStartingComponent = () => {
|
||||
const usersPreference = getStartingView();
|
||||
switch (usersPreference) {
|
||||
case 'default': return Home;
|
||||
case 'minimal': return Minimal;
|
||||
case 'workspace': return Workspace;
|
||||
case 'minimal': return () => import('./views/Minimal.vue');
|
||||
case 'workspace': return () => import('./views/Workspace.vue');
|
||||
default: return Home;
|
||||
}
|
||||
};
|
||||
|
@ -93,19 +89,19 @@ const router = new Router({
|
|||
{ // Workspace view page
|
||||
path: routePaths.workspace,
|
||||
name: 'workspace',
|
||||
component: Workspace,
|
||||
component: () => import('./views/Workspace.vue'),
|
||||
meta: makeMetaTags('Workspace'),
|
||||
},
|
||||
{ // Minimal view page
|
||||
path: routePaths.minimal,
|
||||
name: 'minimal',
|
||||
component: Minimal,
|
||||
component: () => import('./views/Minimal.vue'),
|
||||
meta: makeMetaTags('Start Page'),
|
||||
},
|
||||
{ // The login page
|
||||
path: routePaths.login,
|
||||
name: 'login',
|
||||
component: Login,
|
||||
component: () => import('./views/Login.vue'),
|
||||
beforeEnter: (to, from, next) => {
|
||||
// If the user already logged in + guest mode not enabled, then redirect home
|
||||
if (isAuthenticated() && !isGuestAccessEnabled()) router.push({ path: '/' });
|
||||
|
|
|
@ -24,7 +24,7 @@ module.exports = {
|
|||
/* Default Font-Awesome API key, for FA icons (if used) */
|
||||
fontAwesomeKey: '0821c65656',
|
||||
/* Default API to use for fetching of user service favicon icons (if enabled) */
|
||||
faviconApi: 'faviconkit',
|
||||
faviconApi: 'allesedv',
|
||||
/* The default sort order for sections */
|
||||
sortOrder: 'default',
|
||||
/* The page paths for each route within the app for the router */
|
||||
|
@ -184,6 +184,7 @@ module.exports = {
|
|||
mdi: 'https://cdn.jsdelivr.net/npm/@mdi/font@5.9.55/css/materialdesignicons.min.css',
|
||||
si: 'https://unpkg.com/simple-icons@v5/icons',
|
||||
generative: 'https://avatars.dicebear.com/api/identicon/{icon}.svg',
|
||||
generativeFallback: 'https://evatar.io/{icon}',
|
||||
localPath: './item-icons',
|
||||
faviconName: 'favicon.ico',
|
||||
homeLabIcons: 'https://raw.githubusercontent.com/WalkxCode/dashboard-icons/master/png/{icon}.png',
|
||||
|
|
Loading…
Reference in New Issue