From 9c5fa41162ea7829755abb76fc11ed34601b642a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Dec 2025 04:05:32 +0000 Subject: [PATCH] Fix: Allow password change in readonly mode by adding /auth/change-password to readonlyAllowPaths Co-authored-by: samanhappy <2755122+samanhappy@users.noreply.github.com> --- src/middlewares/auth.ts | 2 +- tests/middlewares/auth.readonly.test.ts | 59 +++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 tests/middlewares/auth.readonly.test.ts diff --git a/src/middlewares/auth.ts b/src/middlewares/auth.ts index 404ddde..b01d8c1 100644 --- a/src/middlewares/auth.ts +++ b/src/middlewares/auth.ts @@ -19,7 +19,7 @@ const validateBearerAuth = (req: Request, routingConfig: any): boolean => { return authHeader.substring(7) === routingConfig.bearerAuthKey; }; -const readonlyAllowPaths = ['/tools/call/']; +const readonlyAllowPaths = ['/tools/call/', '/auth/change-password']; const checkReadonly = (req: Request): boolean => { if (!defaultConfig.readonly) { diff --git a/tests/middlewares/auth.readonly.test.ts b/tests/middlewares/auth.readonly.test.ts new file mode 100644 index 0000000..04b1a63 --- /dev/null +++ b/tests/middlewares/auth.readonly.test.ts @@ -0,0 +1,59 @@ +// Tests for readonly mode in auth middleware +// Verifies that password change is allowed in readonly mode + +describe('Auth Readonly Mode Tests', () => { + // Test the readonlyAllowPaths configuration + describe('Readonly Allow Paths', () => { + // Simulate the checkReadonly logic + const readonlyAllowPaths = ['/tools/call/', '/auth/change-password']; + + const checkReadonlyPath = (path: string, method: string, basePath: string = ''): boolean => { + for (const allowedPath of readonlyAllowPaths) { + if (path.startsWith(basePath + allowedPath)) { + return true; + } + } + return method === 'GET'; + }; + + it('should allow /tools/call/ in readonly mode', () => { + const result = checkReadonlyPath('/tools/call/test', 'POST'); + expect(result).toBe(true); + }); + + it('should allow /auth/change-password in readonly mode', () => { + const result = checkReadonlyPath('/auth/change-password', 'POST'); + expect(result).toBe(true); + }); + + it('should allow GET requests in readonly mode', () => { + const result = checkReadonlyPath('/api/servers', 'GET'); + expect(result).toBe(true); + }); + + it('should block other POST requests in readonly mode', () => { + const result = checkReadonlyPath('/api/servers', 'POST'); + expect(result).toBe(false); + }); + + it('should block PUT requests in readonly mode', () => { + const result = checkReadonlyPath('/api/servers/1', 'PUT'); + expect(result).toBe(false); + }); + + it('should block DELETE requests in readonly mode', () => { + const result = checkReadonlyPath('/api/servers/1', 'DELETE'); + expect(result).toBe(false); + }); + + it('should work with base path for /auth/change-password', () => { + const result = checkReadonlyPath('/api/auth/change-password', 'POST', '/api'); + expect(result).toBe(true); + }); + + it('should work with base path for /tools/call/', () => { + const result = checkReadonlyPath('/api/tools/call/test', 'POST', '/api'); + expect(result).toBe(true); + }); + }); +});