From c8841a253f793d8eda6ea97ddbe57218908e609a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20FAMIBELLE-PRONZOLA?= Date: Wed, 15 Jul 2026 23:04:19 +0400 Subject: [PATCH] =?UTF-8?q?fix:=20rendre=20le=20proxy=20MIZIK=20plus=20rob?= =?UTF-8?q?uste=20et=20tol=C3=A9rer=20l'ancien=20nommage=20des=20credentia?= =?UTF-8?q?ls?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/mizik-stream/[id]/__tests__/route.test.js | 13 +++++++++++++ app/api/mizik-stream/[id]/route.js | 12 ++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/app/api/mizik-stream/[id]/__tests__/route.test.js b/app/api/mizik-stream/[id]/__tests__/route.test.js index a5fdc97..893cf8b 100644 --- a/app/api/mizik-stream/[id]/__tests__/route.test.js +++ b/app/api/mizik-stream/[id]/__tests__/route.test.js @@ -4,6 +4,7 @@ import {GET} from '../route' function fakeUpstreamResponse({status = 200, headers = {}, body = 'audio-bytes'} = {}) { return { status, + ok: status >= 200 && status < 300, body, headers: { get: key => headers[key.toLowerCase()] ?? null @@ -52,4 +53,16 @@ describe('GET /api/mizik-stream/[id]', () => { expect(response.status).toBe(200) expect(response.headers.get('content-type')).toBe('audio/mpeg') }) + + it('renvoie une erreur JSON si le serveur audio répond en erreur', async () => { + global.fetch = vi.fn(async () => fakeUpstreamResponse({status: 401, headers: {'content-type': 'application/json'}, body: '{"error": "unauthorized"}'})) + + const request = new Request('http://localhost/api/mizik-stream/7') + const response = await GET(request, {params: Promise.resolve({id: '7'})}) + + expect(response.status).toBe(401) + expect(response.headers.get('content-type')).toContain('application/json') + const json = await response.json() + expect(json.error).toContain('401') + }) }) diff --git a/app/api/mizik-stream/[id]/route.js b/app/api/mizik-stream/[id]/route.js index c4d5829..7b4d112 100644 --- a/app/api/mizik-stream/[id]/route.js +++ b/app/api/mizik-stream/[id]/route.js @@ -1,6 +1,8 @@ const MIZIK_URL = process.env.NEXT_PUBLIC_OKI_MIZIK_URL || 'https://funkwhale-server.com' -const MIZIK_API_USER = process.env.MIZIK_API_USER || 'user' -const MIZIK_API_PASSWORD = process.env.MIZIK_API_PASSWORD || 'password' +// Les variables publiques sont conservées en fallback pendant la migration +// des déploiements qui utiliseraient encore l’ancien nommage. +const MIZIK_API_USER = process.env.MIZIK_API_USER || process.env.NEXT_PUBLIC_MIZIK_API_USER || 'user' +const MIZIK_API_PASSWORD = process.env.MIZIK_API_PASSWORD || process.env.NEXT_PUBLIC_MIZIK_API_PASSWORD || 'password' const FORWARDED_HEADERS = ['content-type', 'content-length', 'content-range', 'accept-ranges'] @@ -14,6 +16,12 @@ export async function GET(request, props) { headers: range ? {range} : {} }) + if (!upstreamResponse.ok) { + const message = `Le serveur audio a répondu ${upstreamResponse.status}` + console.error(message, upstreamUrl.replace(/p=[^&]+/, 'p=***')) + return Response.json({error: message}, {status: upstreamResponse.status}) + } + const headers = new Headers() for (const key of FORWARDED_HEADERS) { const value = upstreamResponse.headers.get(key)