From 38a34325edaa2380c296fc6c7e79a27f4d5c5f34 Mon Sep 17 00:00:00 2001 From: Jeremias Santos Date: Wed, 17 Jun 2026 09:42:14 -0300 Subject: [PATCH 1/2] fix(pav-55): adicionar credentials: include nas chamadas fetch do jobsService Corrige erro 401 em rotas protegidas para usuarios autenticados, adicionando credentials: "include" em todas as chamadas fetch para que o cookie de sessao (vagas_session) seja enviado nas requests. Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/src/services/jobsService.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/frontend/src/services/jobsService.ts b/frontend/src/services/jobsService.ts index 87bc916..32dc09d 100644 --- a/frontend/src/services/jobsService.ts +++ b/frontend/src/services/jobsService.ts @@ -58,7 +58,9 @@ function readMessage(payload: unknown): string | undefined { } export async function fetchJobFiles(): Promise { - const response = await fetch(buildApiUrl("/api/jobs/files")); + const response = await fetch(buildApiUrl("/api/jobs/files"), { + credentials: "include", + }); const payload = (await readPayload(response)) as { files?: unknown } & Record< string, unknown @@ -86,7 +88,9 @@ export async function fetchJobFiles(): Promise { export async function fetchJobsByFile(fileName: string): Promise { const suffix = fileName ? `?file=${encodeURIComponent(fileName)}` : ""; - const response = await fetch(buildApiUrl(`/api/jobs${suffix}`)); + const response = await fetch(buildApiUrl(`/api/jobs${suffix}`), { + credentials: "include", + }); const payload = (await readPayload(response)) as Record; if (!response.ok) { @@ -106,7 +110,9 @@ export async function fetchJobsByFile(fileName: string): Promise { } export async function fetchKeywords(): Promise { - const response = await fetch(buildApiUrl("/api/keywords")); + const response = await fetch(buildApiUrl("/api/keywords"), { + credentials: "include", + }); const payload = (await readPayload(response)) as { keywords?: unknown; } & Record; @@ -125,6 +131,7 @@ export async function saveKeywords(keywords: string[]): Promise { "Content-Type": "application/json", }, body: JSON.stringify({ keywords }), + credentials: "include", }); const payload = (await readPayload(response)) as Record; @@ -136,6 +143,7 @@ export async function saveKeywords(keywords: string[]): Promise { export async function runScraperRequest(): Promise { const response = await fetch(buildApiUrl("/api/jobs/search"), { method: "POST", + credentials: "include", }); const payload = (await readPayload(response)) as Record; From 3e8e30f3a6bfb4b8fdbc6ddff5b9f43fe5efff3f Mon Sep 17 00:00:00 2001 From: Jeremias Santos Date: Wed, 17 Jun 2026 10:55:05 -0300 Subject: [PATCH 2/2] fix(pav-55): atualizar testes do jobsService para incluir credentials: include Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/tests/unit/utils/jobsService.test.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/frontend/tests/unit/utils/jobsService.test.ts b/frontend/tests/unit/utils/jobsService.test.ts index 820a3b2..4bfa058 100644 --- a/frontend/tests/unit/utils/jobsService.test.ts +++ b/frontend/tests/unit/utils/jobsService.test.ts @@ -23,7 +23,7 @@ describe("jobsService", () => { vi.stubGlobal("fetch", fetchMock); await fetchJobFiles(); - expect(fetchMock).toHaveBeenCalledWith("https://jobsglobalscraper.ddns.net/api/jobs/files"); + expect(fetchMock).toHaveBeenCalledWith("https://jobsglobalscraper.ddns.net/api/jobs/files", { credentials: "include" }); }); it("filtra entradas invalidas ao listar arquivos", async () => { @@ -68,7 +68,7 @@ describe("jobsService", () => { const response = await fetchJobsByFile("vagas.xlsx"); expect(response.total).toBe(1); expect(response.file).toBe("vagas.xlsx"); - expect(fetchMock).toHaveBeenCalledWith("/api/jobs?file=vagas.xlsx"); + expect(fetchMock).toHaveBeenCalledWith("/api/jobs?file=vagas.xlsx", { credentials: "include" }); }); it("usa endpoint sem sufixo quando fileName vazio", async () => { @@ -81,7 +81,7 @@ describe("jobsService", () => { ); await fetchJobsByFile(""); - expect(fetch).toHaveBeenCalledWith("/api/jobs"); + expect(fetch).toHaveBeenCalledWith("/api/jobs", { credentials: "include" }); }); it("normaliza payload invalido ao buscar jobs", async () => { @@ -92,7 +92,7 @@ describe("jobsService", () => { const response = await fetchJobsByFile("vagas com espaco.xlsx"); expect(response).toEqual({ jobs: [], file: "", modifiedAt: null, total: 0 }); - expect(fetch).toHaveBeenCalledWith("/api/jobs?file=vagas%20com%20espaco.xlsx"); + expect(fetch).toHaveBeenCalledWith("/api/jobs?file=vagas%20com%20espaco.xlsx", { credentials: "include" }); }); it("lanca erro com mensagem da API ao buscar jobs", async () => { @@ -173,6 +173,7 @@ describe("jobsService", () => { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ keywords: ["node", "vitest"] }), + credentials: "include", }); });