From 66cd837e9d5686ba522b50fa1b506cb490a50ff2 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Mon, 1 Sep 2025 07:54:31 +0100 Subject: [PATCH] More room preview context stuff --- .../views/rooms/RoomPreviewContext.tsx | 49 +++++++++++++++++-- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/RoomPreviewContext.tsx b/src/components/views/rooms/RoomPreviewContext.tsx index 9b79352e2a..7d1edea20b 100644 --- a/src/components/views/rooms/RoomPreviewContext.tsx +++ b/src/components/views/rooms/RoomPreviewContext.tsx @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { JoinRule, type RoomMember, type Room, KnownMembership } from "matrix-js-sdk/src/matrix"; +import { JoinRule, type RoomMember, type Room, KnownMembership, MatrixError } from "matrix-js-sdk/src/matrix"; import React, { type JSX, useEffect, useMemo, useState, type FC } from "react"; import { Button, InlineSpinner } from "@vector-im/compound-web"; import { CheckCircleIcon, InfoIcon, WarningIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; @@ -54,11 +54,50 @@ function useGetUserSafety(inviterMember: RoomMember | null): { userFirstSeen?: { title: string; description: string; score: InviteScore }; userBanned?: string; userKicked?: string; + isLocalTrustedServer?: boolean; }; } { const client = useMatrixClientContext(); const [joinedTo, setJoinedTo] = useState<{ title: string; description: string; score: InviteScore }>(); const [roomCount, setRoomCount] = useState(); + const [isLocalTrustedServer, setIsLocalTrustedServer] = useState(); + + + useEffect(() => { + if (!inviterMember?.userId) { + return; + } + const inviterDomain = inviterMember.userId.replace(/^.*?:/, ""); + if (inviterDomain !== client.getDomain()) { + setIsLocalTrustedServer(false); + } + + (async () => { + // Try auth metadata first for OIDC + try { + const metadata = await client.getAuthMetadata(); + const openReg = metadata.prompt_values_supported?.includes("create") + setIsLocalTrustedServer(!openReg); + } catch { + // OIDC not configured, fall through. + } + try { + await client.registerRequest({}); + setIsLocalTrustedServer(false); + } catch (ex) { + if (ex instanceof MatrixError && ex.errcode === "M_FORBIDDEN") { + // We only accept M_FORBIDDEN for checking if the server is closed, for safety. + setIsLocalTrustedServer(true); + return; + } + setIsLocalTrustedServer(false); + } + })(); + + return () => { + setIsLocalTrustedServer(false); + }; + }, [client, inviterMember]); useEffect(() => { if (!inviterMember?.userId) { @@ -212,7 +251,7 @@ function useGetUserSafety(inviterMember: RoomMember | null): { }, [client, inviterMember]); const score = useMemo(() => { - if (!roomCount) { + if (roomCount === undefined) { return null; } if (roomCount === 0 || userBanned || userKicked) { @@ -232,6 +271,7 @@ function useGetUserSafety(inviterMember: RoomMember | null): { userBanned, userKicked, userFirstSeen, + isLocalTrustedServer, }, }; } @@ -249,10 +289,11 @@ export const RoomPreviewContext: FC<{ inviterMember: RoomMember | null }> = ({ i ); } - const { roomCount, joinedTo, userBanned, userKicked, userFirstSeen } = details; + const { roomCount, joinedTo, userBanned, userKicked, userFirstSeen, isLocalTrustedServer } = details; return (
    - {roomCount === 0 && } + {isLocalTrustedServer && } + {roomCount === 0 && } {userBanned && (