diff --git a/server/api/subscribe.post.ts b/server/api/subscribe.post.ts index a5f22bb..37b600e 100644 --- a/server/api/subscribe.post.ts +++ b/server/api/subscribe.post.ts @@ -1,13 +1,17 @@ import { readSubscriptions, writeSubscriptions } from "~/server/database"; +import { Subscription } from "~/shared/types/account"; export default defineEventHandler(async (event) => { const body: { subscription: PushSubscriptionJSON } = await readBody(event); const subscriptions = await readSubscriptions(); - const existingIndex = subscriptions.findIndex(sub => sub.endpoint === body.subscription.endpoint); + const existingIndex = subscriptions.findIndex( + sub => sub.type === "push" && sub.push.endpoint === body.subscription.endpoint + ); + const subscription: Subscription = { type: "push", push: body.subscription }; if (existingIndex !== -1) { - subscriptions[existingIndex] = body.subscription; + subscriptions[existingIndex] = subscription; } else { - subscriptions.push(body.subscription); + subscriptions.push(subscription); } await writeSubscriptions(subscriptions); if (existingIndex !== -1) { diff --git a/server/api/unsubscribe.post.ts b/server/api/unsubscribe.post.ts index e84bfcd..259b430 100644 --- a/server/api/unsubscribe.post.ts +++ b/server/api/unsubscribe.post.ts @@ -3,7 +3,9 @@ import { readSubscriptions, writeSubscriptions } from "~/server/database"; export default defineEventHandler(async (event) => { const body: { subscription: PushSubscriptionJSON } = await readBody(event); const subscriptions = await readSubscriptions(); - const existingIndex = subscriptions.findIndex(sub => sub.endpoint === body.subscription.endpoint); + const existingIndex = subscriptions.findIndex( + sub => sub.type === "push" && sub.push.endpoint === body.subscription.endpoint + ); if (existingIndex !== -1) { subscriptions.splice(existingIndex, 1); } else { diff --git a/server/database.ts b/server/database.ts index 7ba2438..299b44a 100644 --- a/server/database.ts +++ b/server/database.ts @@ -1,6 +1,7 @@ import { readFile, writeFile } from "node:fs/promises"; import { Schedule } from "~/shared/types/schedule"; import { generateDemoSchedule } from "./generate-demo-schedule"; +import { Subscription } from "~/shared/types/account"; // For this demo I'm just storing the runtime data in JSON files. When making // this into proper application this should be replaced with an actual database. @@ -29,10 +30,14 @@ export async function writeSchedule(schedule: Schedule) { } export async function readSubscriptions() { - let subscriptions = await readJson(subscriptionsPath, []); + let subscriptions = await readJson(subscriptionsPath, []); + if (subscriptions.length && "keys" in subscriptions[0]) { + // Discard old format + subscriptions = []; + } return subscriptions; } -export async function writeSubscriptions(subscriptions: PushSubscriptionJSON[]) { +export async function writeSubscriptions(subscriptions: Subscription[]) { await writeFile(subscriptionsPath, JSON.stringify(subscriptions, undefined, "\t") + "\n", "utf-8"); } diff --git a/server/web-push.ts b/server/web-push.ts index 0f7178d..ee5f8e3 100644 --- a/server/web-push.ts +++ b/server/web-push.ts @@ -14,9 +14,11 @@ export async function sendPush(title: string, body: string) { const removeIndexes = []; for (let index = 0; index < subscriptions.length; index += 1) { const subscription = subscriptions[index]; + if (subscription.type !== "push") + continue; try { await webPush.sendNotification( - subscription as webPush.PushSubscription, + subscription.push as webPush.PushSubscription, payload, { TTL: 3600, @@ -24,10 +26,11 @@ export async function sendPush(title: string, body: string) { } ) } catch (err: any) { - console.error("Received error sending push notice:", err.message, err?.statusCode) - console.error(err); - if (err?.statusCode >= 400 && err?.statusCode < 500) { - removeIndexes.push(index) + if (err?.statusCode === 410) { + removeIndexes.push(index); + } else { + console.error("Received error sending push notice:", err.message, err?.statusCode) + console.error(err); } } } diff --git a/shared/types/account.d.ts b/shared/types/account.d.ts new file mode 100644 index 0000000..b441e25 --- /dev/null +++ b/shared/types/account.d.ts @@ -0,0 +1,4 @@ +export interface Subscription { + type: "push", + push: PushSubscriptionJSON, +}