121 lines
3.5 KiB
TypeScript
121 lines
3.5 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { S3Client, ListObjectsV2Command } from "@aws-sdk/client-s3";
|
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
import { GetObjectCommand } from "@aws-sdk/client-s3";
|
|
import { createSbServiceRole } from "@/lib/supabaseServer";
|
|
|
|
const s3Client = new S3Client({
|
|
region: process.env.AWS_REGION || "eu-west-3",
|
|
credentials: {
|
|
accessKeyId: process.env.AWS_ACCESS_KEY_ID || "",
|
|
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || "",
|
|
},
|
|
});
|
|
|
|
const BUCKET_NAME = (process.env.AWS_S3_BUCKET || "odentas-docs").trim();
|
|
|
|
// Mapping des noms de fichiers vers des libellés lisibles
|
|
const FILE_TYPE_LABELS: Record<string, string> = {
|
|
"piece-identite": "Pièce d'identité",
|
|
"attestation-secu": "Attestation Sécurité Sociale",
|
|
"rib": "RIB",
|
|
"medecine-travail": "Médecine du travail",
|
|
"autre": "Autre document"
|
|
};
|
|
|
|
interface S3Document {
|
|
key: string;
|
|
name: string;
|
|
type: string;
|
|
size: number;
|
|
lastModified: string;
|
|
downloadUrl: string;
|
|
}
|
|
|
|
export async function GET(req: NextRequest) {
|
|
try {
|
|
const { searchParams } = new URL(req.url);
|
|
const matricule = searchParams.get('matricule');
|
|
|
|
if (!matricule) {
|
|
return NextResponse.json({
|
|
error: "Matricule requis"
|
|
}, { status: 400 });
|
|
}
|
|
|
|
// Vérifier que l'utilisateur est staff
|
|
const supabase = createSbServiceRole();
|
|
|
|
// Construire le préfixe pour les fichiers de ce salarié
|
|
const prefix = `justif-salaries/${matricule}/`;
|
|
|
|
// Lister les fichiers dans S3
|
|
const listCommand = new ListObjectsV2Command({
|
|
Bucket: BUCKET_NAME,
|
|
Prefix: prefix,
|
|
});
|
|
|
|
const listResponse = await s3Client.send(listCommand);
|
|
|
|
if (!listResponse.Contents || listResponse.Contents.length === 0) {
|
|
return NextResponse.json({
|
|
documents: [],
|
|
count: 0
|
|
});
|
|
}
|
|
|
|
// Générer des URLs pré-signées pour chaque fichier
|
|
const documents = await Promise.all(
|
|
listResponse.Contents.map(async (item) => {
|
|
if (!item.Key) return null;
|
|
|
|
// Générer une URL pré-signée valide 1 heure
|
|
const getCommand = new GetObjectCommand({
|
|
Bucket: BUCKET_NAME,
|
|
Key: item.Key,
|
|
});
|
|
|
|
const signedUrl = await getSignedUrl(s3Client, getCommand, {
|
|
expiresIn: 3600 // 1 heure
|
|
});
|
|
|
|
// Extraire le nom du fichier
|
|
const fileName = item.Key.split('/').pop() || item.Key;
|
|
|
|
// Déterminer le type de document basé sur le nom
|
|
let documentType = "Autre document";
|
|
for (const [typeKey, label] of Object.entries(FILE_TYPE_LABELS)) {
|
|
if (fileName.toLowerCase().includes(typeKey)) {
|
|
documentType = label;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return {
|
|
key: item.Key,
|
|
name: fileName,
|
|
type: documentType,
|
|
size: item.Size || 0,
|
|
lastModified: item.LastModified?.toISOString() || new Date().toISOString(),
|
|
downloadUrl: signedUrl
|
|
};
|
|
})
|
|
);
|
|
|
|
// Filtrer les nulls
|
|
const validDocuments = documents.filter(doc => doc !== null) as S3Document[];
|
|
|
|
return NextResponse.json({
|
|
documents: validDocuments,
|
|
count: validDocuments.length,
|
|
matricule
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error("Erreur récupération documents S3:", error);
|
|
return NextResponse.json(
|
|
{ error: "Erreur lors de la récupération des documents" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|