This commit is contained in:
Philipinho
2026-04-10 18:30:30 +01:00
parent 0b9a180b69
commit 291b1a0fc1
3 changed files with 25 additions and 1 deletions
@@ -13,6 +13,15 @@ export default function AiChatLayout() {
const location = useLocation(); const location = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
const chatInfoQuery = useChatInfoQuery(chatId); const chatInfoQuery = useChatInfoQuery(chatId);
// If the URL points at a chat the user does not own, the info fetch 404s.
// Bounce them back to /ai so they cannot interact with any chat UI (including
// kicking off orphan uploads) tied to a chat they have no access to.
useEffect(() => {
if (chatId && chatInfoQuery.isError) {
navigate("/ai", { replace: true });
}
}, [chatId, chatInfoQuery.isError, navigate]);
const { const {
messages, messages,
streamingContent, streamingContent,
@@ -48,6 +57,12 @@ export default function AiChatLayout() {
const hasMessages = messages.length > 0 || isStreaming; const hasMessages = messages.length > 0 || isStreaming;
// While the redirect effect is running (or if the user is still on this
// component for any reason) never render the chat UI for a forbidden chat.
if (chatId && chatInfoQuery.isError) {
return null;
}
return ( return (
<div className={classes.main}> <div className={classes.main}>
{error && ( {error && (
@@ -73,6 +73,15 @@ export default function AsideChatPanel() {
} }
}, [chatInfoQuery.data, hydrateFromServer]); }, [chatInfoQuery.data, hydrateFromServer]);
// Drop the open chatId if the current user lost access to it (404/403 on
// the info fetch). Reverts the panel to a fresh chat instead of presenting
// an input tied to a chat the user does not own.
useEffect(() => {
if (chatId && chatInfoQuery.isError) {
setChatId(undefined);
}
}, [chatId, chatInfoQuery.isError]);
const handleNewChat = useCallback( const handleNewChat = useCallback(
(event: React.MouseEvent<HTMLAnchorElement>) => { (event: React.MouseEvent<HTMLAnchorElement>) => {
if ( if (