├── .devcontainer └── devcontainer.json ├── .dockerignore ├── .editorconfig ├── .env ├── .github ├── .lycheeexclude ├── .misspell-fixer.ignore ├── AUTHORS.txt ├── CHANGELOG.md ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug.yml │ ├── feature-request.yml │ ├── question.yml │ ├── share-feedback.md │ └── showcase-addition.yml ├── LATEST_CHANGELOG.md ├── LEGAL.md ├── SECURITY.md ├── SUPPORT.md ├── close-label.yml ├── dependabot.yml ├── issue-auto-comments.yml ├── issue-report-config.json ├── pr-auto-comments.yml ├── pr-badge.yml ├── pr-branch-labeler.yml ├── pull_request_template.md └── workflows │ ├── add-comment-from-tag.yml │ ├── auto-rebase-pr.yml │ ├── build-docs-site.yml │ ├── check-merge-conflicts.yml │ ├── close-incomplete-issues.yml │ ├── close-stale-issues.yml │ ├── create-tag-for-version.yml │ ├── dependency-updates-summary.yml │ ├── docker-build-publish.yml │ ├── draft-release.yml │ ├── generate-credits.yml │ ├── get-size.yml │ ├── lgtm-comment.yml │ ├── manage-pending-labels-closed.yml │ ├── manage-pending-labels.yml │ ├── mirror.yml │ ├── release-commenter.yml │ ├── update-docs-site.yml │ └── wiki-sync.yml ├── .gitignore ├── .gitpod.yml ├── .vscode ├── launch.json └── tasks.json ├── .yarnrc.yml ├── CNAME ├── Dockerfile ├── LICENSE ├── Procfile ├── README.md ├── app.json ├── docker-compose.yml ├── docker ├── Dockerfile-arm32v7 ├── Dockerfile-arm64v8 ├── Dockerfile-lite ├── Dockerfile-old ├── docker-readme.md ├── hooks │ └── pre_build └── nginx.conf ├── docs ├── alternate-views.md ├── assets │ ├── CONTRIBUTORS.svg │ ├── config-editor-demo.gif │ ├── logo.png │ ├── minimal-view-demo.gif │ ├── repo-visualization.svg │ ├── sponsor-button.svg │ ├── status-check-demo.gif │ ├── theme-config-demo.gif │ ├── theme-slideshow.gif │ └── workspace-demo.gif ├── authentication.md ├── backup-restore.md ├── configuring.md ├── contributing.md ├── credits.md ├── deployment.md ├── developing.md ├── development-guides.md ├── icons.md ├── management.md ├── multi-language-support.md ├── pages-and-sections.md ├── privacy.md ├── quick-start.md ├── readme.md ├── release-workflow.md ├── searching.md ├── showcase.md ├── showcase │ ├── 1-home-lab-material.png │ ├── 10-dashy-live.png │ ├── 11-ricky-cz.png │ ├── 12-evo-dashboard.png │ ├── 13-dragons-lair.png │ ├── 2-networking-services-minimal-dark.png │ ├── 3-cft-toolbox.png │ ├── 4-bookmarks-colourful.png │ ├── 5-project-management.png │ ├── 6-nas-home-dashboard.png │ ├── 7-ground-control-dtctek.png │ ├── 8-shadowking001s-dashy.png │ ├── 9-home-lab-oblivion.png │ └── readme.md ├── status-indicators.md ├── theming.md ├── troubleshooting.md └── widgets.md ├── netlify.toml ├── package.json ├── public ├── .nojekyll ├── favicon.ico ├── fonts │ ├── Audiowide-Regular.ttf │ ├── CutiveMono-Regular.ttf │ ├── Digital-Regular.ttf │ ├── FrancoisOne-Regular.ttf │ ├── Podkova-Medium.ttf │ ├── Roboto-Light.ttf │ ├── Shrikhand-Regular.ttf │ ├── Sniglet-Regular.ttf │ └── VT323-Regular.ttf ├── index.html ├── initialization.html ├── item-icons │ └── .gitignore ├── loading-screen.css ├── manifest.json ├── robots.txt ├── web-icons │ ├── dashy-logo.png │ ├── dashy-pwa_144x144.png │ ├── dashy-pwa_192x192.png │ ├── dashy-pwa_48x48.png │ ├── dashy-pwa_512x512.png │ ├── dashy-pwa_72x72.png │ ├── dashy-pwa_96x96.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon-64x64.png └── widget-resources │ ├── WeatherIcons.eot │ ├── WeatherIcons.svg │ ├── WeatherIcons.ttf │ ├── WeatherIcons.woff │ └── WeatherIcons.woff2 ├── server.js ├── services ├── config-validator.js ├── cors-proxy.js ├── get-user.js ├── healthcheck.js ├── print-message.js ├── rebuild-app.js ├── save-config.js ├── serverless-functions │ ├── cloud-status-check.js │ ├── netlify-cors.js │ └── not-supported.js ├── ssl-server.js ├── status-check.js ├── system-info.js └── update-checker.js ├── src ├── App.vue ├── assets │ ├── fonts │ │ ├── Inconsolata-Light.ttf │ │ ├── PTMono-Regular.ttf │ │ └── Raleway-Variable.ttf │ ├── interface-icons │ │ ├── add-new.svg │ │ ├── application-about.svg │ │ ├── application-change-view.svg │ │ ├── application-home.svg │ │ ├── application-minimal.svg │ │ ├── application-rebuild.svg │ │ ├── application-reload.svg │ │ ├── application-workspace.svg │ │ ├── back-arrow.svg │ │ ├── broken-icon.svg │ │ ├── burger-menu.svg │ │ ├── cloud-backup-restore.svg │ │ ├── config-backup.svg │ │ ├── config-cancel.svg │ │ ├── config-close.svg │ │ ├── config-color-palette.svg │ │ ├── config-custom-css.svg │ │ ├── config-delete-local.svg │ │ ├── config-download-file.svg │ │ ├── config-edit-json.svg │ │ ├── config-editor.svg │ │ ├── config-language.svg │ │ ├── config-meta-data.svg │ │ ├── config-open-settings.svg │ │ ├── config-pages.svg │ │ ├── config-restore.svg │ │ ├── icon-size-large.svg │ │ ├── icon-size-medium.svg │ │ ├── icon-size-small.svg │ │ ├── interactive-editor-add.svg │ │ ├── interactive-editor-app-config.svg │ │ ├── interactive-editor-cancel-changes.svg │ │ ├── interactive-editor-copy-clipboard.svg │ │ ├── interactive-editor-edit-mode.svg │ │ ├── interactive-editor-export-changes.svg │ │ ├── interactive-editor-move-to.svg │ │ ├── interactive-editor-page-info.svg │ │ ├── interactive-editor-remove.svg │ │ ├── interactive-editor-save-disk.svg │ │ ├── interactive-editor-save-locally.svg │ │ ├── layout-default.svg │ │ ├── layout-horizontal.svg │ │ ├── layout-vertical.svg │ │ ├── loader.svg │ │ ├── open-clipboard.svg │ │ ├── open-current-tab.svg │ │ ├── open-iframe.svg │ │ ├── open-new-tab.svg │ │ ├── open-parent.svg │ │ ├── open-top.svg │ │ ├── open-workspace.svg │ │ ├── save-config.svg │ │ ├── section-expand-collapse.svg │ │ ├── unknown-icon.svg │ │ ├── user-logout.svg │ │ └── widget-update.svg │ └── locales │ │ ├── ar.json │ │ ├── bg.json │ │ ├── bn.json │ │ ├── cs.json │ │ ├── da.json │ │ ├── de.json │ │ ├── el.json │ │ ├── en.json │ │ ├── es.json │ │ ├── fr.json │ │ ├── gl.json │ │ ├── hi.json │ │ ├── it.json │ │ ├── ja.json │ │ ├── ko.json │ │ ├── nb.json │ │ ├── nl.json │ │ ├── pl.json │ │ ├── pt.json │ │ ├── ro.json │ │ ├── ru.json │ │ ├── sk.json │ │ ├── sl.json │ │ ├── sv.json │ │ ├── tr.json │ │ ├── ua.json │ │ ├── zh-CN.json │ │ ├── zh-TW.json │ │ └── zz-pirate.json ├── components │ ├── Charts │ │ ├── Gauge.vue │ │ └── PercentageChart.vue │ ├── Configuration │ │ ├── AccessError.vue │ │ ├── AppInfoModal.vue │ │ ├── AppVersion.vue │ │ ├── CloudBackupRestore.vue │ │ ├── ConfigContainer.vue │ │ ├── CustomCss.vue │ │ ├── EditSiteMeta.vue │ │ ├── JsonEditor.vue │ │ └── RebuildApp.vue │ ├── FormElements │ │ ├── Button.vue │ │ ├── Input.vue │ │ ├── Radio.vue │ │ ├── Select.vue │ │ └── Toggle.vue │ ├── InteractiveEditor │ │ ├── AddNewSectionLauncher.vue │ │ ├── EditAppConfig.vue │ │ ├── EditItem.vue │ │ ├── EditModeSaveMenu.vue │ │ ├── EditModeTopBanner.vue │ │ ├── EditMultiPages.vue │ │ ├── EditPageInfo.vue │ │ ├── EditSection.vue │ │ ├── ExportConfigMenu.vue │ │ ├── MoveItemTo.vue │ │ └── SaveCancelButtons.vue │ ├── LinkItems │ │ ├── Collapsable.vue │ │ ├── IframeModal.vue │ │ ├── Item.vue │ │ ├── ItemContextMenu.vue │ │ ├── ItemIcon.vue │ │ ├── ItemOpenMethodIcon.vue │ │ ├── Section.vue │ │ ├── SectionContextMenu.vue │ │ ├── StatusIndicator.vue │ │ ├── SubItem.vue │ │ └── SubItemGroup.vue │ ├── MinimalView │ │ ├── MinimalHeading.vue │ │ ├── MinimalSearch.vue │ │ └── MinimalSection.vue │ ├── PageStrcture │ │ ├── CriticalError.vue │ │ ├── Footer.vue │ │ ├── Header.vue │ │ ├── LoadingScreen.vue │ │ ├── Nav.vue │ │ └── PageTitle.vue │ ├── Settings │ │ ├── AuthButtons.vue │ │ ├── ConfigLauncher.vue │ │ ├── CustomThemeMaker.vue │ │ ├── ItemSizeSelector.vue │ │ ├── LanguageSwitcher.vue │ │ ├── LayoutSelector.vue │ │ ├── LocalConfigWarning.vue │ │ ├── SearchBar.vue │ │ ├── SettingsContainer.vue │ │ ├── ThemeSelector.vue │ │ └── ViewSwitcher.vue │ ├── Widgets │ │ ├── AdGuardDnsInfo.vue │ │ ├── AdGuardFilterStatus.vue │ │ ├── AdGuardStats.vue │ │ ├── AdGuardTopDomains.vue │ │ ├── AnonAddy.vue │ │ ├── Apod.vue │ │ ├── BlacklistCheck.vue │ │ ├── Blank.vue │ │ ├── Clock.vue │ │ ├── CodeStats.vue │ │ ├── CovidStats.vue │ │ ├── CryptoPriceChart.vue │ │ ├── CryptoWatchList.vue │ │ ├── CustomSearch.vue │ │ ├── CveVulnerabilities.vue │ │ ├── DomainMonitor.vue │ │ ├── DroneCi.vue │ │ ├── EmbedWidget.vue │ │ ├── EthGasPrices.vue │ │ ├── ExchangeRates.vue │ │ ├── Flights.vue │ │ ├── GitHubProfile.vue │ │ ├── GitHubTrending.vue │ │ ├── GlAlerts.vue │ │ ├── GlCpuCores.vue │ │ ├── GlCpuGauge.vue │ │ ├── GlCpuHistory.vue │ │ ├── GlCpuSpeedometer.vue │ │ ├── GlCpuTemp.vue │ │ ├── GlDiskIo.vue │ │ ├── GlDiskSpace.vue │ │ ├── GlIpAddress.vue │ │ ├── GlLoadHistory.vue │ │ ├── GlMemGauge.vue │ │ ├── GlMemHistory.vue │ │ ├── GlMemSpeedometer.vue │ │ ├── GlNetworkInterfaces.vue │ │ ├── GlNetworkTraffic.vue │ │ ├── GlSystemLoad.vue │ │ ├── GluetunStatus.vue │ │ ├── HackernewsTrending.vue │ │ ├── HealthChecks.vue │ │ ├── IframeWidget.vue │ │ ├── ImageWidget.vue │ │ ├── Jokes.vue │ │ ├── Linkding.vue │ │ ├── MinecraftStatus.vue │ │ ├── MullvadStatus.vue │ │ ├── Mvg.vue │ │ ├── MvgConnection.vue │ │ ├── NdCpuHistory.vue │ │ ├── NdLoadHistory.vue │ │ ├── NdRamHistory.vue │ │ ├── NewsHeadlines.vue │ │ ├── NextcloudNotifications.vue │ │ ├── NextcloudPhpOpcache.vue │ │ ├── NextcloudStats.vue │ │ ├── NextcloudSystem.vue │ │ ├── NextcloudUser.vue │ │ ├── NextcloudUserStatus.vue │ │ ├── PiHoleStats.vue │ │ ├── PiHoleTopQueries.vue │ │ ├── PiHoleTraffic.vue │ │ ├── Proxmox.vue │ │ ├── PublicHolidays.vue │ │ ├── PublicIp.vue │ │ ├── RescueTime.vue │ │ ├── RssFeed.vue │ │ ├── Sabnzbd.vue │ │ ├── SportsScores.vue │ │ ├── StatPing.vue │ │ ├── StockPriceChart.vue │ │ ├── SynologyDownload.vue │ │ ├── SystemInfo.vue │ │ ├── TacticalRMM.vue │ │ ├── TflStatus.vue │ │ ├── UptimeKuma.vue │ │ ├── WalletBalance.vue │ │ ├── Weather.vue │ │ ├── WeatherForecast.vue │ │ ├── WidgetBase.vue │ │ └── XkcdComic.vue │ └── Workspace │ │ ├── MultiTaskingWebComtent.vue │ │ ├── SideBar.vue │ │ ├── SideBarItem.vue │ │ ├── SideBarSection.vue │ │ ├── WebContent.vue │ │ └── WidgetView.vue ├── directives │ ├── ClickOutside.js │ └── LongPress.js ├── main.js ├── mixins │ ├── ChartingMixin.js │ ├── ConfigSaving.js │ ├── GlancesMixin.js │ ├── HomeMixin.js │ ├── ItemMixin.js │ ├── NextcloudMixin.js │ ├── ThemingMixin.js │ └── WidgetMixin.js ├── router.js ├── store.js ├── styles │ ├── color-palette.scss │ ├── color-themes.scss │ ├── dimensions.scss │ ├── global-styles.scss │ ├── media-queries.scss │ ├── schema-editor.scss │ ├── style-helpers.scss │ ├── typography.scss │ ├── user-defined-themes.scss │ ├── weather-icons.scss │ └── widgets │ │ └── nextcloud-shared.scss ├── utils │ ├── ArrowKeyNavigation.js │ ├── Auth.js │ ├── CheckItemVisibility.js │ ├── CheckPageVisibility.js │ ├── CheckSectionVisibility.js │ ├── CloudBackup.js │ ├── ConfigAccumalator.js │ ├── ConfigHelpers.js │ ├── ConfigSchema.json │ ├── CoolConsole.js │ ├── EmojiUnicodeRegex.js │ ├── ErrorHandler.js │ ├── ErrorReporting.js │ ├── HeaderAuth.js │ ├── InitServiceWorker.js │ ├── IsVisibleToUser.js │ ├── KeycloakAuth.js │ ├── MiscHelpers.js │ ├── OidcAuth.js │ ├── Search.js │ ├── SectionHelpers.js │ ├── StoreMutations.js │ ├── defaults.js │ ├── emojis.json │ └── languages.js └── views │ ├── 404.vue │ ├── About.vue │ ├── DownloadConfig.vue │ ├── Home.vue │ ├── Login.vue │ ├── Minimal.vue │ └── Workspace.vue ├── tsconfig.json ├── user-data └── conf.yml ├── vue.config.js └── yarn.lock /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node 3 | { 4 | "name": "Dashy", 5 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 6 | "image": "mcr.microsoft.com/devcontainers/javascript-node:1-18-bullseye", 7 | "customizations": { 8 | "vscode": { 9 | "extensions": [ 10 | "Vue.volar", 11 | "dbaeumer.vscode-eslint", 12 | "ms-azuretools.vscode-docker", 13 | "ms-edgedevtools.vscode-edge-devtools", 14 | "firefox-devtools.vscode-firefox-debug", 15 | "aaravb.chrome-extension-developer-tools" 16 | ] 17 | } 18 | }, 19 | 20 | // Features to add to the dev container. More info: https://containers.dev/features. 21 | "features": { 22 | "ghcr.io/devcontainers/features/github-cli:1": {} 23 | }, 24 | 25 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 26 | // "forwardPorts": [], 27 | 28 | // Use 'postCreateCommand' to run commands after the container is created. 29 | "postCreateCommand": "yarn install --ignore-engines --immutable --no-cache --network-timeout 300000 --network-concurrency 1" 30 | 31 | // Configure tool-specific properties. 32 | // "customizations": {}, 33 | 34 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 35 | // "remoteUser": "root" 36 | } 37 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Files specified here are not required for Docker 2 | # so ignoring them helps to reduce the container size 3 | # The Docker container MUST have the following files: 4 | # package.json yarn.lock server.js vue.config.js src/ services/ 5 | 6 | node_modules 7 | docs 8 | .git 9 | .github 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | # Basics - All Files 4 | [*] 5 | end_of_line = lf 6 | charset = utf-8 7 | insert_final_newline = true 8 | 9 | # JS, TS and Vue 10 | [*.{js,jsx,ts,tsx,vue}] 11 | indent_style = space 12 | indent_size = 2 13 | trim_trailing_whitespace = true 14 | insert_final_newline = true 15 | 16 | # YAML, for config file 17 | [*.{yml,yaml}] 18 | indent_size = 2 19 | 20 | # Markdown for docs 21 | [*.md] 22 | trim_trailing_whitespace = false 23 | 24 | # Licensed under MIT, (C) 2024 Alicia Sykes -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | # Store environmental variables here. All variables are optional. 2 | # Lines beginning in '#' are ignored. 3 | 4 | # Can be either development, production or test 5 | # NODE_ENV=production 6 | 7 | # The port to expose the running application on 8 | # PORT=4000 9 | 10 | # If you've proved SSL certs, then can set HTTPS port 11 | # SSL_PORT=4001 12 | 13 | # The host that Dashy is running on, domain or IP 14 | # HOST=localhost 15 | 16 | # The default base path for serving up static assets 17 | # BASE_URL=./ 18 | 19 | # Optionally, specify the path of SSL private + public keys 20 | # SSL_PRIV_KEY_PATH=/etc/ssl/certs/dashy-priv.key 21 | # SSL_PUB_KEY_PATH=/etc/ssl/certs/dashy-pub.pem 22 | 23 | # If SSL enabled, choose whether or not to redirect http to https 24 | # Defaults to true 25 | # REDIRECT_HTTPS=true 26 | 27 | # The path to the user data directory 28 | # USER_DATA_DIR=user-data 29 | 30 | # Enable HTTP basic auth to protect your *.yml config files 31 | # ENABLE_HTTP_AUTH=true 32 | 33 | # Enable basic HTTP auth to protect your *.yml config files 34 | # BASIC_AUTH_USERNAME 35 | # BASIC_AUTH_PASSWORD 36 | 37 | # If you'd like frontend to automatically authenticate when basic auth enabled, set credentials here too 38 | # VUE_APP_BASIC_AUTH_USERNAME 39 | # VUE_APP_BASIC_AUTH_PASSWORD 40 | 41 | # Override where the path to the configuration file is, can be a remote URL 42 | # VUE_APP_CONFIG_PATH=/conf.yml 43 | 44 | # Usually the same as BASE_URL, but accessible in frontend 45 | # VUE_APP_DOMAIN=https://dashy.to 46 | 47 | # Override the page title for the frontend app 48 | # VUE_APP_TITLE='' 49 | 50 | # Set the default view to load on startup (can be `minimal`, `workspace` or `home`) 51 | # VUE_APP_STARTING_VIEW=home 52 | 53 | # Set the Vue app routing mode (can be 'hash', 'history' or 'abstract') 54 | # VUE_APP_ROUTING_MODE=history 55 | 56 | # Should enable SRI for build script and link resources 57 | # INTEGRITY=true 58 | 59 | # Computed automatically on build. Indicates if running in container 60 | # IS_DOCKER=true 61 | 62 | # Again, set automatically using package.json during build time 63 | # VUE_APP_VERSION=2.0.0 64 | 65 | # Directory for conf.yml backups 66 | # BACKUP_DIR=./user-data/config-backups 67 | 68 | # Setup any other user defined vars by prepending VUE_APP_ to the var name 69 | # VUE_APP_pihole_ip=http://your.pihole.ip 70 | # VUE_APP_pihole_key=your_pihole_secret_key 71 | -------------------------------------------------------------------------------- /.github/.lycheeexclude: -------------------------------------------------------------------------------- 1 | # Ignore list, for automated broken link checking 2 | 3 | https://fonts.gstatic.com/** 4 | https://metager.org/meta/** 5 | https://developers.cloudflare.com/** 6 | 7 | http://localhost** 8 | https://localhost** 9 | http://192.168** 10 | https://192.168** 11 | file:///github/** 12 | http://[dashy-location]** 13 | https://[dashy-location]** 14 | **.local/** -------------------------------------------------------------------------------- /.github/.misspell-fixer.ignore: -------------------------------------------------------------------------------- 1 | /src/assets/locales/fr.json 2 | ^./src/assets/locales/de.json 3 | ^./src/assets/locales/es.json 4 | ^./src/assets/locales/fr.json 5 | ^./src/assets/locales/nl.json 6 | ^./src/assets/locales/sl.json 7 | ^./src/assets/locales/zh-CN.json 8 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Code Owners helps give greater control to those who developed a feature 2 | # PR's which modify files that you own will be marked as trusted 3 | # After developing a feature, you can add yourself as it's owner 4 | # Each line starts with file pattern, followed by one or more owners 5 | # Codeowners Docs: https://github.blog/2017-07-06-introducing-code-owners/ 6 | 7 | # Repo Owners 8 | * @lissy93 9 | 10 | # Translations 11 | src/assets/locales/fr.json @EVOTk 12 | 13 | # Bot PR Permissions 14 | docs/assets/CONTRIBUTORS.svg @liss-bot 15 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # Support Dashy's Development! 2 | 3 | github: lissy93 4 | custom: ['https://notes.aliciasykes.com/tip'] 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request ✨ 2 | description: Suggest an idea for future development of Dashy 3 | title: '[FEATURE_REQUEST] ' 4 | labels: ['🦄 Feature Request'] 5 | assignees: 6 | - Lissy93 7 | 8 | body: 9 | 10 | # Field 1 - Is it bug-related 11 | - type: textarea 12 | id: issue 13 | attributes: 14 | label: Is your feature request related to a problem? If so, please describe. 15 | description: 16 | placeholder: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 17 | validations: 18 | required: false 19 | 20 | # Field 2 - Describe feature 21 | - type: textarea 22 | id: solution 23 | attributes: 24 | label: Describe the solution you'd like 25 | placeholder: An outline of how you would like this to be implemented, include as much details as possible 26 | validations: 27 | required: true 28 | 29 | # Field 3 - Priority 30 | - type: dropdown 31 | id: priority 32 | attributes: 33 | label: Priority 34 | description: How urgent is the development of this feature 35 | options: 36 | - Low (Nice-to-have) 37 | - Medium (Would be very useful) 38 | - High (The app does not function without it) 39 | validations: 40 | required: true 41 | 42 | # Field 3 - Can the user implement 43 | - type: dropdown 44 | id: canImplement 45 | attributes: 46 | label: Is this something you would be keen to implement 47 | description: Are you raising this ticket in order to get an issue number for your PR? 48 | options: 49 | - 'No' 50 | - 'Maybe' 51 | - 'Yes!' 52 | validations: 53 | required: false 54 | 55 | # Final text 56 | - type: markdown 57 | attributes: 58 | value: |- 59 | ## Thanks 🙏 60 | Thank you for your feature suggestion, you should expect a reply within 48 hours :) 61 | Please note that there is no guarantee that your idea will be implemented 62 | If you haven't already done so, please Star the Dashy's repository on GitHub, to help other users discover it 63 | validations: 64 | required: false 65 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/share-feedback.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Share Feedback \U0001F308" 3 | about: Share what you think about Dashy, and any ideas or suggestions you have 4 | title: "[FEEDBACK]" 5 | labels: "\U0001F308 Feedback" 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/showcase-addition.yml: -------------------------------------------------------------------------------- 1 | name: Add your Dashboard to the Showcase 🌟 2 | description: Share a screenshot of your dashboard to the Readme showcase! 3 | title: '[SHOWCASE] <title>' 4 | labels: ['💯 Showcase'] 5 | assignees: 6 | - lissy93 7 | 8 | body: 9 | # 1 - Title 10 | - type: input 11 | id: title 12 | attributes: 13 | label: Title 14 | description: Pick a title for your addition 15 | placeholder: My Awesome Dashboard 16 | validations: 17 | required: false 18 | # 2 - Link to Screenshot 19 | - type: textarea 20 | id: screenshot 21 | attributes: 22 | label: Screenshot 23 | description: Either upload your screenshot here, or include a link to a png/jpg on a CDN / image hosting service 24 | validations: 25 | required: true 26 | # 3 - Credit user 27 | - type: dropdown 28 | id: attribution 29 | attributes: 30 | label: Would you like your name/ username included? 31 | description: This will be displayed above the screenshot to your dashboard in the showcase page 32 | options: 33 | - 'Yes' 34 | - 'No' 35 | validations: 36 | required: true 37 | # 4 - Social links 38 | - type: input 39 | id: links 40 | attributes: 41 | label: Link to your Website/ Profile/ Twitter (optional) 42 | description: You can optionally have your name link to your profile or website. If you'd like this, include the URL to your site below 43 | validations: 44 | required: false 45 | # 5 - Description 46 | - type: textarea 47 | id: description 48 | attributes: 49 | label: Description (Optional) 50 | description: You can optionally also include a short description. If there's anything else you'd like to include, then put it here 51 | validations: 52 | required: false 53 | # 6 - All done 54 | - type: markdown 55 | attributes: 56 | value: |- 57 | ## That's It! 58 | Thanks for sharing your dashboard :) You will receive an update to this ticket once it's added to the showcase 59 | validations: 60 | required: false 61 | -------------------------------------------------------------------------------- /.github/LATEST_CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## ✨ 2.1.1 Improvements [PR #775](https://github.com/Lissy93/dashy/pull/775) 2 | 3 | #### Bug Fixes 🐛 4 | 5 | - Update APOD widget to use https://apod.as93.net 6 | - #745 by @k073l 7 | - Fixes theme applying bug (#774) 8 | 9 | #### Improvements ⚡️ 10 | 11 | - Stop status checks when item destroyed 12 | - #767 by @marekful 13 | - Ensure first SSL certificate check finished before second 14 | - #760 by @marekful 15 | - Huge improvement to the way widgets are defined 16 | - #758 by @patrickheeney 17 | 18 | #### Features ✨ 19 | 20 | - A set of awesome NextCloud widgets 21 | - #740 by @marekful 22 | - Add Elizabeth + non-underground lines to TFL widget 23 | - #766 by @dougaldhub 24 | - Option to show / hide detailed info for StatPing widget 25 | - #714 by @marekful 26 | - Korean translations 27 | - #711 by @boggy-cs 28 | - Adds option to force ignore widget errors 29 | 30 | #### Docs 📕 31 | 32 | - Small docs update 33 | - #741 by @markusdd 34 | - Small docs update 35 | - #705 by @pablomalo 36 | - Adds Dipanghosh's dash to showcase 37 | 38 | --- 39 | 40 | 41 | Big thanks to the above developers, for their awesome work on this release! 42 | 43 | V 2.1.2 is in the works, and includes an overhaul of how the config is loaded, so stay tuned for that! 44 | 45 | And Happy Friday! 46 | -------------------------------------------------------------------------------- /.github/SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | Security is taken very seriously 3 | 4 | ## Supported Versions 5 | The current versions, and previous minor versions and / or the past 5 versions are supported. Releases either older than 5 versions, or from the last major version are no longer maintained or monitored, and hence the security of which cannot be guaranteed. 6 | 7 | ## Keeping your Instance of Dashy Secure 8 | See [Docs: Management - Security](/docs/management.md#securing) 9 | 10 | ## Reporting a Security Issue 11 | If you think you've found a critical issue, please send an email to `security@mail.alicia.omg.lol`, to encrypt it, you can use [`0688 F8D3 4587 D954 E9E5 1FB8 FEDB 68F5 5C02 83A7`](https://keybase.io/aliciasykes/pgp_keys.asc?fingerprint=0688f8d34587d954e9e51fb8fedb68f55c0283a7). You should receive a response within 48 hours. 12 | 13 | All non-critical issues can be raised as a ticket. 14 | 15 | Please include the following information: 16 | - Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 17 | - Full paths of source file(s) related to the manifestation of the issue 18 | - The location of the affected source code (tag/branch/commit or direct URL) 19 | - Any special configuration required to reproduce the issue 20 | - Step-by-step instructions to reproduce the issue 21 | - Proof-of-concept or exploit code (if possible) 22 | - Impact of the issue, including how an attacker might exploit the issue 23 | 24 | This info will help with finding and fixing the issue. 25 | 26 | Please use only English. 27 | 28 | ## Issues That Should Not Be Raised 29 | Please do not raise issues in this repo which relate to Vue or Vue CLI, we're already using the latest versions of these dependencies, so any issues here to be taken up with Vue. The same applies to other dev dependencies that are at the latest version. 30 | 31 | ## Known Issues 32 | 33 | > **01/09/2021** - [Inefficient Regular Expression Complexity](https://www.huntr.dev/bounties/1e8f07fc-c384-4ff9-8498-0690de2e8c31/) in Axios (Re: [CWE-1333](https://cwe.mitre.org/data/definitions/1333.html)). 34 | 35 | This ReDos vuln, was raised and fixed by @ready-research in Axios in August 2021. The issue was resolved in [`5b45711`](https://github.com/axios/axios/commit/5b457116e31db0e88fede6c428e969e87f290929), but Snyk sometime just takes a while to show updates. Dashy is using the latest version of Axios, and so is not affected by this issue. 36 | -------------------------------------------------------------------------------- /.github/SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | To report a potential vulnerability, follow the steps in **[Security](https://github.com/Lissy93/dashy/blob/master/.github/SECURITY.md#reporting-a-security-issue)**. 4 | 5 | For setup and usage guides, see **[dashy.to/docs](https://dashy.to/)** or the **[GitHub](https://github.com/Lissy93/dashy)** repo. 6 | 7 | To raise a bug, for something that's not working, **[Open a new Issue](https://github.com/Lissy93/dashy/issues/new/choose)**. 8 | 9 | For help with getting Dashy up and running, please see the **[Discussions](https://github.com/Lissy93/dashy/discussions)**. 10 | 11 | If you'd like to help support Dashy's future development, see **[Contributing](https://github.com/Lissy93/dashy/blob/master/docs/contributing.md)**. 12 | 13 | To get in contact with the author, email me at **`alicia at omg dot lol`** **[[PGP]](https://keybase.io/aliciasykes/pgp_keys.asc?fingerprint=0688f8d34587d954e9e51fb8fedb68f55c0283a7)**. 14 | 15 | -Thank you 16 | 17 | > <sub>Prior to raising a ticket, please check the [docs](https://github.com/Lissy93/dashy/tree/master/docs#readme), [troubleshooting guide](https://github.com/Lissy93/dashy/blob/master/docs/troubleshooting.md) and [previous issues](https://github.com/Lissy93/dashy/issues?q=is%3Aissue).</sub><br><sup>If you're new here, consider also staring the repo before submitting your ticket.</sup> 18 | -------------------------------------------------------------------------------- /.github/close-label.yml: -------------------------------------------------------------------------------- 1 | 🐛 Bug: ✅ Fixed 2 | 🦄 Feature Request: ✅ Implemented 3 | 🤷‍♂️ Question: ✅ Answered 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for more information: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | # https://containers.dev/guide/dependabot 6 | 7 | version: 2 8 | updates: 9 | - package-ecosystem: "devcontainers" 10 | directory: "/" 11 | schedule: 12 | interval: weekly 13 | -------------------------------------------------------------------------------- /.github/issue-report-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "section": "Feature Requests", 4 | "labels": [ 5 | "🦄 Feature Request" 6 | ], 7 | "threshold": 100 8 | }, 9 | { 10 | "section": "Bugs", 11 | "labels": [ 12 | "🐛 Bug" 13 | ], 14 | "threshold": 100 15 | }, 16 | { 17 | "section": "Questions & Feedback", 18 | "labels": [ 19 | "🤷‍♂️ Question", 20 | "🌈 Feedback" 21 | ], 22 | "threshold": 100 23 | } 24 | ] -------------------------------------------------------------------------------- /.github/pr-branch-labeler.yml: -------------------------------------------------------------------------------- 1 | # PR labels and the branch patterns they should be auto-assigned to 2 | ✨ New Feature: ['FEATURE/*', 'FEAT/*'] 3 | 🚚 Refactor: ['IMPROVMENTS/*', 'REFACTOR/*'] 4 | 🦋 Bug Fix: ['FIX/*', 'HOT-FIX/*', 'BUG-FIX/*'] 5 | 💯 Showcase: ['SHOWCASE/*', 'SHOWCASE_SUBMISSION/*'] 6 | 💄 Stylistic Changes: ['STYLES/*', 'THEME/*', 'UI/*'] 7 | 🏗️ Architectural Changes: ['ARCH/*', 'ARCHITECTURE/*'] 8 | 🛠️ Build Changes: ['DOCKER/*', 'BUILD/*', 'CI/*', 'ACTIONS/*'] 9 | 🌐 Language: ['LANG/*', 'INTERNATIONALIZATION/*', 'I18N/*', 'TEXT-UPDATE/*'] 10 | 🤖 Auto: ['AUTO/*', 'BOT/*', 'snyk-upgrade-*', 'snyk-fix-*'] 11 | ⛔ Don't Merge: ['WEBSITE/*', 'EXPERIMENT/*', 'DEPLOY/*', 'deploy_*', 'gh-pages', 'dev-demo'] -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | <!-- 2 | Thank you for contributing to Dashy! 3 | So that your PR can be handled effectively, please populate the following fields 4 | --> 5 | 6 | **Category**: 7 | > One of: Bugfix / Feature / Code style update / Refactoring Only / Build related changes / Documentation / Other (please specify) 8 | 9 | **Overview** 10 | > Briefly outline your new changes... 11 | 12 | **Issue Number** _(if applicable)_ #00 13 | 14 | **New Vars** _(if applicable)_ 15 | > If you've added any new build scripts, environmental variables, config file options, dependency or devDependency, please outline here 16 | 17 | **Screenshot** _(if applicable)_ 18 | > If you've introduced any significant UI changes, please include a screenshot 19 | 20 | **Code Quality Checklist** _(Please complete)_ 21 | - [ ] All changes are backwards compatible 22 | - [ ] All lint checks and tests are passing 23 | - [ ] There are no (new) build warnings or errors 24 | - [ ] _(If a new config option is added)_ Attribute is outlined in the schema and documented 25 | - [ ] _(If a new dependency is added)_ Package is essential, and has been checked out for security or performance 26 | - [ ] _(If significant change)_ Bumps version in package.json 27 | 28 | -------------------------------------------------------------------------------- /.github/workflows/add-comment-from-tag.yml: -------------------------------------------------------------------------------- 1 | # Based on a label applied to an issue, the bot will add a comment with some additional info 2 | name: 🎯 Auto-Reply to Labeled Tickets 3 | on: 4 | issues: 5 | types: 6 | - labeled 7 | - unlabeled 8 | pull_request_target: 9 | types: 10 | - labeled 11 | - unlabeled 12 | permissions: 13 | contents: read 14 | issues: write 15 | pull-requests: write 16 | 17 | jobs: 18 | comment: 19 | runs-on: ubuntu-20.04 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@v2 23 | - name: Label Commenter 24 | uses: peaceiris/actions-label-commenter@v1 25 | with: 26 | config_file: .github/issue-auto-comments.yml 27 | github_token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 28 | -------------------------------------------------------------------------------- /.github/workflows/auto-rebase-pr.yml: -------------------------------------------------------------------------------- 1 | # When a '/rebase' comment is added to a PR, it will be rebased from the main branch 2 | name: 🏗️ Automatic PR Rebase 3 | on: 4 | issue_comment: 5 | types: [created] 6 | jobs: 7 | rebase: 8 | name: Rebase 9 | if: > 10 | github.event.issue.pull_request != '' 11 | && contains(github.event.comment.body, '/rebase') 12 | && github.event.comment.author_association == 'MEMBER' 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout 16 | uses: actions/checkout@v2 17 | with: 18 | token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 19 | fetch-depth: 0 20 | - name: Rebase 21 | uses: cirrus-actions/rebase@1.4 22 | env: 23 | GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/build-docs-site.yml: -------------------------------------------------------------------------------- 1 | # Builds and published Dashy's documentation website 2 | name: 📝 Build Docs Site 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: [ WEBSITE/docs-site-source ] 7 | jobs: 8 | deploy: 9 | runs-on: ubuntu-latest 10 | if: github.ref == 'refs/heads/WEBSITE/docs-site-source' 11 | steps: 12 | - uses: actions/checkout@master 13 | - uses: redkubes/docusaurus-deploy-action@v1 14 | with: 15 | source-folder: ./ 16 | git-user: ${{ github.actor }} 17 | git-password: ${{ secrets.GITHUB_TOKEN }} 18 | deployment-branch: gh-pages 19 | -------------------------------------------------------------------------------- /.github/workflows/check-merge-conflicts.yml: -------------------------------------------------------------------------------- 1 | # Detect and label pull requests that have merge conflicts 2 | name: 🏗️ Check Merge Conflicts 3 | on: 4 | push: 5 | branches: 6 | - master 7 | jobs: 8 | check-conflicts: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: mschilde/auto-label-merge-conflicts@master 12 | with: 13 | CONFLICT_LABEL_NAME: "🚫 Merge Conflicts" 14 | GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 15 | MAX_RETRIES: 5 16 | WAIT_MS: 5000 17 | -------------------------------------------------------------------------------- /.github/workflows/close-incomplete-issues.yml: -------------------------------------------------------------------------------- 1 | # Close any issue that does not match any of the issue templates 2 | name: 🎯 Close Incomplete Issues 3 | on: 4 | issues: 5 | types: [opened, edited] 6 | jobs: 7 | auto_close_issues: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v1 12 | - name: Automatically close issues that don't follow the issue template 13 | uses: lucasbento/auto-close-issues@v1.0.2 14 | with: 15 | github-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 16 | closed-issues-label: '🙁 Auto-Closed' 17 | issue-close-message: | 18 | Hello @${issue.user.login} 👋 19 | Unfortunately your issue does not follow the format outlined in the template, and has therefore been auto-closed. 20 | To ensure that all relevant info is included, please either update or recreate your issue, and complete the sub-headings provided. 21 | Thank you :) 22 | -------------------------------------------------------------------------------- /.github/workflows/create-tag-for-version.yml: -------------------------------------------------------------------------------- 1 | # When Dashy's version in package.json is updated 2 | # this workflow will create a new tag 3 | # And then publish it to the repository 4 | name: 🏗️ Tag on Version Change 5 | 6 | on: 7 | workflow_dispatch: 8 | push: 9 | branches: 10 | - master 11 | paths: 12 | - 'package.json' 13 | 14 | jobs: 15 | tag-if-version-updated: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - name: Check Out Repository 🛎️ 20 | uses: actions/checkout@v2 21 | 22 | - name: Set Up Python 🐍 23 | uses: actions/setup-python@v4 24 | with: 25 | python-version: '3.x' 26 | 27 | - name: Extract Version from package.json 🔢 28 | id: package_version 29 | run: | 30 | import json 31 | with open('package.json', 'r') as f: 32 | version = json.load(f)['version'] 33 | print(f"::set-output name=VERSION::{version}") 34 | shell: python 35 | 36 | - name: Get Latest Tag 🏷️ 37 | id: latest_tag 38 | run: | 39 | git fetch --tags 40 | latest_tag=$(git describe --tags `git rev-list --tags --max-count=1` 2>/dev/null) 41 | echo "::set-output name=TAG::${latest_tag:-0}" 42 | 43 | - name: Create and Push Tag ⤴️ 44 | if: steps.package_version.outputs.VERSION != steps.latest_tag.outputs.TAG && steps.latest_tag.outputs.TAG != '0' 45 | run: | 46 | git config --local user.email "liss-bot@d0h.co" 47 | git config --local user.name "Liss-Bot" 48 | git tag -a ${{ steps.package_version.outputs.VERSION }} -m "Release v${{ steps.package_version.outputs.VERSION }}" 49 | git push origin ${{ steps.package_version.outputs.VERSION }} 50 | env: 51 | GIT_AUTHOR_NAME: Liss-Bot 52 | GIT_AUTHOR_EMAIL: liss-bot@d0h.co 53 | GIT_COMMITTER_NAME: Liss-Bot 54 | GIT_COMMITTER_EMAIL: liss-bot@d0h.co 55 | GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 56 | -------------------------------------------------------------------------------- /.github/workflows/dependency-updates-summary.yml: -------------------------------------------------------------------------------- 1 | # Shows changes to any yarn.lock in PR comment 2 | # Useful for easily understanding dependency changes and consequences 3 | name: 💡 Show Dependency Changes 4 | on: [pull_request] 5 | jobs: 6 | check: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@v2 11 | - name: Yarn Lock Changes 12 | uses: Simek/yarn-lock-changes@main 13 | with: 14 | token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 15 | collapsibleThreshold: '25' 16 | failOnDowngrade: 'false' 17 | path: 'yarn.lock' 18 | -------------------------------------------------------------------------------- /.github/workflows/draft-release.yml: -------------------------------------------------------------------------------- 1 | name: 🏗️ Draft New Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - '^[0-9]+\.[0-9]+\.[0-9]+$' 7 | - '**' 8 | workflow_dispatch: 9 | inputs: 10 | tag: 11 | description: 'Tag to draft a release for (must already exist)' 12 | required: true 13 | 14 | jobs: 15 | create-draft-release: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout code 🛎️ 19 | uses: actions/checkout@v2 20 | with: 21 | fetch-depth: 0 # We need all history for generating release notes 22 | 23 | - name: Create Draft Release 📝 24 | id: create_release 25 | uses: actions/create-release@v1 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 28 | with: 29 | tag_name: ${{ github.event.inputs.tag || github.ref_name }} 30 | release_name: Release ${{ github.event.inputs.tag || github.ref_name }} 31 | draft: true 32 | prerelease: false 33 | generate_release_notes: true 34 | 35 | - name: Output new release URL ↗️ 36 | run: 'echo "Draft release URL: ${{ steps.create_release.outputs.html_url }}"' 37 | -------------------------------------------------------------------------------- /.github/workflows/get-size.yml: -------------------------------------------------------------------------------- 1 | # Adds a comment to new PRs, showing the compressed size and size difference of new code 2 | # And also labels the PR based on the number of lines changes 3 | name: 🌈 Check PR Size 4 | on: [pull_request] 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@v2 11 | # Find and comment with compressed size 12 | - name: Get Compressed Size 13 | uses: preactjs/compressed-size-action@v2 14 | with: 15 | repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 16 | pattern: './dist/**/*.{js,css,html}' 17 | strip-hash: '\\b\\w{8}\\.' 18 | exclude: '{./dist/manifest.json,**/*.map,**/node_modules/**}' 19 | minimum-change-threshold: 100 20 | # Check number of lines of code added 21 | - name: Label based on Lines of Code 22 | uses: codelytv/pr-size-labeler@v1 23 | with: 24 | GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 25 | xs_max_size: '10' 26 | s_max_size: '100' 27 | m_max_size: '500' 28 | l_max_size: '1000' 29 | s_label: '🟩 PR - Small' 30 | m_label: '🟨 PR - Medium' 31 | l_label: '🟧 PR - Large' 32 | xl_label: '🟥 PR - XL' 33 | fail_if_xl: 'false' 34 | message_if_xl: > 35 | It looks like this PR is very large (over 1000 lines). 36 | Try to avoid addressing multiple issues in a single PR, and 37 | in the future consider breaking large tasks down into smaller steps. 38 | This it to make reviewing, testing, reverting and general quality management easier. 39 | -------------------------------------------------------------------------------- /.github/workflows/lgtm-comment.yml: -------------------------------------------------------------------------------- 1 | # Replies with a random looks-good GIF, when a PR is reviewed with a LGTM comment 2 | name: 💡 Random LGTM GIF 3 | on: 4 | issue_comment: { types: [created] } 5 | pull_request_review: { types: [submitted] } 6 | jobs: 7 | post: 8 | runs-on: ubuntu-latest 9 | if: (!contains(github.actor, '[bot]')) # Exclude bot comment 10 | steps: 11 | - uses: ddradar/choose-random-action@v1 12 | id: act 13 | with: 14 | contents: | 15 | https://media4.giphy.com/media/11ISwbgCxEzMyY/giphy.gif 16 | https://media4.giphy.com/media/SgwPtMD47PV04/giphy.gif 17 | https://media1.giphy.com/media/3orifdxwbvVLfS3CrS/giphy.gif 18 | https://media4.giphy.com/media/RPwrO4b46mOdy/giphy.gif 19 | https://media2.giphy.com/media/3o7abGQa0aRJUurpII/giphy.gif 20 | https://media3.giphy.com/media/ZZrDTGSJXlHW9Y2khu/giphy.gif 21 | https://media3.giphy.com/media/5DQdk5oZzNgGc/giphy.gif 22 | https://media4.giphy.com/media/3o7abB06u9bNzA8lu8/giphy.gif 23 | https://media4.giphy.com/media/l2JJrEx9aRsjNruhi/giphy.gif 24 | - uses: ddradar/lgtm-action@v1 25 | with: 26 | image-url: ${{ steps.act.outputs.selected }} 27 | token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/manage-pending-labels-closed.yml: -------------------------------------------------------------------------------- 1 | # When a new comment is added to an issue, if it had the Stale or Awaiting User Response labels, 2 | # then those labels will be removed, providing it was not user lissy93 who added the commend. 3 | name: 🎯 Remove Pending Labels on Close 4 | on: 5 | issues: 6 | types: [closed] 7 | jobs: 8 | remove-labels: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Remove Labels when Closed 12 | uses: actions-cool/issues-helper@v2 13 | with: 14 | actions: remove-labels 15 | token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 16 | issue-number: ${{ github.event.issue.number }} 17 | labels: '🚏 Awaiting User Response,⚰️ Stale,👤 Awaiting Maintainer Response' 18 | -------------------------------------------------------------------------------- /.github/workflows/manage-pending-labels.yml: -------------------------------------------------------------------------------- 1 | # When a new comment is added to an issue, if it had the Stale or Awaiting User Response labels, 2 | # then those labels will be removed, providing it was not user lissy93 who added the commend. 3 | name: 🎯 Add/ Remove Awaiting Response Labels 4 | on: 5 | issue_comment: 6 | types: [created] 7 | jobs: 8 | remove-stale: 9 | runs-on: ubuntu-latest 10 | if: ${{ github.event.comment.author_association != 'COLLABORATOR' && github.event.comment.author_association != 'OWNER' }} 11 | steps: 12 | - name: Remove Stale labels when Updated 13 | uses: actions-cool/issues-helper@v2 14 | with: 15 | actions: remove-labels 16 | token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 17 | issue-number: ${{ github.event.issue.number }} 18 | labels: '🚏 Awaiting User Response,⚰️ Stale' 19 | 20 | add-awaiting-author: 21 | runs-on: ubuntu-latest 22 | if: ${{!github.event.issue.pull_request && github.event.comment.author_association != 'COLLABORATOR' && github.event.comment.author_association != 'OWNER' && github.event.issue.state == 'open' }} 23 | steps: 24 | - name: Add Awaiting Author labels when Updated 25 | uses: actions-cool/issues-helper@v2 26 | with: 27 | actions: add-labels 28 | token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 29 | issue-number: ${{ github.event.issue.number }} 30 | labels: '👤 Awaiting Maintainer Response' 31 | 32 | remove-awaiting-author: 33 | runs-on: ubuntu-latest 34 | if: ${{ github.event.comment.author_association == 'OWNER' }} 35 | steps: 36 | - name: Remove Awaiting Author labels when Updated 37 | uses: actions-cool/issues-helper@v2 38 | with: 39 | actions: remove-labels 40 | token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 41 | issue-number: ${{ github.event.issue.number }} 42 | labels: '👤 Awaiting Maintainer Response' 43 | -------------------------------------------------------------------------------- /.github/workflows/mirror.yml: -------------------------------------------------------------------------------- 1 | # Pushes the contents of the repo to the Codeberg mirror 2 | name: 🪞 Mirror to Codeberg 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: '30 3 * * 0' # At 03:30 on Sunday 7 | jobs: 8 | codeberg: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | with: { fetch-depth: 0 } 13 | - uses: pixta-dev/repository-mirroring-action@v1 14 | with: 15 | target_repo_url: git@codeberg.org:alicia/dashy.git 16 | ssh_private_key: ${{ secrets.CODEBERG_SSH }} 17 | -------------------------------------------------------------------------------- /.github/workflows/release-commenter.yml: -------------------------------------------------------------------------------- 1 | # Adds a comment to all issues & PRs that were fixed on a new release 2 | name: 💡 Update Issue after Release 3 | on: 4 | release: 5 | types: [published] 6 | jobs: 7 | release: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: apexskier/github-release-commenter@v1 11 | with: 12 | GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 13 | label-template: 🛩️ Released {release_tag} 14 | comment-template: | 15 | **This has now been released in {release_name} ✨** 16 | 17 | If you haven't done so already, please [update your instance](https://github.com/Lissy93/dashy/blob/master/docs/management.md#updating) to `{release_tag}` or later. See {release_link} for full info. 18 | -------------------------------------------------------------------------------- /.github/workflows/update-docs-site.yml: -------------------------------------------------------------------------------- 1 | name: 📝 Update Documentation 2 | 3 | # This will run whenever the /docs directory in master branch is updated, 4 | # or if the workflow is manually dispatched, plus a sync check on Sun at 03:30 UTC 5 | on: 6 | workflow_dispatch: 7 | schedule: 8 | - cron: '30 3 * * 0' 9 | push: 10 | branches: 11 | - master 12 | paths: 13 | - 'docs/**' 14 | 15 | 16 | # Jobs to be run: 17 | # 1. Checkout master branch 18 | # 2. Checkout website source code branch 19 | # 3. Install Python 20 | # 4. Copy /docs from master to website branch 21 | # 5. Run the script which processes documentation 22 | # 6. Commit and push updated docs to the website source code branch 23 | jobs: 24 | update-docs: 25 | runs-on: ubuntu-latest 26 | steps: 27 | - name: Checkout master branch 🛎️ 28 | uses: actions/checkout@v2 29 | with: 30 | path: 'master-docs' 31 | 32 | - name: Checkout WEBSITE/docs-site-source branch 🛎️ 33 | uses: actions/checkout@v2 34 | with: 35 | ref: 'WEBSITE/docs-site-source' 36 | path: 'website-docs' 37 | 38 | - name: Install Python 🐍 39 | uses: actions/setup-python@v2 40 | with: 41 | python-version: '3.x' 42 | 43 | - name: Run script to update documentation 🪄 44 | working-directory: website-docs 45 | run: | 46 | cp -r ../master-docs/docs ./ 47 | python ./do-markdown-magic.py 48 | 49 | - name: Commit changes 🚀 50 | run: | 51 | cd website-docs 52 | git config --local user.email "liss-bot@d0h.co" 53 | git config --local user.name "Liss-Bot" 54 | git add docs 55 | git commit -m "Update documentation" || echo "No changes to commit" 56 | git push 57 | env: 58 | GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 59 | -------------------------------------------------------------------------------- /.github/workflows/wiki-sync.yml: -------------------------------------------------------------------------------- 1 | # Uses the contents of the ./docs directory for Dashy's GH Wiki page 2 | name: 📊 Wiki Sync 3 | on: 4 | workflow_dispatch: # Manual dispatch 5 | schedule: 6 | - cron: '0 1 * * 0' # At 01:00 on Sunday. 7 | jobs: 8 | update-wiki: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@master 13 | - name: Upload Docs to GH Wiki 14 | uses: docker://decathlon/wiki-page-creator-action:latest 15 | env: 16 | GH_PAT: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} 17 | ACTION_MAIL: alicia-gh-bot@mail.as93.net 18 | ACTION_NAME: liss-bot 19 | OWNER: Lissy93 20 | REPO_NAME: Dashy 21 | MD_FOLDER: docs/ 22 | # - name: Sync Wiki 23 | # uses: joeizzard/action-wiki-sync@master 24 | # with: 25 | # username: example 26 | # access_token: ${{ secrets.GITHUB_TOKEN }} 27 | # wiki_folder: ./docs 28 | # commit_username: 'liss-bot' 29 | # commit_email: 'liss-bot@d0h.co' 30 | # commit_message: '📕 Chore: Sync Wiki' 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | *.suo 17 | *.ntvs* 18 | *.njsproj 19 | *.sln 20 | *.sw? 21 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | # Config for running Dashy in GitPod's cloud dev environment 2 | # Docs: https://www.gitpod.io/docs/references/gitpod-yml 3 | 4 | # Commands to start on workspace startup 5 | tasks: 6 | - init: yarn install 7 | command: yarn dev 8 | # Ports to expose on workspace startup 9 | ports: 10 | - port: 8080 # Default dev server 11 | visibility: private 12 | onOpen: open-preview 13 | - port: 4000 # Default prod server 14 | visibility: public 15 | onOpen: open-preview 16 | prebuilds: 17 | # Adds 'Open in GitPod' to PRs 18 | addBadge: true 19 | addComment: false 20 | vscode: 21 | # Adds Vue.js and formatting extensions 22 | extensions: 23 | - octref.vetur 24 | - dbaeumer.vscode-eslint 25 | - streetsidesoftware.code-spell-checker 26 | - PKief.material-icon-theme 27 | - wix.vscode-import-cost 28 | - oderwat.indent-rainbow 29 | - eamodio.gitlens 30 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "msedge", 9 | "request": "launch", 10 | "name": "dashy: edge", 11 | "url": "http://localhost:8080", 12 | "webRoot": "${workspaceFolder}", 13 | "breakOnLoad": true, 14 | "pathMapping": { 15 | "/_karma_webpack_": "${workspaceFolder}" 16 | }, 17 | "sourceMapPathOverrides": { 18 | "webpack:/*": "${webRoot}/*", 19 | "/./*": "${webRoot}/*", 20 | "/src/*": "${webRoot}/*", 21 | "/*": "*", 22 | "/./~/*": "${webRoot}/node_modules/*" 23 | }, 24 | "preLaunchTask": "dashy start" 25 | }, 26 | { 27 | "type": "chrome", 28 | "request": "launch", 29 | "name": "dashy: chrome", 30 | "url": "http://localhost:8080", 31 | "webRoot": "${workspaceFolder}", 32 | "breakOnLoad": true, 33 | "pathMapping": { 34 | "/_karma_webpack_": "${workspaceFolder}" 35 | }, 36 | "sourceMapPathOverrides": { 37 | "webpack:/*": "${webRoot}/*", 38 | "/./*": "${webRoot}/*", 39 | "/src/*": "${webRoot}/*", 40 | "/*": "*", 41 | "/./~/*": "${webRoot}/node_modules/*" 42 | }, 43 | "preLaunchTask": "dashy start" 44 | }, 45 | { 46 | "type": "firefox", 47 | "request": "launch", 48 | "name": "dashy: firefox", 49 | "url": "http://localhost:8080", 50 | "webRoot": "${workspaceFolder}", 51 | "breakOnLoad": true, 52 | "pathMapping": { 53 | "/_karma_webpack_": "${workspaceFolder}" 54 | }, 55 | "sourceMapPathOverrides": { 56 | "webpack:/*": "${webRoot}/*", 57 | "/./*": "${webRoot}/*", 58 | "/src/*": "${webRoot}/*", 59 | "/*": "*", 60 | "/./~/*": "${webRoot}/node_modules/*" 61 | }, 62 | "preLaunchTask": "dashy start" 63 | } 64 | ] 65 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "dashy start", 6 | "type": "npm", 7 | "script": "dev", 8 | "isBackground": true, 9 | "problemMatcher": [ 10 | { 11 | "base": "$tsc-watch", 12 | "background": { 13 | "activeOnStart": true, 14 | "beginsPattern": "Starting development server", 15 | "endsPattern": "Compiled successfully" 16 | } 17 | } 18 | ], 19 | } 20 | ] 21 | } -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | dashy.to -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18.19.1-alpine AS BUILD_IMAGE 2 | 3 | # Set the platform to build image for 4 | ARG TARGETPLATFORM 5 | ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64} 6 | 7 | # Install additional tools needed if on arm64 / armv7 8 | RUN \ 9 | case "${TARGETPLATFORM}" in \ 10 | 'linux/arm64') apk add --no-cache python3 make g++ ;; \ 11 | 'linux/arm/v7') apk add --no-cache python3 make g++ ;; \ 12 | esac 13 | 14 | # Create and set the working directory 15 | WORKDIR /app 16 | 17 | # Install app dependencies 18 | COPY package.json yarn.lock ./ 19 | RUN yarn install --ignore-engines --immutable --no-cache --network-timeout 300000 --network-concurrency 1 20 | 21 | # Copy over all project files and folders to the working directory 22 | COPY . ./ 23 | 24 | # Build initial app for production 25 | RUN yarn build --mode production --no-clean 26 | 27 | # Production stage 28 | FROM node:20.11.1-alpine3.19 29 | 30 | # Define some ENV Vars 31 | ENV PORT=8080 \ 32 | DIRECTORY=/app \ 33 | IS_DOCKER=true 34 | 35 | # Create and set the working directory 36 | WORKDIR ${DIRECTORY} 37 | 38 | # Update tzdata for setting timezone 39 | RUN apk add --no-cache tzdata 40 | 41 | # Copy built application from build phase 42 | COPY --from=BUILD_IMAGE /app ./ 43 | 44 | # Finally, run start command to serve up the built application 45 | CMD [ "yarn", "build-and-start" ] 46 | 47 | # Expose the port 48 | EXPOSE ${PORT} 49 | 50 | # Run simple healthchecks every 5 mins, to check that everythings still great 51 | HEALTHCHECK --interval=5m --timeout=5s --start-period=30s CMD yarn health-check 52 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2024 Alicia Sykes <https://aliciasykes.com> 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: npm run build-and-start 2 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Dashy", 3 | "website": "https://dashy.to/", 4 | "description": "A Dashboard for your Homelab 🚀", 5 | "repository": "https://github.com/lissy93/dashy", 6 | "logo": "https://raw.githubusercontent.com/Lissy93/dashy/master/docs/assets/logo.png", 7 | "keywords": [ 8 | "node", 9 | "vue", 10 | "static", 11 | "dashboard", 12 | "self-hosted", 13 | "home-lab", 14 | "lissy93" 15 | ], 16 | "stack": "heroku-20" 17 | } 18 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Welcome to Dashy! To get started, run `docker compose up -d` 3 | # You can configure your container here, by modifying this file 4 | version: "3.8" 5 | services: 6 | dashy: 7 | container_name: Dashy 8 | 9 | # Pull latest image from DockerHub 10 | image: lissy93/dashy 11 | 12 | # To build from source, replace 'image: lissy93/dashy' with 'build: .' 13 | # build: . 14 | 15 | # You can also use an image with a different tag, or pull from a different registry, e.g: 16 | # image: ghcr.io/lissy93/dashy or image: lissy93/dashy:3.0.0 17 | 18 | # Pass in your config file below, by specifying the path on your host machine 19 | # volumes: 20 | # - /path/to/my-config.yml:/app/user-data/conf.yml 21 | # - /path/to/item-icons:/app/user-data/item-icons/ 22 | 23 | # Set port that web service will be served on. Keep container port as 8080 24 | ports: 25 | - 4000:8080 26 | 27 | # Set any environmental variables 28 | environment: 29 | - NODE_ENV=production 30 | # Specify your user ID and group ID. You can find this by running `id -u` and `id -g` 31 | # - UID=1000 32 | # - GID=1000 33 | 34 | # Specify restart policy 35 | restart: unless-stopped 36 | 37 | # Configure healthchecks 38 | healthcheck: 39 | test: ['CMD', 'node', '/app/services/healthcheck'] 40 | interval: 1m30s 41 | timeout: 10s 42 | retries: 3 43 | start_period: 40s 44 | -------------------------------------------------------------------------------- /docker/Dockerfile-arm32v7: -------------------------------------------------------------------------------- 1 | FROM alpine:3.12 AS builder 2 | 3 | # Download QEMU, see https://github.com/docker/hub-feedback/issues/1261 4 | RUN QEMU_URL=https://github.com/balena-io/qemu/releases/download/v5.2.0%2Bbalena4/qemu-5.2.0.balena4-arm.tar.gz \ 5 | && apk add curl && curl -L $QEMU_URL | tar zxvf - -C . --strip-components 1 6 | 7 | # Start second (arm32v7) stage 8 | FROM arm32v7/alpine:3.12 9 | 10 | # Add QEMU from build stage 11 | COPY --from=builder qemu-arm-static /usr/bin 12 | 13 | # Install Node and Yarn 14 | RUN apk add --update --no-cache nodejs npm yarn 15 | 16 | # Define some ENV Vars 17 | ENV PORT=80 \ 18 | DIRECTORY=/app \ 19 | IS_DOCKER=true 20 | 21 | # Create and set the working directory 22 | WORKDIR ${DIRECTORY} 23 | 24 | # Copy over both 'package.json' and 'package-lock.json' (if available) 25 | COPY package*.json ./ 26 | 27 | # Install project dependencies 28 | RUN yarn 29 | 30 | # Copy over all project files and folders to the working directory 31 | COPY . . 32 | 33 | # Build initial app for production 34 | RUN yarn build 35 | 36 | # Expose given port 37 | EXPOSE ${PORT} 38 | 39 | # Finally, run start command to serve up the built application 40 | CMD [ "yarn", "build-and-start"] 41 | 42 | # Run simple healthchecks every 5 mins, to check the Dashy's everythings great 43 | HEALTHCHECK --interval=5m --timeout=2s --start-period=30s CMD yarn health-check 44 | -------------------------------------------------------------------------------- /docker/Dockerfile-arm64v8: -------------------------------------------------------------------------------- 1 | FROM alpine:3.12 AS builder 2 | 3 | # Download QEMU, see https://github.com/docker/hub-feedback/issues/1261 4 | RUN QEMU_URL=https://github.com/balena-io/qemu/releases/download/v5.2.0%2Bbalena4/qemu-5.2.0.balena4-aarch64.tar.gz \ 5 | && apk add curl && curl -L $QEMU_URL | tar zxvf - -C . --strip-components 1 6 | 7 | # Start second (arm64v8) stage 8 | FROM arm64v8/alpine:3.12 9 | 10 | # Add QEMU from build stage 11 | COPY --from=builder qemu-aarch64-static /usr/bin 12 | 13 | # Install Node and Yarn 14 | RUN apk add --update --no-cache nodejs npm yarn 15 | 16 | # Define some ENV Vars 17 | ENV PORT=80 \ 18 | DIRECTORY=/app \ 19 | IS_DOCKER=true 20 | 21 | # Create and set the working directory 22 | WORKDIR ${DIRECTORY} 23 | 24 | # Copy over both 'package.json' and 'package-lock.json' (if available) 25 | COPY package*.json ./ 26 | 27 | # Install project dependencies 28 | RUN yarn 29 | 30 | # Copy over all project files and folders to the working directory 31 | COPY . . 32 | 33 | # Build initial app for production 34 | RUN yarn build 35 | 36 | # Expose given port 37 | EXPOSE ${PORT} 38 | 39 | # Finally, run start command to serve up the built application 40 | CMD [ "yarn", "build-and-start"] 41 | 42 | # Run simple healthchecks every 5 mins, to check the Dashy's everythings great 43 | HEALTHCHECK --interval=5m --timeout=2s --start-period=30s CMD yarn health-check 44 | -------------------------------------------------------------------------------- /docker/Dockerfile-lite: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------------------------------------- 2 | # A light-weight alternative Docker image, using NGINX rather than Node.js to serve the app 3 | # This means that certain features that require server-side endpoints will not be available 4 | # ----------------------------------------------------------------------------------------- 5 | 6 | # Build Stage - Install dependencies + build the app 7 | FROM node:lts-alpine3.14 as build 8 | WORKDIR /dashy 9 | COPY package*.json . 10 | COPY yarn.lock . 11 | RUN yarn 12 | COPY . . 13 | RUN yarn build 14 | 15 | # Production Stage - Serve up built files with NGINX 16 | FROM nginx:alpine as production 17 | COPY ./docker/nginx.conf /etc/nginx/nginx.conf 18 | COPY --from=build /dashy/dist /usr/share/nginx/html 19 | EXPOSE 80 20 | ENTRYPOINT ["nginx", "-g", "daemon off;"] 21 | 22 | LABEL maintainer="Alicia Sykes <alicia@omg.lol>" 23 | -------------------------------------------------------------------------------- /docker/Dockerfile-old: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine3.14 2 | 3 | # Define some ENV Vars 4 | ENV PORT=80 \ 5 | DIRECTORY=/app \ 6 | IS_DOCKER=true 7 | 8 | # Create and set the working directory 9 | WORKDIR ${DIRECTORY} 10 | 11 | # Copy over both 'package.json' and 'package-lock.json' (if available) 12 | COPY package*.json ./ 13 | COPY yarn.lock ./ 14 | 15 | # Install project dependencies 16 | RUN yarn 17 | 18 | # Copy over all project files and folders to the working directory 19 | COPY . . 20 | 21 | # Build initial app for production 22 | RUN yarn build 23 | 24 | # Expose given port 25 | EXPOSE ${PORT} 26 | 27 | # Finally, run start command to serve up the built application 28 | CMD [ "yarn", "build-and-start"] 29 | 30 | # Run simple healthchecks every 5 mins, to check the Dashy's everythings great 31 | HEALTHCHECK --interval=5m --timeout=2s --start-period=30s CMD yarn health-check 32 | -------------------------------------------------------------------------------- /docker/hooks/pre_build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Used to setup QEMU to build arm images on amd64 processors. 4 | # Source: https://git.io/J0ezo 5 | 6 | # Register qemu-*-static for all supported processors except the 7 | # current one, but also remove all registered binfmt_misc before 8 | docker run --rm --privileged multiarch/qemu-user-static:register --reset 9 | -------------------------------------------------------------------------------- /docker/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes 4; 2 | 3 | events { worker_connections 1024; } 4 | 5 | http { 6 | server { 7 | listen 80; 8 | root /usr/share/nginx/html; 9 | include /etc/nginx/mime.types; 10 | 11 | location /appui { 12 | try_files $uri /index.html; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /docs/assets/config-editor-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/assets/config-editor-demo.gif -------------------------------------------------------------------------------- /docs/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/assets/logo.png -------------------------------------------------------------------------------- /docs/assets/minimal-view-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/assets/minimal-view-demo.gif -------------------------------------------------------------------------------- /docs/assets/sponsor-button.svg: -------------------------------------------------------------------------------- 1 | <svg width="223px" height="30px" version="1.1" viewBox="0 0 223 30" xmlns="http://www.w3.org/2000/svg"> 2 | <title>Artboard 3 | Created with Sketch. 4 | 5 | 6 | Sponsor me on Github 7 | -------------------------------------------------------------------------------- /docs/assets/status-check-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/assets/status-check-demo.gif -------------------------------------------------------------------------------- /docs/assets/theme-config-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/assets/theme-config-demo.gif -------------------------------------------------------------------------------- /docs/assets/theme-slideshow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/assets/theme-slideshow.gif -------------------------------------------------------------------------------- /docs/assets/workspace-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/assets/workspace-demo.gif -------------------------------------------------------------------------------- /docs/showcase/1-home-lab-material.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/showcase/1-home-lab-material.png -------------------------------------------------------------------------------- /docs/showcase/10-dashy-live.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/showcase/10-dashy-live.png -------------------------------------------------------------------------------- /docs/showcase/11-ricky-cz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/showcase/11-ricky-cz.png -------------------------------------------------------------------------------- /docs/showcase/12-evo-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/showcase/12-evo-dashboard.png -------------------------------------------------------------------------------- /docs/showcase/13-dragons-lair.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/showcase/13-dragons-lair.png -------------------------------------------------------------------------------- /docs/showcase/2-networking-services-minimal-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/showcase/2-networking-services-minimal-dark.png -------------------------------------------------------------------------------- /docs/showcase/3-cft-toolbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/showcase/3-cft-toolbox.png -------------------------------------------------------------------------------- /docs/showcase/4-bookmarks-colourful.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/showcase/4-bookmarks-colourful.png -------------------------------------------------------------------------------- /docs/showcase/5-project-management.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/showcase/5-project-management.png -------------------------------------------------------------------------------- /docs/showcase/6-nas-home-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/showcase/6-nas-home-dashboard.png -------------------------------------------------------------------------------- /docs/showcase/7-ground-control-dtctek.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/showcase/7-ground-control-dtctek.png -------------------------------------------------------------------------------- /docs/showcase/8-shadowking001s-dashy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/showcase/8-shadowking001s-dashy.png -------------------------------------------------------------------------------- /docs/showcase/9-home-lab-oblivion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/docs/showcase/9-home-lab-oblivion.png -------------------------------------------------------------------------------- /docs/showcase/readme.md: -------------------------------------------------------------------------------- 1 | 2 | See: [Showcase](/docs/showcase.md). -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | # Enables you to easily deploy a fork of Dashy to Netlify 2 | # without the need to configure anything in admin UI 3 | # Docs: https://www.netlify.com/docs/netlify-toml-reference/ 4 | 5 | # Essential site config 6 | [build] 7 | base = "/" 8 | command = "yarn build" 9 | publish = "dist" 10 | functions = "services/serverless-functions" 11 | 12 | # Environmental variables for build command 13 | [build.environment] 14 | NODE_VERSION = "20.11.1" 15 | NODE_OPTIONS = "--openssl-legacy-provider" 16 | YARN_FLAGS = "--ignore-engines" 17 | 18 | # Redirect the Node endpoints to serverless functions 19 | [[redirects]] 20 | from = "/status-check" 21 | to = "/.netlify/functions/cloud-status-check" 22 | status = 301 23 | force = true 24 | [[redirects]] 25 | from = "/config-manager/*" 26 | to = "/.netlify/functions/not-supported" 27 | status = 301 28 | force = true 29 | [[redirects]] 30 | from = "/cors-proxy" 31 | to = "/.netlify/functions/netlify-cors" 32 | status = 301 33 | force = true 34 | 35 | # For router history mode, ensure pages land on index 36 | [[redirects]] 37 | from = "/*" 38 | to = "/index.html" 39 | status = 200 40 | 41 | # Set any security headers here 42 | [[headers]] 43 | for = "/*" 44 | [headers.values] 45 | # Uncomment to enable Netlify user control. Requires premium plan. 46 | # Basic-Auth = "someuser:somepassword anotheruser:anotherpassword" 47 | 48 | -------------------------------------------------------------------------------- /public/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/.nojekyll -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/favicon.ico -------------------------------------------------------------------------------- /public/fonts/Audiowide-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/fonts/Audiowide-Regular.ttf -------------------------------------------------------------------------------- /public/fonts/CutiveMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/fonts/CutiveMono-Regular.ttf -------------------------------------------------------------------------------- /public/fonts/Digital-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/fonts/Digital-Regular.ttf -------------------------------------------------------------------------------- /public/fonts/FrancoisOne-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/fonts/FrancoisOne-Regular.ttf -------------------------------------------------------------------------------- /public/fonts/Podkova-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/fonts/Podkova-Medium.ttf -------------------------------------------------------------------------------- /public/fonts/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/fonts/Roboto-Light.ttf -------------------------------------------------------------------------------- /public/fonts/Shrikhand-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/fonts/Shrikhand-Regular.ttf -------------------------------------------------------------------------------- /public/fonts/Sniglet-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/fonts/Sniglet-Regular.ttf -------------------------------------------------------------------------------- /public/fonts/VT323-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/fonts/VT323-Regular.ttf -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Dashy 17 | 18 | 19 | 20 | 21 |
22 | 23 |
24 |

Dashy

25 |

Loading...

26 | 27 | 39 |
40 |
41 | 42 | 45 | 46 | 47 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /public/item-icons/.gitignore: -------------------------------------------------------------------------------- 1 | # Place any custom icons used by your instance of Dashy here. 2 | # For more info, see Icon docs at: https://git.io/JZwc5 3 | 4 | # Ignore everything in this directory 5 | * 6 | # Except this file 7 | !.gitignore -------------------------------------------------------------------------------- /public/loading-screen.css: -------------------------------------------------------------------------------- 1 | /* Styles applied to index.html for the loading screen, prior to the app being injected */ 2 | /* Dashy - Licensed under MIT, (C) Alicia Sykes 2024 */ 3 | 4 | body { margin: 0; } 5 | #app .loading-placeholder { 6 | position: absolute; 7 | margin: 0; 8 | padding: 0; 9 | width: 100%; 10 | height: 100%; 11 | display: flex; 12 | flex-direction: column; 13 | justify-content: center; 14 | align-items: center; 15 | cursor: progress; 16 | background: #121212; 17 | } 18 | #app .loading-placeholder h1 { 19 | font-size: 20vh; 20 | margin: 1rem auto; 21 | font-family: Tahoma, monospace; 22 | cursor: progress; 23 | color: #0c0c0c; 24 | text-shadow: 0px 4px 4px #090909, 0 0 0 #000, 0px 2px 2px #000000; 25 | } 26 | #app .loading-placeholder p.loading { 27 | font-size: 2rem; 28 | opacity: 0.75; 29 | font-family: monospace; 30 | cursor: progress; 31 | color: #0c0c0c; 32 | display: flex; 33 | flex-direction: column; 34 | align-items: center; 35 | text-shadow: 0 1px 1px #090909, 0 0 0 #000, 0 1px 1px #000000; 36 | } 37 | #app .loading-placeholder .catastrophic-error p { 38 | color: #e11a4bfc; 39 | margin: 0.5rem 0; 40 | font-weight: bold; 41 | font-size: 4vh; 42 | text-align: center; 43 | font-family: monospace; 44 | text-shadow: 1px 2px 1px #090909, 0 0 0 #000, 0 1px 1px #000000 45 | } 46 | #app .loading-placeholder .catastrophic-error p.err-l2 { 47 | opacity: 0.75; 48 | font-size: 2vh; 49 | font-weight: normal; 50 | padding: 0 1rem; 51 | } 52 | #app .loading-placeholder .catastrophic-error p.err-l2 a { 53 | color: #e11a4bfc; 54 | } 55 | #app .loading-placeholder.still-not-loaded { cursor: default; } 56 | #app .loading-placeholder.still-not-loaded p.loading { display: none; } 57 | #app .loading-placeholder.still-not-loaded .catastrophic-error { display: block !important; } 58 | @media (max-width: 780px) { 59 | .loading-placeholder h1 { font-size: 12vh !important; } 60 | #app .loading-placeholder .catastrophic-error p { font-size: 2.5vh !important; } 61 | #app .loading-placeholder .catastrophic-error p.err-l2 { font-size: 1.2vh !important; } 62 | } 63 | ::selection { background-color: #e11a4bfc; color: #121212; } 64 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Dashy Web", 3 | "short_name": "Dashy", 4 | "description": "A Dashboard for your Homelab", 5 | "scope": "/", 6 | "start_url": "./", 7 | "display": "standalone", 8 | "background_color": "#0b1021", 9 | "theme_color": "#4DBA87", 10 | "lang": "en-GB", 11 | "orientation": "portrait-primary", 12 | "icons": [ 13 | { 14 | "src": "./web-icons/dashy-pwa_512x512.png", 15 | "sizes": "512x512" 16 | }, 17 | { 18 | "src": "./web-icons/dashy-pwa_192x192.png", 19 | "sizes": "192x192" 20 | }, 21 | { 22 | "src": "./web-icons/dashy-pwa_144x144.png", 23 | "sizes": "144x144" 24 | }, 25 | { 26 | "src": "./web-icons/dashy-pwa_96x96.png", 27 | "sizes": "96x96" 28 | }, 29 | { 30 | "src": "./web-icons/dashy-pwa_72x72.png", 31 | "sizes": "72x72" 32 | }, 33 | { 34 | "src": "./web-icons/dashy-pwa_48x48.png", 35 | "sizes": "48x48" 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /public/web-icons/dashy-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/web-icons/dashy-logo.png -------------------------------------------------------------------------------- /public/web-icons/dashy-pwa_144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/web-icons/dashy-pwa_144x144.png -------------------------------------------------------------------------------- /public/web-icons/dashy-pwa_192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/web-icons/dashy-pwa_192x192.png -------------------------------------------------------------------------------- /public/web-icons/dashy-pwa_48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/web-icons/dashy-pwa_48x48.png -------------------------------------------------------------------------------- /public/web-icons/dashy-pwa_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/web-icons/dashy-pwa_512x512.png -------------------------------------------------------------------------------- /public/web-icons/dashy-pwa_72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/web-icons/dashy-pwa_72x72.png -------------------------------------------------------------------------------- /public/web-icons/dashy-pwa_96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/web-icons/dashy-pwa_96x96.png -------------------------------------------------------------------------------- /public/web-icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/web-icons/favicon-16x16.png -------------------------------------------------------------------------------- /public/web-icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/web-icons/favicon-32x32.png -------------------------------------------------------------------------------- /public/web-icons/favicon-64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/web-icons/favicon-64x64.png -------------------------------------------------------------------------------- /public/widget-resources/WeatherIcons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/widget-resources/WeatherIcons.eot -------------------------------------------------------------------------------- /public/widget-resources/WeatherIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/widget-resources/WeatherIcons.ttf -------------------------------------------------------------------------------- /public/widget-resources/WeatherIcons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/widget-resources/WeatherIcons.woff -------------------------------------------------------------------------------- /public/widget-resources/WeatherIcons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/public/widget-resources/WeatherIcons.woff2 -------------------------------------------------------------------------------- /services/cors-proxy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple CORS proxy, for accessing API services which aren't CORS-enabled. 3 | * Receives requests from frontend, applies correct access control headers, 4 | * makes request to endpoint, then responds to the frontend with the response 5 | */ 6 | 7 | const axios = require('axios'); 8 | 9 | module.exports = (req, res) => { 10 | // Apply allow-all response headers 11 | res.header('Access-Control-Allow-Origin', '*'); 12 | res.header('Access-Control-Allow-Methods', 'GET, PUT, PATCH, POST, DELETE'); 13 | if (req.header('access-control-request-headers')) { 14 | res.header('Access-Control-Allow-Headers', req.header('access-control-request-headers')); 15 | } 16 | 17 | // Pre-flight 18 | if (req.method === 'OPTIONS') { 19 | res.send(); 20 | return; 21 | } 22 | 23 | // Get desired URL, from Target-URL header 24 | const targetURL = req.header('Target-URL'); 25 | if (!targetURL) { 26 | res.status(500).send({ error: 'There is no Target-Endpoint header in the request' }); 27 | return; 28 | } 29 | // Apply any custom headers, if needed 30 | const headers = req.header('CustomHeaders') ? JSON.parse(req.header('CustomHeaders')) : {}; 31 | 32 | // Prepare the request 33 | const requestConfig = { 34 | method: req.method, 35 | url: targetURL, 36 | json: req.body, 37 | headers, 38 | }; 39 | 40 | // Make the request, and respond with result 41 | axios.request(requestConfig) 42 | .then((response) => { 43 | res.status(200).send(response.data); 44 | }).catch((error) => { 45 | res.status(500).send({ error }); 46 | }); 47 | }; 48 | -------------------------------------------------------------------------------- /services/get-user.js: -------------------------------------------------------------------------------- 1 | module.exports = (config, req) => { 2 | try { 3 | if (config.appConfig.auth.enableHeaderAuth) { 4 | const { userHeader } = config.appConfig.auth.headerAuth; 5 | const { proxyWhitelist } = config.appConfig.auth.headerAuth; 6 | if (proxyWhitelist.includes(req.socket.remoteAddress)) { 7 | return { success: true, user: req.headers[userHeader.toLowerCase()] }; 8 | } 9 | } 10 | return {}; 11 | } catch (e) { 12 | console.warn('Error get-user: ', e); 13 | return { success: false }; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /services/healthcheck.js: -------------------------------------------------------------------------------- 1 | /** 2 | * An endpoint for confirming that the application is up and running 3 | * Used for better Docker healthcheck results 4 | * Note that exiting with code 1 indicates failure, and 0 is success 5 | */ 6 | 7 | const isSsl = !!process.env.SSL_PRIV_KEY_PATH && !!process.env.SSL_PUB_KEY_PATH; 8 | 9 | // eslint-disable-next-line import/no-dynamic-require 10 | const http = require(isSsl ? 'https' : 'http'); 11 | 12 | /* Location of the server to test */ 13 | const isDocker = !!process.env.IS_DOCKER; 14 | 15 | /* Get the port to use (depending on, if docker, if SSL) */ 16 | const sslPort = process.env.SSL_PORT || (isDocker ? 443 : 4001); 17 | const normalPort = process.env.PORT || (isDocker ? 8080 : 4000); 18 | const port = isSsl ? sslPort : normalPort; 19 | 20 | const host = process.env.HOST || '0.0.0.0'; 21 | const timeout = 2000; 22 | 23 | const agent = new http.Agent({ 24 | rejectUnauthorized: false, // Allow self-signed certificates 25 | }); 26 | 27 | const requestOptions = { 28 | host, port, timeout, agent, 29 | }; 30 | 31 | const startTime = new Date(); // Initialize timestamp to calculate time taken 32 | 33 | console.log(`[${startTime}] Running health check...`); 34 | 35 | /* Creates an HTTP Request to attempt to send GET to app, then exits with appropriate exit code */ 36 | const healthCheck = http.request(requestOptions, (response) => { 37 | const totalTime = (new Date() - startTime) / 1000; 38 | const status = response.statusCode; 39 | const color = status === 200 ? '\x1b[32m' : '\x1b[31m'; 40 | const message = `${color}Status: ${status}\nRequest took ${totalTime} seconds\n\x1b[0m---`; 41 | console.log(message); // Print out healthcheck response 42 | process.exit(status === 200 ? 0 : 1); // Exit with 0 (success), if response is 200 okay 43 | }); 44 | 45 | /* If the server is not running, then print the error code, and exit with 1 */ 46 | healthCheck.on('error', (err) => { 47 | console.error(`\x1b[31mHealthceck Failed, Error: ${'\x1b[33m'}${err.code}\x1b[0m`); 48 | process.exit(1); 49 | }); 50 | 51 | healthCheck.end(); 52 | -------------------------------------------------------------------------------- /services/rebuild-app.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This script programmatically triggers a production build 3 | * and responds with the status, message and full output 4 | */ 5 | const { exec } = require('child_process'); 6 | 7 | module.exports = () => new Promise((resolve, reject) => { 8 | const buildProcess = exec('NODE_OPTIONS="--max-old-space-size=512" npm run build'); // Trigger the build command 9 | 10 | let output = ''; // Will store console output 11 | 12 | // Write output to console, and append to var for returning 13 | buildProcess.stdout.on('data', (data) => { 14 | process.stdout.write(data); 15 | output += data; 16 | }); 17 | 18 | // Handle errors, by sending the reject 19 | buildProcess.on('error', (error) => { 20 | reject(Error({ 21 | success: false, 22 | error, 23 | output, 24 | })); 25 | }); 26 | 27 | // When finished, check success, make message and resolve response 28 | buildProcess.on('exit', (response) => { 29 | const success = response === 0; 30 | const message = `Build process exited with ${response}: ` 31 | + `${success ? 'Success' : 'Possible Error'}`; 32 | resolve({ success, message, output }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /services/serverless-functions/cloud-status-check.js: -------------------------------------------------------------------------------- 1 | /* A cloud function that wraps the status checking method, for use on Netlify */ 2 | const statusCheck = require('../status-check'); 3 | 4 | exports.handler = (event, context, callback) => { 5 | const paramStr = event.rawQuery; 6 | statusCheck(paramStr, (results) => { 7 | callback(null, { 8 | statusCode: 200, 9 | body: results, 10 | }); 11 | }); 12 | }; 13 | -------------------------------------------------------------------------------- /services/serverless-functions/netlify-cors.js: -------------------------------------------------------------------------------- 1 | /* A Netlify cloud function to handle requests to CORS-disabled services */ 2 | const axios = require('axios'); 3 | 4 | exports.handler = (event, context, callback) => { 5 | // Get input data 6 | const { body, headers, queryStringParameters } = event; 7 | 8 | // Get URL from header or GET param 9 | const requestUrl = queryStringParameters.url || headers['Target-URL'] || headers['target-url']; 10 | 11 | const returnError = (msg, error) => { 12 | callback(null, { 13 | statusCode: 400, 14 | body: JSON.stringify({ success: false, msg, error }), 15 | }); 16 | }; 17 | // If URL missing, return error 18 | if (!requestUrl) { 19 | returnError('Missing Target-URL header', null); 20 | } 21 | 22 | let custom = {}; 23 | try { 24 | custom = JSON.parse(headers.CustomHeaders || headers.customheaders || '{}'); 25 | } catch (e) { returnError('Unable to parse custom headers'); } 26 | 27 | // Response headers 28 | const requestHeaders = { 29 | 'Access-Control-Allow-Origin': '*', 30 | ...custom, 31 | }; 32 | 33 | // Prepare request 34 | const requestConfig = { 35 | method: 'GET', 36 | url: requestUrl, 37 | json: body, 38 | headers: requestHeaders, 39 | }; 40 | 41 | // Make request 42 | axios.request(requestConfig) 43 | .then((response) => { 44 | callback(null, { statusCode: 200, body: JSON.stringify(response.data) }); 45 | }).catch((error) => { 46 | returnError('Request failed', error); 47 | }); 48 | }; 49 | -------------------------------------------------------------------------------- /services/serverless-functions/not-supported.js: -------------------------------------------------------------------------------- 1 | /* A Netlify cloud function to return a message endpoints that are not available */ 2 | exports.handler = async () => ({ 3 | statusCode: 200, 4 | body: JSON.stringify({ 5 | success: false, 6 | error: 'This action is not supported on Netlify', 7 | }), 8 | }); 9 | -------------------------------------------------------------------------------- /services/ssl-server.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const util = require('util'); 3 | const https = require('https'); 4 | 5 | const promise = util.promisify; 6 | const stat = promise(fs.stat); 7 | 8 | const host = process.env.HOST || '0.0.0.0'; 9 | 10 | const httpsCerts = { 11 | private: process.env.SSL_PRIV_KEY_PATH || '/etc/ssl/certs/dashy-priv.key', 12 | public: process.env.SSL_PUB_KEY_PATH || '/etc/ssl/certs/dashy-pub.pem', 13 | }; 14 | 15 | const isDocker = !!process.env.IS_DOCKER; 16 | const SSLPort = process.env.SSL_PORT || (isDocker ? 443 : 4001); 17 | const redirectHttps = process.env.REDIRECT_HTTPS ? process.env.REDIRECT_HTTPS : true; 18 | 19 | const printNotSoGood = (msg) => { 20 | console.log(`SSL Not Enabled: ${msg}`); 21 | }; 22 | 23 | const printSuccess = () => { 24 | console.log(`🔐 HTTPS server successfully started (port: ${SSLPort} ${isDocker ? 'of container' : ''})`); 25 | }; 26 | 27 | // Check if the SSL certs are present and SSL should be enabled 28 | let enableSSL = false; 29 | const checkCertificateFiles = stat(httpsCerts.public).then(() => { 30 | return stat(httpsCerts.private).then(() => { 31 | enableSSL = true; 32 | }).catch(() => { printNotSoGood('Private key not present'); }); 33 | }).catch(() => { printNotSoGood('Public key not present'); }); 34 | 35 | const startSSLServer = (app) => { 36 | checkCertificateFiles.then(() => { 37 | // If SSL should be enabled, create a secured server and start it 38 | if (enableSSL) { 39 | const httpsServer = https.createServer({ 40 | key: fs.readFileSync(httpsCerts.private), 41 | cert: fs.readFileSync(httpsCerts.public), 42 | }, app); 43 | httpsServer.listen(SSLPort, host, () => { printSuccess(); }); 44 | } 45 | }); 46 | }; 47 | 48 | const middleware = (req, res, next) => { 49 | if (enableSSL && redirectHttps && req.protocol === 'http') { 50 | res.redirect(`https://${req.hostname + ((SSLPort === 443) ? '' : `:${SSLPort}`) + req.url}`); 51 | } else { 52 | next(); 53 | } 54 | }; 55 | 56 | module.exports = { startSSLServer, middleware }; 57 | -------------------------------------------------------------------------------- /services/system-info.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Gets basic system info, for the resource usage widget 3 | */ 4 | const os = require('os'); 5 | 6 | module.exports = () => { 7 | const meta = { 8 | timestamp: new Date(), 9 | uptime: os.uptime(), 10 | hostname: os.hostname(), 11 | username: os.userInfo().username, 12 | system: `${os.version()} (${os.platform()})`, 13 | }; 14 | 15 | const memory = { 16 | total: `${Math.round(os.totalmem() / (1024 * 1024 * 1024))} GB`, 17 | freePercent: (os.freemem() / os.totalmem()).toFixed(2), 18 | }; 19 | 20 | const loadAv = os.loadavg(); 21 | const load = { one: loadAv[0], five: loadAv[1], fifteen: loadAv[2] }; 22 | 23 | return { meta, memory, load }; 24 | }; 25 | -------------------------------------------------------------------------------- /services/update-checker.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios').default; 2 | 3 | const currentVersion = require('../package.json').version; 4 | 5 | const packageUrl = 'https://raw.githubusercontent.com/Lissy93/dashy/master/package.json'; 6 | 7 | const logToConsole = (msg) => { 8 | console.log(msg); // eslint-disable-line no-console 9 | }; 10 | 11 | const makeMsg = (latestVersion) => { 12 | const parse = (version) => parseInt(version.replace(/\./g, ''), 10); 13 | const difference = parse(latestVersion) - parse(currentVersion); 14 | let msg = ''; 15 | if (difference <= 0) { 16 | msg = '\x1b[1m\x1b[32m✅ Dashy is Up-to-Date\x1b[0m\n'; 17 | } else { 18 | msg = `\x1b[103m\x1b[34m${new Array(27).fill('━').join('')}\x1b[0m\n` 19 | + `\x1b[103m\x1b[34m⚠️ Update Available: ${latestVersion} \x1b[0m\n` 20 | + `\x1b[103m\x1b[34m${new Array(27).fill('━').join('')}\x1b[0m\n`; 21 | } 22 | return msg; 23 | }; 24 | 25 | axios.get(packageUrl).then((response) => { 26 | if (response && response.data && response.data.version) { 27 | logToConsole(`\nUsing Dashy V-${currentVersion}. Update Check Complete`); 28 | logToConsole(makeMsg(response.data.version)); 29 | } 30 | }).catch(() => { 31 | logToConsole('Unable to check for updates'); 32 | }); 33 | -------------------------------------------------------------------------------- /src/assets/fonts/Inconsolata-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/src/assets/fonts/Inconsolata-Light.ttf -------------------------------------------------------------------------------- /src/assets/fonts/PTMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/src/assets/fonts/PTMono-Regular.ttf -------------------------------------------------------------------------------- /src/assets/fonts/Raleway-Variable.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lissy93/dashy/126e083e12d2bebed7e512e35c4e855c707871fa/src/assets/fonts/Raleway-Variable.ttf -------------------------------------------------------------------------------- /src/assets/interface-icons/add-new.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/application-about.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/application-change-view.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/application-home.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/application-minimal.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/application-rebuild.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/application-reload.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/application-workspace.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/back-arrow.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/broken-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/assets/interface-icons/burger-menu.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/cloud-backup-restore.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-backup.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-cancel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-color-palette.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-custom-css.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-delete-local.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-download-file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-edit-json.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-editor.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-language.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-meta-data.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-open-settings.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-pages.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/config-restore.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/icon-size-large.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/icon-size-medium.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/icon-size-small.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/interactive-editor-add.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/interactive-editor-cancel-changes.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/interactive-editor-copy-clipboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/interactive-editor-edit-mode.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/interactive-editor-export-changes.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/interactive-editor-move-to.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/interactive-editor-page-info.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/interactive-editor-remove.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/interactive-editor-save-disk.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/interactive-editor-save-locally.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/layout-default.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/layout-horizontal.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/layout-vertical.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/loader.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 18 | 26 | 32 | 33 | -------------------------------------------------------------------------------- /src/assets/interface-icons/open-clipboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/open-current-tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/open-iframe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/open-new-tab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/open-parent.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/open-top.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/open-workspace.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/save-config.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/section-expand-collapse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/unknown-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/user-logout.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/interface-icons/widget-update.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/components/Configuration/AccessError.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 21 | 22 | 38 | -------------------------------------------------------------------------------- /src/components/FormElements/Button.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 39 | 40 | 82 | -------------------------------------------------------------------------------- /src/components/InteractiveEditor/AddNewSectionLauncher.vue: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 50 | 51 | 68 | -------------------------------------------------------------------------------- /src/components/InteractiveEditor/EditModeTopBanner.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 21 | -------------------------------------------------------------------------------- /src/components/InteractiveEditor/SaveCancelButtons.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 33 | 34 | 65 | -------------------------------------------------------------------------------- /src/components/LinkItems/IframeModal.vue: -------------------------------------------------------------------------------- 1 |