mirror of
https://github.com/open-reception/appointment-booking-software.git
synced 2026-09-29 20:24:50 +02:00
Refactor/error and api handling (#82)
* DB migrations * Format errors in migrations * Implemented new error and permission handling. * Updated and fixed tests * Update src/routes/api/tenants/[id]/appointments/[appointmentId]/cancel/+server.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/routes/api/tenants/[id]/agents/[agentId]/absences/[absenceId]/+server.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/routes/api/tenants/[id]/channels/+server.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fixed test * Added error constants --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,17 @@
|
||||
import { ERRORS } from "$lib/errors";
|
||||
import type { UniversalLogger } from "$lib/logger";
|
||||
import { json } from "@sveltejs/kit";
|
||||
|
||||
export const logError =
|
||||
(logger: UniversalLogger) =>
|
||||
(message: string, error: unknown, requestedBy?: string, tenantId?: string) => {
|
||||
logger.error(message, {
|
||||
tenantId,
|
||||
requestedBy,
|
||||
error: JSON.stringify(error || "?"),
|
||||
});
|
||||
};
|
||||
|
||||
export class BackendError extends Error {
|
||||
constructor(
|
||||
message: string,
|
||||
@@ -8,13 +20,23 @@ export class BackendError extends Error {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public toJson = () => json({ message: this.message }, { status: this.code });
|
||||
public toJson = () => json({ error: this.message, message: this.message }, { status: this.code });
|
||||
}
|
||||
|
||||
export class AuthorizationError extends BackendError {
|
||||
constructor(
|
||||
message: string = ERRORS.SECURITY.AUTHORIZATION_FAILED,
|
||||
public code = 403,
|
||||
) {
|
||||
super(message, code);
|
||||
this.name = "AuthorizationError";
|
||||
}
|
||||
}
|
||||
|
||||
export class AuthenticationError extends BackendError {
|
||||
constructor(
|
||||
message: string,
|
||||
public code = 403,
|
||||
message: string = ERRORS.SECURITY.AUTHENTICATION_REQUIRED,
|
||||
public code = 401,
|
||||
) {
|
||||
super(message, code);
|
||||
this.name = "AuthenticationError";
|
||||
@@ -50,3 +72,13 @@ export class ConflictError extends BackendError {
|
||||
this.name = "ConflictError";
|
||||
}
|
||||
}
|
||||
|
||||
export class InternalError extends BackendError {
|
||||
constructor(
|
||||
message: string = ERRORS.BACKEND.OBFUSCATED,
|
||||
public code = 500,
|
||||
) {
|
||||
super(message, code);
|
||||
this.name = "InternalError";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { json } from "@sveltejs/kit";
|
||||
import { AuthenticationError, AuthorizationError } from "./errors";
|
||||
|
||||
/**
|
||||
* Check whether the user can access the data within a route.
|
||||
@@ -10,29 +10,32 @@ export const checkPermission = (
|
||||
locals: App.Locals,
|
||||
tenantId: string | null,
|
||||
administrative: boolean = false,
|
||||
): Response | null => {
|
||||
global: boolean = false,
|
||||
): void => {
|
||||
if (!locals.user) {
|
||||
return json({ error: "Authentication required" }, { status: 401 });
|
||||
throw new AuthenticationError();
|
||||
}
|
||||
if (locals.user.role === "GLOBAL_ADMIN") {
|
||||
// Global admin can view absences for any tenant
|
||||
return null;
|
||||
return;
|
||||
} else if (
|
||||
!global &&
|
||||
locals.user.role === "TENANT_ADMIN" &&
|
||||
tenantId != null &&
|
||||
locals.user.tenantId === tenantId
|
||||
) {
|
||||
// Tenant admin and staff can view absences for their own tenant
|
||||
return null;
|
||||
return;
|
||||
} else if (
|
||||
!global &&
|
||||
!administrative &&
|
||||
locals.user.role === "STAFF" &&
|
||||
tenantId != null &&
|
||||
locals.user.tenantId === tenantId
|
||||
) {
|
||||
// Tenant admin and staff can view absences for their own tenant
|
||||
return null;
|
||||
return;
|
||||
} else {
|
||||
return json({ error: "Insufficient permissions" }, { status: 403 });
|
||||
throw new AuthorizationError();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user