From 213b51e5984c42a4509fffc4dd26e2f03ec7c722 Mon Sep 17 00:00:00 2001 From: Berg Pinheiro Date: Tue, 24 Feb 2026 03:06:06 -0300 Subject: [PATCH] [core] Fix apps GET/PUT/DELETE 403 by adding CheckPolicies guard (#1927) Add @CheckPolicies(CanServer(Action.Read)) to GET, PUT, and DELETE /:id endpoints so the PoliciesGuard has an explicit policy instead of throwing when no handler is present. Session name is not available at guard time for these routes, so the guard only enforces server-level read; handlers continue to enforce Action.Use on the app's session via req.ability?.can(). Fix #1926 Co-authored-by: Cursor --- src/apps/app_sdk/api/apps.controller.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/apps/app_sdk/api/apps.controller.ts b/src/apps/app_sdk/api/apps.controller.ts index 5bd818ce..bc0f6c7d 100644 --- a/src/apps/app_sdk/api/apps.controller.ts +++ b/src/apps/app_sdk/api/apps.controller.ts @@ -22,7 +22,12 @@ import { import { SessionManager } from '@waha/core/abc/manager.abc'; import { CheckPolicies } from '@waha/core/auth/policies.decorator'; import { PoliciesGuard } from '@waha/core/auth/policies.guard'; -import { CanSession, FromBody, FromQuery } from '@waha/core/auth/policies'; +import { + CanServer, + CanSession, + FromBody, + FromQuery, +} from '@waha/core/auth/policies'; import { Action, session as SessionName } from '@waha/core/auth/casl.types'; import { WAHAValidationPipe } from '@waha/nestjs/pipes/WAHAValidationPipe'; @@ -65,6 +70,7 @@ export class AppsController { @Get('/:id') @ApiOperation({ summary: 'Get app by ID' }) + @CheckPolicies(CanServer(Action.Read)) @UsePipes(new WAHAValidationPipe()) async get(@Param('id') id: string, @Req() req: any): Promise { const app = await this.appsService.get(this.manager, id); @@ -79,6 +85,7 @@ export class AppsController { @Put('/:id') @ApiOperation({ summary: 'Update an existing app' }) + @CheckPolicies(CanServer(Action.Read)) @UsePipes(new WAHAValidationPipe()) async update( @Param('id') id: string, @@ -114,6 +121,7 @@ export class AppsController { @Delete('/:id') @ApiOperation({ summary: 'Delete an app' }) + @CheckPolicies(CanServer(Action.Read)) @UsePipes(new WAHAValidationPipe()) async delete(@Param('id') id: string, @Req() req: any): Promise { const existing = await this.appsService.get(this.manager, id);