hardlounge/client/js/webpush.js

146 lines
3.9 KiB
JavaScript
Raw Normal View History

2017-07-10 19:47:03 +00:00
"use strict";
const storage = require("./localStorage");
const socket = require("./socket");
2019-11-07 09:29:04 +00:00
const vueApp = require("./vue");
const store = require("./store").default;
2017-07-10 19:47:03 +00:00
let clientSubscribed = null;
let applicationServerKey;
if ("serviceWorker" in navigator) {
navigator.serviceWorker.addEventListener("message", (event) => {
if (event.data && event.data.type === "open") {
2019-11-07 09:29:04 +00:00
const id = event.data.channel.substr(5); // remove "chan-" prefix
const channelTarget = store.getters.findChannel(id);
2019-11-04 14:11:17 +00:00
if (channelTarget) {
2019-11-07 09:29:04 +00:00
vueApp.switchToChannel(channelTarget);
2019-11-04 14:11:17 +00:00
}
}
});
}
module.exports.hasServiceWorker = false;
2017-07-10 19:47:03 +00:00
module.exports.configurePushNotifications = (subscribedOnServer, key) => {
applicationServerKey = key;
// If client has push registration but the server knows nothing about it,
// this subscription is broken and client has to register again
if (clientSubscribed === true && subscribedOnServer === false) {
2019-11-04 14:11:17 +00:00
store.commit("pushNotificationState", "loading");
2017-07-10 19:47:03 +00:00
navigator.serviceWorker.ready
2017-07-10 19:47:03 +00:00
.then((registration) => registration.pushManager.getSubscription())
.then((subscription) => subscription && subscription.unsubscribe())
.then((successful) => {
2019-11-04 14:11:17 +00:00
store.commit("pushNotificationState", successful ? "supported" : "unsupported");
2017-07-10 19:47:03 +00:00
});
}
};
2017-11-07 20:22:16 +00:00
module.exports.initialize = () => {
if (!isAllowedServiceWorkersHost()) {
store.commit("pushNotificationState", "nohttps");
2017-11-07 20:22:16 +00:00
return;
}
2017-07-10 19:47:03 +00:00
if ("serviceWorker" in navigator) {
2019-07-17 09:33:59 +00:00
navigator.serviceWorker
.register("service-worker.js")
.then((registration) => {
module.exports.hasServiceWorker = true;
2019-07-17 09:33:59 +00:00
if (!registration.pushManager) {
return;
}
2017-07-10 19:47:03 +00:00
2019-07-17 09:33:59 +00:00
return registration.pushManager.getSubscription().then((subscription) => {
clientSubscribed = !!subscription;
2017-07-10 19:47:03 +00:00
2019-11-04 14:11:17 +00:00
store.commit(
"pushNotificationState",
clientSubscribed ? "subscribed" : "supported"
);
2019-07-17 09:33:59 +00:00
});
})
.catch(() => {
store.commit("pushNotificationState", "unsupported");
});
2017-07-10 19:47:03 +00:00
}
2017-11-07 20:22:16 +00:00
};
2017-07-10 19:47:03 +00:00
module.exports.onPushButton = () => {
2019-11-04 14:11:17 +00:00
store.commit("pushNotificationState", "loading");
2017-07-10 19:47:03 +00:00
2019-07-17 09:33:59 +00:00
navigator.serviceWorker.ready
.then((registration) =>
2019-11-04 14:11:17 +00:00
registration.pushManager.getSubscription().then((existingSubscription) => {
if (existingSubscription) {
socket.emit("push:unregister");
return existingSubscription.unsubscribe().then(() => {
store.commit("pushNotificationState", "supported");
});
}
return registration.pushManager
.subscribe({
applicationServerKey: urlBase64ToUint8Array(applicationServerKey),
userVisibleOnly: true,
})
.then((subscription) => {
const rawKey = subscription.getKey ? subscription.getKey("p256dh") : "";
const key = rawKey
? window.btoa(String.fromCharCode(...new Uint8Array(rawKey)))
: "";
const rawAuthSecret = subscription.getKey
? subscription.getKey("auth")
: "";
const authSecret = rawAuthSecret
? window.btoa(String.fromCharCode(...new Uint8Array(rawAuthSecret)))
: "";
socket.emit("push:register", {
token: storage.get("token"),
endpoint: subscription.endpoint,
keys: {
p256dh: key,
auth: authSecret,
},
2019-07-17 09:33:59 +00:00
});
2019-11-04 14:11:17 +00:00
store.commit("pushNotificationState", "subscribed");
});
})
2019-07-17 09:33:59 +00:00
)
2019-08-03 19:03:45 +00:00
.catch(() => {
store.commit("pushNotificationState", "unsupported");
2019-07-17 09:33:59 +00:00
});
2017-07-10 19:47:03 +00:00
return false;
};
2017-07-10 19:47:03 +00:00
function urlBase64ToUint8Array(base64String) {
2019-07-17 09:33:59 +00:00
const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
2017-07-10 19:47:03 +00:00
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
function isAllowedServiceWorkersHost() {
2019-07-17 09:33:59 +00:00
return (
location.protocol === "https:" ||
location.hostname === "localhost" ||
location.hostname === "127.0.0.1"
);
2017-07-10 19:47:03 +00:00
}