Exige storage compatível com S3 (S3, R2, MinIO). Sem ele as duas rotas respondem
501 uploads_unavailable e GET /v1/session informa uploads_available: false.O fluxo
1
Peça uma URL assinada
2
Faça o PUT direto no bucket
3
Salve a URL pública
O logo da organização
Idêntico, com duas diferenças: exigeorganization:update, e a URL é salva com
PATCH /v1/organization.
O que é permitido
Uma allowlist, não uma blocklist — deliberadamente. Esses arquivos são servidos de
volta a partir de um host público, e
text/html entre eles seria um vetor de XSS
armazenado naquele host.
O tipo e o tamanho fazem parte da assinatura, então é o bucket que os impõe. A
verificação no lado da API existe para te dar um erro legível, não para ser a
imposição.
Substituindo uma imagem
Cada upload ganha uma chave de objeto aleatória, então substituir uma imagem nunca sobrescreve o objeto antigo. Uma URL em cache num CDN ou num e-mail não pode começar a servir a foto de outra pessoa. O objeto antigo fica para trás. Limpar é um job de manutenção, não parte da requisição.Fazendo isso do navegador
O painel faz exatamente os três passos acima a partir do código no cliente. A URL pré-assinada é de vida curta e delimitada a um objeto, um content type e um tamanho, então entregá-la ao navegador não dá nada reutilizável.No painel isso passa pelo proxy
/api/* do app Next, que anexa o token de sessão a
partir do cookie httpOnly. O PUT vai direto para o bucket e não carrega credencial
nenhuma nossa.