Upload (Audio nur per Magic Bytes, versiegelt, 2 MiB), Text-Weg, Liste, Abruf, Wiederholen, Verwerfen, alle verwerfen, Konfiguration und Zähler unter /voice-captures. Rechte voice-captures:use plus inspections:create (eigener Guard, API-Schlüssel ausgeschlossen), Zähler nur mit system:manage; jede Abfrage auf den Besitzer begrenzt. Grenzen je Benutzer unter Advisory-Lock (10 offen, 30 je Tag, 10 je 60 s), Wiederholen ebenfalls begrenzt und gedrosselt, Audio für QUEUED nur unter 24 h. Verwerfen löscht Inhalt und Claim sofort. Keine Inhalte in Log oder Audit. Wächter gegen Sprachinhalte in Suche, Export und Berichten erweitert. Refs #27 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
27 lines
1015 B
TypeScript
27 lines
1015 B
TypeScript
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
|
|
import { PermissionResolverService } from '../../auth/permissions/permission-resolver.service';
|
|
import type { AuthenticatedUser } from '../../auth/types/authenticated-user';
|
|
|
|
interface RequestWithUser {
|
|
user?: AuthenticatedUser;
|
|
}
|
|
|
|
/**
|
|
* Voice notes end in an inspection, so every voice endpoint also needs
|
|
* inspections:create (spec 3) on top of voice-captures:use. @RequirePermission
|
|
* is "any of", so the second right is its own guard. A request without a
|
|
* signed-in person (an API key) never passes.
|
|
*/
|
|
@Injectable()
|
|
export class InspectionCreateGuard implements CanActivate {
|
|
constructor(private readonly permissionResolver: PermissionResolverService) {}
|
|
|
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
const user = context.switchToHttp().getRequest<RequestWithUser>().user;
|
|
if (!user) {
|
|
return false;
|
|
}
|
|
return this.permissionResolver.hasAny(user.id, ['inspections:create']);
|
|
}
|
|
}
|