mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-10-28 00:16:48 +09:00
Only room pages posted the subscription again, so a browser that
changed its password and closed the profile page went without
notifications until it next opened a room. A small controller in the
layout does it now, still once per session, and the bell is back to how
it was.
Two tabs posting at once after a password change could both miss the
row and insert two, so the endpoint is looked up again under the same
write lock as the session check.
From #371.
(cherry picked from commit 3786ee5244)
33 lines
1.4 KiB
JavaScript
33 lines
1.4 KiB
JavaScript
import { Controller } from "@hotwired/stimulus"
|
|
import { post } from "@rails/request.js"
|
|
|
|
const SYNCED_SESSION_KEY = "push-subscription-synced-session"
|
|
|
|
// A password change removes the account's push subscriptions, the one this browser holds included. Post it again
|
|
// once per session, so a browser that's still signed in keeps getting notifications. A failure here leaves the
|
|
// browser's own subscription alone: the next session tries again.
|
|
export default class extends Controller {
|
|
static values = { url: String, session: String }
|
|
|
|
async connect() {
|
|
if (this.#allowed && this.sessionValue && localStorage.getItem(SYNCED_SESSION_KEY) !== this.sessionValue) {
|
|
const registration = await navigator.serviceWorker.getRegistration(window.location.origin)
|
|
const subscription = await registration?.pushManager?.getSubscription()
|
|
|
|
if (Notification.permission === "granted" && subscription) {
|
|
await post(this.urlValue, { body: this.#payload(subscription), responseKind: "turbo-stream" })
|
|
localStorage.setItem(SYNCED_SESSION_KEY, this.sessionValue)
|
|
}
|
|
}
|
|
}
|
|
|
|
get #allowed() {
|
|
return navigator.serviceWorker && window.Notification
|
|
}
|
|
|
|
#payload(subscription) {
|
|
const { endpoint, keys: { p256dh, auth } } = subscription.toJSON()
|
|
return JSON.stringify({ push_subscription: { endpoint, p256dh_key: p256dh, auth_key: auth } })
|
|
}
|
|
}
|