summaryrefslogtreecommitdiff
path: root/src/client/scripts/initialize-sw.ts
diff options
context:
space:
mode:
authortamaina <tamaina@hotmail.co.jp>2021-02-06 18:55:53 +0900
committerGitHub <noreply@github.com>2021-02-06 18:55:53 +0900
commit40bfa3ef0407f83484031bfe74dcecb149c202a0 (patch)
tree8128fa49e2041e00f6b130cb150f6571cf2a5ec7 /src/client/scripts/initialize-sw.ts
parentResolve #7096 (diff)
downloadsharkey-40bfa3ef0407f83484031bfe74dcecb149c202a0.tar.gz
sharkey-40bfa3ef0407f83484031bfe74dcecb149c202a0.tar.bz2
sharkey-40bfa3ef0407f83484031bfe74dcecb149c202a0.zip
Resurrect Service Worker (#7108)
* Resolve #7106 * fix lint * fix lint * save lang in idb * fix lint * fix * cache locale file * fix lint * :v: * wip * fix [wip] * fix [wip] Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
Diffstat (limited to 'src/client/scripts/initialize-sw.ts')
-rw-r--r--src/client/scripts/initialize-sw.ts68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/client/scripts/initialize-sw.ts b/src/client/scripts/initialize-sw.ts
new file mode 100644
index 0000000000..d6dbd5dbd4
--- /dev/null
+++ b/src/client/scripts/initialize-sw.ts
@@ -0,0 +1,68 @@
+import { instance } from '@/instance';
+import { $i } from '@/account';
+import { api } from '@/os';
+import { lang } from '@/config';
+
+export async function initializeSw() {
+ if (instance.swPublickey &&
+ ('serviceWorker' in navigator) &&
+ ('PushManager' in window) &&
+ $i && $i.token) {
+ navigator.serviceWorker.register(`/sw.js`);
+
+ navigator.serviceWorker.ready.then(registration => {
+ registration.active?.postMessage({
+ msg: 'initialize',
+ lang,
+ });
+ // SEE: https://developer.mozilla.org/en-US/docs/Web/API/PushManager/subscribe#Parameters
+ registration.pushManager.subscribe({
+ userVisibleOnly: true,
+ applicationServerKey: urlBase64ToUint8Array(instance.swPublickey)
+ }).then(subscription => {
+ function encode(buffer: ArrayBuffer | null) {
+ return btoa(String.fromCharCode.apply(null, new Uint8Array(buffer)));
+ }
+
+ // Register
+ api('sw/register', {
+ endpoint: subscription.endpoint,
+ auth: encode(subscription.getKey('auth')),
+ publickey: encode(subscription.getKey('p256dh'))
+ });
+ })
+ // When subscribe failed
+ .catch(async (err: Error) => {
+ // 通知が許可されていなかったとき
+ if (err.name === 'NotAllowedError') {
+ return;
+ }
+
+ // 違うapplicationServerKey (または gcm_sender_id)のサブスクリプションが
+ // 既に存在していることが原因でエラーになった可能性があるので、
+ // そのサブスクリプションを解除しておく
+ const subscription = await registration.pushManager.getSubscription();
+ if (subscription) subscription.unsubscribe();
+ });
+ });
+ }
+}
+
+/**
+ * Convert the URL safe base64 string to a Uint8Array
+ * @param base64String base64 string
+ */
+function urlBase64ToUint8Array(base64String: string): Uint8Array {
+ const padding = '='.repeat((4 - base64String.length % 4) % 4);
+ const base64 = (base64String + padding)
+ .replace(/-/g, '+')
+ .replace(/_/g, '/');
+
+ 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;
+}