From db31066724a39bce315f37d24a5baffba578f846 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 6 May 2024 15:59:42 +0300 Subject: [PATCH 1/6] try another PWA plugin, debug .env on TEST/STAGING improve /notify API --- .env | 8 +- .env.development | 1 + .env.test.staging | 1 + components/PwaManager.tsx | 19 +- next.config.js | 53 ++- package-lock.json | 915 +++++++++++++++++++++++++++++--------- package.json | 1 + pages/api/notify.ts | 26 +- server.js | 1 + workbox-config.js | 34 ++ worker/index.js | 4 +- 11 files changed, 816 insertions(+), 247 deletions(-) create mode 100644 workbox-config.js diff --git a/.env b/.env index f86855c..229de8a 100644 --- a/.env +++ b/.env @@ -2,7 +2,7 @@ # HOST=localhost # PORT=3003 # NEXT_PUBLIC_PUBLIC_URL=http://localhost:3003 - +ENV_ENV='.env' # Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32 NEXTAUTH_SECRET=ed8a9681efc414df89dfd03cd188ed58 @@ -69,5 +69,7 @@ MAILTRAP_PASS=c7bc05f171c96c TELEGRAM_BOT=false TELEGRAM_BOT_TOKEN=7050075088:AAH6VRpNCyQd9x9sW6CLm6q0q4ibUgYBfnM -NEXT_PUBLIC_VAPID_PUBLIC_KEY=BGxXJ0jdsQ4ihE7zp8mxrBO-QPSjeEtO9aCtPoMTuxc1VLW0OfRIt-DYinK9ekjTl2w-j0eQbeprIyBCpmmfciI -VAPID_PRIVATE_KEY=VXHu2NgcyM4J4w3O4grkS_0yLwWHCvVKDJexyBjqgx0 +NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY=BGxXJ0jdsQ4ihE7zp8mxrBO-QPSjeEtO9aCtPoMTuxc1VLW0OfRIt-DYinK9ekjTl2w-j0eQbeprIyBCpmmfciI +WEB_PUSH_PRIVATE_KEY=VXHu2NgcyM4J4w3O4grkS_0yLwWHCvVKDJexyBjqgx0 +# NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY= BBAbKJk4B6lYfNhe4sPc9bpLJXAcXwb2JEkQBlpyZG9DrKvVT1GdAi5d4a3VNgdJuYDlC43w20l5Aia13b748sE +# WEB_PUSH_PRIVATE_KEY= Xe1NhMTE_QxRnxv5eovqA692G2fC-n4QDlIS6U1qsJI diff --git a/.env.development b/.env.development index 6e49486..39f5519 100644 --- a/.env.development +++ b/.env.development @@ -1,5 +1,6 @@ NODE_TLS_REJECT_UNAUTHORIZED=0 # NODE_EXTRA_CA_CERTS=C:\\Users\\popov\\AppData\\Local\\mkcert +ENV_ENV=.env.development PROTOCOL=https PORT=3003 HOST=localhost diff --git a/.env.test.staging b/.env.test.staging index 38c9d2f..c1c813e 100644 --- a/.env.test.staging +++ b/.env.test.staging @@ -1,4 +1,5 @@ NODE_ENV=test +ENV_ENV=test.staging PROTOCOL=http HOST=staging.mwitnessing.com diff --git a/components/PwaManager.tsx b/components/PwaManager.tsx index 3bce4fc..9d89667 100644 --- a/components/PwaManager.tsx +++ b/components/PwaManager.tsx @@ -82,14 +82,29 @@ function PwaManager() { try { e.preventDefault(); + if (!navigator.serviceWorker) { + console.error('Service worker is not supported by this browser.'); + return; + } + + const registration = await navigator.serviceWorker.ready; if (!registration) { console.error('Service worker registration not found.'); - registration return; } + + let vapidPublicKey = process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY; + if (!vapidPublicKey) { + // Fetch the public key from the server if not present in env variables + const response = await fetch('/api/notify', { method: 'GET' }); + vapidPublicKey = await response.text(); + if (!vapidPublicKey) { + throw new Error("Failed to fetch VAPID public key from server."); + } + } const sub = await registration.pushManager.subscribe({ userVisibleOnly: true, - applicationServerKey: base64ToUint8Array(process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY) + applicationServerKey: base64ToUint8Array(vapidPublicKey) }); // Call your API to save subscription data on server setSubscription(sub); diff --git a/next.config.js b/next.config.js index bc25166..7e695a0 100644 --- a/next.config.js +++ b/next.config.js @@ -1,14 +1,15 @@ const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); +const { InjectManifest } = require('workbox-webpack-plugin'); const withPWA = require('next-pwa')({ dest: 'public', register: true, // ? publicExcludes: ["!_error*.js"], //? - //disable: process.env.NODE_ENV === 'development', + disable: process.env.NODE_ENV === 'development', }) -module.exports = withPWA({ +module.exports = { typescript: { // !! WARN !! // Dangerously allow production builds to successfully complete even if @@ -22,23 +23,41 @@ module.exports = withPWA({ env: process.env.NODE_ENV, server: process.env.NEXT_PUBLIC_PUBLIC_URL }, - webpack(config, { isServer }) { + plugins: [ + // Other plugins... + new InjectManifest({ + // These are some common options, and not all are required. + // Consult the docs for more info. + //exclude: [/.../, '...'], + maximumFileSizeToCacheInBytes: 1 * 1024 * 1024, + swSrc: './worker/index.js', + }), + ], + webpack: (config, { isServer, buildId, dev }) => { + // Configure optimization and source maps + config.optimization.minimize = !dev; + //config.productionBrowserSourceMaps = true; + // Enable source maps based on non-production environments + if (!dev) { + config.devtool = 'source-map'; + } + // Add custom fallbacks + config.resolve.fallback = { ...config.resolve.fallback, fs: false }; - config.optimization.minimize = true, - productionBrowserSourceMaps = true, + // InjectManifest configuration + if (!isServer) { + config.plugins.push(new InjectManifest({ + swSrc: './worker/index.js', // Path to source service worker file + swDest: '/worker/index.js', // Destination filename in the build output + maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, // Adjust as needed + exclude: [/\.map$/, /_error.js$/, /favicon.ico$/] // Customize exclusion patterns + }) + ); + } - config.resolve.fallback = { - - // if you miss it, all the other options in fallback, specified - // by next.js will be dropped. - ...config.resolve.fallback, - - fs: false, // the solution - }; - - - // Only run the bundle analyzer for production builds and when the ANALYZE environment variable is set + // Bundle Analyzer Configuration if (process.env.ANALYZE && !isServer) { + const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); config.plugins.push( new BundleAnalyzerPlugin({ analyzerMode: 'static', @@ -58,4 +77,4 @@ module.exports = withPWA({ defaultLocale: 'bg', localeDetection: false, }, -}) \ No newline at end of file +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 17cee5c..97b71d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -90,6 +90,7 @@ "webpack-bundle-analyzer": "^4.10.1", "winston": "^3.13.0", "winston-daily-rotate-file": "^5.0.0", + "workbox-webpack-plugin": "^7.1.0", "xlsx": "https://cdn.sheetjs.com/xlsx-0.19.1/xlsx-0.19.1.tgz", "xlsx-style": "^0.8.13", "xml-js": "^1.6.11", @@ -321,18 +322,18 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.4.tgz", - "integrity": "sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz", + "integrity": "sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.24.5", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.24.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-split-export-declaration": "^7.24.5", "semver": "^6.3.1" }, "engines": { @@ -375,9 +376,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", - "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -442,11 +443,11 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz", + "integrity": "sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==", "dependencies": { - "@babel/types": "^7.23.0" + "@babel/types": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -493,9 +494,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", - "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz", + "integrity": "sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==", "engines": { "node": ">=6.9.0" } @@ -555,28 +556,28 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz", + "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz", + "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", + "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", "engines": { "node": ">=6.9.0" } @@ -590,13 +591,13 @@ } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.5.tgz", + "integrity": "sha512-/xxzuNvgRl4/HLNKvnFwdhdgN3cpLxgLROeLDl83Yx0AJ1SGvq1ak0OszTOjDfiB8Vx03eJbeDWh9r+jCCWttw==", "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" + "@babel/helper-function-name": "^7.23.0", + "@babel/template": "^7.24.0", + "@babel/types": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -641,12 +642,12 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.4.tgz", - "integrity": "sha512-qpl6vOOEEzTLLcsuqYYo8yDtrTocmu2xkGvgNebvPjT9DTtfFYGmgDqY+rBYXNlqL4s9qLDn6xkrJv4RxAPiTA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.5.tgz", + "integrity": "sha512-LdXRi1wEMTrHVR4Zc9F8OewC3vdm5h4QB6L71zy6StmYeqGi1b3ttIO8UC+BfZKcH9jdr4aI249rBkm+3+YvHw==", "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -990,11 +991,11 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.4.tgz", - "integrity": "sha512-nIFUZIpGKDf9O9ttyRXpHFpKC+X3Y5mtshZONuEUYBomAKoM4y029Jr+uB1bHGPhNmK8YXHevDtKDOLmtRrp6g==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.5.tgz", + "integrity": "sha512-sMfBc3OxghjC95BkYrYocHL3NaOplrcaunblzwXhGmlPwpmfsxr4vK+mBBt49r+S240vahmv+kUxkeKgs+haCw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -1035,17 +1036,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz", - "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.5.tgz", + "integrity": "sha512-gWkLP25DFj2dwe9Ck8uwMOpko4YsqyfZJrOmqqcegeDYEbp7rmn4U6UQZNj08UF6MaX39XenSpKRCvpDRBtZ7Q==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.5", "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-split-export-declaration": "^7.24.5", "globals": "^11.1.0" }, "engines": { @@ -1071,11 +1072,11 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", - "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.5.tgz", + "integrity": "sha512-SZuuLyfxvsm+Ah57I/i1HVjveBENYK9ue8MJ7qkc7ndoNjqquJiElzA7f5yaAXjyW2hKojosOTAQQRX50bPSVg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -1370,14 +1371,14 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", - "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.5.tgz", + "integrity": "sha512-7EauQHszLGM3ay7a161tTQH7fj+3vVM/gThlz5HpFtnygTxjrlvoeq7MPVA1Vy9Q555OB8SnAOsMkLShNkkrHA==", "dependencies": { "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.1" + "@babel/plugin-transform-parameters": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -1417,11 +1418,11 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz", - "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz", + "integrity": "sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, @@ -1433,11 +1434,11 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", - "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.5.tgz", + "integrity": "sha512-9Co00MqZ2aoky+4j2jhofErthm6QVLKbpQrvz20c3CH9KQCLHyNB+t2ya4/UrRpQGR+Wrwjg9foopoeSdnHOkA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -1462,13 +1463,13 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", - "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.5.tgz", + "integrity": "sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ==", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-create-class-features-plugin": "^7.24.5", + "@babel/helper-plugin-utils": "^7.24.5", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -1579,11 +1580,11 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz", - "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.5.tgz", + "integrity": "sha512-UTGnhYVZtTAjdwOTzT+sCyXmTn8AhaxOS/MjG9REclZ6ULHWF9KoCZur0HSGU7hk8PdBFKKbYe6+gqdXWz84Jg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -1652,15 +1653,15 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.4.tgz", - "integrity": "sha512-7Kl6cSmYkak0FK/FXjSEnLJ1N9T/WA2RkMhu17gZ/dsxKJUuTYNIylahPTzqpLyJN4WhDif8X0XK1R8Wsguo/A==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.5.tgz", + "integrity": "sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==", "dependencies": { "@babel/compat-data": "^7.24.4", "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.5", "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.4", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.5", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", @@ -1687,12 +1688,12 @@ "@babel/plugin-transform-async-generator-functions": "^7.24.3", "@babel/plugin-transform-async-to-generator": "^7.24.1", "@babel/plugin-transform-block-scoped-functions": "^7.24.1", - "@babel/plugin-transform-block-scoping": "^7.24.4", + "@babel/plugin-transform-block-scoping": "^7.24.5", "@babel/plugin-transform-class-properties": "^7.24.1", "@babel/plugin-transform-class-static-block": "^7.24.4", - "@babel/plugin-transform-classes": "^7.24.1", + "@babel/plugin-transform-classes": "^7.24.5", "@babel/plugin-transform-computed-properties": "^7.24.1", - "@babel/plugin-transform-destructuring": "^7.24.1", + "@babel/plugin-transform-destructuring": "^7.24.5", "@babel/plugin-transform-dotall-regex": "^7.24.1", "@babel/plugin-transform-duplicate-keys": "^7.24.1", "@babel/plugin-transform-dynamic-import": "^7.24.1", @@ -1712,13 +1713,13 @@ "@babel/plugin-transform-new-target": "^7.24.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", "@babel/plugin-transform-numeric-separator": "^7.24.1", - "@babel/plugin-transform-object-rest-spread": "^7.24.1", + "@babel/plugin-transform-object-rest-spread": "^7.24.5", "@babel/plugin-transform-object-super": "^7.24.1", "@babel/plugin-transform-optional-catch-binding": "^7.24.1", - "@babel/plugin-transform-optional-chaining": "^7.24.1", - "@babel/plugin-transform-parameters": "^7.24.1", + "@babel/plugin-transform-optional-chaining": "^7.24.5", + "@babel/plugin-transform-parameters": "^7.24.5", "@babel/plugin-transform-private-methods": "^7.24.1", - "@babel/plugin-transform-private-property-in-object": "^7.24.1", + "@babel/plugin-transform-private-property-in-object": "^7.24.5", "@babel/plugin-transform-property-literals": "^7.24.1", "@babel/plugin-transform-regenerator": "^7.24.1", "@babel/plugin-transform-reserved-words": "^7.24.1", @@ -1726,7 +1727,7 @@ "@babel/plugin-transform-spread": "^7.24.1", "@babel/plugin-transform-sticky-regex": "^7.24.1", "@babel/plugin-transform-template-literals": "^7.24.1", - "@babel/plugin-transform-typeof-symbol": "^7.24.1", + "@babel/plugin-transform-typeof-symbol": "^7.24.5", "@babel/plugin-transform-unicode-escapes": "^7.24.1", "@babel/plugin-transform-unicode-property-regex": "^7.24.1", "@babel/plugin-transform-unicode-regex": "^7.24.1", @@ -1837,12 +1838,12 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz", + "integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.1", + "@babel/helper-validator-identifier": "^7.24.5", "to-fast-properties": "^2.0.0" }, "engines": { @@ -4234,22 +4235,48 @@ } }, "node_modules/@rollup/plugin-node-resolve": { - "version": "11.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", - "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "version": "15.2.3", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", + "integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==", "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", + "@rollup/pluginutils": "^5.0.1", + "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", + "is-builtin-module": "^3.2.1", "is-module": "^1.0.0", - "resolve": "^1.19.0" + "resolve": "^1.22.1" }, "engines": { - "node": ">= 10.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" + "rollup": "^2.78.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/plugin-node-resolve/node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, "node_modules/@rollup/plugin-replace": { @@ -4272,6 +4299,27 @@ "sourcemap-codec": "^1.4.8" } }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/pluginutils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", @@ -4417,8 +4465,7 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "peer": true + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/express": { "version": "4.17.21", @@ -4567,12 +4614,9 @@ } }, "node_modules/@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "dependencies": { - "@types/node": "*" - } + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==" }, "node_modules/@types/retry": { "version": "0.12.0", @@ -5411,12 +5455,12 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", - "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.1", + "@babel/helper-define-polyfill-provider": "^0.6.2", "semver": "^6.3.1" }, "peerDependencies": { @@ -5444,11 +5488,11 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", - "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1" + "@babel/helper-define-polyfill-provider": "^0.6.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -6351,9 +6395,9 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/core-js-compat": { - "version": "3.36.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", - "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz", + "integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==", "dependencies": { "browserslist": "^4.23.0" }, @@ -7202,9 +7246,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dependencies": { "jake": "^10.8.5" }, @@ -7542,8 +7586,7 @@ "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" }, "node_modules/esutils": { "version": "2.0.3", @@ -9317,6 +9360,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -9685,9 +9742,9 @@ } }, "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", + "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", @@ -11030,6 +11087,343 @@ "next": ">=9.0.0" } }, + "node_modules/next-pwa/node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/next-pwa/node_modules/@rollup/plugin-node-resolve": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", + "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "@types/resolve": "1.17.1", + "builtin-modules": "^3.1.0", + "deepmerge": "^4.2.2", + "is-module": "^1.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/next-pwa/node_modules/@types/resolve": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", + "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/next-pwa/node_modules/ajv": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", + "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/next-pwa/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/next-pwa/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/next-pwa/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/next-pwa/node_modules/tempy": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", + "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", + "dependencies": { + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/next-pwa/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/next-pwa/node_modules/type-fest": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/next-pwa/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "node_modules/next-pwa/node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/next-pwa/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/next-pwa/node_modules/workbox-background-sync": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", + "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/next-pwa/node_modules/workbox-broadcast-update": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", + "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/next-pwa/node_modules/workbox-build": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", + "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^7.1.6", + "lodash": "^4.17.20", + "pretty-bytes": "^5.3.0", + "rollup": "^2.43.1", + "rollup-plugin-terser": "^7.0.0", + "source-map": "^0.8.0-beta.0", + "stringify-object": "^3.3.0", + "strip-comments": "^2.0.1", + "tempy": "^0.6.0", + "upath": "^1.2.0", + "workbox-background-sync": "6.6.0", + "workbox-broadcast-update": "6.6.0", + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-google-analytics": "6.6.0", + "workbox-navigation-preload": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-range-requests": "6.6.0", + "workbox-recipes": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0", + "workbox-streams": "6.6.0", + "workbox-sw": "6.6.0", + "workbox-window": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/next-pwa/node_modules/workbox-build/node_modules/source-map": { + "version": "0.8.0-beta.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", + "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/next-pwa/node_modules/workbox-cacheable-response": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", + "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", + "deprecated": "workbox-background-sync@6.6.0", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/next-pwa/node_modules/workbox-expiration": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", + "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/next-pwa/node_modules/workbox-google-analytics": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", + "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", + "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", + "dependencies": { + "workbox-background-sync": "6.6.0", + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/next-pwa/node_modules/workbox-navigation-preload": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", + "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/next-pwa/node_modules/workbox-precaching": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", + "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/next-pwa/node_modules/workbox-range-requests": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", + "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/next-pwa/node_modules/workbox-recipes": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", + "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", + "dependencies": { + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/next-pwa/node_modules/workbox-routing": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", + "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/next-pwa/node_modules/workbox-strategies": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", + "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/next-pwa/node_modules/workbox-streams": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", + "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0" + } + }, + "node_modules/next-pwa/node_modules/workbox-sw": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", + "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==" + }, + "node_modules/next-pwa/node_modules/workbox-webpack-plugin": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", + "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", + "dependencies": { + "fast-json-stable-stringify": "^2.1.0", + "pretty-bytes": "^5.4.1", + "upath": "^1.2.0", + "webpack-sources": "^1.4.3", + "workbox-build": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "webpack": "^4.4.0 || ^5.9.0" + } + }, "node_modules/next-tick": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-0.2.2.tgz", @@ -16199,6 +16593,11 @@ "node": ">=7.0.0" } }, + "node_modules/smob": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", + "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==" + }, "node_modules/smtp-connection": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz", @@ -18250,34 +18649,45 @@ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" }, "node_modules/workbox-background-sync": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", - "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-7.1.0.tgz", + "integrity": "sha512-rMbgrzueVWDFcEq1610YyDW71z0oAXLfdRHRQcKw4SGihkfOK0JUEvqWHFwA6rJ+6TClnMIn7KQI5PNN1XQXwQ==", "dependencies": { "idb": "^7.0.1", - "workbox-core": "6.6.0" + "workbox-core": "7.1.0" } }, + "node_modules/workbox-background-sync/node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, "node_modules/workbox-broadcast-update": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", - "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-7.1.0.tgz", + "integrity": "sha512-O36hIfhjej/c5ar95pO67k1GQw0/bw5tKP7CERNgK+JdxBANQhDmIuOXZTNvwb2IHBx9hj2kxvcDyRIh5nzOgQ==", "dependencies": { - "workbox-core": "6.6.0" + "workbox-core": "7.1.0" } }, + "node_modules/workbox-broadcast-update/node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, "node_modules/workbox-build": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", - "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-7.1.0.tgz", + "integrity": "sha512-F6R94XAxjB2j4ETMkP1EXKfjECOtDmyvt0vz3BzgWJMI68TNSXIVNkgatwUKBlPGOfy9n2F/4voYRNAhEvPJNg==", "dependencies": { "@apideck/better-ajv-errors": "^0.3.1", - "@babel/core": "^7.11.1", + "@babel/core": "^7.24.4", "@babel/preset-env": "^7.11.0", "@babel/runtime": "^7.11.2", "@rollup/plugin-babel": "^5.2.0", - "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "^2.4.1", + "@rollup/plugin-terser": "^0.4.3", "@surma/rollup-plugin-off-main-thread": "^2.2.3", "ajv": "^8.6.0", "common-tags": "^1.8.0", @@ -18287,30 +18697,29 @@ "lodash": "^4.17.20", "pretty-bytes": "^5.3.0", "rollup": "^2.43.1", - "rollup-plugin-terser": "^7.0.0", "source-map": "^0.8.0-beta.0", "stringify-object": "^3.3.0", "strip-comments": "^2.0.1", "tempy": "^0.6.0", "upath": "^1.2.0", - "workbox-background-sync": "6.6.0", - "workbox-broadcast-update": "6.6.0", - "workbox-cacheable-response": "6.6.0", - "workbox-core": "6.6.0", - "workbox-expiration": "6.6.0", - "workbox-google-analytics": "6.6.0", - "workbox-navigation-preload": "6.6.0", - "workbox-precaching": "6.6.0", - "workbox-range-requests": "6.6.0", - "workbox-recipes": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0", - "workbox-streams": "6.6.0", - "workbox-sw": "6.6.0", - "workbox-window": "6.6.0" + "workbox-background-sync": "7.1.0", + "workbox-broadcast-update": "7.1.0", + "workbox-cacheable-response": "7.1.0", + "workbox-core": "7.1.0", + "workbox-expiration": "7.1.0", + "workbox-google-analytics": "7.1.0", + "workbox-navigation-preload": "7.1.0", + "workbox-precaching": "7.1.0", + "workbox-range-requests": "7.1.0", + "workbox-recipes": "7.1.0", + "workbox-routing": "7.1.0", + "workbox-strategies": "7.1.0", + "workbox-streams": "7.1.0", + "workbox-sw": "7.1.0", + "workbox-window": "7.1.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=16.0.0" } }, "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { @@ -18330,14 +18739,14 @@ } }, "node_modules/workbox-build/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", + "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "uri-js": "^4.4.1" }, "funding": { "type": "github", @@ -18425,126 +18834,188 @@ "webidl-conversions": "^4.0.2" } }, - "node_modules/workbox-cacheable-response": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", - "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", - "deprecated": "workbox-background-sync@6.6.0", + "node_modules/workbox-build/node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, + "node_modules/workbox-build/node_modules/workbox-window": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-7.1.0.tgz", + "integrity": "sha512-ZHeROyqR+AS5UPzholQRDttLFqGMwP0Np8MKWAdyxsDETxq3qOAyXvqessc3GniohG6e0mAqSQyKOHmT8zPF7g==", "dependencies": { - "workbox-core": "6.6.0" + "@types/trusted-types": "^2.0.2", + "workbox-core": "7.1.0" } }, + "node_modules/workbox-cacheable-response": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-7.1.0.tgz", + "integrity": "sha512-iwsLBll8Hvua3xCuBB9h92+/e0wdsmSVgR2ZlvcfjepZWwhd3osumQB3x9o7flj+FehtWM2VHbZn8UJeBXXo6Q==", + "dependencies": { + "workbox-core": "7.1.0" + } + }, + "node_modules/workbox-cacheable-response/node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, "node_modules/workbox-core": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==" }, "node_modules/workbox-expiration": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", - "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-7.1.0.tgz", + "integrity": "sha512-m5DcMY+A63rJlPTbbBNtpJ20i3enkyOtSgYfv/l8h+D6YbbNiA0zKEkCUaMsdDlxggla1oOfRkyqTvl5Ni5KQQ==", "dependencies": { "idb": "^7.0.1", - "workbox-core": "6.6.0" + "workbox-core": "7.1.0" } }, + "node_modules/workbox-expiration/node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, "node_modules/workbox-google-analytics": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", - "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", - "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-7.1.0.tgz", + "integrity": "sha512-FvE53kBQHfVTcZyczeBVRexhh7JTkyQ8HAvbVY6mXd2n2A7Oyz/9fIwnY406ZcDhvE4NFfKGjW56N4gBiqkrew==", "dependencies": { - "workbox-background-sync": "6.6.0", - "workbox-core": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0" + "workbox-background-sync": "7.1.0", + "workbox-core": "7.1.0", + "workbox-routing": "7.1.0", + "workbox-strategies": "7.1.0" } }, + "node_modules/workbox-google-analytics/node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, "node_modules/workbox-navigation-preload": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", - "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-7.1.0.tgz", + "integrity": "sha512-4wyAbo0vNI/X0uWNJhCMKxnPanNyhybsReMGN9QUpaePLTiDpKxPqFxl4oUmBNddPwIXug01eTSLVIFXimRG/A==", "dependencies": { - "workbox-core": "6.6.0" + "workbox-core": "7.1.0" } }, + "node_modules/workbox-navigation-preload/node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, "node_modules/workbox-precaching": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", - "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-7.1.0.tgz", + "integrity": "sha512-LyxzQts+UEpgtmfnolo0hHdNjoB7EoRWcF7EDslt+lQGd0lW4iTvvSe3v5JiIckQSB5KTW5xiCqjFviRKPj1zA==", "dependencies": { - "workbox-core": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0" + "workbox-core": "7.1.0", + "workbox-routing": "7.1.0", + "workbox-strategies": "7.1.0" } }, + "node_modules/workbox-precaching/node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, "node_modules/workbox-range-requests": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", - "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-7.1.0.tgz", + "integrity": "sha512-m7+O4EHolNs5yb/79CrnwPR/g/PRzMFYEdo01LqwixVnc/sbzNSvKz0d04OE3aMRel1CwAAZQheRsqGDwATgPQ==", "dependencies": { - "workbox-core": "6.6.0" + "workbox-core": "7.1.0" } }, + "node_modules/workbox-range-requests/node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, "node_modules/workbox-recipes": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", - "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-7.1.0.tgz", + "integrity": "sha512-NRrk4ycFN9BHXJB6WrKiRX3W3w75YNrNrzSX9cEZgFB5ubeGoO8s/SDmOYVrFYp9HMw6sh1Pm3eAY/1gVS8YLg==", "dependencies": { - "workbox-cacheable-response": "6.6.0", - "workbox-core": "6.6.0", - "workbox-expiration": "6.6.0", - "workbox-precaching": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0" + "workbox-cacheable-response": "7.1.0", + "workbox-core": "7.1.0", + "workbox-expiration": "7.1.0", + "workbox-precaching": "7.1.0", + "workbox-routing": "7.1.0", + "workbox-strategies": "7.1.0" } }, + "node_modules/workbox-recipes/node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, "node_modules/workbox-routing": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", - "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-7.1.0.tgz", + "integrity": "sha512-oOYk+kLriUY2QyHkIilxUlVcFqwduLJB7oRZIENbqPGeBP/3TWHYNNdmGNhz1dvKuw7aqvJ7CQxn27/jprlTdg==", "dependencies": { - "workbox-core": "6.6.0" + "workbox-core": "7.1.0" } }, + "node_modules/workbox-routing/node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, "node_modules/workbox-strategies": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", - "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-7.1.0.tgz", + "integrity": "sha512-/UracPiGhUNehGjRm/tLUQ+9PtWmCbRufWtV0tNrALuf+HZ4F7cmObSEK+E4/Bx1p8Syx2tM+pkIrvtyetdlew==", "dependencies": { - "workbox-core": "6.6.0" + "workbox-core": "7.1.0" } }, + "node_modules/workbox-strategies/node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, "node_modules/workbox-streams": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", - "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-7.1.0.tgz", + "integrity": "sha512-WyHAVxRXBMfysM8ORwiZnI98wvGWTVAq/lOyBjf00pXFvG0mNaVz4Ji+u+fKa/mf1i2SnTfikoYKto4ihHeS6w==", "dependencies": { - "workbox-core": "6.6.0", - "workbox-routing": "6.6.0" + "workbox-core": "7.1.0", + "workbox-routing": "7.1.0" } }, + "node_modules/workbox-streams/node_modules/workbox-core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-7.1.0.tgz", + "integrity": "sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==" + }, "node_modules/workbox-sw": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", - "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==" + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-7.1.0.tgz", + "integrity": "sha512-Hml/9+/njUXBglv3dtZ9WBKHI235AQJyLBV1G7EFmh4/mUdSQuXui80RtjDeVRrXnm/6QWgRUEHG3/YBVbxtsA==" }, "node_modules/workbox-webpack-plugin": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", - "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-7.1.0.tgz", + "integrity": "sha512-em0vY0Uq7zXzOeEJYpFNX7x6q3RrRVqfaMhA4kadd3UkX/JuClgT9IUW2iX2cjmMPwI3W611c4fSRjtG5wPm2w==", "dependencies": { "fast-json-stable-stringify": "^2.1.0", "pretty-bytes": "^5.4.1", "upath": "^1.2.0", "webpack-sources": "^1.4.3", - "workbox-build": "6.6.0" + "workbox-build": "7.1.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=16.0.0" }, "peerDependencies": { - "webpack": "^4.4.0 || ^5.9.0" + "webpack": "^4.4.0 || ^5.91.0" } }, "node_modules/workbox-webpack-plugin/node_modules/source-map": { diff --git a/package.json b/package.json index ba51f22..e351a4c 100644 --- a/package.json +++ b/package.json @@ -108,6 +108,7 @@ "webpack-bundle-analyzer": "^4.10.1", "winston": "^3.13.0", "winston-daily-rotate-file": "^5.0.0", + "workbox-webpack-plugin": "^7.1.0", "xlsx": "https://cdn.sheetjs.com/xlsx-0.19.1/xlsx-0.19.1.tgz", "xlsx-style": "^0.8.13", "xml-js": "^1.6.11", diff --git a/pages/api/notify.ts b/pages/api/notify.ts index 34ebd93..94dccc1 100644 --- a/pages/api/notify.ts +++ b/pages/api/notify.ts @@ -1,17 +1,39 @@ const webPush = require('web-push') +//generate and store VAPID keys in .env.local if not already done +if (!process.env.NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY || !process.env.WEB_PUSH_PRIVATE_KEY) { + const { publicKey, privateKey } = webPush.generateVAPIDKeys() + console.log('VAPID keys generated:') + console.log('Public key:', publicKey) + console.log('Private key:', privateKey) + console.log('Store these keys in your .env.local file:') + console.log('NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY=', publicKey) + console.log('WEB_PUSH_PRIVATE_KEY=', privateKey) + process.exit(0) +} + webPush.setVapidDetails( `mailto:${process.env.WEB_PUSH_EMAIL}`, process.env.NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY, process.env.WEB_PUSH_PRIVATE_KEY ) -const Notification = (req, res) => { +const Notification = async (req, res) => { + if (req.method == 'GET') { + res.statusCode = 200 + res.setHeader('Allow', 'POST') + // send the public key in the response headers + //res.setHeader('Content-Type', 'text/plain') + res.end(process.env.NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY) + res.end() + } + // on PUT store the subscription object in the database + if (req.method == 'POST') { const { subscription } = req.body - webPush + await webPush .sendNotification( subscription, JSON.stringify({ title: 'Hello Web Push', message: 'Your web push notification is here!' }) diff --git a/server.js b/server.js index f9b7f5c..29f3589 100644 --- a/server.js +++ b/server.js @@ -49,6 +49,7 @@ console.log("process.env.APPLE_APP_ID = ", process.env.APPLE_APP_ID); logger.info("App started on " + process.env.PROTOCOL + "://" + process.env.HOST + ":" + process.env.PORT + ""); logger.info("process.env.GIT_COMMIT_ID = " + process.env.GIT_COMMIT_ID); logger.info("process.env.APP_ENV = " + process.env.APP_ENV); +logger.info("process.env.ENV_ENV = " + process.env.ENV_ENV); logger.info("process.env.NODE_ENV = " + process.env.NODE_ENV); logger.info("process.env.APPLE_APP_ID = " + process.env.APPLE_APP_ID); logger.info("process.env.EMAIL_SERVICE = " + process.env.EMAIL_SERVICE); diff --git a/workbox-config.js b/workbox-config.js new file mode 100644 index 0000000..480eeff --- /dev/null +++ b/workbox-config.js @@ -0,0 +1,34 @@ +importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'); + +// Only import the modules you need; skip precaching and routing if not needed +workbox.core.skipWaiting(); +workbox.core.clientsClaim(); + +//workbox.precaching.cleanupOutdatedCaches(); +//disable precaching +workbox.precaching.precacheAndRoute(self.__WB_MANIFEST); + +module.exports = { + // Other webpack config... + plugins: [ + // Other plugins... + new InjectManifest({ + // These are some common options, and not all are required. + // Consult the docs for more info. + exclude: [/.../, '...'], + maximumFileSizeToCacheInBytes: 1 * 1024 * 1024, + swSrc: './worker/index.js', + }), + ], +}; + +// Example: Set up push notification handling +self.addEventListener('push', event => { + const data = event.data.json(); + event.waitUntil( + self.registration.showNotification(data.title, { + body: data.message, + icon: '/path/to/icon.png' + }) + ); +}); diff --git a/worker/index.js b/worker/index.js index 751e25e..c3efe3d 100644 --- a/worker/index.js +++ b/worker/index.js @@ -1,9 +1,11 @@ 'use strict' -console.log('Service Worker Loaded...') +console.log('Service Worker worker/index.js Loaded...') +workbox.precaching.precacheAndRoute(self.__WB_MANIFEST); self.addEventListener('fetch', (event) => { try { + console.log('Fetch event for ', event.request.url); if (event.request.url.includes('/api/auth/callback/')) { // Use network only strategy for auth routes, or bypass SW completely event.respondWith(fetch(event.request)); From a39a0aec4d17f409a192cd7d87eac24f1e39f786 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 6 May 2024 20:20:44 +0300 Subject: [PATCH 2/6] setup push email; enable local creds again --- .env | 1 + pages/api/auth/[...nextauth].ts | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.env b/.env index 229de8a..4390662 100644 --- a/.env +++ b/.env @@ -69,6 +69,7 @@ MAILTRAP_PASS=c7bc05f171c96c TELEGRAM_BOT=false TELEGRAM_BOT_TOKEN=7050075088:AAH6VRpNCyQd9x9sW6CLm6q0q4ibUgYBfnM +WEB_PUSH_EMAIL=mwitnessing@gmail.com NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY=BGxXJ0jdsQ4ihE7zp8mxrBO-QPSjeEtO9aCtPoMTuxc1VLW0OfRIt-DYinK9ekjTl2w-j0eQbeprIyBCpmmfciI WEB_PUSH_PRIVATE_KEY=VXHu2NgcyM4J4w3O4grkS_0yLwWHCvVKDJexyBjqgx0 # NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY= BBAbKJk4B6lYfNhe4sPc9bpLJXAcXwb2JEkQBlpyZG9DrKvVT1GdAi5d4a3VNgdJuYDlC43w20l5Aia13b748sE diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts index cde6ebe..8cb4f4d 100644 --- a/pages/api/auth/[...nextauth].ts +++ b/pages/api/auth/[...nextauth].ts @@ -86,9 +86,9 @@ export const authOptions: NextAuthOptions = { // // Return null if user data could not be retrieved // return null const users = [ - { id: "1", name: "admin", email: "admin@example.com", password: "admin123", role: "ADMIN" }, - { id: "2", name: "krasi", email: "krasi@example.com", password: "krasi123", role: "ADMIN" }, - { id: "3", name: "popov", email: "popov@example.com", password: "popov123", role: "ADMIN" } + { id: "1", name: "admin", email: "admin@example.com", password: "admin123", role: "ADMIN", static: true }, + { id: "2", name: "krasi", email: "krasi@example.com", password: "krasi123", role: "ADMIN", static: true }, + { id: "3", name: "popov", email: "popov@example.com", password: "popov123", role: "ADMIN", static: true } ]; const user = users.find(user => @@ -174,6 +174,10 @@ export const authOptions: NextAuthOptions = { callbacks: { // https://codevoweb.com/implement-authentication-with-nextauth-in-nextjs-14/ async signIn({ user, account, profile }) { + if (account.provider === 'credentials' && user?.static) { + return true; + } + var prisma = common.getPrismaClient(); console.log("[nextauth] signIn:", account.provider, user.email) From 4e1bbbbd573da46e2b88bd87a640177b02283a26 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 6 May 2024 20:30:15 +0300 Subject: [PATCH 3/6] (wip) PWA Push Notifications --- .gitignore | 4 +- components/PwaManager.tsx | 46 ++++++- next.config.js | 60 +++++---- pages/_app.tsx | 55 +++++--- pages/api/notify.ts | 125 +++++++++++++++--- pages/cart/calendar/index.tsx | 16 ++- pages/dash.tsx | 4 +- .../migration.sql | 2 + prisma/schema.prisma | 1 + src/axiosServer.js | 2 +- workbox-config.js | 63 ++++----- worker.js | 71 ++++++++++ worker/index.js | 61 --------- 13 files changed, 348 insertions(+), 162 deletions(-) create mode 100644 prisma/migrations/20240506162944_add_publiher_push_subsctiption/migration.sql create mode 100644 worker.js delete mode 100644 worker/index.js diff --git a/.gitignore b/.gitignore index 2902a54..13cf87a 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,7 @@ lerna-debug.log* **/public/sw.js.map **/public/workbox-*.js.map **/public/worker-*.js.map - +public/worker.js .eslintcache *.tsbuildinfo @@ -35,4 +35,4 @@ certificates content/output/* public/content/output/* public/content/output/shifts 2024.1.json -!public/content/uploads/* \ No newline at end of file +!public/content/uploads/* diff --git a/components/PwaManager.tsx b/components/PwaManager.tsx index 9d89667..e7fe746 100644 --- a/components/PwaManager.tsx +++ b/components/PwaManager.tsx @@ -1,5 +1,7 @@ import React, { useEffect, useState } from 'react'; import common from '../src/helpers/common'; // Ensure this path is correct +//use session to get user role +import { useSession } from "next-auth/react" function PwaManager() { const [deferredPrompt, setDeferredPrompt] = useState(null); @@ -10,6 +12,8 @@ function PwaManager() { const [registration, setRegistration] = useState(null); const [notificationPermission, setNotificationPermission] = useState(Notification.permission); + const { data: session } = useSession(); + // Handle PWA installation useEffect(() => { @@ -54,7 +58,7 @@ function PwaManager() { }, []); const installPWA = async (e) => { - + console.log('installing PWA'); e.preventDefault(); if (deferredPrompt) { deferredPrompt.prompt(); @@ -107,9 +111,25 @@ function PwaManager() { applicationServerKey: base64ToUint8Array(vapidPublicKey) }); // Call your API to save subscription data on server - setSubscription(sub); - setIsSubscribed(true); - console.log('Web push subscribed!'); + if (session.user?.id != null) { + await fetch(`/api/notify`, { + method: 'PUT', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ subscription: sub, id: session.user.id }) + }).then(response => { + if (!response.ok) { + throw new Error('Failed to save subscription data on server.'); + } + else { + console.log('Subscription data saved on server.'); + setSubscription(sub); + setIsSubscribed(true); + console.log('Web push subscribed!'); + } + }); + } console.log(sub); } catch (error) { console.error('Error subscribing to notifications:', error); @@ -124,6 +144,24 @@ function PwaManager() { // Call your API to delete or invalidate subscription data on server setSubscription(null); setIsSubscribed(false); + if (session?.user?.id != null) { + await fetch(`/api/notify`, + { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ id: session?.user.id }), + } + ).then(response => { + if (!response.ok) { + throw new Error('Failed to delete subscription data on server.'); + } + else { + console.log('Subscription data deleted on server.'); + } + }); + } console.log('Web push unsubscribed!'); } catch (error) { console.error('Error unsubscribing from notifications:', error); diff --git a/next.config.js b/next.config.js index 7e695a0..9f43873 100644 --- a/next.config.js +++ b/next.config.js @@ -1,15 +1,15 @@ const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); -const { InjectManifest } = require('workbox-webpack-plugin'); +const { InjectManifest, GenerateSW } = require('workbox-webpack-plugin'); const withPWA = require('next-pwa')({ dest: 'public', register: true, // ? publicExcludes: ["!_error*.js"], //? - - disable: process.env.NODE_ENV === 'development', + skipWaiting: true, + // disable: process.env.NODE_ENV === 'development', }) -module.exports = { +module.exports = withPWA({ typescript: { // !! WARN !! // Dangerously allow production builds to successfully complete even if @@ -20,19 +20,31 @@ module.exports = { compress: false, pageExtensions: ['ts', 'tsx', 'md', 'mdx'], // Replace `jsx?` with `tsx?` env: { - env: process.env.NODE_ENV, + env: process.env.APP_ENV, server: process.env.NEXT_PUBLIC_PUBLIC_URL }, - plugins: [ - // Other plugins... - new InjectManifest({ - // These are some common options, and not all are required. - // Consult the docs for more info. - //exclude: [/.../, '...'], - maximumFileSizeToCacheInBytes: 1 * 1024 * 1024, - swSrc: './worker/index.js', - }), - ], + // pwa: { + // dest: 'public', + // register: true, + // publicExcludes: ["!_error*.js"], + // disable: process.env.NODE_ENV === 'development', + // // sw: './worker/index.js', // Custom service worker file name + // }, + + // plugins: [ + // // new InjectManifest({ + // // // These are some common options, and not all are required. + // // // Consult the docs for more info. + // // //exclude: [/.../, '...'], + // // maximumFileSizeToCacheInBytes: 1 * 1024 * 1024, + // // swSrc: './worker.js', + // // }), + // // new GenerateSW({ + // // //disable all files + // // maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, + // // // swSrc: './worker.js', + // // }), + // ], webpack: (config, { isServer, buildId, dev }) => { // Configure optimization and source maps config.optimization.minimize = !dev; @@ -46,18 +58,18 @@ module.exports = { // InjectManifest configuration if (!isServer) { - config.plugins.push(new InjectManifest({ - swSrc: './worker/index.js', // Path to source service worker file - swDest: '/worker/index.js', // Destination filename in the build output - maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, // Adjust as needed - exclude: [/\.map$/, /_error.js$/, /favicon.ico$/] // Customize exclusion patterns - }) - ); + // config.plugins.push(new InjectManifest({ + // // swSrc: './worker.js', // Path to source service worker file + // // swDest: '/worker.js', // Destination filename in the build output + // maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, // Adjust as needed + // exclude: [/\.map$/, /_error.js$/, /favicon.ico$/] // Customize exclusion patterns + // }) + // ); } // Bundle Analyzer Configuration if (process.env.ANALYZE && !isServer) { - const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); + //const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); config.plugins.push( new BundleAnalyzerPlugin({ analyzerMode: 'static', @@ -77,4 +89,4 @@ module.exports = { defaultLocale: 'bg', localeDetection: false, }, -} \ No newline at end of file +}) \ No newline at end of file diff --git a/pages/_app.tsx b/pages/_app.tsx index 2093f0a..1f33946 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -26,26 +26,47 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs' // appleWebApp: true, // } +// (custom) Service worker registration and push notification logic +// function registerServiceWorkerAndPushNotifications() { +// useEffect(() => { +// const registerServiceWorker = async () => { +// if ('serviceWorker' in navigator) { +// try { +// const registration = await navigator.serviceWorker.register('/worker/index.js') +// .then((registration) => console.log('reg: ', registration)); +// } catch (error) { +// console.log('Service Worker registration failed:', error); +// } +// } +// }; + +// const askForNotificationPermission = async () => { +// if ('serviceWorker' in navigator && 'PushManager' in window) { +// try { +// const permission = await Notification.requestPermission(); +// if (permission === 'granted') { +// console.log('Notification permission granted.'); +// // TODO: Subscribe the user to push notifications here +// } else { +// console.log('Notification permission not granted.'); +// } +// } catch (error) { +// console.error('Error during service worker registration:', error); +// } +// } else { +// console.log('Service Worker or Push notifications not supported in this browser.'); +// } +// }; + +// registerServiceWorker(); +// askForNotificationPermission(); +// }, []); +// } //function SmwsApp({ Component, pageProps: { locale, messages, session, ...pageProps }, }: AppProps<{ session: Session }>) { function SmwsApp({ Component, pageProps, session, locale, messages }) { - // dynamic locale loading using our API endpoint - // const [locale, setLocale] = useState(_locale); - // const [messages, setMessages] = useState(_messages); - // useEffect(() => { - // async function loadLocaleData() { - // const res = await fetch(`/api/translations/${locale}`); - // if (res.ok) { - // const localeMessages = await res.json(); - // console.log("Loaded messages for locale:", locale, localeMessages); - // setMessages(localeMessages); - // } else { - // const localeMessages = await import(`../content/i18n/${locale}.json`); setMessages(localeMessages.default); - // } - // console.log("locale set to'", locale, "' ",); - // } - // loadLocaleData(); - // }, [locale]); + + //registerServiceWorkerAndPushNotifications(); useEffect(() => { const use = async () => { diff --git a/pages/api/notify.ts b/pages/api/notify.ts index 94dccc1..09ba2cb 100644 --- a/pages/api/notify.ts +++ b/pages/api/notify.ts @@ -1,6 +1,8 @@ const webPush = require('web-push') +import common from '../../src/helpers/common'; + //generate and store VAPID keys in .env.local if not already done if (!process.env.NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY || !process.env.WEB_PUSH_PRIVATE_KEY) { const { publicKey, privateKey } = webPush.generateVAPIDKeys() @@ -28,28 +30,66 @@ const Notification = async (req, res) => { res.end(process.env.NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY) res.end() } - // on PUT store the subscription object in the database + if (req.method == 'PUT') { + // store the subscription object in the database + // publisher.pushSubscription = subscription + const prisma = common.getPrismaClient(); + const { subscription, id } = req.body + const publisher = await prisma.publisher.update({ + where: { id }, + data: { pushSubscription: subscription } + }) + console.log('Subscription for publisher', id, 'updated:', subscription) + res.statusCode = 200 + res.end() + } + if (req.method == 'DELETE') { + // remove the subscription object from the database + // publisher.pushSubscription = null + const prisma = common.getPrismaClient(); + const { id } = req.body + const publisher = await prisma.publisher.update({ + where: { id }, + data: { pushSubscription: null } + }) + console.log('Subscription for publisher', id, 'deleted') + res.statusCode = 200 + res.end() + } + if (req.method == 'POST') { - const { subscription } = req.body - - await webPush - .sendNotification( - subscription, - JSON.stringify({ title: 'Hello Web Push', message: 'Your web push notification is here!' }) - ) - .then(response => { - res.writeHead(response.statusCode, response.headers).end(response.body) - }) - .catch(err => { - if ('statusCode' in err) { - res.writeHead(err.statusCode, err.headers).end(err.body) - } else { - console.error(err) - res.statusCode = 500 - res.end() - } - }) + const { subscription, id, broadcast, title = 'Hello Web Push', message = 'Your web push notification is here!' } = req.body + if (broadcast) { + await broadcastPush(title, message) + res.statusCode = 200 + res.end() + return + } + else if (id) { + await sendPush(id, title, message) + res.statusCode = 200 + res.end() + return + } else if (subscription) { + await webPush + .sendNotification( + subscription, + JSON.stringify({ title, message }) + ) + .then(response => { + res.writeHead(response.statusCode, response.headers).end(response.body) + }) + .catch(err => { + if ('statusCode' in err) { + res.writeHead(err.statusCode, err.headers).end(err.body) + } else { + console.error(err) + res.statusCode = 500 + res.end() + } + }) + } } else { res.statusCode = 405 res.end() @@ -57,3 +97,48 @@ const Notification = async (req, res) => { } export default Notification + +//export pushNotification(userId or email) for use in other files +export const sendPush = async (id, title, message) => { + const prisma = common.getPrismaClient(); + const publisher = await prisma.publisher.findUnique({ + where: { id } + }) + if (!publisher.pushSubscription) { + console.log('No push subscription found for publisher', id) + return + } + + await webPush + .sendNotification( + publisher.pushSubscription, + JSON.stringify({ title, message }) + ) + .then(response => { + console.log('Push notification sent to publisher', id) + }) + .catch(err => { + console.error('Error sending push notification to publisher', id, ':', err) + }) +} +//export breoadcastNotification for use in other files +export const broadcastPush = async (title, message) => { + const prisma = common.getPrismaClient(); + const publishers = await prisma.publisher.findMany({ + where: { pushSubscription: { not: null } } + }) + + for (const publisher of publishers) { + await webPush + .sendNotification( + publisher.pushSubscription, + JSON.stringify({ title, message }) + ) + .then(response => { + console.log('Push notification sent to publisher', publisher.id) + }) + .catch(err => { + console.error('Error sending push notification to publisher', publisher.id, ':', err) + }) + } +} diff --git a/pages/cart/calendar/index.tsx b/pages/cart/calendar/index.tsx index 5a4aa7d..e54d4f8 100644 --- a/pages/cart/calendar/index.tsx +++ b/pages/cart/calendar/index.tsx @@ -15,6 +15,8 @@ import { toast } from 'react-toastify'; import ProtectedRoute from '../../../components/protectedRoute'; import ConfirmationModal from '../../../components/ConfirmationModal'; import LocalShippingIcon from '@mui/icons-material/LocalShipping'; +// import notify api +import { sendPush, broadcastPush } from '../../api/notify'; const { DateTime } = require('luxon'); // import { FaPlus, FaCogs, FaTrashAlt, FaSpinner } from 'react-icons/fa'; // Import FontAwesome icons @@ -734,7 +736,19 @@ export default function CalendarPage({ initialEvents, initialShifts }) { {pub.currentWeekAssignments || 0} {pub.currentMonthAssignments || 0} {pub.previousMonthAssignments || 0} - + + + ); diff --git a/pages/dash.tsx b/pages/dash.tsx index fa8beb1..dc5d560 100644 --- a/pages/dash.tsx +++ b/pages/dash.tsx @@ -226,8 +226,8 @@ export const getServerSideProps = async (context) => { // log first availability startTime to verify timezone and UTC conversion - console.log("First availability startTime: " + items[0].startTime); - console.log("First availability startTime: " + items[0].startTime.toLocaleString()); + console.log("First availability startTime: " + items[0]?.startTime); + console.log("First availability startTime: " + items[0]?.startTime.toLocaleString()); const prisma = common.getPrismaClient(); let cartEvents = await prisma.cartEvent.findMany({ diff --git a/prisma/migrations/20240506162944_add_publiher_push_subsctiption/migration.sql b/prisma/migrations/20240506162944_add_publiher_push_subsctiption/migration.sql new file mode 100644 index 0000000..def0cde --- /dev/null +++ b/prisma/migrations/20240506162944_add_publiher_push_subsctiption/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE `publisher` ADD COLUMN `pushSubscription` JSON NULL; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 6fcc599..391079f 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -123,6 +123,7 @@ model Publisher { Message Message[] EventLog EventLog[] lastLogin DateTime? + pushSubscription Json? } model Availability { diff --git a/src/axiosServer.js b/src/axiosServer.js index 071e7e1..77faaeb 100644 --- a/src/axiosServer.js +++ b/src/axiosServer.js @@ -31,7 +31,7 @@ const axiosServer = async (context) => { } else { //redirect to next-auth login page - context.res.writeHead(302, { Location: '/api/auth/signin' }); + context.res.writeHead(302, { Location: encodeURIComponent('/api/auth/signin') }); context.res.end(); return { props: {} }; } diff --git a/workbox-config.js b/workbox-config.js index 480eeff..a3d8487 100644 --- a/workbox-config.js +++ b/workbox-config.js @@ -1,34 +1,37 @@ -importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'); +// importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'); -// Only import the modules you need; skip precaching and routing if not needed -workbox.core.skipWaiting(); -workbox.core.clientsClaim(); +// // ToDo: probably not used now as we use next-pwa( check config) +// // Only import the modules you need; skip precaching and routing if not needed -//workbox.precaching.cleanupOutdatedCaches(); -//disable precaching -workbox.precaching.precacheAndRoute(self.__WB_MANIFEST); +// workbox.core.skipWaiting(); +// workbox.core.clientsClaim(); -module.exports = { - // Other webpack config... - plugins: [ - // Other plugins... - new InjectManifest({ - // These are some common options, and not all are required. - // Consult the docs for more info. - exclude: [/.../, '...'], - maximumFileSizeToCacheInBytes: 1 * 1024 * 1024, - swSrc: './worker/index.js', - }), - ], -}; +// //workbox.precaching.cleanupOutdatedCaches(); +// //disable precaching +// workbox.precaching.precacheAndRoute(self.__WB_MANIFEST); -// Example: Set up push notification handling -self.addEventListener('push', event => { - const data = event.data.json(); - event.waitUntil( - self.registration.showNotification(data.title, { - body: data.message, - icon: '/path/to/icon.png' - }) - ); -}); +// module.exports = { +// // Other webpack config... +// plugins: [ +// // Other plugins... +// new InjectManifest({ +// // These are some common options, and not all are required. +// // Consult the docs for more info. +// exclude: [/.../, '...'], +// maximumFileSizeToCacheInBytes: 1 * 1024 * 1024, +// // swSrc: './worker.js', +// }), +// ], +// }; + +// // Example: Set up push notification handling +// self.addEventListener('push', event => { +// console.log('Push event received at workbox.config: ', event); +// const data = event.data.json(); +// event.waitUntil( +// self.registration.showNotification(data.title, { +// body: data.message, +// icon: '/path/to/icon.png' +// }) +// ); +// }); diff --git a/worker.js b/worker.js new file mode 100644 index 0000000..8ef95ff --- /dev/null +++ b/worker.js @@ -0,0 +1,71 @@ +// 'use strict' +// // currently not used as we ise next-pwa and in next.config.js we have withPWA. +// // maybe we can have withPWA({sw: './worker.js'}) ? +// console.log('Service Worker worker/index.js Loaded...') +// workbox.precaching.precacheAndRoute(self.__WB_MANIFEST); + + +// self.addEventListener('install', () => { +// console.log('service worker installed') +// }); + +// self.addEventListener('activate', () => { +// console.log('service worker activated') +// }); + +// self.addEventListener('fetch', (event) => { +// try { +// console.log('Fetch event for ', event.request.url); +// if (event.request.url.includes('/api/auth/callback/')) { +// // Use network only strategy for auth routes, or bypass SW completely +// event.respondWith(fetch(event.request)); +// return; +// } +// // other caching strategies... +// } catch (error) { +// console.error(error) +// } +// }); + +// self.addEventListener('push', function (event) { +// console.log('Push message', event) +// if (!(self.Notification && self.Notification.permission === 'granted')) { +// return +// } +// const data = JSON.parse(event.data.text()) +// event.waitUntil( +// registration.showNotification(data.title, { +// body: data.message, +// icon: '/icons/android-chrome-192x192.png' +// }) +// ) +// }) + +// self.addEventListener('notificationclick', function (event) { +// console.log('Notification click: tag', event.notification.tag) +// event.notification.close() +// event.waitUntil( +// clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function (clientList) { +// if (clientList.length > 0) { +// let client = clientList[0] +// for (let i = 0; i < clientList.length; i++) { +// if (clientList[i].focused) { +// client = clientList[i] +// } +// } +// return client.focus() +// } +// return clients.openWindow('/') +// }) +// ) +// }) + +// // self.addEventListener('pushsubscriptionchange', function(event) { +// // event.waitUntil( +// // Promise.all([ +// // Promise.resolve(event.oldSubscription ? deleteSubscription(event.oldSubscription) : true), +// // Promise.resolve(event.newSubscription ? event.newSubscription : subscribePush(registration)) +// // .then(function(sub) { return saveSubscription(sub) }) +// // ]) +// // ) +// // }) \ No newline at end of file diff --git a/worker/index.js b/worker/index.js deleted file mode 100644 index c3efe3d..0000000 --- a/worker/index.js +++ /dev/null @@ -1,61 +0,0 @@ -'use strict' - -console.log('Service Worker worker/index.js Loaded...') -workbox.precaching.precacheAndRoute(self.__WB_MANIFEST); - -self.addEventListener('fetch', (event) => { - try { - console.log('Fetch event for ', event.request.url); - if (event.request.url.includes('/api/auth/callback/')) { - // Use network only strategy for auth routes, or bypass SW completely - event.respondWith(fetch(event.request)); - return; - } - // other caching strategies... - } catch (error) { - console.error(error) - } -}); - -self.addEventListener('push', function (event) { - console.log('Push message', event) - if (!(self.Notification && self.Notification.permission === 'granted')) { - return - } - const data = JSON.parse(event.data.text()) - event.waitUntil( - registration.showNotification(data.title, { - body: data.message, - icon: '/icons/android-chrome-192x192.png' - }) - ) -}) - -self.addEventListener('notificationclick', function (event) { - console.log('Notification click: tag', event.notification.tag) - event.notification.close() - event.waitUntil( - clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function (clientList) { - if (clientList.length > 0) { - let client = clientList[0] - for (let i = 0; i < clientList.length; i++) { - if (clientList[i].focused) { - client = clientList[i] - } - } - return client.focus() - } - return clients.openWindow('/') - }) - ) -}) - -// self.addEventListener('pushsubscriptionchange', function(event) { -// event.waitUntil( -// Promise.all([ -// Promise.resolve(event.oldSubscription ? deleteSubscription(event.oldSubscription) : true), -// Promise.resolve(event.newSubscription ? event.newSubscription : subscribePush(registration)) -// .then(function(sub) { return saveSubscription(sub) }) -// ]) -// ) -// }) \ No newline at end of file From 92a745b58154ded9408ac70a9c53b5def91c16c3 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 6 May 2024 21:08:41 +0300 Subject: [PATCH 4/6] cherrypicks --- components/PwaManager.tsx | 14 +------------- src/helpers/common.js | 11 +++++++++++ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/components/PwaManager.tsx b/components/PwaManager.tsx index e7fe746..623fd17 100644 --- a/components/PwaManager.tsx +++ b/components/PwaManager.tsx @@ -70,18 +70,6 @@ function PwaManager() { } }; - // Utility function for converting base64 string to Uint8Array - const base64ToUint8Array = base64 => { - const padding = '='.repeat((4 - (base64.length % 4)) % 4); - const b64 = (base64 + padding).replace(/-/g, '+').replace(/_/g, '/'); - const rawData = window.atob(b64); - const outputArray = new Uint8Array(rawData.length); - for (let i = 0; i < rawData.length; ++i) { - outputArray[i] = rawData.charCodeAt(i); - } - return outputArray; - }; - const subscribeToNotifications = async (e) => { try { @@ -108,7 +96,7 @@ function PwaManager() { } const sub = await registration.pushManager.subscribe({ userVisibleOnly: true, - applicationServerKey: base64ToUint8Array(vapidPublicKey) + applicationServerKey: common.base64ToUint8Array(vapidPublicKey) }); // Call your API to save subscription data on server if (session.user?.id != null) { diff --git a/src/helpers/common.js b/src/helpers/common.js index 89a7811..2a84eab 100644 --- a/src/helpers/common.js +++ b/src/helpers/common.js @@ -912,6 +912,17 @@ function adjustDateForDST(date, timezone) { } exports.adjustDateForDST = adjustDateForDST; + +export function base64ToUint8Array(base64) { + const padding = '='.repeat((4 - (base64.length % 4)) % 4); + const b64 = (base64 + padding).replace(/-/g, '+').replace(/_/g, '/'); + const rawData = window.atob(b64); + const outputArray = new Uint8Array(rawData.length); + for (let i = 0; i < rawData.length; ++i) { + outputArray[i] = rawData.charCodeAt(i); + } + return outputArray; +} // exports.getInitials = function (names) { // const parts = names.split(' '); // Split the full name into parts // if (parts.length === 0) { From 145e71834d32891379ca74d995f0c0039b1704f6 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 6 May 2024 21:24:24 +0300 Subject: [PATCH 5/6] refactoring --- src/helpers/common.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/helpers/common.js b/src/helpers/common.js index 2a84eab..192a273 100644 --- a/src/helpers/common.js +++ b/src/helpers/common.js @@ -913,15 +913,17 @@ function adjustDateForDST(date, timezone) { exports.adjustDateForDST = adjustDateForDST; -export function base64ToUint8Array(base64) { - const padding = '='.repeat((4 - (base64.length % 4)) % 4); - const b64 = (base64 + padding).replace(/-/g, '+').replace(/_/g, '/'); - const rawData = window.atob(b64); - const outputArray = new Uint8Array(rawData.length); +exports.base64ToUint8Array = function (base64String) { + const padding = '='.repeat((4 - base64String.length % 4) % 4); + const base64 = (base64String + padding) + .replace(/-/g, '+') + .replace(/_/g, '/'); + const rawData = atob(base64); + const buffer = new Uint8Array(rawData.length); for (let i = 0; i < rawData.length; ++i) { - outputArray[i] = rawData.charCodeAt(i); + buffer[i] = rawData.charCodeAt(i); } - return outputArray; + return buffer; } // exports.getInitials = function (names) { // const parts = names.split(' '); // Split the full name into parts From 931e820981fa68bf58cea29d4dbaad24fcfc4124 Mon Sep 17 00:00:00 2001 From: Dobromir Popov Date: Mon, 6 May 2024 21:50:37 +0300 Subject: [PATCH 6/6] fix migration again --- .../20240506162944_add_publiher_push_subsctiption/migration.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prisma/migrations/20240506162944_add_publiher_push_subsctiption/migration.sql b/prisma/migrations/20240506162944_add_publiher_push_subsctiption/migration.sql index def0cde..332899f 100644 --- a/prisma/migrations/20240506162944_add_publiher_push_subsctiption/migration.sql +++ b/prisma/migrations/20240506162944_add_publiher_push_subsctiption/migration.sql @@ -1,2 +1,2 @@ -- AlterTable -ALTER TABLE `publisher` ADD COLUMN `pushSubscription` JSON NULL; +ALTER TABLE `Publisher` ADD COLUMN `pushSubscription` JSON NULL; \ No newline at end of file