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)))
|
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 = () => {
|
this.installationId = () => {
|
||||||
const key = "wnh.push.installation-id"
|
const key = "wnh.push.installation-id"
|
||||||
const existing = window.localStorage.getItem(key)
|
const existing = window.localStorage.getItem(key)
|
||||||
|
|
@ -806,11 +834,7 @@ export const Hooks = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const registration = await navigator.serviceWorker.ready
|
const registration = await navigator.serviceWorker.ready
|
||||||
const subscription = await registration.pushManager.getSubscription() ||
|
const subscription = await this.subscriptionForPublicKey(registration, publicKey)
|
||||||
await registration.pushManager.subscribe({
|
|
||||||
userVisibleOnly: true,
|
|
||||||
applicationServerKey: this.decodeApplicationServerKey(publicKey)
|
|
||||||
})
|
|
||||||
const json = subscription.toJSON()
|
const json = subscription.toJSON()
|
||||||
|
|
||||||
await this.registerDevice({
|
await this.registerDevice({
|
||||||
|
|
@ -850,14 +874,20 @@ export const Hooks = {
|
||||||
try {
|
try {
|
||||||
const registration = await navigator.serviceWorker.ready
|
const registration = await navigator.serviceWorker.ready
|
||||||
const subscription = await registration.pushManager.getSubscription()
|
const subscription = await registration.pushManager.getSubscription()
|
||||||
|
const currentKey = subscription &&
|
||||||
|
this.subscriptionUsesPublicKey(subscription, publicKey)
|
||||||
const deviceId = window.localStorage.getItem("wnh.push.server-device-id")
|
const deviceId = window.localStorage.getItem("wnh.push.server-device-id")
|
||||||
const activeServerDevice = deviceId &&
|
const activeServerDevice = deviceId &&
|
||||||
[...this.el.querySelectorAll("[data-disable-device]")]
|
[...this.el.querySelectorAll("[data-disable-device]")]
|
||||||
.some(element => element.dataset.disableDevice === deviceId)
|
.some(element => element.dataset.disableDevice === deviceId)
|
||||||
|
|
||||||
if (subscription && activeServerDevice) {
|
if (subscription && currentKey && activeServerDevice) {
|
||||||
this.setButtonState(true)
|
this.setButtonState(true)
|
||||||
this.setStatus("Push notifications are enabled on this device.")
|
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) {
|
} else if (subscription || activeServerDevice) {
|
||||||
this.setStatus("This browser has a push subscription. Enable it to reconnect this device.")
|
this.setStatus("This browser has a push subscription. Enable it to reconnect this device.")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user