Added Backend
This commit is contained in:
41
backend/src/routes/publiclinks/publiclinks-authenticated.ts
Normal file
41
backend/src/routes/publiclinks/publiclinks-authenticated.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { FastifyRequest, FastifyReply, FastifyInstance } from 'fastify';
|
||||
import { publicLinkService } from '../../modules/publiclinks.service';
|
||||
|
||||
|
||||
export default async function publiclinksAuthenticatedRoutes(server: FastifyInstance) {
|
||||
server.post("/publiclinks", async (req, reply) => {
|
||||
try {
|
||||
const tenantId = 21; // Hardcoded für Test, später: req.user.tenantId
|
||||
|
||||
const { name, isProtected, pin, customToken, config, defaultProfileId } = req.body as { name:string, isProtected:boolean, pin:string, customToken:string, config:Object, defaultProfileId:string};
|
||||
|
||||
const newLink = await publicLinkService.createLink(server, tenantId,
|
||||
name,
|
||||
isProtected,
|
||||
pin,
|
||||
customToken,
|
||||
config,
|
||||
defaultProfileId);
|
||||
|
||||
return reply.code(201).send({
|
||||
success: true,
|
||||
data: {
|
||||
id: newLink.id,
|
||||
token: newLink.token,
|
||||
fullUrl: `/public/${newLink.token}`, // Helper für Frontend
|
||||
isProtected: newLink.isProtected
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error: any) {
|
||||
server.log.error(error);
|
||||
|
||||
// Einfache Fehlerbehandlung
|
||||
if (error.message.includes("bereits vergeben")) {
|
||||
return reply.code(409).send({ error: error.message });
|
||||
}
|
||||
|
||||
return reply.code(500).send({ error: "Fehler beim Erstellen des Links", details: error.message });
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import { FastifyRequest, FastifyReply, FastifyInstance } from 'fastify';
|
||||
import { publicLinkService } from '../../modules/publiclinks.service';
|
||||
|
||||
|
||||
export default async function publiclinksNonAuthenticatedRoutes(server: FastifyInstance) {
|
||||
server.get("/workflows/context/:token", async (req, reply) => {
|
||||
const { token } = req.params as { token: string };
|
||||
|
||||
// Wir lesen die PIN aus dem Header (Best Practice für Security)
|
||||
const pin = req.headers['x-public-pin'] as string | undefined;
|
||||
|
||||
try {
|
||||
const context = await publicLinkService.getLinkContext(server, token, pin);
|
||||
|
||||
return reply.send(context);
|
||||
|
||||
} catch (error: any) {
|
||||
// Spezifische Fehlercodes für das Frontend
|
||||
if (error.message === "Link_NotFound") {
|
||||
return reply.code(404).send({ error: "Link nicht gefunden oder abgelaufen" });
|
||||
}
|
||||
|
||||
if (error.message === "Pin_Required") {
|
||||
return reply.code(401).send({
|
||||
error: "PIN erforderlich",
|
||||
code: "PIN_REQUIRED",
|
||||
requirePin: true
|
||||
});
|
||||
}
|
||||
|
||||
if (error.message === "Pin_Invalid") {
|
||||
return reply.code(403).send({
|
||||
error: "PIN falsch",
|
||||
code: "PIN_INVALID",
|
||||
requirePin: true
|
||||
});
|
||||
}
|
||||
|
||||
server.log.error(error);
|
||||
return reply.code(500).send({ error: "Interner Server Fehler" });
|
||||
}
|
||||
});
|
||||
|
||||
server.post("/workflows/submit/:token", async (req, reply) => {
|
||||
const { token } = req.params as { token: string };
|
||||
// PIN sicher aus dem Header lesen
|
||||
const pin = req.headers['x-public-pin'] as string | undefined;
|
||||
// Der Body enthält { profile, project, service, ... }
|
||||
const payload = req.body;
|
||||
|
||||
console.log(payload)
|
||||
|
||||
try {
|
||||
// Service aufrufen (führt die 3 Schritte aus: Lieferschein -> Zeit -> History)
|
||||
const result = await publicLinkService.submitFormData(server, token, payload, pin);
|
||||
|
||||
// 201 Created zurückgeben
|
||||
return reply.code(201).send(result);
|
||||
|
||||
} catch (error: any) {
|
||||
console.log(error);
|
||||
|
||||
// Fehler-Mapping für saubere HTTP Codes
|
||||
if (error.message === "Link_NotFound") {
|
||||
return reply.code(404).send({ error: "Link ungültig oder nicht aktiv" });
|
||||
}
|
||||
|
||||
if (error.message === "Pin_Required") {
|
||||
return reply.code(401).send({ error: "PIN erforderlich" });
|
||||
}
|
||||
|
||||
if (error.message === "Pin_Invalid") {
|
||||
return reply.code(403).send({ error: "PIN ist falsch" });
|
||||
}
|
||||
|
||||
if (error.message === "Profile_Missing") {
|
||||
return reply.code(400).send({ error: "Kein Mitarbeiter-Profil gefunden (weder im Link noch in der Eingabe)" });
|
||||
}
|
||||
|
||||
if (error.message === "Project not found" || error.message === "Service not found") {
|
||||
return reply.code(400).send({ error: "Ausgewähltes Projekt oder Leistung existiert nicht mehr." });
|
||||
}
|
||||
|
||||
// Fallback für alle anderen Fehler (z.B. DB Constraints)
|
||||
return reply.code(500).send({
|
||||
error: "Interner Fehler beim Speichern",
|
||||
details: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user