Commit Graph
19 Commits
Author SHA1 Message Date
evandro 37b88f3ff2 refactor(server): reduz a complexidade das funções de netGuard 2026-10-10 04:01:25 -03:00
evandro 656e7b3b5d docs: atualiza o README (configuração, testes, SSRF e limitações) 2026-10-10 04:00:26 -03:00
evandro dee0771ac5 fix(server): bloqueia SSRF e path traversal na sessão e segue redirects
- SSRF: /api/queue aceitava qualquer URL, inclusive localhost, rede
  privada e 169.254.169.254. Agora só http/https e, por padrão, nada de
  endereço local/privado (checagem na fila e no conector do undici, que
  cobre DNS rebinding e redirects). ALLOW_PRIVATE_NETWORK=true libera.
- O header x-session-id virava nome de diretório sem validação; com ".."
  a expiração faria rmSync em server/. Agora só UUID é aceito.
- Respostas 3xx eram salvas como se fossem o arquivo; agora segue até 5
  redirects e trata 3xx restante como erro.
- decodeURIComponent inválido no Content-Disposition derrubava o download.
- web: useCallback em refreshTasks (corrige o warning exhaustive-deps).
2026-10-10 03:59:44 -03:00
evandro bc9a43d6de feat(web): exibe erros ao enfileirar e melhora acessibilidade e contraste
- Mostra no formulário o erro devolvido pela API ao enfileirar (antes só ia ao console) e desabilita o botão durante o envio.
- Adiciona aria-label no campo de URL, role=alert no erro e role=progressbar na barra.
- Clareia a cor destructive (contraste do texto de erro sobre o fundo escuro ~2:1 para ~4,5:1).
- Corrige o título da página (era 'web').
2026-10-10 03:56:37 -03:00
evandro 6fbc1222b4 perf(server): descarta as tasks de sessões expiradas e adiciona testes do servidor
O Map de tasks em DownloadManager nunca removia entradas; em um servidor
de longa duração ele crescia sem limite, mesmo com os arquivos da sessão
já apagados. O SessionManager agora avisa quando destrói uma sessão e o
DownloadManager descarta as tasks dela.
2026-10-10 03:56:15 -03:00
evandro d181c76dfd chore: remove código morto e padroniza scripts e CI 2026-10-10 03:55:30 -03:00
evandro 1bcb35d169 refactor(web): reduz a complexidade do DownloadItem e adiciona testes com vitest 2026-10-10 03:55:02 -03:00
Evandro Fonseca Junior cc5147946c docs: reescreve o README para o estado real do projeto
O README descrevia um proxy de streaming com `GET /stream?url=&offset=` que não
existe mais (a rota responde 410 desde a reescrita do backend), falava em
"retomar downloads" e não mencionava sessão, storage temporário, polling de
tasks nem o endpoint de entrega do arquivo.

O novo texto segue o padrão da auditoria: one-liner, badges reais (sem licença
e sem CI, que não existem no repo), Sobre, Como funciona com diagrama, Stack,
Requisitos, Início rápido testado, Uso, API, Produção, Estrutura do projeto,
Verificação, Estado atual e limitações, Documentação e Licença.

O que está escrito corresponde ao que foi executado nesta auditoria: install,
build, lint, 13 checagens de API, download de 10 MB com sha256 idêntico ao da
origem e a interface rodando em Chrome headless.
2026-09-14 06:08:51 -03:00
Evandro Fonseca Junior ddccc80a70 fix(web): faz o modo dev funcionar e unifica a URL da API
Com `pnpm dev` e nenhuma configuração, o frontend chamava `/api` na própria
origem do Vite (5173), que devolvia o index.html da SPA em vez de JSON, e a
sessão nunca inicializava. Além disso os dois arquivos que falam com a API
usavam padrões diferentes: `SessionContext` usava URL relativa (correto em
produção, onde o Fastify serve a API e o build) e `DownloadItem` fixava
`http://localhost:3000`, o que quebra o botão "Save to Disk" quando o app roda
em outra máquina/VPS.

- `vite.config.ts`: proxy de `/api` para o backend em dev (alvo configurável por
  `VITE_API_PROXY`, padrão `http://localhost:3000`).
- `DownloadItem.tsx`: mesma origem por padrão, igual ao SessionContext
  (`VITE_API_URL` continua valendo para apontar para outro host).

