feat: allow client-based web tokens

This commit is contained in:
DecDuck
2025-04-08 16:16:40 +10:00
parent 043ef6dcd2
commit 42349ad4e1
8 changed files with 59 additions and 7 deletions

View File

@@ -0,0 +1,31 @@
import { APITokenMode } from "@prisma/client";
import { DateTime } from "luxon";
import { UserACL } from "~/server/internal/acls";
import { defineClientEventHandler } from "~/server/internal/clients/event-handler";
import prisma from "~/server/internal/db/database";
export default defineClientEventHandler(
async (h3, { fetchUser, fetchClient, clientId }) => {
const user = await fetchUser();
const client = await fetchClient();
const acls: UserACL = [
"read",
"store:read",
"collections:read",
"object:read",
];
const token = await prisma.aPIToken.create({
data: {
name: `${client.name} Web Access Token ${DateTime.now().toISO()}`,
clientId,
userId: user.id,
mode: APITokenMode.Client,
acls,
},
});
return token.token;
}
);

View File

@@ -2,7 +2,7 @@ import aclManager from "~/server/internal/acls";
import userLibraryManager from "~/server/internal/userlibrary";
export default defineEventHandler(async (h3) => {
const userId = await aclManager.getUserIdACL(h3, ["collections:new"]);
const userId = await aclManager.getUserIdACL(h3, ["collections:read"]);
if (!userId)
throw createError({
statusCode: 403,

View File

@@ -33,7 +33,7 @@ export const userACLs = [
] as const;
const userACLPrefix = "user:";
type UserACL = Array<(typeof userACLs)[number]>;
export type UserACL = Array<(typeof userACLs)[number]>;
export const systemACLs = [
"auth:read",
@@ -69,7 +69,7 @@ export const systemACLs = [
] as const;
const systemACLPrefix = "system:";
type SystemACL = Array<(typeof systemACLs)[number]>;
export type SystemACL = Array<(typeof systemACLs)[number]>;
class ACLManager {
private getAuthorizationToken(request: MinimumRequestObject) {
@@ -90,16 +90,25 @@ class ACLManager {
const authorizationToken = this.getAuthorizationToken(request);
if (!authorizationToken) return undefined;
const token = await prisma.aPIToken.findUnique({
where: { token: authorizationToken },
where: {
token: authorizationToken,
mode: { in: [APITokenMode.User, APITokenMode.Client] },
},
});
if (!token) return undefined;
if (token.mode != APITokenMode.User || !token.userId) return undefined; // If it's a system token
if (!token.userId)
throw new Error(
"No userId on user or client token - is something broken?"
);
for (const acl of acls) {
const tokenACLIndex = token.acls.findIndex((e) => e == acl);
if (tokenACLIndex != -1) return token.userId;
}
console.log(token);
console.log(acls);
return undefined;
}