Checkpoint: Ajout du secours de stockage réservé aux PDF de paie chiffrés : lorsque Forge est indisponible en recette, les octets AES-256-GCM sont stockés dans un volume hôte Docker persistant, jamais dans l'image ni la base. Import, réindexation et consultation passent par cette même abstraction, avec test de round-trip sans Forge. Compose transmet la clé AES et monte le volume dédié. Validation complète : 56 tests, TypeScript, build et format YAML.
All checks were successful
Validation applicative / TypeScript, tests et build (push) Successful in 2m9s
All checks were successful
Validation applicative / TypeScript, tests et build (push) Successful in 2m9s
This commit is contained in:
@@ -9,14 +9,14 @@ vi.mock("./db", () => ({
|
||||
getSalaireLiasseById: vi.fn(),
|
||||
replaceSalaireLiasseIndex: vi.fn(),
|
||||
}));
|
||||
vi.mock("./storage", () => ({ storagePut: vi.fn(), storageGetBuffer: vi.fn() }));
|
||||
vi.mock("./storage", () => ({ payrollStoragePut: vi.fn(), payrollStorageGetBuffer: vi.fn() }));
|
||||
vi.mock("pdf-parse/lib/pdf-parse.js", () => ({ default: vi.fn() }));
|
||||
|
||||
import { sdk } from "./_core/sdk";
|
||||
import { createSalaireLiasse, getSalaireLiasseById, getSalaireLiasseByPeriod } from "./db";
|
||||
import { encryptPayrollPdf } from "./payrollCrypto";
|
||||
import { registerSalairesHttpRoutes } from "./salairesHttp";
|
||||
import { storageGetBuffer, storagePut } from "./storage";
|
||||
import { payrollStorageGetBuffer, payrollStoragePut } from "./storage";
|
||||
import pdfParse from "pdf-parse/lib/pdf-parse.js";
|
||||
|
||||
const EXTRACTED_TEXT = `##BULLETIN##05-2026##009999##DUPONT##TEST##
|
||||
@@ -49,13 +49,13 @@ describe("routes HTTP Salaires", () => {
|
||||
.expect(403);
|
||||
|
||||
expect(createSalaireLiasse).not.toHaveBeenCalled();
|
||||
expect(storagePut).not.toHaveBeenCalled();
|
||||
expect(payrollStoragePut).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("chiffre et archive une liasse administrateur sans persister de donnée sensible", async () => {
|
||||
(sdk.authenticateRequest as ReturnType<typeof vi.fn>).mockResolvedValue({ id: 1, role: "admin" });
|
||||
(pdfParse as ReturnType<typeof vi.fn>).mockResolvedValue({ text: EXTRACTED_TEXT });
|
||||
(storagePut as ReturnType<typeof vi.fn>).mockResolvedValue({ key: "salaires/2026/05/liasse_opaque.enc" });
|
||||
(payrollStoragePut as ReturnType<typeof vi.fn>).mockResolvedValue({ key: "salaires/2026/05/liasse_opaque.enc" });
|
||||
(createSalaireLiasse as ReturnType<typeof vi.fn>).mockResolvedValue({ liasseId: 12, bulletins: 1 });
|
||||
|
||||
const response = await request(makeApp())
|
||||
@@ -81,7 +81,7 @@ describe("routes HTTP Salaires", () => {
|
||||
const plaintext = Buffer.from("%PDF-1.7 contenu de bulletin", "utf8");
|
||||
const encrypted = encryptPayrollPdf(plaintext);
|
||||
(getSalaireLiasseById as ReturnType<typeof vi.fn>).mockResolvedValue({ id: 30001, stockageKey: "opaque", ivBase64: encrypted.ivBase64, authTagBase64: encrypted.authTagBase64, annee: 2026, mois: 5 });
|
||||
(storageGetBuffer as ReturnType<typeof vi.fn>).mockResolvedValue(encrypted.ciphertext);
|
||||
(payrollStorageGetBuffer as ReturnType<typeof vi.fn>).mockResolvedValue(encrypted.ciphertext);
|
||||
|
||||
const response = await request(makeApp()).get("/api/salaires/liasses/30001/pdf").expect(200);
|
||||
|
||||
@@ -103,7 +103,7 @@ describe("routes HTTP Salaires", () => {
|
||||
(sdk.authenticateRequest as ReturnType<typeof vi.fn>).mockResolvedValue({ id: 1, role: "admin" });
|
||||
const encrypted = encryptPayrollPdf(Buffer.from("%PDF-1.7 contenu de bulletin", "utf8"));
|
||||
(getSalaireLiasseById as ReturnType<typeof vi.fn>).mockResolvedValue({ id: 30001, stockageKey: "opaque", ivBase64: encrypted.ivBase64, authTagBase64: encrypted.authTagBase64, annee: 2026, mois: 5 });
|
||||
(storageGetBuffer as ReturnType<typeof vi.fn>).mockResolvedValue(encrypted.ciphertext);
|
||||
(payrollStorageGetBuffer as ReturnType<typeof vi.fn>).mockResolvedValue(encrypted.ciphertext);
|
||||
(pdfParse as ReturnType<typeof vi.fn>).mockResolvedValue({ text: EXTRACTED_TEXT });
|
||||
(replaceSalaireLiasseIndex as ReturnType<typeof vi.fn>).mockResolvedValue({ bulletins: 1 });
|
||||
|
||||
@@ -113,6 +113,6 @@ describe("routes HTTP Salaires", () => {
|
||||
statutExtraction: "ready",
|
||||
bulletins: [expect.objectContaining({ matricule: "009999" })],
|
||||
}));
|
||||
expect(storagePut).not.toHaveBeenCalled();
|
||||
expect(payrollStoragePut).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user