diff --git a/src/.env.example b/src/.env.example index adf345d..4e9d400 100644 --- a/src/.env.example +++ b/src/.env.example @@ -6,7 +6,6 @@ APP_DOMAIN=localhost APP_URL="https://${APP_DOMAIN}" APP_UID_BYTES=8 -APP_JS_INTEGRITY_HASH="" GIT_HASH="00000000" GIT_TAG="x.x.x" GIT_BRANCH="master" @@ -57,3 +56,10 @@ PUSHER_APP_CLUSTER=mt1 MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" + +INTEGRITY_HASH_HUMANS_TXT="" +INTEGRITY_HASH_COPYRIGHT_HTML="" +INTEGRITY_HASH_NUNITO_REGULAR_WOFF2_FONT="" +INTEGRITY_HASH_POIRETONE_REGULAR_WOFF2_FONT="" +INTEGRITY_HASH_APP_CSS="" +INTEGRITY_HASH_APP_JS="" diff --git a/src/resources/js/Components/Card.vue b/src/resources/js/Components/Card.vue index 054a4fb..e04b9a1 100644 --- a/src/resources/js/Components/Card.vue +++ b/src/resources/js/Components/Card.vue @@ -1,3 +1,28 @@ + + - - diff --git a/src/resources/js/Layouts/AppLayout.vue b/src/resources/js/Layouts/AppLayout.vue index ae05ee2..eeeb34d 100644 --- a/src/resources/js/Layouts/AppLayout.vue +++ b/src/resources/js/Layouts/AppLayout.vue @@ -239,6 +239,7 @@ import { Head, Link } from '@inertiajs/inertia-vue3' import SuccessNotifications from '@/Components/Notifications/SuccessNotifications.vue' import ErrorNotifications from '@/Components/Notifications/ErrorNotifications.vue' import GenericNotifications from '@/Components/Notifications/GenericNotifications.vue' +import WarningNotifications from '@/Components/Notifications/WarningNotifications.vue' import ApplicationMark from '@/Jetstream/ApplicationMark.vue' import ResponsiveNavLink from '@/Components/ResponsiveNavLink.vue' import SidenavLink from '@/Components/SidenavLink.vue' @@ -257,6 +258,7 @@ export default defineComponent({ SuccessNotifications, ErrorNotifications, GenericNotifications, + WarningNotifications, ApplicationMark, ResponsiveNavLink, SidenavLink, diff --git a/src/resources/views/app.blade.php b/src/resources/views/app.blade.php index f961ee0..82ef3bc 100644 --- a/src/resources/views/app.blade.php +++ b/src/resources/views/app.blade.php @@ -4,15 +4,25 @@ + + + - + + + + + + + + @@ -21,8 +31,12 @@ {{ config('app.name', 'Laravel') }} + + + + @@ -37,23 +51,27 @@ {{-- --}} - - + + {{-- --}} {{-- --}} + + + + {{-- --}} {{-- --}} {{-- --}} - + - + @routes - + + + @inertia diff --git a/src/tailwind.config.js b/src/tailwind.config.js index a91defe..de884af 100644 --- a/src/tailwind.config.js +++ b/src/tailwind.config.js @@ -12,241 +12,233 @@ module.exports = { darkMode: 'class', theme: { - colors: { - // use https://uicolors.app/create - // neutals - 'nomad': { - 50: '#fbfbf8', - 100: '#f6f6f3', - 200: '#e9e5e2', - 300: '#dad3cd', - 400: '#b5a89c', - 500: '#827262', - 600: '#5e5647', - 700: '#4b4235', - 800: '#2d2420', - 900: '#201913', - }, - - // reds - 'mulberry': { - 50: '#fbf4f9', - 100: '#f9eaf4', - 200: '#f5d5ea', - 300: '#eeb3d8', - 400: '#e284bd', - 500: '#d55fa3', - 600: '#c54b8c', - 700: '#a72f6c', - 800: '#8a2a59', - 900: '#74274d', - }, - - // oranges - 'vesuvius': { - 50: '#fffbeb', - 100: '#fef3c7', - 200: '#fde58a', - 300: '#fbd24e', - 400: '#fabe25', - 500: '#f49d0c', - 600: '#d87607', - 700: '#bc560a', - 800: '#923f0e', - 900: '#78340f', - }, - - // yellows - - - // greens - 'bright-green': { - 50: '#efffe6', - 100: '#daffc8', - 200: '#b7fe98', - 300: '#88fa5c', - 400: '#5ff02a', - 500: '#3fd60c', - 600: '#2bac04', - 700: '#238209', - 800: '#20670d', - 900: '#1d5710', - }, - - 'spring-green': { - 50: '#effef6', - 100: '#d9ffee', - 200: '#b5fddd', - 300: '#7bfac4', - 400: '#3aeea2', - 500: '#12e78d', - 600: '#07b26a', - 700: '#0a8b55', - 800: '#0e6d46', - 900: '#0d5a3c', - }, - - 'forest-green': { - 50: '#f1fdf0', - 100: '#ddfcdc', - 200: '#bff6bc', - 300: '#8aee87', - 400: '#50dc4c', - 500: '#24b321', - 600: '#1ba118', - 700: '#187f16', - 800: '#186417', - 900: '#155215', - }, - - 'mountain-meadow': { - 50: '#ecfdf3', - 100: '#d1fae1', - 200: '#a7f3c9', - 300: '#6ee7ac', - 400: '#34d38b', - 500: '#0fa968', - 600: '#05965c', - 700: '#04784c', - 800: '#065f3e', - 900: '#064e34', - }, - - 'eucalyptus': { - 50: '#f1fcf5', - 100: '#dff9ea', - 200: '#c0f2d5', - 300: '#8fe6b5', - 400: '#57d18c', - 500: '#30b76b', - 600: '#239654', - 700: '#22844d', - 800: '#1d5e3a', - 900: '#1a4d31', - }, - - // teals - 'aquamarine': { - 50: '#eafff7', - 100: '#cdfeea', - 200: '#a1fadb', - 300: '#63f2c9', - 400: '#25e2b2', - 500: '#01c89c', - 600: '#00a380', - 700: '#00836b', - 800: '#006756', - 900: '#005548', - }, - - 'bermuda': { - 50: '#f2fbf9', - 100: '#d2f5f0', - 200: '#a5eae1', - 300: '#7bdbd1', - 400: '#42bfb6', - 500: '#29a39c', - 600: '#1e837f', - 700: '#1c6967', - 800: '#1b5453', - 900: '#1b4645', - }, - - 'tiber': { - 50: '#edfffc', - 100: '#c2fff8', - 200: '#86fff4', - 300: '#42ffed', - 400: '#0bf6e0', - 500: '#00d9c7', - 600: '#00afa5', - 700: '#008b85', - 800: '#016e6b', - 900: '#05403e', - }, - - 'wedgewood': { - 50: '#f2f9f9', - 100: '#ddeff0', - 200: '#bfe0e2', - 300: '#92cace', - 400: '#5faab1', - 500: '#438e96', - 600: '#3b757f', - 700: '#356169', - 800: '#325158', - 900: '#2d464c', - }, - - - // blues - 'fun-blue': { - 50: '#f2f7fd', - 100: '#e4edfa', - 200: '#c3d9f4', - 300: '#8dbaec', - 400: '#5197df', - 500: '#2a7acd', - 600: '#1b5daa', - 700: '#174c8d', - 800: '#174175', - 900: '#193961', - }, - - // purples - 'electric-violet': { - 50: '#f3f1ff', - 100: '#ebe5ff', - 200: '#d9ceff', - 300: '#bea6ff', - 400: '#9f75ff', - 500: '#843dff', - 600: '#7916ff', - 700: '#6b04fd', - 800: '#5a03d5', - 900: '#4b05ad', - }, - - - // pinks - 'mandy': { - 50: '#fef2f3', - 100: '#fde6e7', - 200: '#fbd0d5', - 300: '#f7aab2', - 400: '#f27a8a', - 500: '#ea546c', - 600: '#d5294d', - 700: '#b31d3f', - 800: '#961b3c', - 900: '#811a39', - }, - - 'amaranth': { - 50: '#fff1f4', - 100: '#ffe3e8', - 200: '#ffcbd8', - 300: '#ffa1b8', - 400: '#ff6d94', - 500: '#fa3972', - 600: '#e91f64', - 700: '#c40c4f', - 800: '#a40d49', - 900: '#8c0f45', - }, - - - }, - fontFamily: { - sans: ['OpenSans', ...defaultTheme.fontFamily.sans], - serif: ['Nunito', ...defaultTheme.fontFamily.serif], - mono: ['RobotoMono', ...defaultTheme.fontFamily.mono], - display: ['PoiretOne', ...defaultTheme.fontFamily.display], - body: ['OpenSans', ...defaultTheme.fontFamily.body], + display: ['PoiretOne'], + body: ['OpenSans'], }, - extend: {}, + extend: { + colors: { + // use https://uicolors.app/create + // neutals + 'nomad': { + 50: '#fbfbf8', + 100: '#f6f6f3', + 200: '#e9e5e2', + 300: '#dad3cd', + 400: '#b5a89c', + 500: '#827262', + 600: '#5e5647', + 700: '#4b4235', + 800: '#2d2420', + 900: '#201913', + }, + + // reds + 'mulberry': { + 50: '#fbf4f9', + 100: '#f9eaf4', + 200: '#f5d5ea', + 300: '#eeb3d8', + 400: '#e284bd', + 500: '#d55fa3', + 600: '#c54b8c', + 700: '#a72f6c', + 800: '#8a2a59', + 900: '#74274d', + }, + + // oranges + + + // yellows + + + // greens + 'bright-green': { + 50: '#efffe6', + 100: '#daffc8', + 200: '#b7fe98', + 300: '#88fa5c', + 400: '#5ff02a', + 500: '#3fd60c', + 600: '#2bac04', + 700: '#238209', + 800: '#20670d', + 900: '#1d5710', + }, + + 'spring-green': { + 50: '#effef6', + 100: '#d9ffee', + 200: '#b5fddd', + 300: '#7bfac4', + 400: '#3aeea2', + 500: '#12e78d', + 600: '#07b26a', + 700: '#0a8b55', + 800: '#0e6d46', + 900: '#0d5a3c', + }, + + 'forest-green': { + 50: '#f1fdf0', + 100: '#ddfcdc', + 200: '#bff6bc', + 300: '#8aee87', + 400: '#50dc4c', + 500: '#24b321', + 600: '#1ba118', + 700: '#187f16', + 800: '#186417', + 900: '#155215', + }, + + 'mountain-meadow': { + 50: '#ecfdf3', + 100: '#d1fae1', + 200: '#a7f3c9', + 300: '#6ee7ac', + 400: '#34d38b', + 500: '#0fa968', + 600: '#05965c', + 700: '#04784c', + 800: '#065f3e', + 900: '#064e34', + }, + + 'eucalyptus': { + 50: '#f1fcf5', + 100: '#dff9ea', + 200: '#c0f2d5', + 300: '#8fe6b5', + 400: '#57d18c', + 500: '#30b76b', + 600: '#239654', + 700: '#22844d', + 800: '#1d5e3a', + 900: '#1a4d31', + }, + + // teals + 'aquamarine': { + 50: '#eafff7', + 100: '#cdfeea', + 200: '#a1fadb', + 300: '#63f2c9', + 400: '#25e2b2', + 500: '#01c89c', + 600: '#00a380', + 700: '#00836b', + 800: '#006756', + 900: '#005548', + }, + + 'bermuda': { + 50: '#f2fbf9', + 100: '#d2f5f0', + 200: '#a5eae1', + 300: '#7bdbd1', + 400: '#42bfb6', + 500: '#29a39c', + 600: '#1e837f', + 700: '#1c6967', + 800: '#1b5453', + 900: '#1b4645', + }, + + 'tiber': { + 50: '#edfffc', + 100: '#c2fff8', + 200: '#86fff4', + 300: '#42ffed', + 400: '#0bf6e0', + 500: '#00d9c7', + 600: '#00afa5', + 700: '#008b85', + 800: '#016e6b', + 900: '#05403e', + }, + + 'wedgewood': { + 50: '#f2f9f9', + 100: '#ddeff0', + 200: '#bfe0e2', + 300: '#92cace', + 400: '#5faab1', + 500: '#438e96', + 600: '#3b757f', + 700: '#356169', + 800: '#325158', + 900: '#2d464c', + }, + + + // blues + 'fun-blue': { + 50: '#f2f7fd', + 100: '#e4edfa', + 200: '#c3d9f4', + 300: '#8dbaec', + 400: '#5197df', + 500: '#2a7acd', + 600: '#1b5daa', + 700: '#174c8d', + 800: '#174175', + 900: '#193961', + }, + + // purples + 'electric-violet': { + 50: '#f3f1ff', + 100: '#ebe5ff', + 200: '#d9ceff', + 300: '#bea6ff', + 400: '#9f75ff', + 500: '#843dff', + 600: '#7916ff', + 700: '#6b04fd', + 800: '#5a03d5', + 900: '#4b05ad', + }, + + + // pinks + 'mandy': { + 50: '#fef2f3', + 100: '#fde6e7', + 200: '#fbd0d5', + 300: '#f7aab2', + 400: '#f27a8a', + 500: '#ea546c', + 600: '#d5294d', + 700: '#b31d3f', + 800: '#961b3c', + 900: '#811a39', + }, + + 'amaranth': { + 50: '#fff1f4', + 100: '#ffe3e8', + 200: '#ffcbd8', + 300: '#ffa1b8', + 400: '#ff6d94', + 500: '#fa3972', + 600: '#e91f64', + 700: '#c40c4f', + 800: '#a40d49', + 900: '#8c0f45', + }, + + + }, + + fontFamily: { + sans: ['OpenSans', ...defaultTheme.fontFamily.sans], + serif: ['Nunito', ...defaultTheme.fontFamily.serif], + mono: ['RobotoMono', ...defaultTheme.fontFamily.mono], + }, + }, }, plugins: [ diff --git a/src/webpack.mix.js b/src/webpack.mix.js index a83650d..0e5c4e7 100644 --- a/src/webpack.mix.js +++ b/src/webpack.mix.js @@ -1,7 +1,14 @@ const mix = require('laravel-mix'); const { exec } = require('child_process'); -const shaCmd = "cat public/js/app.js | openssl dgst -sha512 -binary | openssl base64 -A"; +const resIntegrityFiles = [ + { "envKey": "HUMANS_TXT", "path": "public/humans.txt" }, + { "envKey": "COPYRIGHT_HTML", "path": "public/copyright.html" }, + { "envKey": "NUNITO_REGULAR_WOFF2_FONT", "path": "public/fonts/Nunito/Nunito-Regular.woff2" }, + { "envKey": "POIRETONE_REGULAR_WOFF2_FONT", "path": "public/fonts/PoiretOne/PoiretOne-Regular.woff2" }, + { "envKey": "APP_CSS", "path": "public/css/app.css" }, + { "envKey": "APP_JS", "path": "public/js/app.js" }, +]; /* |-------------------------------------------------------------------------- @@ -17,38 +24,40 @@ const shaCmd = "cat public/js/app.js | openssl dgst -sha512 -binary | openssl ba mix.js('resources/js/app.js', 'public/js') .vue() .sourceMaps() - .after(stats => { - exec(shaCmd, (shaError, shaStdout, shaStderr) => { - if (shaError) { - console.error(`shaCmd error: ${shaError.message}`); - return; - } - if (shaStderr) { - console.error(`shaCmd stderr: ${shaStderr}`); - return; - } - let sha512Hash = shaStdout; - let sedCmd = `sed -i '/^APP_JS_INTEGRITY_HASH="*/c\APP_JS_INTEGRITY_HASH="sha512-${sha512Hash}"' .env`; - - exec(sedCmd, (sedError, sedStdout, sedStderr) => { - if (sedError) { - console.error(`sedCmd error: ${sedError.message}`); - return; - } - if (sedStderr) { - console.error(`sedCmd stderr: ${sedStderr}`); - return; - } - console.log('Replaced SHA512 hash for integrity attribute.'); - }) - }) - }) .postCss('resources/css/app.css', 'public/css', [ require('postcss-import'), require('tailwindcss'), ]) .sourceMaps() - .webpackConfig(require('./webpack.config')); + .webpackConfig(require('./webpack.config')) + .after(stats => { + resIntegrityFiles.forEach(file => { + exec(`cat ${file.path} | openssl dgst -sha512 -binary | openssl base64 -A`, (shaError, shaStdout, shaStderr) => { + if (shaError) { + console.error(`error getting SHA hash for ${file.path}: ${shaError.message}`); + return; + } + if (shaStderr) { + console.error(`error getting SHA hash for ${file.path}: ${shaStderr}`); + return; + } + let sha512Hash = shaStdout; + let sedCmd = `sed -i '/^INTEGRITY_HASH_${file.envKey}="*/c\INTEGRITY_HASH_${file.envKey}="sha512-${sha512Hash}"' .env`; + + exec(sedCmd, (sedError, sedStdout, sedStderr) => { + if (sedError) { + console.error(`error executing sed command for ${file.envKey}: ${sedError.message}`); + return; + } + if (sedStderr) { + console.error(`error executing sed command for ${file.envKey}`); + return; + } + console.log(`Replaced SHA512 hash for ${file.envKey}.`); + }); + }); + }); + }); if (mix.inProduction()) { mix.version();