espace-paie-odentas/app/api/auto-declaration/documents/route.ts

148 lines
4.3 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 token = searchParams.get('token');
if (!token) {
return NextResponse.json({
error: "Token d'accès manquant"
}, { status: 400 });
}
// Vérifier le token et récupérer les infos du salarié
const supabase = createSbServiceRole();
const { data: tokenData, error: tokenError } = await supabase
.from('auto_declaration_tokens')
.select(`
salarie_id,
expires_at,
used,
salaries (
code_salarie
)
`)
.eq('token', token)
.single();
if (tokenError || !tokenData) {
return NextResponse.json({ error: "Token d'accès invalide" }, { status: 403 });
}
// Vérifier l'expiration du token
if (new Date() > new Date(tokenData.expires_at)) {
return NextResponse.json({ error: "Token d'accès expiré" }, { status: 403 });
}
const matricule = (tokenData.salaries as any)?.code_salarie;
if (!matricule) {
return NextResponse.json({ error: "Matricule du salarié non trouvé" }, { status: 404 });
}
// 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,
matricule
});
}
// 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 }
);
}
}