v1.4: Segurança multi-tenant, file serving via API e UX humanizada
- Validação cross-tenant no login e rotas protegidas
- File serving via /api/files/{bucket}/{path} (eliminação DNS)
- Mensagens de erro humanizadas inline (sem pop-ups)
- Middleware tenant detection via headers customizados
- Upload de logos retorna URLs via API
- README atualizado com changelog v1.4 completo
This commit is contained in:
54
front-end-agency/components/layout/FaviconUpdater.tsx
Normal file
54
front-end-agency/components/layout/FaviconUpdater.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { getUser } from '@/lib/auth';
|
||||
|
||||
export function FaviconUpdater() {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!mounted) return;
|
||||
|
||||
const updateFavicon = () => {
|
||||
const user = getUser();
|
||||
if (user?.logoUrl) {
|
||||
// Usar requestAnimationFrame para garantir que o DOM esteja estável após hidratação
|
||||
requestAnimationFrame(() => {
|
||||
const link: HTMLLinkElement = document.querySelector("link[rel*='icon']") || document.createElement('link');
|
||||
link.type = 'image/x-icon';
|
||||
link.rel = 'shortcut icon';
|
||||
link.href = user.logoUrl!;
|
||||
if (!link.parentNode) {
|
||||
document.getElementsByTagName('head')[0].appendChild(link);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Atraso pequeno para garantir que a hidratação terminou
|
||||
const timer = setTimeout(() => {
|
||||
updateFavicon();
|
||||
}, 0);
|
||||
|
||||
// Ouve mudanças no localStorage
|
||||
const handleStorage = () => {
|
||||
requestAnimationFrame(() => updateFavicon());
|
||||
};
|
||||
window.addEventListener('storage', handleStorage);
|
||||
|
||||
// Custom event para atualização interna na mesma aba
|
||||
window.addEventListener('auth-update', handleStorage);
|
||||
|
||||
return () => {
|
||||
clearTimeout(timer);
|
||||
window.removeEventListener('storage', handleStorage);
|
||||
window.removeEventListener('auth-update', handleStorage);
|
||||
};
|
||||
}, [mounted]);
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user