From 307552d9f87d31edc0a99d47390f9a4ea49a0e91 Mon Sep 17 00:00:00 2001 From: Huskydog9988 <39809509+Huskydog9988@users.noreply.github.com> Date: Wed, 14 May 2025 22:53:09 -0400 Subject: [PATCH] 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 --- .../migration.sql | 2 ++ server/prisma/models/user.prisma | 3 ++ .../api/v1/client/capability/index.post.ts | 1 + .../server/api/v1/notifications/index.get.ts | 33 ++++++++++++++++++- server/server/internal/acls/index.ts | 2 ++ server/server/internal/library/index.ts | 1 + server/server/internal/notifications/index.ts | 4 ++- server/server/tasks/check/update.ts | 1 + 8 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 server/prisma/migrations/20250515024929_add_required_perms_to_notifications/migration.sql diff --git a/server/prisma/migrations/20250515024929_add_required_perms_to_notifications/migration.sql b/server/prisma/migrations/20250515024929_add_required_perms_to_notifications/migration.sql new file mode 100644 index 00000000..0af03689 --- /dev/null +++ b/server/prisma/migrations/20250515024929_add_required_perms_to_notifications/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "Notification" ADD COLUMN "requiredPerms" TEXT[] DEFAULT ARRAY[]::TEXT[]; diff --git a/server/prisma/models/user.prisma b/server/prisma/models/user.prisma index 0b4f272c..bb088441 100644 --- a/server/prisma/models/user.prisma +++ b/server/prisma/models/user.prisma @@ -34,6 +34,9 @@ model Notification { description String actions String[] + // ACL items + requiredPerms String[] @default([]) + read Boolean @default(false) @@unique([userId, nonce]) diff --git a/server/server/api/v1/client/capability/index.post.ts b/server/server/api/v1/client/capability/index.post.ts index 0123860a..37f5a30d 100644 --- a/server/server/api/v1/client/capability/index.post.ts +++ b/server/server/api/v1/client/capability/index.post.ts @@ -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 {}; diff --git a/server/server/api/v1/notifications/index.get.ts b/server/server/api/v1/notifications/index.get.ts index 8797aa8c..98f43c62 100644 --- a/server/server/api/v1/notifications/index.get.ts +++ b/server/server/api/v1/notifications/index.get.ts @@ -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; }); diff --git a/server/server/internal/acls/index.ts b/server/server/internal/acls/index.ts index 6f42ddc5..8198b284 100644 --- a/server/server/internal/acls/index.ts +++ b/server/server/internal/acls/index.ts @@ -70,6 +70,8 @@ const systemACLPrefix = "system:"; export type SystemACL = Array<(typeof systemACLs)[number]>; +export type ValidACLItems = Array; + class ACLManager { private getAuthorizationToken(request: MinimumRequestObject) { const [type, token] = diff --git a/server/server/internal/library/index.ts b/server/server/internal/library/index.ts index 6556702b..b24925c8 100644 --- a/server/server/internal/library/index.ts +++ b/server/server/internal/library/index.ts @@ -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); diff --git a/server/server/internal/notifications/index.ts b/server/server/internal/notifications/index.ts index 67570dc4..16b224b7 100644 --- a/server/server/internal/notifications/index.ts +++ b/server/server/internal/notifications/index.ts @@ -9,10 +9,12 @@ Design goals: import type { Notification } from "~/prisma/client"; import prisma from "../db/database"; +// type Optional = Pick, K> & Omit; + // TODO: document notification action format export type NotificationCreateArgs = Pick< Notification, - "title" | "description" | "actions" | "nonce" + "title" | "description" | "actions" | "nonce" | "requiredPerms" >; class NotificationSystem { diff --git a/server/server/tasks/check/update.ts b/server/server/tasks/check/update.ts index 6fbaa801..c0e5ec9b 100644 --- a/server/server/tasks/check/update.ts +++ b/server/server/tasks/check/update.ts @@ -100,6 +100,7 @@ export default defineTask({ 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");