diff --git a/src/app/api/auth/login/route.ts b/src/app/api/auth/login/route.ts index 2e8c6b5..3000df2 100644 --- a/src/app/api/auth/login/route.ts +++ b/src/app/api/auth/login/route.ts @@ -1,5 +1,8 @@ import { NextResponse } from "next/server"; import { AuthServerService } from "@/lib/services/auth-server.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export async function POST(request: Request) { try { @@ -9,14 +12,17 @@ export async function POST(request: Request) { const userData = await AuthServerService.loginUser(email, password); AuthServerService.setUserCookie(userData); - return NextResponse.json({ message: "Connexion réussie", user: userData }); + return NextResponse.json({ + message: "✅ Connexion réussie", + user: userData, + }); } catch (error) { - if (error instanceof Error && error.message === "INVALID_CREDENTIALS") { + if (error instanceof AppError) { return NextResponse.json( { error: { - code: "INVALID_CREDENTIALS", - message: "Email ou mot de passe incorrect", + code: error.code, + message: ERROR_MESSAGES[error.code], }, }, { status: 401 } @@ -29,8 +35,8 @@ export async function POST(request: Request) { return NextResponse.json( { error: { - code: "SERVER_ERROR", - message: "Une erreur est survenue lors de la connexion", + code: ERROR_CODES.AUTH.INVALID_CREDENTIALS, + message: ERROR_MESSAGES[ERROR_CODES.AUTH.INVALID_CREDENTIALS], }, }, { status: 500 } diff --git a/src/app/api/auth/logout/route.ts b/src/app/api/auth/logout/route.ts index 8eee72d..986dd7a 100644 --- a/src/app/api/auth/logout/route.ts +++ b/src/app/api/auth/logout/route.ts @@ -1,9 +1,23 @@ import { NextResponse } from "next/server"; import { cookies } from "next/headers"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; export async function POST() { - // Supprimer le cookie - cookies().delete("stripUser"); - - return NextResponse.json({ message: "Déconnexion réussie" }); + try { + // Supprimer le cookie + cookies().delete("stripUser"); + return NextResponse.json({ message: "👋 Déconnexion réussie" }); + } catch (error) { + console.error("Erreur lors de la déconnexion:", error); + return NextResponse.json( + { + error: { + code: ERROR_CODES.AUTH.LOGOUT_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.AUTH.LOGOUT_ERROR], + }, + }, + { status: 500 } + ); + } } diff --git a/src/app/api/auth/register/route.ts b/src/app/api/auth/register/route.ts index 632fe92..52ae88e 100644 --- a/src/app/api/auth/register/route.ts +++ b/src/app/api/auth/register/route.ts @@ -1,5 +1,8 @@ import { NextResponse } from "next/server"; import { AuthServerService } from "@/lib/services/auth-server.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export async function POST(request: Request) { try { @@ -9,28 +12,25 @@ export async function POST(request: Request) { const userData = await AuthServerService.createUser(email, password); AuthServerService.setUserCookie(userData); - return NextResponse.json({ message: "Inscription réussie", user: userData }); + return NextResponse.json({ + message: "✅ Inscription réussie", + user: userData, + }); } catch (error) { - if (error instanceof Error && error.message === "EMAIL_EXISTS") { + if (error instanceof AppError) { + const status = + error.code === ERROR_CODES.AUTH.EMAIL_EXISTS || + error.code === ERROR_CODES.AUTH.PASSWORD_NOT_STRONG + ? 400 + : 500; return NextResponse.json( { error: { - code: "EMAIL_EXISTS", - message: "Cet email est déjà utilisé", + code: error.code, + message: ERROR_MESSAGES[error.code], }, }, - { status: 400 } - ); - } - if (error instanceof Error && error.message === "PASSWORD_NOT_STRONG") { - return NextResponse.json( - { - error: { - code: "PASSWORD_NOT_STRONG", - message: "Le mot de passe est trop faible", - }, - }, - { status: 400 } + { status } ); } throw error; @@ -40,8 +40,8 @@ export async function POST(request: Request) { return NextResponse.json( { error: { - code: "SERVER_ERROR", - message: "Une erreur est survenue lors de l'inscription", + code: ERROR_CODES.AUTH.INVALID_USER_DATA, + message: ERROR_MESSAGES[ERROR_CODES.AUTH.INVALID_USER_DATA], }, }, { status: 500 } diff --git a/src/app/api/debug/route.ts b/src/app/api/debug/route.ts index a88daec..e4055e0 100644 --- a/src/app/api/debug/route.ts +++ b/src/app/api/debug/route.ts @@ -1,12 +1,35 @@ import { NextRequest, NextResponse } from "next/server"; import { DebugService } from "@/lib/services/debug.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export async function GET() { try { const logs = await DebugService.getRequestLogs(); return NextResponse.json(logs); } catch (error) { - return NextResponse.json({ error: "Erreur lors de la récupération des logs" }, { status: 500 }); + console.error("Erreur lors de la récupération des logs:", error); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } + return NextResponse.json( + { + error: { + code: ERROR_CODES.DEBUG.FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.DEBUG.FETCH_ERROR], + }, + }, + { status: 500 } + ); } } @@ -14,17 +37,61 @@ export async function POST(request: NextRequest) { try { const timing = await request.json(); await DebugService.logRequest(timing); - return NextResponse.json({ success: true }); + return NextResponse.json({ + message: "✅ Log enregistré avec succès", + }); } catch (error) { - return NextResponse.json({ error: "Erreur lors de l'enregistrement du log" }, { status: 500 }); + console.error("Erreur lors de l'enregistrement du log:", error); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } + return NextResponse.json( + { + error: { + code: ERROR_CODES.DEBUG.SAVE_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.DEBUG.SAVE_ERROR], + }, + }, + { status: 500 } + ); } } export async function DELETE() { try { await DebugService.clearLogs(); - return NextResponse.json({ success: true }); + return NextResponse.json({ + message: "🧹 Logs supprimés avec succès", + }); } catch (error) { - return NextResponse.json({ error: "Erreur lors de la suppression des logs" }, { status: 500 }); + console.error("Erreur lors de la suppression des logs:", error); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } + return NextResponse.json( + { + error: { + code: ERROR_CODES.DEBUG.CLEAR_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.DEBUG.CLEAR_ERROR], + }, + }, + { status: 500 } + ); } } diff --git a/src/app/api/komga/books/[bookId]/pages/[pageNumber]/route.ts b/src/app/api/komga/books/[bookId]/pages/[pageNumber]/route.ts index 72fdba3..1dfa66b 100644 --- a/src/app/api/komga/books/[bookId]/pages/[pageNumber]/route.ts +++ b/src/app/api/komga/books/[bookId]/pages/[pageNumber]/route.ts @@ -1,14 +1,30 @@ -import { NextResponse } from "next/server"; +import { NextRequest, NextResponse } from "next/server"; import { BookService } from "@/lib/services/book.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export const dynamic = "force-dynamic"; export async function GET( - request: Request, + request: NextRequest, { params }: { params: { bookId: string; pageNumber: string } } ) { try { - const response = await BookService.getPage(params.bookId, parseInt(params.pageNumber)); + const pageNumber = parseInt(params.pageNumber); + if (isNaN(pageNumber) || pageNumber < 0) { + return NextResponse.json( + { + error: { + code: ERROR_CODES.IMAGE.FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.IMAGE.FETCH_ERROR], + }, + }, + { status: 400 } + ); + } + + const response = await BookService.getPage(params.bookId, pageNumber); const buffer = await response.arrayBuffer(); const headers = new Headers(); headers.set("Content-Type", response.headers.get("Content-Type") || "image/jpeg"); @@ -19,9 +35,25 @@ export async function GET( headers, }); } catch (error) { - console.error("API Book Page - Erreur:", error); + console.error("Erreur lors de la récupération de la page:", error); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } return NextResponse.json( - { error: "Erreur lors de la récupération de la page" }, + { + error: { + code: ERROR_CODES.IMAGE.FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.IMAGE.FETCH_ERROR], + }, + }, { status: 500 } ); } diff --git a/src/app/api/komga/books/[bookId]/read-progress/route.ts b/src/app/api/komga/books/[bookId]/read-progress/route.ts index bcb7284..4bf71dc 100644 --- a/src/app/api/komga/books/[bookId]/read-progress/route.ts +++ b/src/app/api/komga/books/[bookId]/read-progress/route.ts @@ -1,35 +1,76 @@ -import { NextResponse } from "next/server"; +import { NextRequest, NextResponse } from "next/server"; import { BookService } from "@/lib/services/book.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; -export async function PATCH(request: Request, { params }: { params: { bookId: string } }) { +export async function PATCH(request: NextRequest, { params }: { params: { bookId: string } }) { try { const { page, completed } = await request.json(); if (typeof page !== "number") { return NextResponse.json( - { error: "Le numéro de page est requis et doit être un nombre" }, + { + error: { + code: ERROR_CODES.BOOK.PROGRESS_UPDATE_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.BOOK.PROGRESS_UPDATE_ERROR], + }, + }, { status: 400 } ); } await BookService.updateReadProgress(params.bookId, page, completed); - return NextResponse.json({ message: "Progression mise à jour avec succès" }); + return NextResponse.json({ message: "📖 Progression mise à jour avec succès" }); } catch (error) { - console.error("API Read Progress - Erreur:", error); + console.error("Erreur lors de la mise à jour de la progression:", error); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } return NextResponse.json( - { error: "Erreur lors de la mise à jour de la progression" }, + { + error: { + code: ERROR_CODES.BOOK.PROGRESS_UPDATE_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.BOOK.PROGRESS_UPDATE_ERROR], + }, + }, { status: 500 } ); } } -export async function DELETE(request: Request, { params }: { params: { bookId: string } }) { + +export async function DELETE(request: NextRequest, { params }: { params: { bookId: string } }) { try { await BookService.deleteReadProgress(params.bookId); - return NextResponse.json({ message: "Progression supprimée avec succès" }); + return NextResponse.json({ message: "🗑️ Progression supprimée avec succès" }); } catch (error) { - console.error("API Delete Read Progress - Erreur:", error); + console.error("Erreur lors de la suppression de la progression:", error); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } return NextResponse.json( - { error: "Erreur lors de la suppression de la progression" }, + { + error: { + code: ERROR_CODES.BOOK.PROGRESS_DELETE_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.BOOK.PROGRESS_DELETE_ERROR], + }, + }, { status: 500 } ); } diff --git a/src/app/api/komga/books/[bookId]/route.ts b/src/app/api/komga/books/[bookId]/route.ts index 6df2218..0e4a6a0 100644 --- a/src/app/api/komga/books/[bookId]/route.ts +++ b/src/app/api/komga/books/[bookId]/route.ts @@ -1,5 +1,8 @@ import { NextResponse } from "next/server"; import { BookService } from "@/lib/services/book.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export async function GET(request: Request, { params }: { params: { bookId: string } }) { try { @@ -7,6 +10,25 @@ export async function GET(request: Request, { params }: { params: { bookId: stri return NextResponse.json(data); } catch (error) { console.error("API Books - Erreur:", error); - return NextResponse.json({ error: "Erreur lors de la récupération du tome" }, { status: 500 }); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } + return NextResponse.json( + { + error: { + code: ERROR_CODES.BOOK.NOT_FOUND, + message: ERROR_MESSAGES[ERROR_CODES.BOOK.NOT_FOUND], + }, + }, + { status: 500 } + ); } } diff --git a/src/app/api/komga/cache/clear/route.ts b/src/app/api/komga/cache/clear/route.ts index 5bdbcec..f58c9b1 100644 --- a/src/app/api/komga/cache/clear/route.ts +++ b/src/app/api/komga/cache/clear/route.ts @@ -1,8 +1,23 @@ import { NextResponse } from "next/server"; import { getServerCacheService } from "@/lib/services/server-cache.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; export async function POST() { - const cacheService = await getServerCacheService(); - cacheService.clear(); - return NextResponse.json({ message: "Cache cleared" }); + try { + const cacheService = await getServerCacheService(); + cacheService.clear(); + return NextResponse.json({ message: "🧹 Cache vidé avec succès" }); + } catch (error) { + console.error("Erreur lors de la suppression du cache:", error); + return NextResponse.json( + { + error: { + code: ERROR_CODES.CACHE.CLEAR_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.CACHE.CLEAR_ERROR], + }, + }, + { status: 500 } + ); + } } diff --git a/src/app/api/komga/cache/mode/route.ts b/src/app/api/komga/cache/mode/route.ts index affb6d7..3738e50 100644 --- a/src/app/api/komga/cache/mode/route.ts +++ b/src/app/api/komga/cache/mode/route.ts @@ -1,9 +1,24 @@ import { NextResponse } from "next/server"; import { getServerCacheService } from "@/lib/services/server-cache.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; export async function GET() { - const cacheService = await getServerCacheService(); - return NextResponse.json({ mode: cacheService.getCacheMode() }); + try { + const cacheService = await getServerCacheService(); + return NextResponse.json({ mode: cacheService.getCacheMode() }); + } catch (error) { + console.error("Erreur lors de la récupération du mode de cache:", error); + return NextResponse.json( + { + error: { + code: ERROR_CODES.CACHE.MODE_FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.CACHE.MODE_FETCH_ERROR], + }, + }, + { status: 500 } + ); + } } export async function POST(request: Request) { @@ -11,7 +26,12 @@ export async function POST(request: Request) { const { mode } = await request.json(); if (mode !== "file" && mode !== "memory") { return NextResponse.json( - { error: "Invalid mode. Must be 'file' or 'memory'" }, + { + error: { + code: ERROR_CODES.CACHE.INVALID_MODE, + message: ERROR_MESSAGES[ERROR_CODES.CACHE.INVALID_MODE], + }, + }, { status: 400 } ); } @@ -21,6 +41,14 @@ export async function POST(request: Request) { return NextResponse.json({ mode: cacheService.getCacheMode() }); } catch (error) { console.error("Erreur lors de la mise à jour du mode de cache:", error); - return NextResponse.json({ error: "Invalid request" }, { status: 400 }); + return NextResponse.json( + { + error: { + code: ERROR_CODES.CACHE.MODE_UPDATE_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.CACHE.MODE_UPDATE_ERROR], + }, + }, + { status: 500 } + ); } } diff --git a/src/app/api/komga/config/route.ts b/src/app/api/komga/config/route.ts index 003e47b..826eb54 100644 --- a/src/app/api/komga/config/route.ts +++ b/src/app/api/komga/config/route.ts @@ -1,5 +1,7 @@ import { NextResponse } from "next/server"; import { ConfigDBService } from "@/lib/services/config-db.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; export const dynamic = "force-dynamic"; @@ -15,16 +17,29 @@ export async function POST(request: Request) { userId: mongoConfig.userId, }; return NextResponse.json( - { message: "Configuration sauvegardée avec succès", config }, + { message: "⚙️ Configuration sauvegardée avec succès", config }, { status: 200 } ); } catch (error) { console.error("Erreur lors de la sauvegarde de la configuration:", error); if (error instanceof Error && error.message === "Utilisateur non authentifié") { - return NextResponse.json({ error: "Non autorisé" }, { status: 401 }); + return NextResponse.json( + { + error: { + code: ERROR_CODES.MIDDLEWARE.UNAUTHORIZED, + message: ERROR_MESSAGES[ERROR_CODES.MIDDLEWARE.UNAUTHORIZED], + }, + }, + { status: 401 } + ); } return NextResponse.json( - { error: "Erreur lors de la sauvegarde de la configuration" }, + { + error: { + code: ERROR_CODES.CONFIG.SAVE_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.CONFIG.SAVE_ERROR], + }, + }, { status: 500 } ); } @@ -45,14 +60,35 @@ export async function GET() { console.error("Erreur lors de la récupération de la configuration:", error); if (error instanceof Error) { if (error.message === "Utilisateur non authentifié") { - return NextResponse.json({ error: "Non autorisé" }, { status: 401 }); + return NextResponse.json( + { + error: { + code: ERROR_CODES.MIDDLEWARE.UNAUTHORIZED, + message: ERROR_MESSAGES[ERROR_CODES.MIDDLEWARE.UNAUTHORIZED], + }, + }, + { status: 401 } + ); } if (error.message === "Configuration non trouvée") { - return NextResponse.json({ error: "Configuration non trouvée" }, { status: 404 }); + return NextResponse.json( + { + error: { + code: ERROR_CODES.KOMGA.MISSING_CONFIG, + message: ERROR_MESSAGES[ERROR_CODES.KOMGA.MISSING_CONFIG], + }, + }, + { status: 404 } + ); } } return NextResponse.json( - { error: "Erreur lors de la récupération de la configuration" }, + { + error: { + code: ERROR_CODES.CONFIG.FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.CONFIG.FETCH_ERROR], + }, + }, { status: 500 } ); } diff --git a/src/app/api/komga/favorites/route.ts b/src/app/api/komga/favorites/route.ts index 6299109..40e8dab 100644 --- a/src/app/api/komga/favorites/route.ts +++ b/src/app/api/komga/favorites/route.ts @@ -1,5 +1,8 @@ import { NextResponse } from "next/server"; import { FavoriteService } from "@/lib/services/favorite.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export async function GET() { try { @@ -7,8 +10,24 @@ export async function GET() { return NextResponse.json(favoriteIds); } catch (error) { console.error("Erreur lors de la récupération des favoris:", error); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } return NextResponse.json( - { error: "Erreur lors de la récupération des favoris" }, + { + error: { + code: ERROR_CODES.FAVORITE.FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.FAVORITE.FETCH_ERROR], + }, + }, { status: 500 } ); } @@ -18,10 +37,29 @@ export async function POST(request: Request) { try { const { seriesId } = await request.json(); await FavoriteService.addToFavorites(seriesId); - return NextResponse.json({ message: "Favori ajouté avec succès" }); + return NextResponse.json({ message: "⭐️ Série ajoutée aux favoris" }); } catch (error) { console.error("Erreur lors de l'ajout du favori:", error); - return NextResponse.json({ error: "Erreur lors de l'ajout du favori" }, { status: 500 }); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } + return NextResponse.json( + { + error: { + code: ERROR_CODES.FAVORITE.ADD_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.FAVORITE.ADD_ERROR], + }, + }, + { status: 500 } + ); } } @@ -29,9 +67,28 @@ export async function DELETE(request: Request) { try { const { seriesId } = await request.json(); await FavoriteService.removeFromFavorites(seriesId); - return NextResponse.json({ message: "Favori supprimé avec succès" }); + return NextResponse.json({ message: "💔 Série retirée des favoris" }); } catch (error) { console.error("Erreur lors de la suppression du favori:", error); - return NextResponse.json({ error: "Erreur lors de la suppression du favori" }, { status: 500 }); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } + return NextResponse.json( + { + error: { + code: ERROR_CODES.FAVORITE.DELETE_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.FAVORITE.DELETE_ERROR], + }, + }, + { status: 500 } + ); } } diff --git a/src/app/api/komga/images/books/[bookId]/pages/[pageNumber]/route.ts b/src/app/api/komga/images/books/[bookId]/pages/[pageNumber]/route.ts index dacb942..a266567 100644 --- a/src/app/api/komga/images/books/[bookId]/pages/[pageNumber]/route.ts +++ b/src/app/api/komga/images/books/[bookId]/pages/[pageNumber]/route.ts @@ -1,5 +1,8 @@ import { NextRequest, NextResponse } from "next/server"; import { BookService } from "@/lib/services/book.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export const dynamic = "force-dynamic"; @@ -12,6 +15,25 @@ export async function GET( return response; } catch (error) { console.error("Erreur lors de la récupération de la page du livre:", error); - return new NextResponse("Erreur lors de la récupération de la page", { status: 500 }); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } + return NextResponse.json( + { + error: { + code: ERROR_CODES.IMAGE.FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.IMAGE.FETCH_ERROR], + }, + }, + { status: 500 } + ); } } diff --git a/src/app/api/komga/images/books/[bookId]/pages/[pageNumber]/thumbnail/route.ts b/src/app/api/komga/images/books/[bookId]/pages/[pageNumber]/thumbnail/route.ts index 851d3e2..9616e42 100644 --- a/src/app/api/komga/images/books/[bookId]/pages/[pageNumber]/thumbnail/route.ts +++ b/src/app/api/komga/images/books/[bookId]/pages/[pageNumber]/thumbnail/route.ts @@ -1,28 +1,52 @@ -import { NextResponse } from "next/server"; +import { NextRequest, NextResponse } from "next/server"; import { BookService } from "@/lib/services/book.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export const dynamic = "force-dynamic"; export async function GET( - request: Request, + request: NextRequest, { params }: { params: { bookId: string; pageNumber: string } } ) { try { // Convertir le numéro de page en nombre const pageNumber = parseInt(params.pageNumber); if (isNaN(pageNumber) || pageNumber < 0) { - return NextResponse.json({ error: "Numéro de page invalide" }, { status: 400 }); + return NextResponse.json( + { + error: { + code: ERROR_CODES.BOOK.PAGES_FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.BOOK.PAGES_FETCH_ERROR], + }, + }, + { status: 400 } + ); } const response = await BookService.getPageThumbnail(params.bookId, pageNumber); return response; } catch (error) { - console.error("API Book Page Thumbnail - Erreur:", error); - if (error instanceof Error) { - return NextResponse.json({ error: error.message }, { status: 500 }); + console.error("Erreur lors de la récupération de la miniature de la page:", error); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); } return NextResponse.json( - { error: "Une erreur est survenue lors de la récupération de la miniature" }, + { + error: { + code: ERROR_CODES.IMAGE.FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.IMAGE.FETCH_ERROR], + }, + }, { status: 500 } ); } diff --git a/src/app/api/komga/images/books/[bookId]/thumbnail/route.ts b/src/app/api/komga/images/books/[bookId]/thumbnail/route.ts index ef228fe..d514f17 100644 --- a/src/app/api/komga/images/books/[bookId]/thumbnail/route.ts +++ b/src/app/api/komga/images/books/[bookId]/thumbnail/route.ts @@ -1,5 +1,8 @@ import { NextRequest, NextResponse } from "next/server"; import { BookService } from "@/lib/services/book.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export async function GET(request: NextRequest, { params }: { params: { bookId: string } }) { try { @@ -7,6 +10,25 @@ export async function GET(request: NextRequest, { params }: { params: { bookId: return response; } catch (error) { console.error("Erreur lors de la récupération de la miniature du livre:", error); - return new NextResponse("Erreur lors de la récupération de la miniature", { status: 500 }); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } + return NextResponse.json( + { + error: { + code: ERROR_CODES.IMAGE.FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.IMAGE.FETCH_ERROR], + }, + }, + { status: 500 } + ); } } diff --git a/src/app/api/komga/images/series/[seriesId]/first-page/route.ts b/src/app/api/komga/images/series/[seriesId]/first-page/route.ts index a8b62fc..82329dc 100644 --- a/src/app/api/komga/images/series/[seriesId]/first-page/route.ts +++ b/src/app/api/komga/images/series/[seriesId]/first-page/route.ts @@ -1,5 +1,8 @@ import { NextRequest, NextResponse } from "next/server"; import { SeriesService } from "@/lib/services/series.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export const dynamic = "force-dynamic"; @@ -9,6 +12,25 @@ export async function GET(request: NextRequest, { params }: { params: { seriesId return response; } catch (error) { console.error("Erreur lors de la récupération de la couverture de la série:", error); - return new NextResponse("Erreur lors de la récupération de la couverture", { status: 500 }); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } + return NextResponse.json( + { + error: { + code: ERROR_CODES.IMAGE.FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.IMAGE.FETCH_ERROR], + }, + }, + { status: 500 } + ); } } diff --git a/src/app/api/komga/images/series/[seriesId]/thumbnail/route.ts b/src/app/api/komga/images/series/[seriesId]/thumbnail/route.ts index 23472d9..584b926 100644 --- a/src/app/api/komga/images/series/[seriesId]/thumbnail/route.ts +++ b/src/app/api/komga/images/series/[seriesId]/thumbnail/route.ts @@ -1,5 +1,8 @@ import { NextRequest, NextResponse } from "next/server"; import { SeriesService } from "@/lib/services/series.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export async function GET(request: NextRequest, { params }: { params: { seriesId: string } }) { try { @@ -7,6 +10,25 @@ export async function GET(request: NextRequest, { params }: { params: { seriesId return response; } catch (error) { console.error("Erreur lors de la récupération de la miniature de la série:", error); - return new NextResponse("Erreur lors de la récupération de la miniature", { status: 500 }); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } + return NextResponse.json( + { + error: { + code: ERROR_CODES.IMAGE.FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.IMAGE.FETCH_ERROR], + }, + }, + { status: 500 } + ); } } diff --git a/src/app/api/komga/libraries/route.ts b/src/app/api/komga/libraries/route.ts index c8648f1..8a6422f 100644 --- a/src/app/api/komga/libraries/route.ts +++ b/src/app/api/komga/libraries/route.ts @@ -1,5 +1,8 @@ import { NextResponse } from "next/server"; import { LibraryService } from "@/lib/services/library.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export const dynamic = "force-dynamic"; @@ -9,6 +12,25 @@ export async function GET() { return NextResponse.json(libraries); } catch (error) { console.error("API Libraries - Erreur:", error); - return NextResponse.json({ error: "Erreur serveur" }, { status: 500 }); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } + return NextResponse.json( + { + error: { + code: ERROR_CODES.LIBRARY.FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.LIBRARY.FETCH_ERROR], + }, + }, + { status: 500 } + ); } } diff --git a/src/app/api/komga/series/[seriesId]/route.ts b/src/app/api/komga/series/[seriesId]/route.ts index 5a6d502..34815ae 100644 --- a/src/app/api/komga/series/[seriesId]/route.ts +++ b/src/app/api/komga/series/[seriesId]/route.ts @@ -1,5 +1,8 @@ import { NextResponse } from "next/server"; import { SeriesService } from "@/lib/services/series.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export const dynamic = "force-dynamic"; @@ -9,8 +12,24 @@ export async function GET(request: Request, { params }: { params: { seriesId: st return NextResponse.json(series); } catch (error) { console.error("API Series - Erreur:", error); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } return NextResponse.json( - { error: "Erreur lors de la récupération de la série" }, + { + error: { + code: ERROR_CODES.SERIES.FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.SERIES.FETCH_ERROR], + }, + }, { status: 500 } ); } diff --git a/src/app/api/komga/test/route.ts b/src/app/api/komga/test/route.ts index 85540c2..595e1f5 100644 --- a/src/app/api/komga/test/route.ts +++ b/src/app/api/komga/test/route.ts @@ -1,5 +1,7 @@ import { NextResponse } from "next/server"; import { TestService } from "@/lib/services/test.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; export async function POST(request: Request) { try { @@ -12,14 +14,18 @@ export async function POST(request: Request) { }); return NextResponse.json({ - message: "Connexion réussie", - librariesCount: libraries.length, + message: `✅ Connexion réussie ! ${libraries.length} bibliothèque${ + libraries.length > 1 ? "s" : "" + } trouvée${libraries.length > 1 ? "s" : ""}`, }); } catch (error) { console.error("Erreur lors du test de connexion:", error); return NextResponse.json( { - error: error instanceof Error ? error.message : "Erreur inconnue", + error: { + code: ERROR_CODES.KOMGA.CONNECTION_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.KOMGA.CONNECTION_ERROR], + }, }, { status: 400 } ); diff --git a/src/app/api/komga/ttl-config/route.ts b/src/app/api/komga/ttl-config/route.ts index 2b0923d..57a2bf9 100644 --- a/src/app/api/komga/ttl-config/route.ts +++ b/src/app/api/komga/ttl-config/route.ts @@ -1,5 +1,7 @@ import { NextResponse } from "next/server"; import { ConfigDBService } from "@/lib/services/config-db.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; export async function GET() { try { @@ -9,11 +11,24 @@ export async function GET() { console.error("Erreur lors de la récupération de la configuration TTL:", error); if (error instanceof Error) { if (error.message === "Utilisateur non authentifié") { - return NextResponse.json({ error: "Non autorisé" }, { status: 401 }); + return NextResponse.json( + { + error: { + code: ERROR_CODES.MIDDLEWARE.UNAUTHORIZED, + message: ERROR_MESSAGES[ERROR_CODES.MIDDLEWARE.UNAUTHORIZED], + }, + }, + { status: 401 } + ); } } return NextResponse.json( - { error: "Erreur lors de la récupération de la configuration TTL" }, + { + error: { + code: ERROR_CODES.CONFIG.TTL_FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.CONFIG.TTL_FETCH_ERROR], + }, + }, { status: 500 } ); } @@ -24,7 +39,7 @@ export async function POST(request: Request) { const data = await request.json(); const config = await ConfigDBService.saveTTLConfig(data); return NextResponse.json({ - message: "Configuration TTL sauvegardée avec succès", + message: "⏱️ Configuration TTL sauvegardée avec succès", config: { defaultTTL: config.defaultTTL, homeTTL: config.homeTTL, @@ -37,10 +52,23 @@ export async function POST(request: Request) { } catch (error) { console.error("Erreur lors de la sauvegarde de la configuration TTL:", error); if (error instanceof Error && error.message === "Utilisateur non authentifié") { - return NextResponse.json({ error: "Non autorisé" }, { status: 401 }); + return NextResponse.json( + { + error: { + code: ERROR_CODES.MIDDLEWARE.UNAUTHORIZED, + message: ERROR_MESSAGES[ERROR_CODES.MIDDLEWARE.UNAUTHORIZED], + }, + }, + { status: 401 } + ); } return NextResponse.json( - { error: "Erreur lors de la sauvegarde de la configuration TTL" }, + { + error: { + code: ERROR_CODES.CONFIG.TTL_SAVE_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.CONFIG.TTL_SAVE_ERROR], + }, + }, { status: 500 } ); } diff --git a/src/app/api/preferences/route.ts b/src/app/api/preferences/route.ts index 9d656de..fafebc1 100644 --- a/src/app/api/preferences/route.ts +++ b/src/app/api/preferences/route.ts @@ -1,5 +1,8 @@ import { NextRequest, NextResponse } from "next/server"; import { PreferencesService } from "@/lib/services/preferences.service"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; +import { AppError } from "@/utils/errors"; export async function GET() { try { @@ -7,7 +10,26 @@ export async function GET() { return NextResponse.json(preferences); } catch (error) { console.error("Erreur lors de la récupération des préférences:", error); - return new NextResponse("Erreur lors de la récupération des préférences", { status: 500 }); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } + return NextResponse.json( + { + error: { + code: ERROR_CODES.PREFERENCES.FETCH_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.PREFERENCES.FETCH_ERROR], + }, + }, + { status: 500 } + ); } } @@ -18,6 +40,25 @@ export async function PUT(request: NextRequest) { return NextResponse.json(updatedPreferences); } catch (error) { console.error("Erreur lors de la mise à jour des préférences:", error); - return new NextResponse("Erreur lors de la mise à jour des préférences", { status: 500 }); + if (error instanceof AppError) { + return NextResponse.json( + { + error: { + code: error.code, + message: ERROR_MESSAGES[error.code], + }, + }, + { status: 500 } + ); + } + return NextResponse.json( + { + error: { + code: ERROR_CODES.PREFERENCES.UPDATE_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.PREFERENCES.UPDATE_ERROR], + }, + }, + { status: 500 } + ); } } diff --git a/src/components/auth/RegisterForm.tsx b/src/components/auth/RegisterForm.tsx index c5c4e43..b85ed2a 100644 --- a/src/components/auth/RegisterForm.tsx +++ b/src/components/auth/RegisterForm.tsx @@ -4,6 +4,8 @@ import { useState } from "react"; import { useRouter } from "next/navigation"; import { authService } from "@/lib/services/auth.service"; import { AuthError } from "@/types/auth"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; interface RegisterFormProps { from?: string; @@ -26,8 +28,8 @@ export function RegisterForm({ from }: RegisterFormProps) { if (password !== confirmPassword) { setError({ - code: "SERVER_ERROR", - message: "Les mots de passe ne correspondent pas", + code: ERROR_CODES.AUTH.PASSWORD_MISMATCH, + message: ERROR_MESSAGES[ERROR_CODES.AUTH.PASSWORD_MISMATCH], }); setIsLoading(false); return; diff --git a/src/constants/errorCodes.ts b/src/constants/errorCodes.ts index d50d557..b045e7f 100644 --- a/src/constants/errorCodes.ts +++ b/src/constants/errorCodes.ts @@ -7,8 +7,10 @@ export const ERROR_CODES = { UNAUTHENTICATED: "AUTH_UNAUTHENTICATED", INVALID_CREDENTIALS: "AUTH_INVALID_CREDENTIALS", PASSWORD_NOT_STRONG: "AUTH_PASSWORD_NOT_STRONG", + PASSWORD_MISMATCH: "AUTH_PASSWORD_MISMATCH", EMAIL_EXISTS: "AUTH_EMAIL_EXISTS", INVALID_USER_DATA: "AUTH_INVALID_USER_DATA", + LOGOUT_ERROR: "AUTH_LOGOUT_ERROR", }, KOMGA: { MISSING_CONFIG: "KOMGA_MISSING_CONFIG", @@ -54,6 +56,9 @@ export const ERROR_CODES = { SAVE_ERROR: "CACHE_SAVE_ERROR", LOAD_ERROR: "CACHE_LOAD_ERROR", CLEAR_ERROR: "CACHE_CLEAR_ERROR", + MODE_FETCH_ERROR: "CACHE_MODE_FETCH_ERROR", + MODE_UPDATE_ERROR: "CACHE_MODE_UPDATE_ERROR", + INVALID_MODE: "CACHE_INVALID_MODE", }, UI: { TABS_TRIGGER_ERROR: "UI_TABS_TRIGGER_ERROR", @@ -65,6 +70,16 @@ export const ERROR_CODES = { HOME: { FETCH_ERROR: "HOME_FETCH_ERROR", }, + MIDDLEWARE: { + UNAUTHORIZED: "MIDDLEWARE_UNAUTHORIZED", + INVALID_TOKEN: "MIDDLEWARE_INVALID_TOKEN", + INVALID_SESSION: "MIDDLEWARE_INVALID_SESSION", + }, + DEBUG: { + FETCH_ERROR: "DEBUG_FETCH_ERROR", + SAVE_ERROR: "DEBUG_SAVE_ERROR", + CLEAR_ERROR: "DEBUG_CLEAR_ERROR", + }, } as const; type ValueOf = T[keyof T]; diff --git a/src/constants/errorMessages.ts b/src/constants/errorMessages.ts index a6230d0..7b78930 100644 --- a/src/constants/errorMessages.ts +++ b/src/constants/errorMessages.ts @@ -1,6 +1,11 @@ import { ERROR_CODES } from "./errorCodes"; export const ERROR_MESSAGES: Record = { + // Middleware + [ERROR_CODES.MIDDLEWARE.UNAUTHORIZED]: "🚫 Accès non autorisé", + [ERROR_CODES.MIDDLEWARE.INVALID_TOKEN]: "🔐 Session invalide ou expirée", + [ERROR_CODES.MIDDLEWARE.INVALID_SESSION]: "⚠️ Données de session invalides", + // MongoDB [ERROR_CODES.MONGODB.MISSING_URI]: "🔧 Veuillez définir la variable d'environnement MONGODB_URI dans votre fichier .env", @@ -10,8 +15,10 @@ export const ERROR_MESSAGES: Record = { [ERROR_CODES.AUTH.UNAUTHENTICATED]: "🔒 Utilisateur non authentifié", [ERROR_CODES.AUTH.INVALID_CREDENTIALS]: "⛔️ Identifiants invalides", [ERROR_CODES.AUTH.PASSWORD_NOT_STRONG]: "💪 Le mot de passe n'est pas assez fort", + [ERROR_CODES.AUTH.PASSWORD_MISMATCH]: "❌ Les mots de passe ne correspondent pas", [ERROR_CODES.AUTH.EMAIL_EXISTS]: "📧 Cette adresse email est déjà utilisée", [ERROR_CODES.AUTH.INVALID_USER_DATA]: "👤 Données utilisateur invalides", + [ERROR_CODES.AUTH.LOGOUT_ERROR]: "🚪 Erreur lors de la déconnexion", // Komga [ERROR_CODES.KOMGA.MISSING_CONFIG]: "⚙️ Configuration Komga non trouvée", @@ -53,6 +60,9 @@ export const ERROR_MESSAGES: Record = { [ERROR_CODES.CACHE.SAVE_ERROR]: "💾 Erreur lors de la sauvegarde dans le cache", [ERROR_CODES.CACHE.LOAD_ERROR]: "📂 Erreur lors du chargement du cache", [ERROR_CODES.CACHE.CLEAR_ERROR]: "🧹 Erreur lors de la suppression complète du cache", + [ERROR_CODES.CACHE.MODE_FETCH_ERROR]: "⚙️ Erreur lors de la récupération du mode de cache", + [ERROR_CODES.CACHE.MODE_UPDATE_ERROR]: "⚙️ Erreur lors de la mise à jour du mode de cache", + [ERROR_CODES.CACHE.INVALID_MODE]: "⚠️ Mode de cache invalide. Doit être 'file' ou 'memory'", // UI [ERROR_CODES.UI.TABS_TRIGGER_ERROR]: "🔄 TabsTrigger doit être utilisé dans un composant Tabs", @@ -70,4 +80,9 @@ export const ERROR_MESSAGES: Record = { [ERROR_CODES.CONFIG.FETCH_ERROR]: "⚙️ Erreur lors de la récupération de la configuration", [ERROR_CODES.CONFIG.TTL_SAVE_ERROR]: "⏱️ Erreur lors de la sauvegarde de la configuration TTL", [ERROR_CODES.CONFIG.TTL_FETCH_ERROR]: "⏱️ Erreur lors de la récupération de la configuration TTL", + + // Debug + [ERROR_CODES.DEBUG.FETCH_ERROR]: "🔍 Erreur lors de la récupération des logs", + [ERROR_CODES.DEBUG.SAVE_ERROR]: "💾 Erreur lors de l'enregistrement du log", + [ERROR_CODES.DEBUG.CLEAR_ERROR]: "🧹 Erreur lors de la suppression des logs", } as const; diff --git a/src/contexts/PreferencesContext.tsx b/src/contexts/PreferencesContext.tsx index 4b2b378..6dc3620 100644 --- a/src/contexts/PreferencesContext.tsx +++ b/src/contexts/PreferencesContext.tsx @@ -1,6 +1,8 @@ "use client"; import React, { createContext, useContext, useEffect, useState } from "react"; +import { ERROR_CODES } from "../constants/errorCodes"; +import { AppError } from "../utils/errors"; export interface UserPreferences { showThumbnails: boolean; @@ -31,7 +33,9 @@ export function PreferencesProvider({ children }: { children: React.ReactNode }) const fetchPreferences = async () => { try { const response = await fetch("/api/preferences"); - if (!response.ok) throw new Error("Erreur lors de la récupération des préférences"); + if (!response.ok) { + throw new AppError(ERROR_CODES.PREFERENCES.FETCH_ERROR); + } const data = await response.json(); setPreferences({ ...defaultPreferences, @@ -60,7 +64,9 @@ export function PreferencesProvider({ children }: { children: React.ReactNode }) body: JSON.stringify(newPreferences), }); - if (!response.ok) throw new Error("Erreur lors de la mise à jour des préférences"); + if (!response.ok) { + throw new AppError(ERROR_CODES.PREFERENCES.UPDATE_ERROR); + } const updatedPreferences = await response.json(); @@ -89,7 +95,7 @@ export function PreferencesProvider({ children }: { children: React.ReactNode }) export function usePreferences() { const context = useContext(PreferencesContext); if (context === undefined) { - throw new Error("usePreferences must be used within a PreferencesProvider"); + throw new AppError(ERROR_CODES.PREFERENCES.CONTEXT_ERROR); } return context; } diff --git a/src/lib/registerSW.ts b/src/lib/registerSW.ts index 34b7cec..3dee270 100644 --- a/src/lib/registerSW.ts +++ b/src/lib/registerSW.ts @@ -4,8 +4,8 @@ export const registerServiceWorker = async () => { } try { - const registration = await navigator.serviceWorker.register("/sw.js"); - console.log("Service Worker registered with scope:", registration.scope); + await navigator.serviceWorker.register("/sw.js"); + // console.log("Service Worker registered with scope:", registration.scope); } catch (error) { console.error("Service Worker registration failed:", error); } diff --git a/src/lib/services/auth.service.ts b/src/lib/services/auth.service.ts index d1b7f96..549b617 100644 --- a/src/lib/services/auth.service.ts +++ b/src/lib/services/auth.service.ts @@ -1,6 +1,8 @@ "use client"; import { AuthError } from "@/types/auth"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import { ERROR_MESSAGES } from "@/constants/errorMessages"; class AuthService { private static instance: AuthService; @@ -39,8 +41,8 @@ class AuthService { throw error; } throw { - code: "SERVER_ERROR", - message: "Une erreur est survenue lors de la connexion", + code: ERROR_CODES.AUTH.INVALID_CREDENTIALS, + message: ERROR_MESSAGES[ERROR_CODES.AUTH.INVALID_CREDENTIALS], } as AuthError; } } @@ -67,8 +69,8 @@ class AuthService { throw error; } throw { - code: "SERVER_ERROR", - message: "Une erreur est survenue lors de l'inscription", + code: ERROR_CODES.AUTH.INVALID_USER_DATA, + message: ERROR_MESSAGES[ERROR_CODES.AUTH.INVALID_USER_DATA], } as AuthError; } } @@ -77,9 +79,24 @@ class AuthService { * Déconnecte l'utilisateur */ async logout(): Promise { - await fetch("/api/auth/logout", { - method: "POST", - }); + try { + const response = await fetch("/api/auth/logout", { + method: "POST", + }); + + if (!response.ok) { + const data = await response.json(); + throw data.error; + } + } catch (error) { + if ((error as AuthError).code) { + throw error; + } + throw { + code: ERROR_CODES.AUTH.LOGOUT_ERROR, + message: ERROR_MESSAGES[ERROR_CODES.AUTH.LOGOUT_ERROR], + } as AuthError; + } } } diff --git a/src/middleware.ts b/src/middleware.ts index af8f6af..9a4029f 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,5 +1,7 @@ import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; +import { ERROR_CODES } from "./constants/errorCodes"; +import { ERROR_MESSAGES } from "./constants/errorMessages"; // Routes qui ne nécessitent pas d'authentification const publicRoutes = ["/login", "/register", "/images"]; @@ -30,7 +32,10 @@ export function middleware(request: NextRequest) { // Pour toutes les routes protégées, vérifier la présence de l'utilisateur if (!user || !user.value) { if (pathname.startsWith("/api/")) { - return NextResponse.json({ error: "Non autorisé" }, { status: 401 }); + return NextResponse.json( + { error: ERROR_MESSAGES[ERROR_CODES.MIDDLEWARE.UNAUTHORIZED] }, + { status: 401 } + ); } const loginUrl = new URL("/login", request.url); loginUrl.searchParams.set("from", pathname); @@ -40,12 +45,15 @@ export function middleware(request: NextRequest) { try { const userData = JSON.parse(atob(user.value)); if (!userData || !userData.authenticated || !userData.id || !userData.email) { - throw new Error("Invalid user data"); + throw new Error(ERROR_MESSAGES[ERROR_CODES.MIDDLEWARE.INVALID_SESSION]); } } catch (error) { console.error("Erreur de validation du cookie:", error); if (pathname.startsWith("/api/")) { - return NextResponse.json({ error: "Non autorisé" }, { status: 401 }); + return NextResponse.json( + { error: ERROR_MESSAGES[ERROR_CODES.MIDDLEWARE.INVALID_TOKEN] }, + { status: 401 } + ); } const loginUrl = new URL("/login", request.url); loginUrl.searchParams.set("from", pathname); diff --git a/src/types/auth.ts b/src/types/auth.ts index ae98dfd..2df8363 100644 --- a/src/types/auth.ts +++ b/src/types/auth.ts @@ -1,4 +1,5 @@ import { KomgaUser } from "./komga"; +import { ErrorCode } from "@/constants/errorCodes"; export interface AuthConfig { serverUrl: string; @@ -12,8 +13,9 @@ export interface AuthState { } export interface AuthError { - code: AuthErrorCode; + code: ErrorCode; message: string; } -export type AuthErrorCode = "INVALID_CREDENTIALS" | "SERVER_ERROR" | "EMAIL_EXISTS"; +// Deprecated - Use ErrorCode from @/constants/errorCodes instead +export type AuthErrorCode = ErrorCode;