mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-20 09:09:35 +02:00
Merge pull request #567: fix(cases): only refuse the cases folder and its direct children for a custom-folder case
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
7504a2bc8b
5 files changed
+50
-6
No files matched your search
+16
-1
@@ -54,14 +54,29 @@ describe('blockedReason', () => {
|
||||
expect(blockedReason('/usrlocal', c)).toBeNull();
|
||||
});
|
||||
|
||||
it('refuses a cases directory and anything inside it, when given', () => {
|
||||
it('refuses a cases directory and its direct children, when given', () => {
|
||||
const withCases = { ...c, casesDirs: ['/home/u/codeman-cases'] };
|
||||
expect(blockedReason('/home/u/codeman-cases', withCases)).toMatch(/plain Create New/);
|
||||
expect(blockedReason('/home/u/codeman-cases/foo', withCases)).toMatch(/plain Create New/);
|
||||
expect(blockedReason('/home/u/codeman-cases/foo', withCases)).toContain('/home/u/codeman-cases');
|
||||
// Two messages: the cases folder is not "in" itself, and a child that does not exist yet is not
|
||||
// "already" listed.
|
||||
expect(blockedReason('/home/u/codeman-cases', withCases)).toMatch(/cases folder itself/);
|
||||
expect(blockedReason('/home/u/codeman-cases/foo', withCases)).toMatch(/directly in the cases folder/);
|
||||
expect(blockedReason('/home/u/codeman-cases/foo', withCases)).not.toMatch(/already/);
|
||||
expect(blockedReason('/home/u/codeman-cases-old/foo', withCases)).toBeNull();
|
||||
expect(blockedReason('/home/u/codeman-cases/foo', c)).toBeNull();
|
||||
});
|
||||
|
||||
it('allows a folder deeper than a direct child of the cases directory (it is not listed as a local case)', () => {
|
||||
// CODEMAN_CASES_PATH can be a broad root such as /mnt/user/Scripts; GET /api/cases lists only its
|
||||
// direct children, so a folder further down can be linked without appearing twice.
|
||||
const broad = { ...c, casesDirs: ['/mnt/user/Scripts'] };
|
||||
expect(blockedReason('/mnt/user/Scripts/GitHub', broad)).toMatch(/plain Create New/);
|
||||
expect(blockedReason('/mnt/user/Scripts/GitHub/opticon454', broad)).toBeNull();
|
||||
expect(blockedReason('/mnt/user/Scripts/GitHub/opticon454/app', broad)).toBeNull();
|
||||
});
|
||||
|
||||
it('judges against the system roots it is given', () => {
|
||||
expect(blockedReason('/private/etc/x', c)).toBeNull();
|
||||
expect(blockedReason('/private/etc/x', c, ['/private/etc'])).toMatch(/system directory/);
|
||||
|
||||
@@ -183,6 +183,21 @@ describe('POST /api/cases with a custom path', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('creates and links a folder two levels under the cases directory (not listed as a local case)', async () => {
|
||||
const { app } = await createRouteTestHarness(registerCaseRoutes);
|
||||
mkdirSync(join(CASES_DIR(), 'parent-dir'), { recursive: true });
|
||||
try {
|
||||
const target = join(realpathSync(join(CASES_DIR(), 'parent-dir')), 'nested');
|
||||
const res = await create(app, { name: 'nested', path: target });
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res.json().data.case).toEqual({ name: 'nested', path: target });
|
||||
expect(linked()).toEqual({ nested: target });
|
||||
expect(existsSync(join(target, 'CLAUDE.md'))).toBe(true);
|
||||
} finally {
|
||||
safeRmHomeTree(join(CASES_DIR(), 'parent-dir'));
|
||||
}
|
||||
});
|
||||
|
||||
it('multi-user: a non-admin is refused (403) and nothing is created; an admin is allowed', async () => {
|
||||
process.env.CODEMAN_MULTIUSER = '1';
|
||||
const user = await createRouteTestHarness(registerCaseRoutes, { authUser: { username: 'bob', role: 'user' } });
|
||||
|
||||
Reference in new issue
Block a user