Compare commits

...

2 commits

Author SHA1 Message Date
52ace91580 change config
Some checks failed
Publier l'image Docker / test (push) Failing after 21s
Publier l'image Docker / publish (push) Has been skipped
2026-09-19 14:59:16 +02:00
9758fe75f9 update config 2026-09-19 14:49:47 +02:00
5 changed files with 23 additions and 6 deletions

View file

@ -15,7 +15,8 @@
"label": "Vidéos", "label": "Vidéos",
"dir": "./uploads/videos", "dir": "./uploads/videos",
"allowDirectories": true, "allowDirectories": true,
"allowedMimeTypes": ["video/*"] "allowedMimeTypes": ["video/*"],
"permissions": "0666"
}, },
{ "name": "divers", "label": "Divers", "dir": "./uploads/divers" } { "name": "divers", "label": "Divers", "dir": "./uploads/divers" }
], ],

View file

@ -48,6 +48,11 @@
} }
} }
] ]
},
"permissions":{
"type":"string",
"default":"0666",
"description": "Mode d'écriture sur le disque"
} }
} }
} }

View file

@ -60,6 +60,12 @@ export interface DropTarget {
* valeur globale `allowedMimeTypes`. Toujours résolu après parsing. * valeur globale `allowedMimeTypes`. Toujours résolu après parsing.
*/ */
allowedMimeTypes: MimePolicy; allowedMimeTypes: MimePolicy;
/**
* Mode de permission d'écriture
* Par défaut 0o666
*/
permission: number;
} }
/** Liste non vide de cibles de dépôt ; la première est la cible par défaut. */ /** Liste non vide de cibles de dépôt ; la première est la cible par défaut. */
@ -386,6 +392,7 @@ function parseTargets(value: unknown, defaultMimePolicy: MimePolicy): DropTarget
raw.allowedMimeTypes === undefined || raw.allowedMimeTypes === null raw.allowedMimeTypes === undefined || raw.allowedMimeTypes === null
? defaultMimePolicy ? defaultMimePolicy
: parseMimePolicy(raw.allowedMimeTypes, `targets[${String(index)}].allowedMimeTypes`), : parseMimePolicy(raw.allowedMimeTypes, `targets[${String(index)}].allowedMimeTypes`),
permission: parseInt(optionalString(raw.label, `targets[${String(index)}].permission`) ?? "0666",8)
}; };
}; };

View file

@ -33,12 +33,15 @@ export interface SaveFileParams {
/** Dossier de destination (résolu depuis la cible de dépôt choisie). */ /** Dossier de destination (résolu depuis la cible de dépôt choisie). */
targetDir: string; targetDir: string;
maxFileSizeBytes: number; maxFileSizeBytes: number;
/** Permission d'écriture */
permission:number;
/** /**
* Mode dossier : recrée `segments` sous `targetDir` et conserve `fileName` ; * Mode dossier : recrée `segments` sous `targetDir` et conserve `fileName` ;
* un fichier existant au même chemin est écrasé. Absent -> nom dérivé unique * un fichier existant au même chemin est écrasé. Absent -> nom dérivé unique
* à la racine de `targetDir`. * à la racine de `targetDir`.
*/ */
placement?: FilePlacement; placement?: FilePlacement;
} }
const MAX_BASE_LENGTH = 60; const MAX_BASE_LENGTH = 60;
@ -143,7 +146,7 @@ export async function resolveDestination(input: DestinationInput): Promise<Resol
* le fichier partiel est supprimé et `PayloadTooLargeError` est levée. * le fichier partiel est supprimé et `PayloadTooLargeError` est levée.
*/ */
export async function saveFile(params: SaveFileParams): Promise<StoredFile> { export async function saveFile(params: SaveFileParams): Promise<StoredFile> {
const { source, originalName, mimeType, maxFileSizeBytes } = params; const { source, originalName, mimeType, maxFileSizeBytes,permission } = params;
const { storedName, destination } = await resolveDestination(params); const { storedName, destination } = await resolveDestination(params);
let bytesWritten = 0; let bytesWritten = 0;
@ -162,7 +165,7 @@ export async function saveFile(params: SaveFileParams): Promise<StoredFile> {
await pipeline( await pipeline(
source, source,
limiter, limiter,
createWriteStream(destination, { highWaterMark: WRITE_HIGH_WATER_MARK }), createWriteStream(destination, { highWaterMark: WRITE_HIGH_WATER_MARK ,mode:permission}),
); );
} catch (error) { } catch (error) {
await rm(destination, { force: true }); await rm(destination, { force: true });

View file

@ -94,6 +94,7 @@ export const uploadRoutes: FastifyPluginCallback = (app, _options, done) => {
targetDir: target.dir, targetDir: target.dir,
maxFileSizeBytes: app.appConfig.maxFileSizeBytes, maxFileSizeBytes: app.appConfig.maxFileSizeBytes,
...(placement !== undefined ? { placement } : {}), ...(placement !== undefined ? { placement } : {}),
permission:target.permission
}); });
app.notifier.uploadCompleted({ app.notifier.uploadCompleted({