92 lines
3.0 KiB
TypeScript
92 lines
3.0 KiB
TypeScript
import { and, eq, SQL, sql, type Operators } from 'drizzle-orm';
|
|
import useDatabase from '~/composables/useDatabase';
|
|
import { characterTable, userPermissionsTable } from '~/db/schema';
|
|
import { hasPermissions } from '~/shared/auth.util';
|
|
import { group } from '~/shared/general.util';
|
|
import type { Character, Level, MainStat, TrainingLevel } from '~/types/character';
|
|
|
|
export default defineEventHandler(async (e) => {
|
|
let { visibility } = getQuery(e) as { visibility?: "public" | "own" | "admin" };
|
|
|
|
if(!visibility)
|
|
{
|
|
visibility = "own";
|
|
}
|
|
|
|
let where: ((character: typeof characterTable._.config.columns, sql: Operators) => SQL | undefined) | undefined = undefined;
|
|
const db = useDatabase();
|
|
|
|
if(visibility === "own")
|
|
{
|
|
const session = await getUserSession(e);
|
|
if(!session.user)
|
|
{
|
|
setResponseStatus(e, 401);
|
|
return;
|
|
}
|
|
|
|
where = (character, { eq, and }) => and(eq(character.owner, session.user!.id));
|
|
}
|
|
else if(visibility === 'public')
|
|
{
|
|
where = (character, { eq, and }) => eq(character.visibility, "public");
|
|
}
|
|
else if(visibility === 'admin')
|
|
{
|
|
const session = await getUserSession(e);
|
|
if(!session.user)
|
|
{
|
|
setResponseStatus(e, 401);
|
|
return;
|
|
}
|
|
const db = useDatabase();
|
|
|
|
const rights = db.select({ right: userPermissionsTable.permission }).from(userPermissionsTable).where(eq(userPermissionsTable.id, session.user.id)).all();
|
|
if(rights.length === 0 || !hasPermissions(rights.map(e => e.right), ['admin']))
|
|
{
|
|
setResponseStatus(e, 403);
|
|
return;
|
|
}
|
|
|
|
where = undefined;
|
|
}
|
|
|
|
const characters = db.query.characterTable.findMany({
|
|
with: {
|
|
abilities: true,
|
|
levels: true,
|
|
training: true,
|
|
choices: true,
|
|
user: {
|
|
columns: { username: true }
|
|
}
|
|
},
|
|
where: where,
|
|
}).sync();
|
|
|
|
if(characters !== undefined)
|
|
{
|
|
return characters.map(character => ({
|
|
id: character.id,
|
|
|
|
name: character.name,
|
|
people: character.people,
|
|
level: character.level,
|
|
aspect: character.aspect,
|
|
notes: character.notes,
|
|
variables: character.variables,
|
|
|
|
training: character.training.reduce((p, v) => { p[v.stat] ??= {}; p[v.stat][v.level as TrainingLevel] = v.choice; return p; }, {} as Record<MainStat, Partial<Record<TrainingLevel, number>>>),
|
|
leveling: group(character.levels, "level", "choice"),
|
|
abilities: group(character.abilities, "ability", "value"),
|
|
choices: character.choices.reduce((p, v) => { p[v.id] ??= []; p[v.id]?.push(v.choice); return p; }, {} as Record<string, number[]>),
|
|
|
|
owner: character.owner,
|
|
username: character.user.username,
|
|
visibility: character.visibility,
|
|
} as Character));
|
|
}
|
|
|
|
setResponseStatus(e, 404);
|
|
return;
|
|
}); |