unused-vars (25): leftover imports/types across pages, routes and services; write-only sickHours accumulator; unused holidayCount pair; test helpers authPatch/authDelete; TOut dropped from ApiMutationOptions (the hook keeps its own generic — no call-site changes); requireAuth no longer importable in customers/warehouse routes (matches the no-bare-auth-reads convention). useless-assignment (5): initializers proven overwritten on every path (systemQty x2, hours, writtenSize -> let x: number) and the seed's dead adminUser reassignment (create kept, assignment dropped). useless-escape (4): [eE+\-] -> [eE+-] and [\/...] -> [/...] — identical semantics. Behavior-neutral; lint 102 -> 68 warnings (0 errors), suite 641 green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
78 lines
2.0 KiB
TypeScript
78 lines
2.0 KiB
TypeScript
import { FastifyRequest, FastifyReply } from "fastify";
|
|
import { verifyAccessToken } from "../services/auth";
|
|
import { error } from "../utils/response";
|
|
|
|
export async function requireAuth(
|
|
request: FastifyRequest,
|
|
reply: FastifyReply,
|
|
): Promise<void> {
|
|
const authHeader = request.headers.authorization;
|
|
if (!authHeader?.startsWith("Bearer ")) {
|
|
return error(reply, "Vyžadována autentizace", 401);
|
|
}
|
|
|
|
const token = authHeader.slice(7);
|
|
const authData = await verifyAccessToken(token);
|
|
|
|
if (!authData) {
|
|
return error(reply, "Neplatný nebo expirovaný token", 401);
|
|
}
|
|
|
|
request.authData = authData;
|
|
}
|
|
|
|
export async function optionalAuth(
|
|
request: FastifyRequest,
|
|
_reply: FastifyReply,
|
|
): Promise<void> {
|
|
const authHeader = request.headers.authorization;
|
|
if (!authHeader?.startsWith("Bearer ")) return;
|
|
|
|
const token = authHeader.slice(7);
|
|
request.authData = (await verifyAccessToken(token)) ?? undefined;
|
|
}
|
|
|
|
export function requirePermission(...permissionNames: string[]) {
|
|
return async (
|
|
request: FastifyRequest,
|
|
reply: FastifyReply,
|
|
): Promise<void> => {
|
|
await requireAuth(request, reply);
|
|
if (reply.sent) return;
|
|
|
|
const authData = request.authData!;
|
|
|
|
// Admin has all permissions
|
|
if (authData.roleName === "admin") return;
|
|
|
|
const hasAll = permissionNames.every((p) =>
|
|
authData.permissions.includes(p),
|
|
);
|
|
if (!hasAll) {
|
|
return error(reply, "Nedostatečná oprávnění", 403);
|
|
}
|
|
};
|
|
}
|
|
|
|
export function requireAnyPermission(...permissionNames: string[]) {
|
|
return async (
|
|
request: FastifyRequest,
|
|
reply: FastifyReply,
|
|
): Promise<void> => {
|
|
await requireAuth(request, reply);
|
|
if (reply.sent) return;
|
|
|
|
const authData = request.authData!;
|
|
|
|
// Admin has all permissions
|
|
if (authData.roleName === "admin") return;
|
|
|
|
const hasAny = permissionNames.some((p) =>
|
|
authData.permissions.includes(p),
|
|
);
|
|
if (!hasAny) {
|
|
return error(reply, "Nedostatečná oprávnění", 403);
|
|
}
|
|
};
|
|
}
|