feat(auth): add module read/write admin RBAC

Introduce permission catalog, PermissionsGuard, JWT/me payload with
role+permissions, and gate all module controllers. Admins CRUD accepts
role/permissions with safety rules; migrate existing users to super_admin.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-10 15:29:04 +03:30
co-authored by Cursor
parent 4b3a8a1d6c
commit af1e217a68
28 changed files with 532 additions and 75 deletions
+11 -1
View File
@@ -10,6 +10,8 @@ import {
UseGuards,
} from '@nestjs/common';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { PermissionsGuard } from '../auth/permissions.guard';
import { RequirePermissions } from '../auth/permissions.decorator';
import { CurrentUser } from '../auth/current-user.decorator';
import {
CreatePluginDto,
@@ -19,26 +21,30 @@ import {
import { PluginsService } from './plugins.service';
@Controller('plugins')
@UseGuards(JwtAuthGuard)
@UseGuards(JwtAuthGuard, PermissionsGuard)
export class PluginsController {
constructor(private readonly pluginsService: PluginsService) {}
@Get('tenants')
@RequirePermissions('plugins:read')
listTenants() {
return this.pluginsService.listTenants();
}
@Get('expiring')
@RequirePermissions('plugins:read')
expiring(@Query('limit') limit?: string) {
return this.pluginsService.getExpiringSoon(Number(limit) || 5);
}
@Get('tenants/:tenantId')
@RequirePermissions('plugins:read')
getTenantPlugins(@Param('tenantId') tenantId: string) {
return this.pluginsService.getTenantPlugins(tenantId);
}
@Post('tenants/:tenantId')
@RequirePermissions('plugins:write')
create(
@Param('tenantId') tenantId: string,
@Body() dto: CreatePluginDto,
@@ -48,11 +54,13 @@ export class PluginsController {
}
@Get('items/:id')
@RequirePermissions('plugins:read')
getOne(@Param('id') id: string) {
return this.pluginsService.getPlugin(id);
}
@Patch('items/:id')
@RequirePermissions('plugins:write')
update(
@Param('id') id: string,
@Body() dto: UpdatePluginDto,
@@ -62,6 +70,7 @@ export class PluginsController {
}
@Post('items/:id/renew')
@RequirePermissions('plugins:write')
renew(
@Param('id') id: string,
@Body() dto: RenewPluginDto,
@@ -71,6 +80,7 @@ export class PluginsController {
}
@Delete('items/:id')
@RequirePermissions('plugins:write')
remove(@Param('id') id: string, @CurrentUser() user: { id: string }) {
return this.pluginsService.remove(id, user.id);
}
+2 -1
View File
@@ -1,10 +1,11 @@
import { Module } from '@nestjs/common';
import { AuthModule } from '../auth/auth.module';
import { NotificationsModule } from '../notifications/notifications.module';
import { PluginsController } from './plugins.controller';
import { PluginsService } from './plugins.service';
@Module({
imports: [NotificationsModule],
imports: [NotificationsModule, AuthModule],
controllers: [PluginsController],
providers: [PluginsService],
exports: [PluginsService],