Correção de bugs visuais

This commit is contained in:
Gabriel 2026-08-24 17:57:40 -03:00
parent 41512f793f
commit bdf5be845a
4 changed files with 40 additions and 1 deletions

View File

@ -92,7 +92,7 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
REST_FRAMEWORK = { REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [ "DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.SessionAuthentication", "portal_api.authentication.PidSessionAuthentication",
], ],
"DEFAULT_PERMISSION_CLASSES": [ "DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticated", "rest_framework.permissions.IsAuthenticated",

View File

@ -0,0 +1,19 @@
from rest_framework.authentication import SessionAuthentication
from rest_framework.request import Request
class PidSessionAuthentication(SessionAuthentication):
"""`SessionAuthentication` padrão do DRF não define `authenticate_header()`
(devolve `None`) — sem um cabeçalho `WWW-Authenticate` pra anunciar, o DRF
rebaixa `NotAuthenticated` de 401 pra 403 (`rest_framework.views.exception_handler`),
já que semanticamente 401 exige indicar como o cliente deveria se autenticar.
O frontend (`pidApiRequest`, `api.js`) só redireciona pro login em 401 — com o
padrão do DRF, qualquer request sem sessão ativa (cookie expirado, nunca logado)
voltava 403, e a página ficava travada mostrando o shell vazio/sem usuário em vez
de voltar pro login. Devolver um valor não-vazio aqui mantém o status em 401,
sem acionar nenhum prompt nativo do navegador (só "Basic"/"Digest" fazem isso).
"""
def authenticate_header(self, request: Request) -> str:
return "Session"

View File

@ -26,6 +26,20 @@
transition: opacity 420ms ease, transform 420ms cubic-bezier(0.16, 1, 0.3, 1); transition: opacity 420ms ease, transform 420ms cubic-bezier(0.16, 1, 0.3, 1);
} }
/* Antes de access.js aplicar a visibilidade real (união de permissões, vinda
de /api/me/, assíncrona), todo item de menu gated por permissão começa
escondido — "fail closed". Sem isso, o menu inteiro (todas as seções/
aplicações) ficava visível por um instante em qualquer carregamento de
página — inclusive pra quem não tem acesso a todas —, já que o HTML de
cada shell já vem com todos os itens no DOM e só é filtrado depois que o
fetch de /api/me/ resolve. `pidApplyAccessVisibility` (access.js) só marca
`.sidebar` como `.is-ready` depois de já ter escondido cada item que o
usuário não pode ver. */
.sidebar:not(.is-ready) [data-section],
.sidebar:not(.is-ready) [data-app] {
display: none !important;
}
.sidebar__brand { .sidebar__brand {
position: relative; position: relative;
display: flex; display: flex;

View File

@ -45,6 +45,12 @@ function pidApplyAccessVisibility(me) {
document.querySelectorAll("[data-restricted-badge]").forEach((el) => { document.querySelectorAll("[data-restricted-badge]").forEach((el) => {
el.hidden = !isDiretoria; el.hidden = !isDiretoria;
}); });
// Só revela o menu (ver regra `.sidebar:not(.is-ready)` em layout.css) depois
// que todo item já teve sua visibilidade real decidida acima — evita mostrar
// seções/aplicações que o usuário não deveria ver, ainda que por um instante.
const sidebarEl = document.querySelector(".sidebar");
if (sidebarEl) sidebarEl.classList.add("is-ready");
} }
async function pidInitAccess() { async function pidInitAccess() {