All files / src/controllers/public/scan attachment.controller.ts

42.86% Statements 18/42
0% Branches 0/14
0% Functions 0/11
43.24% Lines 16/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 1141x 1x 1x 1x 1x 1x 1x 1x   1x         1x                   1x                                                     1x               1x             1x               1x                                         1x                                    
import {del, get, HttpErrors, param, put, Request, requestBody, RestBindings, Response} from '@loopback/rest';
import multer from 'multer';
import {inject, service} from '@loopback/core';
import {AttachmentService} from '@logchain/services/scan/attachment.service';
import {AttachmentType} from '@logchain/types';
import {authenticate} from '@loopback/authentication';
import {CacheService} from '@logchain/services/cache.service';
import { verifyAttachmentToken } from '@logchain/utils/attachment-link.util';
 
const upload = (multer as any)({
  storage: (multer as any).memoryStorage(),
});
 
@authenticate('aws-cognito')
export class AttachmentController {
  constructor(
    @service(AttachmentService)
    public attachmentService: AttachmentService,
 
    @service(CacheService)
    private cacheService: CacheService,
  ) {}
 
  @put('/attachments/upload')
  async uploadAttachment(
    @param.query.string('type') type: AttachmentType,
    @param.query.string('pmoIds') pmoIdsRaw: string,
    @inject(RestBindings.Http.REQUEST) req: Request,
  ) {
    const file = await new Promise<Express.Multer.File>((resolve, reject) => {
      upload.single('file')(req as any, {} as any, (err: any) => {
        if (err) return reject(new HttpErrors.BadRequest(err.message));
        if (!(req as any).file) return reject(new HttpErrors.BadRequest('No file uploaded'));
        resolve((req as any).file);
      });
    });
 
    const pmoIds = pmoIdsRaw
      ? pmoIdsRaw
          .split(',')
          .map(Number)
          .filter(n => !isNaN(n))
      : [];
 
    return this.attachmentService.uploadMulti(pmoIds, type, file);
  }
 
  /**
   * Get attachments by PMO
   */
  @get('/attachments/pmo/{pmoId}')
  async getByPmo(
    @param.path.number('pmoId')
    pmoId: number,
  ) {
    return this.attachmentService.findByPmoId(pmoId);
  }
 
  @get('/attachments/pmo/{pmoId}/by-type')
  async getByPmoAndType(@param.path.number('pmoId') pmoId: number, @param.query.string('type') type?: AttachmentType) {
    return this.attachmentService.findByPmoIdAndType(pmoId, type);
  }
  /**
   * Delete attachment
   */
  @del('/attachments/{id}')
  async deleteAttachment(
    @param.path.number('id')
    id: number,
  ) {
    return this.attachmentService.delete(id);
  }
 
  @del('/attachments/{id}/group')
  async deleteAttachmentGroup(
    @param.path.number('id') id: number,
    @requestBody({
      content: {
        'application/json': {
          schema: {
            type: 'object',
            properties: {
              pmoIds: {type: 'array', items: {type: 'number'}},
            },
          },
        },
      },
    })
    body: {pmoIds: number[]},
  ) {
    return this.attachmentService.deleteGroup(id, body.pmoIds);
  }
 
  @authenticate.skip()
  @get('/attachments/{id}/view')
  async viewAttachment(
    @param.path.number('id') id: number,
    @param.query.string('t') token: string,
    @inject(RestBindings.Http.RESPONSE) res: Response,
  ) {
    if (!token || !verifyAttachmentToken(id, token)) {
      throw new HttpErrors.Forbidden('Invalid or missing token');
    }
 
    const attachment = await this.attachmentService.attachmentRepo.findById(id).catch(() => null);
    if (!attachment || !attachment.file_url) {
      throw new HttpErrors.NotFound('Attachment not found');
    }
 
    const signedUrl = await this.attachmentService.generateSignedUrl(attachment.file_url);
    res.redirect(302, signedUrl);
  }
}