From 2a7cb5b723441ccdfa1c4bd709fb077f56d179a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81sd=C3=ADs=20Erna=20Gu=C3=B0mundsd=C3=B3ttir?= Date: Tue, 15 Oct 2024 11:18:38 +0000 Subject: [PATCH] feat(service-portal): detailed audit logs for law and order (#16321) * feat: detailed audit logs for law and order * fix: updates after PR review --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../src/lib/law-and-order.resolver.ts | 69 ++++++++++++++++--- 1 file changed, 60 insertions(+), 9 deletions(-) diff --git a/libs/api/domains/law-and-order/src/lib/law-and-order.resolver.ts b/libs/api/domains/law-and-order/src/lib/law-and-order.resolver.ts index f02dee2dcd49..0bbeb280b103 100644 --- a/libs/api/domains/law-and-order/src/lib/law-and-order.resolver.ts +++ b/libs/api/domains/law-and-order/src/lib/law-and-order.resolver.ts @@ -6,14 +6,14 @@ import { ScopesGuard, } from '@island.is/auth-nest-tools' import { ApiScope } from '@island.is/auth/scopes' -import { Audit } from '@island.is/nest/audit' +import { Audit, AuditService } from '@island.is/nest/audit' import { FeatureFlag, FeatureFlagGuard, Features, } from '@island.is/nest/feature-flags' import type { Locale } from '@island.is/shared/types' -import { UseGuards } from '@nestjs/common' +import { Inject, UseGuards } from '@nestjs/common' import { Args, Mutation, Query, Resolver } from '@nestjs/graphql' import { GetCourtCaseInput } from '../dto/getCourtCaseInput' import { GetSubpoenaInput } from '../dto/getSubpoenaInput' @@ -24,6 +24,9 @@ import { DefenseChoice } from '../models/defenseChoice.model' import { Lawyers } from '../models/lawyers.model' import { Subpoena } from '../models/subpoena.model' import { LawAndOrderService } from './law-and-order.service' +import { LOGGER_PROVIDER, type Logger } from '@island.is/logging' + +const LOG_CATEGORY = 'law-and-order-resolver' @UseGuards(IdsUserGuard, ScopesGuard, FeatureFlagGuard) @Resolver() @@ -31,7 +34,11 @@ import { LawAndOrderService } from './law-and-order.service' @FeatureFlag(Features.servicePortalLawAndOrderModuleEnabled) @Scopes(ApiScope.lawAndOrder) export class LawAndOrderResolver { - constructor(private readonly lawAndOrderService: LawAndOrderService) {} + constructor( + private readonly lawAndOrderService: LawAndOrderService, + private readonly auditService: AuditService, + @Inject(LOGGER_PROVIDER) private readonly logger: Logger, + ) {} @Query(() => CourtCases, { name: 'lawAndOrderCourtCasesList', @@ -51,24 +58,34 @@ export class LawAndOrderResolver { nullable: true, }) @Audit() - getCourtCaseDetail( + async getCourtCaseDetail( @CurrentUser() user: User, @Args('input') input: GetCourtCaseInput, @Args('locale', { type: () => String, nullable: true }) locale: Locale = 'is', ) { - return this.lawAndOrderService.getCourtCase(user, input.id, locale) + return this.auditAndHandle( + 'getCourtCaseDetail', + input.id, + this.lawAndOrderService.getCourtCase(user, input.id, locale), + user, + ) } @Query(() => Subpoena, { name: 'lawAndOrderSubpoena', nullable: true }) @Audit() - getSubpoena( + async getSubpoena( @CurrentUser() user: User, @Args('input') input: GetSubpoenaInput, @Args('locale', { type: () => String, nullable: true }) locale: Locale = 'is', ) { - return this.lawAndOrderService.getSubpoena(user, input.id, locale) + return this.auditAndHandle( + 'getSubpoena', + input.id, + this.lawAndOrderService.getSubpoena(user, input.id, locale), + user, + ) } @Query(() => Lawyers, { name: 'lawAndOrderLawyers', nullable: true }) @@ -86,12 +103,46 @@ export class LawAndOrderResolver { nullable: true, }) @Audit() - postDefenseChoice( + async postDefenseChoice( @Args('input') input: PostDefenseChoiceInput, @Args('locale', { type: () => String, nullable: true }) locale: Locale = 'is', @CurrentUser() user: User, ) { - return this.lawAndOrderService.postDefenseChoice(user, input, locale) + return this.auditAndHandle( + 'postDefenseChoice', + input.caseId, + this.lawAndOrderService.postDefenseChoice(user, input, locale), + user, + { defenseChoice: input.choice }, + ) + } + + private async auditAndHandle( + actionName: string, + resources: string, + promise: Promise, + user: User, + meta?: any, + ): Promise { + try { + return await this.auditService.auditPromise( + { + auth: user, + namespace: '@island.is/api/law-and-order', + action: actionName, + resources: resources, + meta: meta, + }, + promise, + ) + } catch (e) { + this.logger.error(`Failed to ${actionName}`, { + category: LOG_CATEGORY, + id: resources, + error: e, + }) + throw e + } } }