Fix up for push notifications on chrome

This commit is contained in:
BordedDev 2025-04-07 00:36:49 +02:00
parent 0057792802
commit 1a26cacb66
No known key found for this signature in database
GPG Key ID: C5F495EAE56673BF
4 changed files with 79 additions and 41 deletions

View File

@ -11,44 +11,61 @@ function arrayBufferToBase64(buffer) {
const keyResponse = await fetch('/push.json') const keyResponse = await fetch('/push.json')
const keyData = await keyResponse.json() const keyData = await keyResponse.json()
console.log("Key data", keyData);
const publicKey = Uint8Array.from(atob(keyData.publicKey), c => c.charCodeAt(0)) const publicKey = Uint8Array.from(atob(keyData.publicKey), c => c.charCodeAt(0))
navigator.serviceWorker export const registerServiceWorker = async () => {
.register("/service-worker.js") navigator.serviceWorker
.then((serviceWorkerRegistration) => { .register("/service-worker.js")
console.log(serviceWorkerRegistration); .then((serviceWorkerRegistration) => {
serviceWorkerRegistration.pushManager.subscribe({ console.log(serviceWorkerRegistration);
userVisibleOnly: true, serviceWorkerRegistration.pushManager.subscribe({
applicationServerKey: publicKey, userVisibleOnly: true,
}).then( applicationServerKey: publicKey,
(pushSubscription) => { }).then(
const subscriptionObject = { (pushSubscription) => {
...pushSubscription.toJSON(), const subscriptionObject = {
encoding: PushManager.supportedContentEncodings, ...pushSubscription.toJSON(),
/* other app-specific data, such as user identity */ encoding: PushManager.supportedContentEncodings,
}; /* other app-specific data, such as user identity */
console.log(pushSubscription.endpoint, pushSubscription, pushSubscription.toJSON(), subscriptionObject); };
// The push subscription details needed by the application console.log(pushSubscription.endpoint, pushSubscription, pushSubscription.toJSON(), subscriptionObject);
// server are now available, and can be sent to it using, // The push subscription details needed by the application
// for example, the fetch() API. // server are now available, and can be sent to it using,
// for example, the fetch() API.
fetch('/push.json', { fetch('/push.json', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
body: JSON.stringify(subscriptionObject), body: JSON.stringify(subscriptionObject),
}).then((response) => { }).then((response) => {
if (!response.ok) { if (!response.ok) {
throw new Error('Bad status code from server.'); throw new Error('Bad status code from server.');
} }
return response.json(); return response.json();
}).then((responseData) => { }).then((responseData) => {
console.log(responseData); console.log(responseData);
}); });
}, },
(error) => { (error) => {
console.error(error); console.error(error);
}, },
); );
});
}
window.registerServiceWorker = () => {
return Notification.requestPermission().then((permission) => {
if (permission === "granted") {
return registerServiceWorker();
} else if (permission === "denied") {
console.log("Permission was denied");
} else {
console.log("Permission was dismissed");
}
}); });
};
registerServiceWorker().catch(console.error);

View File

@ -7,7 +7,6 @@ async function requestNotificationPermission() {
async function subscribeUser() { async function subscribeUser() {
const registration = const registration =
await navigator.serviceWorker.register("/service-worker.js"); await navigator.serviceWorker.register("/service-worker.js");
const subscription = await registration.pushManager.subscribe({ const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true, userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(PUBLIC_VAPID_KEY), applicationServerKey: urlBase64ToUint8Array(PUBLIC_VAPID_KEY),
@ -44,12 +43,15 @@ self.addEventListener("push", (event) => {
const message = const message =
data.message || "Here's something you might want to check out."; data.message || "Here's something you might want to check out.";
const icon = "images/new-notification.png"; const icon = "images/new-notification.png";
console.log("showing message", title, message, icon);
event.waitUntil(self.registration.showNotification(title, { const reg = self.registration.showNotification(title, {
body: message, body: message,
tag: "simple-push-demo-notification", tag: "simple-push-demo-notification",
icon, icon,
})); }).then(e => console.log("success", e)).catch(console.error);
event.waitUntil(reg);
}); });
@ -59,3 +61,21 @@ self.addEventListener("notificationclick", (event) => {
event.waitUntil(clients.openWindow( event.waitUntil(clients.openWindow(
"https://snek.molodetz.nl",)); "https://snek.molodetz.nl",));
}); });
self.addEventListener("notificationclose", (event) => {
})
self.addEventListener("fetch", (event) => {
// console.log("Fetch event for ", event.request.url);
event.respondWith(
caches.match(event.request).then((response) => {
if (response) {
// console.log("Found response in cache: ", response);
return response;
}
// console.log("No response found in cache. About to fetch from network...");
return fetch(event.request);
})
);
})

View File

@ -41,6 +41,7 @@
<a class="no-select" style="display:none" id="install-button" href="#">📥</a> <a class="no-select" style="display:none" id="install-button" href="#">📥</a>
<a class="no-select" href="/threads.html">👥</a> <a class="no-select" href="/threads.html">👥</a>
<a class="no-select" href="/settings/index.html">⚙️</a> <a class="no-select" href="/settings/index.html">⚙️</a>
<a class="no-select" href="#" onclick="registerServiceWorker">✉️</a>
<a class="no-select" href="/logout.html">🔒</a> <a class="no-select" href="/logout.html">🔒</a>
</nav> </nav>

View File

@ -65,7 +65,7 @@ class PushView(BaseFormView):
print(body) print(body)
notifications =get_notifications() notifications =get_notifications()
cert = base64.b64encode( cert = base64.urlsafe_b64encode(
notifications.public_key.public_bytes( notifications.public_key.public_bytes(
encoding=serialization.Encoding.X962, encoding=serialization.Encoding.X962,
format=serialization.PublicFormat.UncompressedPoint format=serialization.PublicFormat.UncompressedPoint