diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md index a8514e7610..b1f4fb38e1 100644 --- a/.github/CHANGELOG.md +++ b/.github/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## ✨ 1.8.4 - Custom Error Pages [PR #257](https://github.com/Lissy93/dashy/pull/257) +- Creates a 404 Not Found page +- Routes any missing views to the 404 page + ## ⚡️ 1.8.3 - Improved UX for Initial Load [PR #238](https://github.com/Lissy93/dashy/pull/238) - Removes the old splash screen - Adds placeholder in the HTML index, which will usually be visible on initial load diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md index 28b824258c..8ed0e88d47 100644 --- a/.github/SUPPORT.md +++ b/.github/SUPPORT.md @@ -1,5 +1,9 @@ -# SUPPORT +# Support -For help with getting Dashy up and running, please see the [Discussion](https://github.com/Lissy93/dashy/discussions). +To raise a bug, please **[Open a new Issue](https://github.com/Lissy93/dashy/issues/new/choose)**. -If you'd like to help support Dashy's future development, see [Contributing](/docs/contributing.md) \ No newline at end of file +To report a potential vulnerability, please see **[Security](https://github.com/Lissy93/dashy/blob/master/.github/SECURITY.md#reporting-a-security-issue)**. + +For help with getting Dashy up and running, please see the **[Discussions](https://github.com/Lissy93/dashy/discussions)**. + +If you'd like to help support Dashy's future development, see **[Contributing](https://github.com/Lissy93/dashy/blob/master/docs/contributing.md)**. \ No newline at end of file diff --git a/package.json b/package.json index 023a0a46e7..7629a0cbd6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Dashy", - "version": "1.8.3", + "version": "1.8.4", "license": "MIT", "main": "server", "scripts": { diff --git a/src/components/Configuration/AppInfoModal.vue b/src/components/Configuration/AppInfoModal.vue index 8ba9dbc64d..d8c4c98f99 100644 --- a/src/components/Configuration/AppInfoModal.vue +++ b/src/components/Configuration/AppInfoModal.vue @@ -1,46 +1,32 @@ @@ -58,71 +44,13 @@ export default { return { modalName: modalNames.ABOUT_APP, appVersion: process.env.VUE_APP_VERSION, - systemInfo: this.getSystemInfo(), errorLog: this.getErrorLog(), - serviceWorkerInfo: 'Checking...', - showInfo: false, }; }, - mounted() { - setTimeout(() => { - this.serviceWorkerInfo = this.getSwStatus(); - }, 100); - }, methods: { getErrorLog() { return sessionStorage.getItem(sessionStorageKeys.ERROR_LOG) || ''; }, - getIsConfigValidStatus() { - const isValidVar = process.env.VUE_APP_CONFIG_VALID; - if (isValidVar === undefined) return 'Config validation status is missing'; - return `Config is ${isValidVar ? 'Valid' : 'Invalid'}`; - }, - getSwStatus() { - const sessionData = sessionStorage[sessionStorageKeys.SW_STATUS]; - const swInfo = sessionData ? JSON.parse(sessionData) : {}; - let swStatus = ''; - if (swInfo.registered) swStatus += 'Service worker registered\n'; - if (swInfo.ready) swStatus += 'Dashy is being served from service worker\n'; - if (swInfo.cached) swStatus += 'Content has been cached for offline use\n'; - if (swInfo.updateFound) swStatus += 'New content is downloading\n'; - if (swInfo.updated) swStatus += 'New content is available; please refresh\n'; - if (swInfo.offline) swStatus += 'No internet connection found. App is running in offline mode\n'; - if (swInfo.error) swStatus += 'Error during service worker registration\n'; - if (swInfo.devMode) swStatus += 'App running in dev mode, no need for service worker\n'; - if (swStatus.length === 0) swStatus += 'No service worker info available'; - return swStatus; - }, - getSystemInfo() { - const { userAgent } = navigator; - - // Find Operating System - let os = 'Unknown'; - if (userAgent.indexOf('Win') !== -1) os = 'Windows'; - else if (userAgent.indexOf('Mac') !== -1) os = 'MacOS'; - else if (userAgent.indexOf('Android') !== -1) os = 'Android'; - else if (userAgent.indexOf('iPhone') !== -1) os = 'iOS'; - else if (userAgent.indexOf('Linux') !== -1) os = 'Linux'; - else if (userAgent.indexOf('X11') !== -1) os = 'UNIX'; - - // Find Browser - let browser = 'Unknown'; - if (userAgent.indexOf('Opera') !== -1) browser = 'Opera'; - else if (userAgent.indexOf('Chrome') !== -1) browser = 'Chrome'; - else if (userAgent.indexOf('Safari') !== -1) browser = 'Safari'; - else if (userAgent.indexOf('Firefox') !== -1) browser = 'Firefox'; - else if (userAgent.indexOf('MSIE') !== -1) browser = 'IE'; - else browser = 'Unknown'; - - const isMobile = !!navigator.userAgent.match(/iphone|android|blackberry/ig) || false; - - return { - os, - browser, - userAgent, - isMobile, - }; - }, }, }; @@ -152,40 +80,17 @@ div.about-modal { } } h3 { - font-size: 1.3rem; - margin: 1rem 0 0.2rem 0; + font-size: 1rem; + margin: 0.5rem 0 0.2rem 0; color: var(--about-page-accent); } - p.small-note { - margin: 0.2rem 0; - } - p.about-text { - margin: 0.2rem 0; - } a { color: var(--about-page-accent); } - ul { - margin-top: 0.2rem; - } a.info { text-decoration: underline; margin-left: 0.2rem; } - .system-info { - font-size: 0.8rem; - background: var(--black); - color: var(--white); - border-radius: var(--curve-factor-small); - padding: 0.5rem; - border: 1px solid var(--white); - width: fit-content; - h4 { - font-size: 0.8rem; - margin: 0 0 0.2rem 0; - text-decoration: underline; - } - } .app-version { text-align: left; } diff --git a/src/router.js b/src/router.js index a1bdd95b93..e76efe4252 100644 --- a/src/router.js +++ b/src/router.js @@ -9,17 +9,17 @@ import Vue from 'vue'; import Router from 'vue-router'; import ProgressBar from 'rsup-progress'; -// Import views +// Import views, that are not lazy-loaded import Home from '@/views/Home.vue'; import Login from '@/views/Login.vue'; import Workspace from '@/views/Workspace.vue'; import Minimal from '@/views/Minimal.vue'; -import DownloadConfig from '@/views/DownloadConfig.vue'; // Import helper functions, config data and defaults import { isAuthEnabled, isLoggedIn, isGuestAccessEnabled } from '@/utils/Auth'; import { config } from '@/utils/ConfigHelpers'; import { metaTagData, startingView, routePaths } from '@/utils/defaults'; +import ErrorHandler from '@/utils/ErrorHandler'; Vue.use(Router); const progress = new ProgressBar({ color: 'var(--progress-bar)' }); @@ -102,16 +102,32 @@ const router = new Router({ { // The about app page path: routePaths.about, name: 'about', // We lazy load the About page so as to not slow down the app - component: () => import(/* webpackChunkName: "about" */ './views/About.vue'), + component: () => import('./views/About.vue'), meta: makeMetaTags('About Dashy'), }, { // The export config page path: routePaths.download, name: 'download', - component: DownloadConfig, + component: () => import('./views/DownloadConfig.vue'), props: config, meta: makeMetaTags('Download Config'), }, + { // Page not found, any non-defined routes will land here + path: routePaths.notFound, + name: '404', + component: () => import('./views/404.vue'), + meta: makeMetaTags('404 Not Found'), + beforeEnter: (to, from, next) => { + if (to.redirectedFrom) { // Log error, if redirected here from another route + ErrorHandler(`Route not found: '${to.redirectedFrom}'`); + } + next(); + }, + }, + { // Redirect any not-found routed to the 404 view + path: '*', + redirect: '/404', + }, ], }); diff --git a/src/utils/defaults.js b/src/utils/defaults.js index 35695eea23..49fa263c19 100644 --- a/src/utils/defaults.js +++ b/src/utils/defaults.js @@ -35,6 +35,7 @@ module.exports = { about: '/about', login: '/login', download: '/download', + notFound: '/404', }, /* Server Endpoints */ serviceEndpoints: { @@ -84,6 +85,7 @@ module.exports = { 'login', 'download', 'landing-page-minimal', + // '404', ], /* Key names for local storage identifiers */ localStorageKeys: { diff --git a/src/views/404.vue b/src/views/404.vue new file mode 100644 index 0000000000..ef2c11f73a --- /dev/null +++ b/src/views/404.vue @@ -0,0 +1,90 @@ + + + + +