Skip to content

Commit

Permalink
Merge branch 'main' into chore/dl-smallchanges
Browse files Browse the repository at this point in the history
  • Loading branch information
stjanilofts authored Sep 27, 2024
2 parents 2fd5f19 + 3a56c8c commit 42153b5
Show file tree
Hide file tree
Showing 290 changed files with 8,055 additions and 1,594 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,16 @@ beforeAll(async () => {
describe('Application system payments callback API', () => {
// Sets the payment status to paid.
it(`POST /application-payment/32eee126-6b7f-4fca-b9a0-a3618b3e42bf/6b11dc9f-a694-440e-b3dd-7163b5f34815 should update payment fulfilled`, async () => {
await server
const response = await server
.post(
'/application-payment/32eee126-6b7f-4fca-b9a0-a3618b3e42bf/6b11dc9f-a694-440e-b3dd-7163b5f34815',
)
.send({
callback: {
receptionID: '1234567890',
chargeItemSubject: 'Very nice subject',
status: 'paid',
},
receptionID: '123e4567-e89b-12d3-a456-426614174000', // Updated to real UUID
chargeItemSubject: 'Very nice subject',
status: 'paid',
})
.expect(201)
expect(response.status).toBe(201)
})

// Fails to set the payment status to paid.
Expand All @@ -37,11 +35,9 @@ describe('Application system payments callback API', () => {
'/application-payment/32eee126-6b7f-4fca-b9a0-a3618b3e42bf/missing-id',
)
.send({
callback: {
receptionID: '1234567890',
chargeItemSubject: 'nice subject.. not',
status: 'paid',
},
receptionID: '123e4567-e89b-12d3-a456-426614174000', // Updated to real UUID
chargeItemSubject: 'nice subject.. not',
status: 'paid',
})
.expect(400)
})
Expand Down
1 change: 1 addition & 0 deletions apps/application-system/api/src/openApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ export const openApi = new DocumentBuilder()
.setVersion('1.0')
.addTag('application')
.addTag('payment')
.addTag('payment-callback')
.addBearerAuth()
.build()
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,16 @@ export class BackendService extends DataSource<{ req: Request }> {
return this.post(`case/${id}/file`, createFile)
}

getCaseFileSignedUrl(caseId: string, id: string): Promise<SignedUrl> {
return this.get(`case/${caseId}/file/${id}/url`)
getCaseFileSignedUrl(
caseId: string,
id: string,
mergedCaseId?: string,
): Promise<SignedUrl> {
const mergedCaseInjection = mergedCaseId
? `/mergedCase/${mergedCaseId}`
: ''

return this.get(`case/${caseId}${mergedCaseInjection}/file/${id}/url`)
}

deleteCaseFile(caseId: string, id: string): Promise<DeleteFileResponse> {
Expand Down Expand Up @@ -426,8 +434,15 @@ export class BackendService extends DataSource<{ req: Request }> {
limitedAccessGetCaseFileSignedUrl(
caseId: string,
id: string,
mergedCaseId?: string,
): Promise<SignedUrl> {
return this.get(`case/${caseId}/limitedAccess/file/${id}/url`)
const mergedCaseInjection = mergedCaseId
? `/mergedCase/${mergedCaseId}`
: ''

return this.get(
`case/${caseId}/limitedAccess${mergedCaseInjection}/file/${id}/url`,
)
}

limitedAccessDeleteCaseFile(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Allow } from 'class-validator'
import { Allow, IsOptional } from 'class-validator'

import { Field, ID, InputType } from '@nestjs/graphql'

Expand All @@ -11,4 +11,9 @@ export class GetSignedUrlInput {
@Allow()
@Field(() => ID)
readonly caseId!: string

@Allow()
@IsOptional()
@Field(() => ID, { nullable: true })
readonly mergedCaseId?: string
}
21 changes: 17 additions & 4 deletions apps/judicial-system/api/src/app/modules/file/file.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,30 @@ export class FileController {
)
}

@Get('caseFilesRecord/:policeCaseNumber')
@Get([
'caseFilesRecord/:policeCaseNumber',
'mergedCase/:mergedCaseId/caseFilesRecord/:policeCaseNumber',
])
@Header('Content-Type', 'application/pdf')
getCaseFilesRecordPdf(
@Param('id') id: string,
@Param('mergedCaseId') mergedCaseId: string,
@Param('policeCaseNumber') policeCaseNumber: string,
@CurrentHttpUser() user: User,
@Req() req: Request,
@Res() res: Response,
): Promise<Response> {
this.logger.debug(`Getting the case files for case ${id} as a pdf document`)

const mergedCaseInjection = mergedCaseId
? `mergedCase/${mergedCaseId}/`
: ''

return this.fileService.tryGetFile(
user.id,
AuditedAction.GET_CASE_FILES_PDF,
id,
`caseFilesRecord/${policeCaseNumber}`,
`${mergedCaseInjection}caseFilesRecord/${policeCaseNumber}`,
req,
res,
'pdf',
Expand Down Expand Up @@ -143,21 +151,26 @@ export class FileController {
)
}

@Get('indictment')
@Get(['indictment', 'mergedCase/:mergedCaseId/indictment'])
@Header('Content-Type', 'application/pdf')
getIndictmentPdf(
@Param('id') id: string,
@Param('mergedCaseId') mergedCaseId: string,
@CurrentHttpUser() user: User,
@Req() req: Request,
@Res() res: Response,
): Promise<Response> {
this.logger.debug(`Getting the indictment for case ${id} as a pdf document`)

const mergedCaseInjection = mergedCaseId
? `mergedCase/${mergedCaseId}/`
: ''

return this.fileService.tryGetFile(
user.id,
AuditedAction.GET_INDICTMENT_PDF,
id,
'indictment',
`${mergedCaseInjection}indictment`,
req,
res,
'pdf',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,14 @@ export class FileResolver {
@Context('dataSources')
{ backendService }: { backendService: BackendService },
): Promise<SignedUrl> {
const { caseId, id } = input
const { caseId, id, mergedCaseId } = input

this.logger.debug(`Getting a signed url for file ${id} of case ${caseId}`)

return this.auditTrailService.audit(
user.id,
AuditedAction.GET_SIGNED_URL,
backendService.getCaseFileSignedUrl(caseId, id),
backendService.getCaseFileSignedUrl(caseId, id, mergedCaseId),
id,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Header,
Inject,
Param,
Query,
Req,
Res,
UseGuards,
Expand All @@ -19,7 +20,7 @@ import {
CurrentHttpUser,
JwtInjectBearerAuthGuard,
} from '@island.is/judicial-system/auth'
import type { User } from '@island.is/judicial-system/types'
import type { SubpoenaType, User } from '@island.is/judicial-system/types'

import { FileService } from './file.service'

Expand Down Expand Up @@ -52,22 +53,30 @@ export class LimitedAccessFileController {
)
}

@Get('caseFilesRecord/:policeCaseNumber')
@Get([
'caseFilesRecord/:policeCaseNumber',
'mergedCase/:mergedCaseId/caseFilesRecord/:policeCaseNumber',
])
@Header('Content-Type', 'application/pdf')
async getCaseFilesRecordPdf(
@Param('id') id: string,
@Param('mergedCaseId') mergedCaseId: string,
@Param('policeCaseNumber') policeCaseNumber: string,
@CurrentHttpUser() user: User,
@Req() req: Request,
@Res() res: Response,
): Promise<Response> {
this.logger.debug(`Getting the case files for case ${id} as a pdf document`)

const mergedCaseInjection = mergedCaseId
? `mergedCase/${mergedCaseId}/`
: ''

return this.fileService.tryGetFile(
user.id,
AuditedAction.GET_CASE_FILES_PDF,
id,
`limitedAccess/caseFilesRecord/${policeCaseNumber}`,
`limitedAccess/${mergedCaseInjection}caseFilesRecord/${policeCaseNumber}`,
req,
res,
'pdf',
Expand Down Expand Up @@ -141,21 +150,53 @@ export class LimitedAccessFileController {
)
}

@Get('indictment')
@Get(['indictment', 'mergedCase/:mergedCaseId/indictment'])
@Header('Content-Type', 'application/pdf')
async getIndictmentPdf(
@Param('id') id: string,
@Param('mergedCaseId') mergedCaseId: string,
@CurrentHttpUser() user: User,
@Req() req: Request,
@Res() res: Response,
): Promise<Response> {
this.logger.debug(`Getting the indictment for case ${id} as a pdf document`)

const mergedCaseInjection = mergedCaseId
? `mergedCase/${mergedCaseId}/`
: ''

return this.fileService.tryGetFile(
user.id,
AuditedAction.GET_INDICTMENT_PDF,
id,
'limitedAccess/indictment',
`limitedAccess/${mergedCaseInjection}indictment`,
req,
res,
'pdf',
)
}

@Get('subpoena/:defendantId')
@Header('Content-Type', 'application/pdf')
getSubpoenaPdf(
@Param('id') id: string,
@Param('defendantId') defendantId: string,
@Query('arraignmentDate') arraignmentDate: string,
@Query('location') location: string,
@Query('subpoenaType') subpoenaType: SubpoenaType,
@CurrentHttpUser() user: User,
@Req() req: Request,
@Res() res: Response,
): Promise<Response> {
this.logger.debug(
`Getting the subpoena for defendant ${defendantId} of case ${id} as a pdf document`,
)

return this.fileService.tryGetFile(
user.id,
AuditedAction.GET_SUBPOENA_PDF,
id,
`limitedAccess/defendant/${defendantId}/subpoena?arraignmentDate=${arraignmentDate}&location=${location}&subpoenaType=${subpoenaType}`,
req,
res,
'pdf',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,18 @@ export class LimitedAccessFileResolver {
@Context('dataSources')
{ backendService }: { backendService: BackendService },
): Promise<SignedUrl> {
const { caseId, id } = input
const { caseId, id, mergedCaseId } = input

this.logger.debug(`Getting a signed url for file ${id} of case ${caseId}`)

return this.auditTrailService.audit(
user.id,
AuditedAction.GET_SIGNED_URL,
backendService.limitedAccessGetCaseFileSignedUrl(caseId, id),
backendService.limitedAccessGetCaseFileSignedUrl(
caseId,
id,
mergedCaseId,
),
id,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,18 @@ export class AwsS3Service {
caseType: CaseType,
key?: string,
timeToLive?: number,
useFreshSession = false,
): Promise<string> {
if (!key) {
throw new Error('Key is required')
}

return new Promise((resolve, reject) => {
this.s3.getSignedUrl(
const s3 = useFreshSession
? new S3({ region: this.config.region })
: this.s3

s3.getSignedUrl(
'getObject',
{
Bucket: this.config.bucket,
Expand All @@ -155,6 +160,7 @@ export class AwsS3Service {
force: boolean,
confirmContent: (content: Buffer) => Promise<string | undefined>,
timeToLive?: number,
useFreshSession = false,
): Promise<string> {
if (!key) {
throw new Error('Key is required')
Expand All @@ -167,19 +173,24 @@ export class AwsS3Service {
const confirmedKey = formatConfirmedIndictmentCaseKey(key)

if (!force && (await this.objectExists(caseType, confirmedKey))) {
return this.getSignedUrl(caseType, confirmedKey, timeToLive)
return this.getSignedUrl(
caseType,
confirmedKey,
timeToLive,
useFreshSession,
)
}

const confirmedContent = await this.getObject(caseType, key).then(
(content) => confirmContent(content),
)

if (!confirmedContent) {
return this.getSignedUrl(caseType, key, timeToLive)
return this.getSignedUrl(caseType, key, timeToLive, useFreshSession)
}

return this.putObject(caseType, confirmedKey, confirmedContent).then(() =>
this.getSignedUrl(caseType, confirmedKey, timeToLive),
this.getSignedUrl(caseType, confirmedKey, timeToLive, useFreshSession),
)
}

Expand Down
Loading

0 comments on commit 42153b5

Please sign in to comment.