fix: get volume if short id is only numbers

This commit is contained in:
Nicolas Meienberger
2026-02-08 16:33:32 +01:00
parent 09c1cbbb94
commit 2d0ae89727
2 changed files with 82 additions and 2 deletions

View File

@@ -9,6 +9,87 @@ import path from "node:path";
import { createTestSession } from "~/test/helpers/auth";
import { withContext } from "~/server/core/request-context";
describe("volumeService", () => {
describe("findVolume", () => {
test("should find volume by numeric id", async () => {
const { organizationId, user } = await createTestSession();
const [volume] = await db
.insert(volumesTable)
.values({
shortId: randomUUID().slice(0, 8),
name: `test-vol-${randomUUID().slice(0, 8)}`,
type: "directory",
status: "mounted",
config: { backend: "directory", path: "/" },
autoRemount: true,
organizationId,
})
.returning();
await withContext({ organizationId, userId: user.id }, async () => {
const result = await volumeService.getVolume(String(volume.id));
expect(result.volume.id).toBe(volume.id);
expect(result.volume.shortId).toBe(volume.shortId);
});
});
test("should find volume by shortId", async () => {
const { organizationId, user } = await createTestSession();
const [volume] = await db
.insert(volumesTable)
.values({
shortId: "test1234",
name: `test-vol-${randomUUID().slice(0, 8)}`,
type: "directory",
status: "mounted",
config: { backend: "directory", path: "/" },
autoRemount: true,
organizationId,
})
.returning();
await withContext({ organizationId, userId: user.id }, async () => {
const result = await volumeService.getVolume(volume.shortId);
expect(result.volume.id).toBe(volume.id);
expect(result.volume.shortId).toBe(volume.shortId);
});
});
test("should find volume by numeric-looking shortId", async () => {
const { organizationId, user } = await createTestSession();
const [volume] = await db
.insert(volumesTable)
.values({
shortId: "499780",
name: `test-vol-${randomUUID().slice(0, 8)}`,
type: "directory",
status: "mounted",
config: { backend: "directory", path: "/" },
autoRemount: true,
organizationId,
})
.returning();
await withContext({ organizationId, userId: user.id }, async () => {
const result = await volumeService.getVolume("499780");
expect(result.volume.id).toBe(volume.id);
expect(result.volume.shortId).toBe("499780");
});
});
test("should throw NotFoundError for non-existent volume", async () => {
const { organizationId, user } = await createTestSession();
await withContext({ organizationId, userId: user.id }, async () => {
expect(volumeService.getVolume("nonexistent")).rejects.toThrow("Volume not found");
});
});
});
});
describe("volumeService security", () => {
describe("path traversal", () => {
test("should reject traversal outside the volume root in listFiles", async () => {

View File

@@ -54,11 +54,10 @@ const listVolumes = async () => {
const findVolume = async (idOrShortId: string | number) => {
const organizationId = getOrganizationId();
const isNumeric = typeof idOrShortId === "number" || /^\d+$/.test(String(idOrShortId));
return await db.query.volumesTable.findFirst({
where: {
AND: [
isNumeric ? { id: Number(idOrShortId) } : { shortId: String(idOrShortId) },
{ OR: [{ id: Number(idOrShortId) }, { shortId: String(idOrShortId) }] },
{ organizationId: organizationId },
],
},