fix(push): reconnect subscriptions after VAPID rotation
This commit is contained in:
parent
39b7d0c6a3
commit
04eb0fe506
|
|
@ -681,6 +681,34 @@ export const Hooks = {
|
|||
return Uint8Array.from([...raw].map(character => character.charCodeAt(0)))
|
||||
}
|
||||
|
||||
this.subscriptionUsesPublicKey = (subscription, publicKey) => {
|
||||
const configuredKey = this.decodeApplicationServerKey(publicKey)
|
||||
const subscribedKey = subscription?.options?.applicationServerKey
|
||||
|
||||
if (!subscribedKey) return false
|
||||
|
||||
const subscribedBytes = new Uint8Array(subscribedKey)
|
||||
return subscribedBytes.length === configuredKey.length &&
|
||||
subscribedBytes.every((byte, index) => byte === configuredKey[index])
|
||||
}
|
||||
|
||||
this.subscriptionForPublicKey = async (registration, publicKey) => {
|
||||
let subscription = await registration.pushManager.getSubscription()
|
||||
|
||||
if (subscription && !this.subscriptionUsesPublicKey(subscription, publicKey)) {
|
||||
const unsubscribed = await subscription.unsubscribe()
|
||||
if (!unsubscribed) throw new Error("stale_push_subscription_could_not_be_removed")
|
||||
|
||||
window.localStorage.removeItem("wnh.push.server-device-id")
|
||||
subscription = null
|
||||
}
|
||||
|
||||
return subscription || registration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: this.decodeApplicationServerKey(publicKey)
|
||||
})
|
||||
}
|
||||
|
||||
this.installationId = () => {
|
||||
const key = "wnh.push.installation-id"
|
||||
const existing = window.localStorage.getItem(key)
|
||||
|
|
@ -806,11 +834,7 @@ export const Hooks = {
|
|||
}
|
||||
|
||||
const registration = await navigator.serviceWorker.ready
|
||||
const subscription = await registration.pushManager.getSubscription() ||
|
||||
await registration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: this.decodeApplicationServerKey(publicKey)
|
||||
})
|
||||
const subscription = await this.subscriptionForPublicKey(registration, publicKey)
|
||||
const json = subscription.toJSON()
|
||||
|
||||
await this.registerDevice({
|
||||
|
|
@ -850,14 +874,20 @@ export const Hooks = {
|
|||
try {
|
||||
const registration = await navigator.serviceWorker.ready
|
||||
const subscription = await registration.pushManager.getSubscription()
|
||||
const currentKey = subscription &&
|
||||
this.subscriptionUsesPublicKey(subscription, publicKey)
|
||||
const deviceId = window.localStorage.getItem("wnh.push.server-device-id")
|
||||
const activeServerDevice = deviceId &&
|
||||
[...this.el.querySelectorAll("[data-disable-device]")]
|
||||
.some(element => element.dataset.disableDevice === deviceId)
|
||||
|
||||
if (subscription && activeServerDevice) {
|
||||
if (subscription && currentKey && activeServerDevice) {
|
||||
this.setButtonState(true)
|
||||
this.setStatus("Push notifications are enabled on this device.")
|
||||
} else if (subscription && !currentKey) {
|
||||
this.setStatus(
|
||||
"Push keys changed. Enable notifications to reconnect this device securely."
|
||||
)
|
||||
} else if (subscription || activeServerDevice) {
|
||||
this.setStatus("This browser has a push subscription. Enable it to reconnect this device.")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user