Project quality audit (#2758)

* Harden security, health checks, and dependency hygiene

Co-authored-by: Amruth Pillai <im.amruth@gmail.com>

* Finalize health and storage hardening adjustments

Co-authored-by: Amruth Pillai <im.amruth@gmail.com>

* remove use of [REDACTED]

* update dependencies

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
This commit is contained in:
Amruth Pillai
2026-02-28 01:14:02 +01:00
committed by GitHub
parent c25c068d20
commit b7e4c86f4e
21 changed files with 1313 additions and 3328 deletions
+7 -3
View File
@@ -18,7 +18,7 @@ export const printerRouter = {
.input(z.object({ id: z.string().describe("The unique identifier of the resume to export.") }))
.output(z.object({ url: z.string().describe("The URL to download the generated PDF file.") }))
.handler(async ({ input, context }) => {
const { id, data, userId } = await resumeService.getByIdForPrinter({ id: input.id });
const { id, data, userId } = await resumeService.getByIdForPrinter({ id: input.id, userId: context.user?.id });
const url = await printerService.printResumeAsPDF({ id, data, userId });
if (!context.user) {
@@ -41,9 +41,13 @@ export const printerRouter = {
})
.input(z.object({ id: z.string().describe("The unique identifier of the resume.") }))
.output(z.object({ url: z.string().nullable().describe("The URL to the screenshot image, or null.") }))
.handler(async ({ input }) => {
.handler(async ({ context, input }) => {
try {
const { id, data, userId, updatedAt } = await resumeService.getByIdForPrinter({ id: input.id });
const { id, data, userId, updatedAt } = await resumeService.getByIdForPrinter({
id: input.id,
userId: context.user.id,
});
const url = await printerService.getResumeScreenshot({ id, data, userId, updatedAt });
return { url };
+21 -5
View File
@@ -11,6 +11,14 @@ const filenameSchema = z.object({
filename: z.string().min(1).describe("The path or filename of the file to delete."),
});
function normalizeKey(input: string): string {
return input.trim().replace(/^\/+/, "").split("/").filter(Boolean).join("/");
}
function isUnsafeStorageKey(key: string): boolean {
return key.split("/").some((segment) => segment === "." || segment === "..");
}
export const storageRouter = {
uploadFile: protectedProcedure
.route({
@@ -76,13 +84,21 @@ export const storageRouter = {
message: "The specified file was not found in storage.",
status: 404,
},
FORBIDDEN: {
message: "You do not have permission to delete this file.",
status: 403,
},
})
.handler(async ({ context, input }): Promise<void> => {
// The filename is now the full path from the URL (e.g., "uploads/userId/pictures/timestamp.ext")
// We need to extract just the path portion that matches the storage key
const key = input.filename.startsWith("uploads/")
? input.filename
: `uploads/${context.user.id}/pictures/${input.filename}`;
const requestedKey = normalizeKey(input.filename);
const key = requestedKey.startsWith("uploads/")
? requestedKey
: normalizeKey(`uploads/${context.user.id}/pictures/${requestedKey}`);
const userPrefix = `uploads/${context.user.id}/`;
if (isUnsafeStorageKey(key) || !key.startsWith(userPrefix)) {
throw new ORPCError("FORBIDDEN");
}
const deleted = await storageService.delete(key);