11import { CONFIG_TOKEN , IConfig } from '@app/common/config/config.module' ;
2- import { BaseServiceException , ServiceValidationException } from '@app/common/exceptions/base.exception' ;
2+ import {
3+ BaseServiceException ,
4+ ServiceNotFoundException ,
5+ ServiceValidationException ,
6+ } from '@app/common/exceptions/base.exception' ;
37import { DeleteObjectCommand , GetObjectCommand , PutObjectCommand , S3Client } from '@aws-sdk/client-s3' ;
48import { getSignedUrl } from '@aws-sdk/s3-request-presigner' ;
59import { MultipartFile } from '@fastify/multipart' ;
610import { Inject , Injectable , Logger } from '@nestjs/common' ;
711import { InjectRepository } from '@nestjs/typeorm' ;
8- import { Repository } from 'typeorm' ;
12+ import { DataSource , Repository } from 'typeorm' ;
913import { v4 } from 'uuid' ;
1014import { ClamAVService } from '../clamav/clamav.service' ;
1115import { User } from '../user/user.entity' ;
12- import {
13- CreateDocumentDto ,
14- DOCUMENT_SOURCE ,
15- DOCUMENT_SYSTEM ,
16- } from './document.dto' ;
16+ import { CreateDocumentDto , DOCUMENT_SOURCE , DOCUMENT_SYSTEM } from './document.dto' ;
1717import { Document } from './document.entity' ;
18+ import { VISIBILITY_FLAG } from '../alcs/application/application-document/application-document.entity' ;
1819
1920const DEFAULT_DB_TAGS = [ 'ORCS Classification: 85100-20' ] ;
2021const DEFAULT_S3_TAGS = 'ORCS-Classification=85100-20' ;
@@ -31,6 +32,7 @@ export class DocumentService {
3132 @InjectRepository ( Document )
3233 private documentRepository : Repository < Document > ,
3334 private clamAvService : ClamAVService ,
35+ private dataSource : DataSource ,
3436 ) {
3537 this . dataStore = new S3Client ( {
3638 region : 'us-east-1' ,
@@ -156,6 +158,47 @@ export class DocumentService {
156158 return { url : await this . getDownloadUrl ( document , openInline ) , fileName : document . fileName } ;
157159 }
158160
161+ async getPublicDownloadUrlAndFileNameByUuid (
162+ uuid : string ,
163+ openInline = false ,
164+ ) : Promise < { url : string ; fileName : string } > {
165+ const document = await this . getDocument ( uuid ) ;
166+
167+ const fileDocuments = await this . dataSource . query (
168+ `
169+ select
170+ ad.visibility_flags
171+ from
172+ alcs.application_document ad
173+ where
174+ ad.document_uuid = $1
175+ union
176+ select
177+ noid.visibility_flags
178+ from
179+ alcs.notice_of_intent_document noid
180+ where
181+ noid.document_uuid = $1
182+ union
183+ select
184+ nd2.visibility_flags
185+ from
186+ alcs.notification_document nd2
187+ where
188+ nd2.document_uuid = $1
189+ ` ,
190+ [ uuid ] ,
191+ ) ;
192+
193+ // Unlikely a document is attached to more than one file document, but if it
194+ // is, as long as any of them have made the doc public, show it
195+ if ( ! fileDocuments . some ( ( doc ) => doc . visibility_flags . includes ( VISIBILITY_FLAG . PUBLIC ) ) ) {
196+ throw new ServiceNotFoundException ( 'Failed to find document' ) ;
197+ }
198+
199+ return { url : await this . getDownloadUrl ( document , openInline ) , fileName : document . fileName } ;
200+ }
201+
159202 async createDocumentRecord ( data : CreateDocumentDto ) {
160203 const command = new GetObjectCommand ( {
161204 Bucket : this . config . get ( 'STORAGE.BUCKET' ) ,
0 commit comments