fix: get volume if short id is only numbers
Some checks failed
Release Workflow / determine-release-type (push) Has been cancelled
Release Workflow / checks (push) Has been cancelled
Release Workflow / e2e-tests (push) Has been cancelled
Release Workflow / build-images (push) Has been cancelled
Release Workflow / publish-release (push) Has been cancelled
Some checks failed
Release Workflow / determine-release-type (push) Has been cancelled
Release Workflow / checks (push) Has been cancelled
Release Workflow / e2e-tests (push) Has been cancelled
Release Workflow / build-images (push) Has been cancelled
Release Workflow / publish-release (push) Has been cancelled
This commit is contained in:
parent
09c1cbbb94
commit
2d0ae89727
2 changed files with 82 additions and 2 deletions
|
|
@ -9,6 +9,87 @@ import path from "node:path";
|
||||||
import { createTestSession } from "~/test/helpers/auth";
|
import { createTestSession } from "~/test/helpers/auth";
|
||||||
import { withContext } from "~/server/core/request-context";
|
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("volumeService security", () => {
|
||||||
describe("path traversal", () => {
|
describe("path traversal", () => {
|
||||||
test("should reject traversal outside the volume root in listFiles", async () => {
|
test("should reject traversal outside the volume root in listFiles", async () => {
|
||||||
|
|
|
||||||
|
|
@ -54,11 +54,10 @@ const listVolumes = async () => {
|
||||||
|
|
||||||
const findVolume = async (idOrShortId: string | number) => {
|
const findVolume = async (idOrShortId: string | number) => {
|
||||||
const organizationId = getOrganizationId();
|
const organizationId = getOrganizationId();
|
||||||
const isNumeric = typeof idOrShortId === "number" || /^\d+$/.test(String(idOrShortId));
|
|
||||||
return await db.query.volumesTable.findFirst({
|
return await db.query.volumesTable.findFirst({
|
||||||
where: {
|
where: {
|
||||||
AND: [
|
AND: [
|
||||||
isNumeric ? { id: Number(idOrShortId) } : { shortId: String(idOrShortId) },
|
{ OR: [{ id: Number(idOrShortId) }, { shortId: String(idOrShortId) }] },
|
||||||
{ organizationId: organizationId },
|
{ organizationId: organizationId },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue