feat: add acl to notifications

not sure if i got all the acls of the different notifications down rn, but it seems to be about right
This commit is contained in:
Huskydog9988
2025-05-14 22:53:09 -04:00
parent 82b123a345
commit 9d2aded70f
8 changed files with 45 additions and 2 deletions

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Notification" ADD COLUMN "requiredPerms" TEXT[] DEFAULT ARRAY[]::TEXT[];

View File

@@ -34,6 +34,9 @@ model Notification {
description String
actions String[]
// ACL items
requiredPerms String[] @default([])
read Boolean @default(false)
@@unique([userId, nonce])

View File

@@ -55,6 +55,7 @@ export default defineClientEventHandler(
title: `"${client.name}" can now access ${capability}`,
description: `A device called "${client.name}" now has access to your ${capability}.`,
actions: ["Review|/account/devices"],
requiredPerms: ["clients:read"],
});
return {};

View File

@@ -1,4 +1,4 @@
import aclManager from "~/server/internal/acls";
import aclManager, { type SystemACL } from "~/server/internal/acls";
import prisma from "~/server/internal/db/database";
export default defineEventHandler(async (h3) => {
@@ -22,5 +22,36 @@ export default defineEventHandler(async (h3) => {
},
});
let i = notifications.length;
while (i--) {
const notif = notifications[i];
const hasPermsForNotif = await aclManager.allowSystemACL(
h3,
notif.requiredPerms as SystemACL,
);
if (!hasPermsForNotif) {
// remove element
console.log(
userId,
"did not have perms to access",
notif.id,
"based on",
notif.requiredPerms,
);
notifications.splice(i, 1);
} else {
console.log(
userId,
"had perms to access",
notif.id,
"based on",
notif.requiredPerms,
);
}
}
return notifications;
});

View File

@@ -70,6 +70,8 @@ const systemACLPrefix = "system:";
export type SystemACL = Array<(typeof systemACLs)[number]>;
export type ValidACLItems = Array<SystemACL[number] | UserACL[number]>;
class ACLManager {
private getAuthorizationToken(request: MinimumRequestObject) {
const [type, token] =

View File

@@ -306,6 +306,7 @@ class LibraryManager {
title: `'${game.mName}' ('${versionName}') finished importing.`,
description: `Drop finished importing version ${versionName} for ${game.mName}.`,
actions: [`View|/admin/library/${gameId}`],
requiredPerms: ["import:game:new"],
});
progress(100);

View File

@@ -9,10 +9,12 @@ Design goals:
import type { Notification } from "~/prisma/client";
import prisma from "../db/database";
// type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
// TODO: document notification action format
export type NotificationCreateArgs = Pick<
Notification,
"title" | "description" | "actions" | "nonce"
"title" | "description" | "actions" | "nonce" | "requiredPerms"
>;
class NotificationSystem {

View File

@@ -100,6 +100,7 @@ export default defineTask<TaskReturn>({
title: `Update available to v${latestVer}`,
description: `A new version of Drop is available v${latestVer}`,
actions: [`View|${body.html_url}`],
requiredPerms: [""],
});
} else {
console.log("[Task check:update]: no update available");