add crypto services to decrypt files path (#28)
Co-authored-by: OxSaitama <arnaud.daubernatali@smart-chain.fr>
This commit is contained in:
parent
36e60ecfc7
commit
9934816b77
@ -21,7 +21,7 @@
|
||||
"dotenv": "^16.0.3",
|
||||
"eslint": "8.36.0",
|
||||
"eslint-config-next": "13.2.4",
|
||||
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.35",
|
||||
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.38",
|
||||
"next": "13.2.4",
|
||||
"prettier": "^2.8.7",
|
||||
"react": "18.2.0",
|
||||
|
87
src/front/Api/LeCoffreApi/SuperAdmin/Files/Files.ts
Normal file
87
src/front/Api/LeCoffreApi/SuperAdmin/Files/Files.ts
Normal file
@ -0,0 +1,87 @@
|
||||
import { File } from "le-coffre-resources/dist/SuperAdmin";
|
||||
import Container, { Service } from "typedi";
|
||||
|
||||
import BaseSuperAdmin from "../BaseSuperAdmin";
|
||||
import CryptoService from "@Front/Services/CryptoService/CryptoService";
|
||||
|
||||
// TODO Type get query params -> Where + inclue + orderby
|
||||
export interface IGetFilesparams {
|
||||
where?: {};
|
||||
include?: {};
|
||||
}
|
||||
|
||||
// TODO Type getbyuid query params
|
||||
|
||||
export type IPutFilesParams = {};
|
||||
|
||||
export interface IPostFilesParams {}
|
||||
|
||||
@Service()
|
||||
export default class Files extends BaseSuperAdmin {
|
||||
private static instance: Files;
|
||||
private readonly baseURl = this.namespaceUrl.concat("/files");
|
||||
|
||||
private constructor(private cryptoService: CryptoService) {
|
||||
super();
|
||||
}
|
||||
|
||||
public static getInstance() {
|
||||
if (!this.instance) {
|
||||
return new this(Container.get(CryptoService));
|
||||
} else {
|
||||
return this.instance;
|
||||
}
|
||||
}
|
||||
|
||||
public async get(q: IGetFilesparams): Promise<File[]> {
|
||||
const url = new URL(this.baseURl);
|
||||
Object.entries(q).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
|
||||
try {
|
||||
const files = await this.getRequest<File[]>(url);
|
||||
files.forEach(async(file) => {
|
||||
file.file_path = await this.cryptoService.decrypt(file.file_path!, file.iv);
|
||||
})
|
||||
return files
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Create a File
|
||||
*/
|
||||
public async post(body: any): Promise<File> {
|
||||
const url = new URL(this.baseURl);
|
||||
try {
|
||||
return await this.postRequest<File>(url, body);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
public async getByUid(uid: string, q?: any): Promise<File> {
|
||||
const url = new URL(this.baseURl.concat(`/${uid}`));
|
||||
const query = { q };
|
||||
if (q) Object.entries(query).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
|
||||
try {
|
||||
const file = await this.getRequest<File>(url);
|
||||
file.file_path = await this.cryptoService.decrypt(file.file_path!, file.iv);
|
||||
return file;
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
public async put(uid: string, body: IPutFilesParams): Promise<File> {
|
||||
const url = new URL(this.baseURl.concat(`/${uid}`));
|
||||
try {
|
||||
return await this.putRequest<File>(url, body);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
}
|
@ -143,8 +143,10 @@ export const fileMock: File = {
|
||||
created_at: new Date(),
|
||||
updated_at: new Date(),
|
||||
document: document,
|
||||
file_name: "file_1",
|
||||
file_path:
|
||||
"https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/Qmf_Yb_Eh_X9st_F_Srq_Ve_Bj_Yb_Aj56xv_AV_Nj6_Wjypo_B4r5ubce_U_ae3303e7ab.pdf",
|
||||
iv: "1"
|
||||
};
|
||||
|
||||
export const fileMock2: File = {
|
||||
@ -152,8 +154,10 @@ export const fileMock2: File = {
|
||||
created_at: new Date(),
|
||||
updated_at: new Date(),
|
||||
document: document,
|
||||
file_name: "file_2",
|
||||
file_path:
|
||||
"https://minteed-prod-euwest3-s3.s3.eu-west-3.amazonaws.com/Qm_Wq_En1_DCA_8yt_RX_Qx_QFA_9_Fm_ZKZH_Qqb_VH_1_Q_Mnv_G_Jtt1_FS_Xp_2a35a36e19",
|
||||
iv: "2"
|
||||
};
|
||||
|
||||
export const identityFile: File = {
|
||||
@ -161,7 +165,9 @@ export const identityFile: File = {
|
||||
created_at: new Date(),
|
||||
updated_at: new Date(),
|
||||
document: document,
|
||||
file_name: "file_3",
|
||||
file_path: "https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/cni_fake_c7259d4923.png",
|
||||
iv: "3"
|
||||
};
|
||||
|
||||
export const documentIdentity: Document = {
|
||||
|
@ -19,6 +19,8 @@ export class FrontendVariables {
|
||||
|
||||
public IDNOT_CLIENT_ID!: string;
|
||||
|
||||
public KEY_DATA!: string;
|
||||
|
||||
private constructor() {}
|
||||
|
||||
public static getInstance(): FrontendVariables {
|
||||
|
64
src/front/Services/CryptoService/CryptoService.ts
Normal file
64
src/front/Services/CryptoService/CryptoService.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { Service } from "typedi";
|
||||
import { FrontendVariables } from "@Front/Config/VariablesFront";
|
||||
import crypto from "crypto";
|
||||
|
||||
@Service()
|
||||
export default class CryptoService {
|
||||
private jwkKey: JsonWebKey;
|
||||
private subtle: SubtleCrypto = crypto.webcrypto.subtle
|
||||
constructor(protected variables: FrontendVariables) {
|
||||
this.jwkKey = {
|
||||
kty: "oct",
|
||||
k: variables.KEY_DATA,
|
||||
alg: "A256GCM",
|
||||
ext: true,
|
||||
};
|
||||
}
|
||||
|
||||
private async getKey() {
|
||||
return await this.subtle.importKey("jwk", this.jwkKey, {name: "AES-GCM"}, false, ["encrypt", "decrypt"]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : encrypt data
|
||||
* @throws {Error} If data cannot be encrypted
|
||||
*/
|
||||
public async encrypt(data: string) {
|
||||
const encodedData = Buffer.from(data);
|
||||
const iv = crypto.getRandomValues(new Uint8Array(16));
|
||||
const key = await this.getKey();
|
||||
const cipherData = await this.subtle.encrypt(
|
||||
{
|
||||
name: "AES-GCM",
|
||||
iv,
|
||||
},
|
||||
key,
|
||||
encodedData,
|
||||
);
|
||||
|
||||
const cipherText = Buffer.from(cipherData).toString('base64');
|
||||
const ivStringified = Buffer.from(iv).toString('base64');
|
||||
|
||||
return { cipherText, ivStringified };
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : decrypt data with an initialization vector
|
||||
* @throws {Error} If data cannot be decrypted
|
||||
*/
|
||||
public async decrypt(cipherText: string, ivStringified: string): Promise<string> {
|
||||
const cipherData = Buffer.from(cipherText, 'base64');
|
||||
const iv = Buffer.from(ivStringified, 'base64');
|
||||
const key = await this.getKey();
|
||||
const decryptedData = await this.subtle.decrypt(
|
||||
{
|
||||
name: "AES-GCM",
|
||||
iv,
|
||||
},
|
||||
key,
|
||||
cipherData,
|
||||
);
|
||||
|
||||
return Buffer.from(decryptedData).toString('utf-8');
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user