Require authentication to participate in chat (#4762)

* feat(chat): require authentication to participate in chat

* fix: it's pretty much impossible to bypass the auth requirement, addressing review feedback anyway

* feat(chat): render chat text input as disabled if chat auth is required

* Commit updated API documentation

---------

Co-authored-by: Owncast <owncast@owncast.online>
This commit is contained in:
Gabe Kangas
2026-01-28 11:49:07 -08:00
committed by GitHub
co-authored by Owncast
parent 83c8b2b3d5
commit 93b482871f
29 changed files with 5194 additions and 5143 deletions
@@ -618,6 +618,22 @@ export const ChatDisabled = {
},
};
export const AuthenticationRequired = {
render: Template,
args: {
loading: false,
messages,
usernameToHighlight: 'testuser',
chatUserId: 'testuser',
isModerator: false,
showInput: true,
chatAvailable: true,
inputEnabled: false,
inputDisabledPlaceholder: 'Authenticate to chat',
},
};
export const SingleMessage = {
render: Template,
@@ -34,6 +34,8 @@ export type ChatContainerProps = {
focusInput?: boolean;
desktop?: boolean;
readonly?: boolean;
inputEnabled?: boolean;
inputDisabledPlaceholder?: string;
};
let resizeWindowCallback: () => void;
@@ -82,11 +84,15 @@ export const ChatContainer: FC<ChatContainerProps> = ({
isModerator,
showInput = true,
height = 'auto',
chatAvailable: chatEnabled,
chatAvailable,
desktop,
focusInput = true,
readonly = false,
inputEnabled,
inputDisabledPlaceholder,
}) => {
// If inputEnabled is explicitly set, use that; otherwise fall back to chatAvailable
const chatInputEnabled = inputEnabled !== undefined ? inputEnabled : chatAvailable;
const [showScrollToBottomButton, setShowScrollToBottomButton] = useState(false);
const [isAtBottom, setIsAtBottom] = useState(false);
@@ -366,7 +372,11 @@ export const ChatContainer: FC<ChatContainerProps> = ({
{MessagesTable}
{showInput && (
<div className={styles.chatTextField}>
<ChatTextField enabled={chatEnabled} focusInput={focusInput} />
<ChatTextField
enabled={chatInputEnabled}
focusInput={focusInput}
disabledPlaceholder={inputDisabledPlaceholder}
/>
</div>
)}
{desktop && (