try another PWA plugin,
debug .env on TEST/STAGING improve /notify API
This commit is contained in:
8
.env
8
.env
@ -2,7 +2,7 @@
|
|||||||
# HOST=localhost
|
# HOST=localhost
|
||||||
# PORT=3003
|
# PORT=3003
|
||||||
# NEXT_PUBLIC_PUBLIC_URL=http://localhost: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
|
# Linux: `openssl rand -hex 32` or go to https://generate-secret.now.sh/32
|
||||||
NEXTAUTH_SECRET=ed8a9681efc414df89dfd03cd188ed58
|
NEXTAUTH_SECRET=ed8a9681efc414df89dfd03cd188ed58
|
||||||
|
|
||||||
@ -69,5 +69,7 @@ MAILTRAP_PASS=c7bc05f171c96c
|
|||||||
TELEGRAM_BOT=false
|
TELEGRAM_BOT=false
|
||||||
TELEGRAM_BOT_TOKEN=7050075088:AAH6VRpNCyQd9x9sW6CLm6q0q4ibUgYBfnM
|
TELEGRAM_BOT_TOKEN=7050075088:AAH6VRpNCyQd9x9sW6CLm6q0q4ibUgYBfnM
|
||||||
|
|
||||||
NEXT_PUBLIC_VAPID_PUBLIC_KEY=BGxXJ0jdsQ4ihE7zp8mxrBO-QPSjeEtO9aCtPoMTuxc1VLW0OfRIt-DYinK9ekjTl2w-j0eQbeprIyBCpmmfciI
|
NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY=BGxXJ0jdsQ4ihE7zp8mxrBO-QPSjeEtO9aCtPoMTuxc1VLW0OfRIt-DYinK9ekjTl2w-j0eQbeprIyBCpmmfciI
|
||||||
VAPID_PRIVATE_KEY=VXHu2NgcyM4J4w3O4grkS_0yLwWHCvVKDJexyBjqgx0
|
WEB_PUSH_PRIVATE_KEY=VXHu2NgcyM4J4w3O4grkS_0yLwWHCvVKDJexyBjqgx0
|
||||||
|
# NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY= BBAbKJk4B6lYfNhe4sPc9bpLJXAcXwb2JEkQBlpyZG9DrKvVT1GdAi5d4a3VNgdJuYDlC43w20l5Aia13b748sE
|
||||||
|
# WEB_PUSH_PRIVATE_KEY= Xe1NhMTE_QxRnxv5eovqA692G2fC-n4QDlIS6U1qsJI
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
NODE_TLS_REJECT_UNAUTHORIZED=0
|
NODE_TLS_REJECT_UNAUTHORIZED=0
|
||||||
# NODE_EXTRA_CA_CERTS=C:\\Users\\popov\\AppData\\Local\\mkcert
|
# NODE_EXTRA_CA_CERTS=C:\\Users\\popov\\AppData\\Local\\mkcert
|
||||||
|
ENV_ENV=.env.development
|
||||||
PROTOCOL=https
|
PROTOCOL=https
|
||||||
PORT=3003
|
PORT=3003
|
||||||
HOST=localhost
|
HOST=localhost
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
NODE_ENV=test
|
NODE_ENV=test
|
||||||
|
ENV_ENV=test.staging
|
||||||
|
|
||||||
PROTOCOL=http
|
PROTOCOL=http
|
||||||
HOST=staging.mwitnessing.com
|
HOST=staging.mwitnessing.com
|
||||||
|
@ -82,14 +82,29 @@ function PwaManager() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
if (!navigator.serviceWorker) {
|
||||||
|
console.error('Service worker is not supported by this browser.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const registration = await navigator.serviceWorker.ready;
|
||||||
if (!registration) {
|
if (!registration) {
|
||||||
console.error('Service worker registration not found.');
|
console.error('Service worker registration not found.');
|
||||||
registration
|
|
||||||
return;
|
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({
|
const sub = await registration.pushManager.subscribe({
|
||||||
userVisibleOnly: true,
|
userVisibleOnly: true,
|
||||||
applicationServerKey: base64ToUint8Array(process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY)
|
applicationServerKey: base64ToUint8Array(vapidPublicKey)
|
||||||
});
|
});
|
||||||
// Call your API to save subscription data on server
|
// Call your API to save subscription data on server
|
||||||
setSubscription(sub);
|
setSubscription(sub);
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
|
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
|
||||||
|
const { InjectManifest } = require('workbox-webpack-plugin');
|
||||||
|
|
||||||
const withPWA = require('next-pwa')({
|
const withPWA = require('next-pwa')({
|
||||||
dest: 'public',
|
dest: 'public',
|
||||||
register: true, // ?
|
register: true, // ?
|
||||||
publicExcludes: ["!_error*.js"], //?
|
publicExcludes: ["!_error*.js"], //?
|
||||||
|
|
||||||
//disable: process.env.NODE_ENV === 'development',
|
disable: process.env.NODE_ENV === 'development',
|
||||||
})
|
})
|
||||||
|
|
||||||
module.exports = withPWA({
|
module.exports = {
|
||||||
typescript: {
|
typescript: {
|
||||||
// !! WARN !!
|
// !! WARN !!
|
||||||
// Dangerously allow production builds to successfully complete even if
|
// Dangerously allow production builds to successfully complete even if
|
||||||
@ -22,23 +23,41 @@ module.exports = withPWA({
|
|||||||
env: process.env.NODE_ENV,
|
env: process.env.NODE_ENV,
|
||||||
server: process.env.NEXT_PUBLIC_PUBLIC_URL
|
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,
|
// InjectManifest configuration
|
||||||
productionBrowserSourceMaps = true,
|
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 = {
|
// Bundle Analyzer Configuration
|
||||||
|
|
||||||
// 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
|
|
||||||
if (process.env.ANALYZE && !isServer) {
|
if (process.env.ANALYZE && !isServer) {
|
||||||
|
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
|
||||||
config.plugins.push(
|
config.plugins.push(
|
||||||
new BundleAnalyzerPlugin({
|
new BundleAnalyzerPlugin({
|
||||||
analyzerMode: 'static',
|
analyzerMode: 'static',
|
||||||
@ -58,4 +77,4 @@ module.exports = withPWA({
|
|||||||
defaultLocale: 'bg',
|
defaultLocale: 'bg',
|
||||||
localeDetection: false,
|
localeDetection: false,
|
||||||
},
|
},
|
||||||
})
|
}
|
915
package-lock.json
generated
915
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -108,6 +108,7 @@
|
|||||||
"webpack-bundle-analyzer": "^4.10.1",
|
"webpack-bundle-analyzer": "^4.10.1",
|
||||||
"winston": "^3.13.0",
|
"winston": "^3.13.0",
|
||||||
"winston-daily-rotate-file": "^5.0.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": "https://cdn.sheetjs.com/xlsx-0.19.1/xlsx-0.19.1.tgz",
|
||||||
"xlsx-style": "^0.8.13",
|
"xlsx-style": "^0.8.13",
|
||||||
"xml-js": "^1.6.11",
|
"xml-js": "^1.6.11",
|
||||||
|
@ -1,17 +1,39 @@
|
|||||||
|
|
||||||
const webPush = require('web-push')
|
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(
|
webPush.setVapidDetails(
|
||||||
`mailto:${process.env.WEB_PUSH_EMAIL}`,
|
`mailto:${process.env.WEB_PUSH_EMAIL}`,
|
||||||
process.env.NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY,
|
process.env.NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY,
|
||||||
process.env.WEB_PUSH_PRIVATE_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') {
|
if (req.method == 'POST') {
|
||||||
const { subscription } = req.body
|
const { subscription } = req.body
|
||||||
|
|
||||||
webPush
|
await webPush
|
||||||
.sendNotification(
|
.sendNotification(
|
||||||
subscription,
|
subscription,
|
||||||
JSON.stringify({ title: 'Hello Web Push', message: 'Your web push notification is here!' })
|
JSON.stringify({ title: 'Hello Web Push', message: 'Your web push notification is here!' })
|
||||||
|
@ -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("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.GIT_COMMIT_ID = " + process.env.GIT_COMMIT_ID);
|
||||||
logger.info("process.env.APP_ENV = " + process.env.APP_ENV);
|
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.NODE_ENV = " + process.env.NODE_ENV);
|
||||||
logger.info("process.env.APPLE_APP_ID = " + process.env.APPLE_APP_ID);
|
logger.info("process.env.APPLE_APP_ID = " + process.env.APPLE_APP_ID);
|
||||||
logger.info("process.env.EMAIL_SERVICE = " + process.env.EMAIL_SERVICE);
|
logger.info("process.env.EMAIL_SERVICE = " + process.env.EMAIL_SERVICE);
|
||||||
|
34
workbox-config.js
Normal file
34
workbox-config.js
Normal file
@ -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'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
@ -1,9 +1,11 @@
|
|||||||
'use strict'
|
'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) => {
|
self.addEventListener('fetch', (event) => {
|
||||||
try {
|
try {
|
||||||
|
console.log('Fetch event for ', event.request.url);
|
||||||
if (event.request.url.includes('/api/auth/callback/')) {
|
if (event.request.url.includes('/api/auth/callback/')) {
|
||||||
// Use network only strategy for auth routes, or bypass SW completely
|
// Use network only strategy for auth routes, or bypass SW completely
|
||||||
event.respondWith(fetch(event.request));
|
event.respondWith(fetch(event.request));
|
||||||
|
Reference in New Issue
Block a user