Email digest: GET-first restore on boot so reloads stop re-sending confirmations
All checks were successful
CI / lint-check-build (pull_request) Successful in 3m25s
All checks were successful
CI / lint-check-build (pull_request) Successful in 3m25s
Mail.sync's boot reconcile now GETs the existing subscription (NIP-98 auth) before deciding what to do. When a subscription already exists for the pubkey with the same email and frequency, its key/callback are restored in memory and the PUT is skipped entirely. Only a matching subscription missing the requested params triggers a PUT, so a page refresh of an unconfirmed address no longer makes mailship re-send a confirmation email (previously each reload sent one).
This commit is contained in:
parent
63cf801ef1
commit
609a2f65ea
1 changed files with 56 additions and 1 deletions
|
|
@ -150,6 +150,42 @@ export class MailNotifications {
|
|||
return this._register
|
||||
}
|
||||
|
||||
// Fetch the existing subscription for this pubkey (if any) without creating
|
||||
// or changing anything. Used at boot to restore state instead of re-PUTting,
|
||||
// which would otherwise re-send a confirmation email for an unconfirmed
|
||||
// address on every reload.
|
||||
async lookup(): Promise<
|
||||
| {
|
||||
key: string
|
||||
callback: string
|
||||
email: string
|
||||
frequency: string
|
||||
confirmed: boolean
|
||||
}
|
||||
| undefined
|
||||
> {
|
||||
const $signer = app.get().user?.signer
|
||||
if (!$signer || !EMAIL_NOTIFICATION_SERVER) return undefined
|
||||
|
||||
try {
|
||||
const authEvent = await $signer.sign(
|
||||
await makeHttpAuth(buildUrl(EMAIL_NOTIFICATION_SERVER, "subscription", "email"), "GET"),
|
||||
)
|
||||
const authHeader = makeHttpAuthHeader(authEvent)
|
||||
|
||||
const res = await fetch(buildUrl(EMAIL_NOTIFICATION_SERVER, "subscription", "email"), {
|
||||
method: "GET",
|
||||
headers: {Authorization: authHeader},
|
||||
})
|
||||
|
||||
if (!res.ok) return undefined
|
||||
|
||||
return await res.json()
|
||||
} catch {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
async unregister() {
|
||||
const {key} = emailNotificationState.get()
|
||||
if (!key) return
|
||||
|
|
@ -231,8 +267,27 @@ export class MailNotifications {
|
|||
|
||||
reconciledPubkey = $pubkey
|
||||
|
||||
// GET-first: if a subscription already exists for this pubkey with the
|
||||
// same email and cadence, restore its state (key/callback) instead of
|
||||
// PUTting. A PUT here would make mailship re-send a confirmation email
|
||||
// for an unconfirmed address on every app reload. Only register when
|
||||
// there's nothing to restore or the settings changed.
|
||||
const existing = await this.lookup()
|
||||
|
||||
try {
|
||||
await this.register(emailAddress, emailFrequency)
|
||||
if (!existing) {
|
||||
await this.register(emailAddress, emailFrequency)
|
||||
} else if (existing.email !== emailAddress || existing.frequency !== emailFrequency) {
|
||||
await this.register(emailAddress, emailFrequency)
|
||||
} else {
|
||||
emailNotificationState.set({
|
||||
key: existing.key,
|
||||
callback: existing.callback,
|
||||
email: existing.email,
|
||||
frequency: existing.frequency,
|
||||
error: undefined,
|
||||
})
|
||||
}
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue