Checkpoint: Fenêtre administrateur Salaires finalisée : import multipart limité, chiffrement AES-256-GCM avant stockage persistant hors conteneur, métadonnées/index métier minimisés en base, consultation PDF déchiffrée côté serveur avec no-store, filtres année/mois et comparaison M-1 expliquée. Réindexation sûre des archives partielles sans écrasement du PDF. Validation réelle sur deux liasses mensuelles : index partiel signalé sans invention de données, comparaison affichée et lecture après redémarrage. 55 tests Vitest, TypeScript et build de production validés.
Some checks failed
Validation applicative / TypeScript, tests et build (push) Failing after 1m54s
Some checks failed
Validation applicative / TypeScript, tests et build (push) Failing after 1m54s
This commit is contained in:
@@ -95,3 +95,15 @@ export async function storageGetSignedUrl(relKey: string): Promise<string> {
|
||||
const { url } = (await resp.json()) as { url: string };
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Télécharge un objet uniquement depuis le serveur. Cette primitive est utilisée
|
||||
* par la consultation de bulletins afin de ne jamais communiquer de lien de
|
||||
* stockage ni de document chiffré au navigateur.
|
||||
*/
|
||||
export async function storageGetBuffer(relKey: string): Promise<Buffer> {
|
||||
const signedUrl = await storageGetSignedUrl(relKey);
|
||||
const response = await fetch(signedUrl, { redirect: "follow" });
|
||||
if (!response.ok) throw new Error(`Storage download failed (${response.status})`);
|
||||
return Buffer.from(await response.arrayBuffer());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user