Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions src/handlers/unknown.js

This file was deleted.

15 changes: 12 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import headHandler from './handlers/head.js';
import getHandler from './handlers/get.js';
import postHandler from './handlers/post.js';
import deleteHandler from './handlers/delete.js';
import unknownHandler from './handlers/unknown.js';

export default {
/**
Expand All @@ -29,7 +28,17 @@ export default {
return daResp({ status: 204 });
}

const daCtx = await getDaCtx(req, env);
let daCtx;
try {
daCtx = await getDaCtx(req, env);
} catch (e) {
if (e.message === 'Invalid path') {
return daResp({ status: 400 });
}
console.error('Error computing context', e);
return daResp({ status: 500 });
}

const { authorized, key } = daCtx;
if (!authorized) {
const status = daCtx.users[0].email === 'anonymous' ? 401 : 403;
Expand Down Expand Up @@ -57,7 +66,7 @@ export default {
respObj = await deleteHandler({ req, env, daCtx });
break;
default:
respObj = unknownHandler();
respObj = { status: 405 };
}

if (!respObj) return daResp({ status: 404 });
Expand Down
7 changes: 7 additions & 0 deletions src/utils/daCtx.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ export default async function getDaCtx(req, env) {
const path = parts.filter((part) => part !== '');
const keyBase = path.join('/');

const pnlc = pathname.toLocaleLowerCase();
const validPath = `/${api}/${org}/${keyBase}`;

if (!org || !(pnlc === validPath || pnlc === `${validPath}/`)) {
throw new Error('Invalid path');
}

// Get the final source name
daCtx.filename = path.pop() || '';

Expand Down
21 changes: 0 additions & 21 deletions test/handlers/unknown.test.js

This file was deleted.

37 changes: 33 additions & 4 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('fetch', () => {

it('should return a response object for unknown', async () => {
const resp = await handler.fetch({ url: 'https://www.example.com', method: 'BLAH' }, {});
assert.strictEqual(resp.status, 501);
assert.strictEqual(resp.status, 400);
});

it('should return 401 when not authorized and not logged in', async () => {
Expand All @@ -49,9 +49,38 @@ describe('fetch', () => {
const resp = await hnd.fetch({ method: 'GET' }, {});
assert.strictEqual(resp.status, 403);
});
});

describe('invalid routes', () => {
const fetchStatus = async (path, method) => {
const resp = await handler.fetch({ method, url: `http://www.sample.com${path}` }, {});
return resp.status;
};

const test = async (path, status) => {
const methods = ['GET', 'POST', 'PUT', 'DELETE'];
for (const method of methods) {
// eslint-disable-next-line no-await-in-loop
const s = await fetchStatus(path, method);
assert.strictEqual(s, status);
}
};

it('return 400 for invalid paths', async () => {
await test('/', 400);
await test('/source/owner', 400);
await test('/source//owner/repo/path/file.html', 400);
await test('/source/owner//repo/path/file.html', 400);
await test('/source/owner/repo//path/file.html', 400);
await test('/source/owner/repo/path//file.html', 400);
});

it('return 404 for unknown paths', async () => {
await test('/unknown/owner/repo/path/file.html', 404);
});

it('return 404 for unknown get route', async () => {
const resp = await handler.fetch({ method: 'GET', url: 'http://www.example.com/' }, {});
assert.strictEqual(resp.status, 404);
it('return 405 for unknown methods', async () => {
const status = await fetchStatus('/source/owner/repo/path/file.html', 'BLAH');
assert.strictEqual(status, 405);
});
});
25 changes: 10 additions & 15 deletions test/storage/utils/list.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import assert from 'node:assert';
import sinon from 'sinon';

import getDaCtx from '../../../src/utils/daCtx.js';
import formatList, { listCommand } from '../../../src/storage/utils/list.js';

const MOCK = {
Expand Down Expand Up @@ -61,12 +60,8 @@ const MOCK = {
],
};

const req = new Request('https://example.com/source/adobecom');

const daCtx = getDaCtx(req, {});
Comment thread
kptdobe marked this conversation as resolved.

describe('Format object list', () => {
const list = formatList(MOCK, daCtx);
const list = formatList(MOCK);

it('should return a true folder / common prefix', () => {
assert.strictEqual(list[0].name, 'blog');
Expand Down Expand Up @@ -98,21 +93,21 @@ describe('Format object list', () => {

it('should handle empty CommonPrefixes', () => {
const emptyMock = { Contents: MOCK.Contents };
const result = formatList(emptyMock, daCtx);
const result = formatList(emptyMock);
assert(Array.isArray(result));
assert(result.length > 0);
});

it('should handle empty Contents', () => {
const emptyMock = { CommonPrefixes: MOCK.CommonPrefixes };
const result = formatList(emptyMock, daCtx);
const result = formatList(emptyMock);
assert(Array.isArray(result));
assert(result.length > 0);
});

it('should handle both empty CommonPrefixes and Contents', () => {
const emptyMock = {};
const result = formatList(emptyMock, daCtx);
const result = formatList(emptyMock);
assert(Array.isArray(result));
assert.strictEqual(result.length, 0);
});
Expand All @@ -124,7 +119,7 @@ describe('Format object list', () => {
{ Prefix: 'normal-folder/' },
],
};
const result = formatList(mockWithExtensionFolder, daCtx);
const result = formatList(mockWithExtensionFolder);
const extensionFolder = result.find((item) => item.name === 'file.jpg');
assert.strictEqual(extensionFolder, undefined);
const normalFolder = result.find((item) => item.name === 'normal-folder');
Expand All @@ -140,7 +135,7 @@ describe('Format object list', () => {
},
],
};
const result = formatList(mockWithComplexFile, daCtx);
const result = formatList(mockWithComplexFile);
assert.strictEqual(result.length, 0);
});

Expand All @@ -153,7 +148,7 @@ describe('Format object list', () => {
},
],
};
const result = formatList(mockWithHiddenFile, daCtx);
const result = formatList(mockWithHiddenFile);
assert.strictEqual(result.length, 0);
});

Expand All @@ -166,7 +161,7 @@ describe('Format object list', () => {
},
],
};
const result = formatList(mockWithProps, daCtx);
const result = formatList(mockWithProps);
const propsItem = result.find((item) => item.name === 'test');
assert(propsItem);
assert.strictEqual(propsItem.ext, undefined);
Expand All @@ -183,7 +178,7 @@ describe('Format object list', () => {
},
],
};
const result = formatList(mockWithBoth, daCtx);
const result = formatList(mockWithBoth);
const testItems = result.filter((item) => item.name === 'test');
assert.strictEqual(testItems.length, 1);
});
Expand All @@ -196,7 +191,7 @@ describe('Format object list', () => {
{ Key: 'beta.html', LastModified: new Date('2025-01-01') },
],
};
const result = formatList(mockForSorting, daCtx);
const result = formatList(mockForSorting);
assert.strictEqual(result[0].name, 'alpha');
assert.strictEqual(result[1].name, 'beta');
assert.strictEqual(result[2].name, 'zebra');
Expand Down