fix(agent): scope instance list to requesting user (multi-user isolation)
GET /api/v1/agent/instances was returning all instances regardless of user. Now decodes JWT: non-admin users only see their own instances; admins see all. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f186c57afb
commit
29c433c7c3
|
|
@ -6,9 +6,11 @@ import {
|
||||||
Delete,
|
Delete,
|
||||||
Body,
|
Body,
|
||||||
Param,
|
Param,
|
||||||
|
Req,
|
||||||
NotFoundException,
|
NotFoundException,
|
||||||
BadRequestException,
|
BadRequestException,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
import { Request } from 'express';
|
||||||
import * as crypto from 'crypto';
|
import * as crypto from 'crypto';
|
||||||
import { AgentInstanceRepository } from '../../../infrastructure/repositories/agent-instance.repository';
|
import { AgentInstanceRepository } from '../../../infrastructure/repositories/agent-instance.repository';
|
||||||
import { AgentInstanceDeployService } from '../../../infrastructure/services/agent-instance-deploy.service';
|
import { AgentInstanceDeployService } from '../../../infrastructure/services/agent-instance-deploy.service';
|
||||||
|
|
@ -28,9 +30,17 @@ export class AgentInstanceController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
async list() {
|
async list(@Req() req: Request) {
|
||||||
|
const jwt = this.decodeJwt(req.headers?.['authorization'] as string | undefined);
|
||||||
|
const userId = jwt?.sub;
|
||||||
|
const roles: string[] = jwt?.roles ?? [];
|
||||||
|
// Admins see all instances; regular users only see their own
|
||||||
|
if (!userId || roles.includes('admin')) {
|
||||||
return this.instanceRepo.findAll();
|
return this.instanceRepo.findAll();
|
||||||
}
|
}
|
||||||
|
const instances = await this.instanceRepo.findByUserId(userId);
|
||||||
|
return instances.map((inst) => this.sanitize(inst));
|
||||||
|
}
|
||||||
|
|
||||||
@Get('user/:userId')
|
@Get('user/:userId')
|
||||||
async listByUser(@Param('userId') userId: string) {
|
async listByUser(@Param('userId') userId: string) {
|
||||||
|
|
@ -210,4 +220,14 @@ export class AgentInstanceController {
|
||||||
const { openclawToken, openclawTokenIv, ...safe } = inst;
|
const { openclawToken, openclawTokenIv, ...safe } = inst;
|
||||||
return { ...safe, hasToken: !!openclawToken };
|
return { ...safe, hasToken: !!openclawToken };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private decodeJwt(authHeader: string | undefined): Record<string, any> | null {
|
||||||
|
if (!authHeader?.startsWith('Bearer ')) return null;
|
||||||
|
try {
|
||||||
|
const payload = authHeader.slice(7).split('.')[1];
|
||||||
|
return JSON.parse(Buffer.from(payload, 'base64url').toString('utf8'));
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue