2023-06-26 10:45:29 +02:00

95 lines
3.0 KiB
TypeScript

import FilesRepository from "@Repositories/FilesRepository";
import BaseService from "@Services/BaseService";
import { Service } from "typedi";
import { File } from "le-coffre-resources/dist/SuperAdmin";
import CryptoService from "../CryptoService/CryptoService";
import IpfsService from "../IpfsService/IpfsService";
import { BackendVariables } from "@Common/config/variables/Variables";
import { Readable } from "stream";
import {v4} from "uuid";
import { Files } from "@prisma/client";
import fetch from "node-fetch";
@Service()
export default class FilesService extends BaseService {
constructor(
private filesRepository: FilesRepository,
private ipfsService: IpfsService,
private variables: BackendVariables,
private cryptoService: CryptoService,
) {
super();
}
/**
* @description : Get all files
* @throws {Error} If files cannot be ge
*/
public async get(query: any): Promise<Files[]> {
return this.filesRepository.findMany(query);
}
/**
* @description : Get a file by uid
* @throws {Error} If project cannot be created
*/
public async getByUid(uid: string): Promise<Files | null> {
return this.filesRepository.findOneByUid(uid);
}
/**
* @description : view a file
* @throws {Error} If file cannot be deleted
*/
public async download(uid: string) {
const file = await this.filesRepository.findOneByUid(uid);
if (!file?.key) return null;
const fileResult = await fetch(file.file_path);
const fileArrayBuffer = await fileResult.arrayBuffer();
return {file: file, buffer: await this.cryptoService.decrypt(Buffer.from(fileArrayBuffer), file.key)};
}
/**
* @description : Create a new file
* @throws {Error} If file cannot be created
*/
public async create(file: File, fileData: Express.Multer.File) {
const key = v4();
const encryptedFile = await this.cryptoService.encrypt(fileData.buffer, key);
const upload = await this.ipfsService.pinFile(Readable.from(encryptedFile), fileData.originalname);
const fileToCreate: File = file;
fileToCreate.file_name = fileData.originalname;
fileToCreate.file_path = this.variables.PINATA_GATEWAY.concat(upload.IpfsHash);
fileToCreate.mimetype = fileData.mimetype;
fileToCreate.size = fileData.size;
return this.filesRepository.create(fileToCreate, key);
}
/**
* @description : Modify a new file
* @throws {Error} If file cannot be modified
*/
public async update(uid: string, file: File): Promise<Files> {
return this.filesRepository.update(uid, file);
}
/**
* @description : Delete a file key and archive
* @throws {Error} If file key cannot be deleted or archived
*/
public async deleteKeyAndArchive(uid: string): Promise<Files> {
try {
const fileToUnpin = await this.filesRepository.findOneByUid(uid);
if(!fileToUnpin) throw new Error("file not found");
const fileHash = fileToUnpin.file_path.substring(this.variables.PINATA_GATEWAY.length);
await this.ipfsService.unpinFile(fileHash);
} catch(error) {
console.error(error);
}
return this.filesRepository.deleteKeyAndArchive(uid);
}
}