fix: parsing payload when registering push notification subscriptions

This commit is contained in:
Eana Hufwe 2024-05-24 23:01:06 +00:00
parent 33b45d1d22
commit 65ce56cc08

View file

@ -4,7 +4,39 @@ import { PaginationHelpers } from "@/server/api/mastodon/helpers/pagination.js";
import type { Notification } from "@/models/entities/notification.js";
import { MastoApiError } from "@/server/api/mastodon/middleware/catch-errors.js";
import type { MastoContext } from "@/server/api/mastodon/index.js";
import type { SwSubscription } from "@/models/entities/sw-subscription";
import type { SwSubscription } from "@/models/entities/sw-subscription.js";
/**
* Normalize object arguments from query string.
*
* @example
* ```ts
* normalizeObjectArgs({
* "subscription[endpoint]": "https://example.com",
* "subscription[keys][p256dh]": "key",
* "subscription[keys][auth]": "auth"
* });
* // { subscription: { endpoint: "https://example.com", keys: { p256dh: "key", auth: "auth" } } }
* ```
*/
function normalizeObjectArgs(q: Record<string, string>) {
const dict: Record<string, any> = {};
for (const k in q) {
if (k.endsWith("]")) {
const segments = k.split("[").map((p) => p.replace(/]$/g, ""));
let d = dict;
for (let i = 0; i < segments.length - 1; i++) {
if (!(segments[i] in d)) d[segments[i]] = {};
d = d[segments[i]];
}
} else {
dict[k] = q[k];
}
}
return dict;
}
export class NotificationHelpers {
public static async getNotifications(
@ -148,7 +180,10 @@ export class NotificationHelpers {
): Promise<SwSubscription> {
const user = ctx.user as ILocalUser;
const tokenId = ctx.tokenId as string;
const body = ctx.request.body as any;
let body = ctx.request.body as any;
if ("subscription[endpoint]" in body) {
body = normalizeObjectArgs(body);
}
const subscription = body.subscription as {
endpoint: string;
keys: { p256dh: string; auth: string };
@ -202,7 +237,10 @@ export class NotificationHelpers {
subscription: SwSubscription,
ctx: MastoContext,
) {
const body = ctx.request.body as any;
let body = ctx.request.body as any;
if ("data[alerts][follow]" in body) {
body = normalizeObjectArgs(body);
}
const alerts = body.data.alerts as Record<
MastodonEntity.NotificationType,
boolean