fix: reduce unauthenticated log noise and add request path context
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 4m46s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 4m46s
This commit is contained in:
@@ -7,7 +7,7 @@ import { PreferencesService } from "@/lib/services/preferences.service";
|
|||||||
import { PreferencesProvider } from "@/contexts/PreferencesContext";
|
import { PreferencesProvider } from "@/contexts/PreferencesContext";
|
||||||
import { I18nProvider } from "@/components/providers/I18nProvider";
|
import { I18nProvider } from "@/components/providers/I18nProvider";
|
||||||
import { AuthProvider } from "@/components/providers/AuthProvider";
|
import { AuthProvider } from "@/components/providers/AuthProvider";
|
||||||
import { cookies } from "next/headers";
|
import { cookies, headers } from "next/headers";
|
||||||
import { defaultPreferences } from "@/types/preferences";
|
import { defaultPreferences } from "@/types/preferences";
|
||||||
import type { UserPreferences } from "@/types/preferences";
|
import type { UserPreferences } from "@/types/preferences";
|
||||||
import type { KomgaLibrary, KomgaSeries } from "@/types/komga";
|
import type { KomgaLibrary, KomgaSeries } from "@/types/komga";
|
||||||
@@ -70,7 +70,10 @@ export const metadata: Metadata = {
|
|||||||
|
|
||||||
export default async function RootLayout({ children }: { children: React.ReactNode }) {
|
export default async function RootLayout({ children }: { children: React.ReactNode }) {
|
||||||
const cookieStore = await cookies();
|
const cookieStore = await cookies();
|
||||||
|
const requestHeaders = await headers();
|
||||||
const locale = cookieStore.get("NEXT_LOCALE")?.value || "fr";
|
const locale = cookieStore.get("NEXT_LOCALE")?.value || "fr";
|
||||||
|
const requestPath = requestHeaders.get("x-request-path") || "unknown";
|
||||||
|
const requestPathname = requestHeaders.get("x-request-pathname") || "unknown";
|
||||||
|
|
||||||
let preferences: UserPreferences = defaultPreferences;
|
let preferences: UserPreferences = defaultPreferences;
|
||||||
let userIsAdmin = false;
|
let userIsAdmin = false;
|
||||||
@@ -78,21 +81,23 @@ export default async function RootLayout({ children }: { children: React.ReactNo
|
|||||||
let favorites: KomgaSeries[] = [];
|
let favorites: KomgaSeries[] = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [preferencesData, isAdminCheck, librariesData, favoritesData] = await Promise.allSettled([
|
const currentUser = await import("@/lib/auth-utils").then((m) => m.getCurrentUser());
|
||||||
|
|
||||||
|
if (currentUser) {
|
||||||
|
const [preferencesData, librariesData, favoritesData] = await Promise.allSettled([
|
||||||
PreferencesService.getPreferences(),
|
PreferencesService.getPreferences(),
|
||||||
import("@/lib/auth-utils").then((m) => m.isAdmin()),
|
|
||||||
import("@/lib/services/library.service").then((m) => m.LibraryService.getLibraries()),
|
import("@/lib/services/library.service").then((m) => m.LibraryService.getLibraries()),
|
||||||
import("@/lib/services/favorites.service").then((m) => m.FavoritesService.getFavorites()),
|
import("@/lib/services/favorites.service").then((m) =>
|
||||||
|
m.FavoritesService.getFavorites({ requestPath, requestPathname })
|
||||||
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
userIsAdmin = currentUser.roles.includes("ROLE_ADMIN");
|
||||||
|
|
||||||
if (preferencesData.status === "fulfilled") {
|
if (preferencesData.status === "fulfilled") {
|
||||||
preferences = preferencesData.value;
|
preferences = preferencesData.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAdminCheck.status === "fulfilled") {
|
|
||||||
userIsAdmin = isAdminCheck.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (librariesData.status === "fulfilled") {
|
if (librariesData.status === "fulfilled") {
|
||||||
libraries = librariesData.value || [];
|
libraries = librariesData.value || [];
|
||||||
}
|
}
|
||||||
@@ -100,8 +105,12 @@ export default async function RootLayout({ children }: { children: React.ReactNo
|
|||||||
if (favoritesData.status === "fulfilled") {
|
if (favoritesData.status === "fulfilled") {
|
||||||
favorites = favoritesData.value;
|
favorites = favoritesData.value;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error({ err: error }, "Erreur lors du chargement des données initiales:");
|
logger.error(
|
||||||
|
{ err: error, requestPath, requestPathname },
|
||||||
|
"Erreur lors du chargement des données initiales:"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -4,7 +4,10 @@ import type { KomgaSeries } from "@/types/komga";
|
|||||||
import logger from "@/lib/logger";
|
import logger from "@/lib/logger";
|
||||||
|
|
||||||
export class FavoritesService {
|
export class FavoritesService {
|
||||||
static async getFavorites(): Promise<KomgaSeries[]> {
|
static async getFavorites(context?: {
|
||||||
|
requestPath?: string;
|
||||||
|
requestPathname?: string;
|
||||||
|
}): Promise<KomgaSeries[]> {
|
||||||
try {
|
try {
|
||||||
const favoriteIds = await FavoriteService.getAllFavoriteIds();
|
const favoriteIds = await FavoriteService.getAllFavoriteIds();
|
||||||
|
|
||||||
@@ -17,7 +20,15 @@ export class FavoritesService {
|
|||||||
try {
|
try {
|
||||||
return await SeriesService.getSeries(id);
|
return await SeriesService.getSeries(id);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error({ err: error, seriesId: id }, "Error fetching favorite series");
|
logger.error(
|
||||||
|
{
|
||||||
|
err: error,
|
||||||
|
seriesId: id,
|
||||||
|
requestPath: context?.requestPath,
|
||||||
|
requestPathname: context?.requestPathname,
|
||||||
|
},
|
||||||
|
"Error fetching favorite series"
|
||||||
|
);
|
||||||
// Si la série n'existe plus, la retirer des favoris
|
// Si la série n'existe plus, la retirer des favoris
|
||||||
try {
|
try {
|
||||||
await FavoriteService.removeFromFavorites(id);
|
await FavoriteService.removeFromFavorites(id);
|
||||||
@@ -31,9 +42,15 @@ export class FavoritesService {
|
|||||||
const results = await Promise.all(promises);
|
const results = await Promise.all(promises);
|
||||||
return results.filter((series): series is KomgaSeries => series !== null);
|
return results.filter((series): series is KomgaSeries => series !== null);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error({ err: error }, "Error fetching favorites");
|
logger.error(
|
||||||
|
{
|
||||||
|
err: error,
|
||||||
|
requestPath: context?.requestPath,
|
||||||
|
requestPathname: context?.requestPathname,
|
||||||
|
},
|
||||||
|
"Error fetching favorites"
|
||||||
|
);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ const defaultLocale = "fr";
|
|||||||
|
|
||||||
export default async function middleware(request: NextRequest) {
|
export default async function middleware(request: NextRequest) {
|
||||||
const { pathname } = request.nextUrl;
|
const { pathname } = request.nextUrl;
|
||||||
|
const requestPath = `${pathname}${request.nextUrl.search}`;
|
||||||
|
const forwardedHeaders = new Headers(request.headers);
|
||||||
|
forwardedHeaders.set("x-request-pathname", pathname);
|
||||||
|
forwardedHeaders.set("x-request-path", requestPath);
|
||||||
|
const createNextResponse = () => NextResponse.next({ request: { headers: forwardedHeaders } });
|
||||||
|
|
||||||
// Gestion de la langue
|
// Gestion de la langue
|
||||||
let locale = request.headers.get("cookie")?.match(/NEXT_LOCALE=([^;]+)/)?.[1];
|
let locale = request.headers.get("cookie")?.match(/NEXT_LOCALE=([^;]+)/)?.[1];
|
||||||
@@ -34,7 +39,7 @@ export default async function middleware(request: NextRequest) {
|
|||||||
pathname === "/favicon.svg" ||
|
pathname === "/favicon.svg" ||
|
||||||
pathname === "/favicon.ico"
|
pathname === "/favicon.ico"
|
||||||
) {
|
) {
|
||||||
return NextResponse.next();
|
return createNextResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vérifier l'authentification avec NextAuth v5
|
// Vérifier l'authentification avec NextAuth v5
|
||||||
@@ -59,7 +64,7 @@ export default async function middleware(request: NextRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Définir le cookie de langue si nécessaire
|
// Définir le cookie de langue si nécessaire
|
||||||
const response = NextResponse.next();
|
const response = createNextResponse();
|
||||||
if (!request.headers.get("cookie")?.includes("NEXT_LOCALE") && locale) {
|
if (!request.headers.get("cookie")?.includes("NEXT_LOCALE") && locale) {
|
||||||
response.cookies.set("NEXT_LOCALE", locale, {
|
response.cookies.set("NEXT_LOCALE", locale, {
|
||||||
path: "/",
|
path: "/",
|
||||||
|
|||||||
Reference in New Issue
Block a user