Files
online-energieausweis/src/pages/api/unterlage.ts
2025-04-05 13:06:50 -03:00

108 lines
2.4 KiB
TypeScript

import { authorizationMiddleware } from "#lib/middleware/authorization.js";
import { prisma } from "#lib/server/prisma.js";
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
import { z } from "zod";
import { UnterlageSchema } from "src/generated/zod/unterlage.js";
import { generatePrefixedId } from "#lib/db.js";
import { VALID_UUID_PREFIXES } from "#lib/constants.js";
import { UUidWithPrefix } from "#components/Ausweis/types.js";
import { PutObjectCommand } from "@aws-sdk/client-s3";
import { s3Client } from "#lib/s3.js";
import mime from "mime"
export const PUT = defineApiRoute({
input: UnterlageSchema.omit({
aufnahme_id: true,
id: true,
}).merge(z.object({
data: z.string(),
})),
output: z.object({
id: UUidWithPrefix
}),
async fetch({ data, name, kategorie, mime: mimeType }, ctx, user) {
const extension = mime.getExtension(mimeType);
if (!extension) {
throw new APIError({
code: "BAD_REQUEST",
message: "Mime Type wird nicht unterstützt."
})
}
const id = generatePrefixedId(6, VALID_UUID_PREFIXES.Unterlage)
await prisma.unterlage.create({
data: {
id,
kategorie: kategorie,
mime: mimeType,
name
}
});
const buffer = Buffer.from(data, "base64");
try {
const command = new PutObjectCommand({
Bucket: "ibc-unterlagen",
Key: `${id}.${extension}`,
Body: buffer,
ACL: "private"
})
const response = await s3Client.send(command)
} catch(e) {
// Unterlage wurde nicht gespeichert, wir löschen den Eintrag wieder
await prisma.unterlage.delete({
where: {
id
}
})
// Und geben einen Fehler zurück
throw new APIError({
code: "UNPROCESSABLE_CONTENT",
message: "Unterlage konnte nicht gespeichert werden.",
});
}
return {
id
};
},
})
export const GET = defineApiRoute({
middleware: authorizationMiddleware,
output: z.array(UnterlageSchema.pick({
kategorie: true,
id: true
})),
async fetch(input, ctx, user) {
const { id } = ctx.params;
const objekt = await prisma.aufnahme.findUnique({
where: {
id,
benutzer_id: user.id
},
select: {
benutzer_id: true,
unterlagen: {
select: {
kategorie: true,
id: true
}
}
}
})
if (!objekt) {
throw new APIError({
code: "FORBIDDEN",
message: "Objekt existiert nicht oder gehört einem anderen Benutzer."
})
}
return objekt.unterlagen
},
})