API Vollständig Umgezogen
This commit is contained in:
@@ -2,8 +2,7 @@ import { z } from "zod";
|
||||
import moment from "moment";
|
||||
import { prisma } from "@ibcornelsen/database/server";
|
||||
import { encodeToken } from "../../../lib/auth/token.js";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { defineApiRoute } from "astro-typesafe-api/server";
|
||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||
import { TokenType } from "#lib/auth/types.js";
|
||||
|
||||
export const GET = defineApiRoute({
|
||||
@@ -35,7 +34,7 @@ export const GET = defineApiRoute({
|
||||
});
|
||||
|
||||
if (!response) {
|
||||
throw new TRPCError({
|
||||
throw new APIError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Der gegebene refresh token ist nicht gültig.",
|
||||
});
|
||||
@@ -48,7 +47,7 @@ export const GET = defineApiRoute({
|
||||
id: response.id,
|
||||
},
|
||||
});
|
||||
throw new TRPCError({
|
||||
throw new APIError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Der gegebene refresh token ist nicht gültig.",
|
||||
});
|
||||
@@ -62,7 +61,7 @@ export const GET = defineApiRoute({
|
||||
// id: response.id
|
||||
// }
|
||||
// })
|
||||
// throw new TRPCError({ code: "BAD_REQUEST", message: "Der gegebene refresh token wurde von einer anderen IP-Adresse ausgestellt, aus Sicherheitsgründen haben wir uns entschieden diesen zu invalidieren." });
|
||||
// throw new APIError({ code: "BAD_REQUEST", message: "Der gegebene refresh token wurde von einer anderen IP-Adresse ausgestellt, aus Sicherheitsgründen haben wir uns entschieden diesen zu invalidieren." });
|
||||
// }
|
||||
|
||||
const user = await prisma.benutzer.findUnique({
|
||||
@@ -78,7 +77,7 @@ export const GET = defineApiRoute({
|
||||
id: response.id,
|
||||
},
|
||||
});
|
||||
throw new TRPCError({
|
||||
throw new APIError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Der gegebene refresh token ist nicht mehr gültig.",
|
||||
});
|
||||
|
||||
84
src/pages/api/bilder/[uid].ts
Normal file
84
src/pages/api/bilder/[uid].ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||
import { GebaeudeBilderSchema, prisma } from "@ibcornelsen/database/server";
|
||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||
import { z } from "zod";
|
||||
import isBase64 from "is-base64";
|
||||
import { fileURLToPath } from "url";
|
||||
import { writeFileSync } from "fs";
|
||||
import { UUidWithPrefix } from "#components/Ausweis/types.js";
|
||||
|
||||
export const PATCH = defineApiRoute({
|
||||
input: GebaeudeBilderSchema.pick({
|
||||
kategorie: true,
|
||||
}).merge(z.object({
|
||||
base64: z.string()
|
||||
})),
|
||||
output: z.void(),
|
||||
middleware: authorizationMiddleware,
|
||||
async fetch(input, ctx, user) {
|
||||
if (!UUidWithPrefix.safeParse(ctx.params.uid).success) {
|
||||
throw new APIError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "UID konnte nicht verifiziert werden."
|
||||
})
|
||||
}
|
||||
|
||||
const image = await prisma.gebaeudeBilder.findUnique({
|
||||
where: {
|
||||
uid: ctx.params.uid,
|
||||
objekt: {
|
||||
benutzer_id: user.id
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (!image) {
|
||||
throw new APIError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Bild existiert nicht oder gehört einem anderen Benutzer."
|
||||
})
|
||||
}
|
||||
|
||||
const base64 = input.base64;
|
||||
|
||||
if (!isBase64(base64, { mimeRequired: true })) {
|
||||
throw new APIError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Das Bild ist nicht base64.",
|
||||
});
|
||||
}
|
||||
|
||||
const dataWithoutPrefix = base64.replace(
|
||||
/^data:image\/\w+;base64,/,
|
||||
""
|
||||
);
|
||||
const buffer = Buffer.from(dataWithoutPrefix, "base64");
|
||||
|
||||
if (input.kategorie !== image.kategorie) {
|
||||
await prisma.gebaeudeBilder.update({
|
||||
where: {
|
||||
id: image.id
|
||||
},
|
||||
data: {
|
||||
kategorie: input.kategorie
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const filePath = fileURLToPath(new URL(`../../../../../persistent/images/${image.uid}.webp`, import.meta.url));
|
||||
|
||||
try {
|
||||
// Wir optimieren das Bild und konvertieren es in WebP
|
||||
// TODO: Sharp scheint nicht zu funktionieren, wir müssen das nochmal testen
|
||||
// const optimizedBuffer = await sharp(buffer).webp({ quality: 80 }).toArray();
|
||||
|
||||
writeFileSync(filePath, buffer)
|
||||
} catch(e) {
|
||||
// Und geben einen Fehler zurück
|
||||
throw new APIError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: "Bild konnte nicht gespeichert werden.",
|
||||
});
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -1,6 +1,6 @@
|
||||
import { OptionalNullable, UUidWithPrefix, VerbrauchsausweisWohnenClient, ZodOverlap } from "#components/Ausweis/types.js";
|
||||
import { exclude } from "#lib/exclude.js";
|
||||
import { authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||
import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||
import { prisma, VerbrauchsausweisWohnenSchema } from "@ibcornelsen/database/server";
|
||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||
import { z } from "zod";
|
||||
@@ -43,6 +43,101 @@ export const PATCH = defineApiRoute({
|
||||
},
|
||||
})
|
||||
|
||||
export const DELETE = defineApiRoute({
|
||||
meta: {
|
||||
description: "Storniert einen Ausweis"
|
||||
},
|
||||
headers: authorizationHeaders,
|
||||
middleware: authorizationMiddleware,
|
||||
async fetch(input, ctx, user) {
|
||||
const { uid } = ctx.params;
|
||||
|
||||
if (!UUidWithPrefix.safeParse(uid).success) {
|
||||
throw new APIError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "UID konnte nicht verifiziert werden."
|
||||
})
|
||||
}
|
||||
|
||||
// Wir holen uns den Verbrauchsausweis
|
||||
// Dieser MUSS mit dem Nutzer verknüpft sein.
|
||||
const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
|
||||
where: {
|
||||
uid,
|
||||
},
|
||||
include: {
|
||||
aufnahme: {
|
||||
select: {
|
||||
storniert: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!ausweis) {
|
||||
// Falls wir den Ausweis nicht finden können, werfen wir einen Fehler
|
||||
throw new APIError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Ausweis konnte nicht gefunden werden.",
|
||||
});
|
||||
}
|
||||
|
||||
// Wir dürfen den Ausweis nur stornieren, wenn er noch nicht ausgestellt wurde
|
||||
// Außerdem müssen wir schauen, ob wir Admin oder der Besitzer des Ausweises sind.
|
||||
if ((ausweis.benutzer_id !== user.id) && user.rolle !== "ADMIN") {
|
||||
// Falls der Ausweis nicht dem Nutzer gehört, werfen wir einen Fehler
|
||||
throw new APIError({
|
||||
code: "FORBIDDEN",
|
||||
message: "Ausweis gehört nicht dem Nutzer.",
|
||||
});
|
||||
}
|
||||
|
||||
// if (ausweis.erledigt) {
|
||||
// // Falls der Ausweis bereits ausgestellt wurde, werfen wir einen Fehler
|
||||
// throw new TRPCError({
|
||||
// code: "BAD_REQUEST",
|
||||
// message: "Ausweis wurde bereits ausgestellt.",
|
||||
// });
|
||||
// }
|
||||
|
||||
if (ausweis.aufnahme.storniert) {
|
||||
// Falls der Ausweis bereits storniert ist, werfen wir einen Fehler
|
||||
throw new APIError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Ausweis wurde bereits storniert.",
|
||||
});
|
||||
}
|
||||
|
||||
await prisma.aufnahme.update({
|
||||
where: {
|
||||
id: ausweis.aufnahme_id
|
||||
},
|
||||
data: {
|
||||
storniert: true
|
||||
}
|
||||
})
|
||||
|
||||
// Wir erstellen ein Event, dass der Ausweis storniert wurde
|
||||
// Dann können wir das in der Historie anzeigen
|
||||
await prisma.event.create({
|
||||
data: {
|
||||
title: "Ausweis storniert",
|
||||
description: ((user.rolle === "ADMIN") && (ausweis.benutzer_id !== user.id)) ? "Ausweis wurde von einem Administrator storniert." : "Ausweis wurde vom Besitzer storniert.",
|
||||
benutzer: {
|
||||
connect: {
|
||||
id: user.id
|
||||
}
|
||||
},
|
||||
aufnahme: {
|
||||
connect: {
|
||||
id: ausweis.aufnahme_id
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
export const GET = defineApiRoute({
|
||||
meta: {
|
||||
description: "Gibt ein spezifisches Gebäude des Benutzers zurück.",
|
||||
|
||||
Reference in New Issue
Block a user