Também deixa `pnpm --filter web lint` verde (4 erros do eslint): tipos de props
de Input/Textarea como type alias, `catch` sem binding e uma exceção
documentada para a regra de fast refresh no módulo do contexto.
2026-09-14 06:04:25 -03:00
Evandro Fonseca Junior b19c989c0e fix(server): conserta start de produção, entrega do arquivo e diretório de storage
Quatro defeitos verificados executando o servidor de produção:

1. `pnpm start` quebrava na primeira linha com ERR_MODULE_NOT_FOUND
   (`server/dist/lib/SessionManager`): os imports relativos não tinham extensão
   e o Node ESM não resolve `./lib/SessionManager`. Os imports agora terminam em
   `.js` (funciona no tsx em dev e no build do tsc).

2. `GET /api/download/:taskId` devolvia o index.html da SPA (450 bytes) em vez
   do arquivo baixado, porque o @fastify/static resolve o caminho a partir do
   `root` do plugin (web/dist). Agora o root do diretório da sessão é passado
   por requisição via `reply.sendFile(fileName, sessionPath)`.

3. O download podia sair truncado: o status virava "completed" logo depois de
   `fileStream.end()`, antes do flush em disco. A gravação passou a usar
   `stream/promises.pipeline` (respeita backpressure, espera o flush e propaga
   erro de escrita), com um Transform no meio mantendo o cálculo de
   progresso/velocidade.

4. A raiz de armazenamento era `resolve(process.cwd(), "server/storage")`; como
   `pnpm start` executa dentro de `server/`, os arquivos iam para
   `server/server/storage`. Agora a raiz é ancorada no diretório do módulo
   (`server/storage`), com override por `STORAGE_ROOT`, e o diretório entrou no
   .gitignore para os downloads não serem versionados.

Também usa `basename()` no nome de arquivo vindo do Content-Disposition e da
URL de origem, evitando escrever fora do diretório da sessão.
2026-09-14 06:04:15 -03:00
Evandro Fonseca Junior aedfe69da0 chore: deixa de versionar o build antigo em server/dist
O arquivo server/dist/index.js estava versionado (apesar de `dist/` estar no
.gitignore) e continha o build de novembro/2025, anterior à reescrita do
backend: ainda tinha o proxy antigo de /stream. O build é regenerado por
`pnpm build` (o nixpacks roda `pnpm build` antes do start), então o artefato
não precisa ficar no repositório.
2026-09-14 06:03:50 -03:00
Evandro Fonseca Junior 1d75dd74fb build(pnpm): autoriza o build do esbuild e documenta as chaves de workspace
O pnpm 11/12 ignora `onlyBuiltDependencies` e falha o install com
ERR_PNPM_IGNORED_BUILDS (esbuild, usado pelo Vite, precisa rodar script de
build). Adiciona `allowBuilds: {esbuild: true}` mantendo
`onlyBuiltDependencies` para pnpm 9/10 e comenta que `overrides` só é lido
pelo pnpm 10+.
2026-09-14 06:03:15 -03:00
Evandro Fonseca Junior 5b1600c210 feat: Inicializa a aplicação Downloader com backend para gerenciamento de sessões e downloads, e frontend para interação. 2026-02-14 18:52:54 -03:00
Evandro Fonseca Junior c2cadc25f3 feat: Adiciona um sistema de agentes abrangente com diversas habilidades e fluxos de trabalho, e implementa um novo componente de formulário de download na interface web. 2026-02-14 18:35:35 -03:00
Evandro Fonseca Junior 456f0fe056 Enhance streaming functionality with optional byte offset support and serve frontend build in production. Added static file serving for SPA and improved error handling for streaming requests. 2025-11-21 23:54:48 -03:00
Evandro Fonseca Junior b9ca713a2a Add explicit route for SPA at root path to serve index.html 2025-11-21 23:51:52 -03:00
Evandro Fonseca Junior 2c6df8186b Update README.md for improved formatting and clarity. Standardized spacing in sections and refined descriptions of frontend and backend functionalities. 2025-11-21 23:36:48 -03:00
Evandro Fonseca Junior 0cca06cc1b Refactor App styles and enhance header with metadata. Adjusted layout properties for better spacing and added a new section for empty downloads state. 2025-11-21 23:34:51 -03:00
Evandro Fonseca Junior aecf4586e5 first 2025-11-21 23:32:19 -03:00