feat(p9): fence AI + calendar + message by-id leaks (tenant scope)
Task T3.2: AiJobService.getArtifact/accept/reject assertOwns on artifact.job.scopeId; listArtifacts scoped to caller. CalendarService.getMeeting/setConsent/generateTranscript/ summarize/listActionItems assertOwns on meeting.scopeId (optional principal → asserts when supplied by a controller, skipped for internal calls). MessageService.getMessageById gains the same optional fence. Controllers thread the principal through. All 46 ai/calendar/routing/messaging tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -217,12 +217,13 @@ export class MessageService {
|
||||
return { interactionId, actorId: actor.id };
|
||||
}
|
||||
|
||||
async getMessageById(id: string): Promise<MessageDto | null> {
|
||||
async getMessageById(id: string, principal?: MessagePrincipal): Promise<MessageDto | null> {
|
||||
const i = await this.prisma.iiosInteraction.findUnique({
|
||||
where: { id },
|
||||
include: { parts: { orderBy: { partIndex: 'asc' } } },
|
||||
});
|
||||
if (!i || !i.threadId) return null;
|
||||
if (principal) await this.actors.assertOwns(principal, i.scopeId); // tenant fence (KG-02) when called on behalf of a caller
|
||||
return this.toDto(i, i.threadId);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user