From 2632d55b1a999a7d43803a02365fa78395b9ff99 Mon Sep 17 00:00:00 2001 From: Ole Wieners Date: Thu, 12 Sep 2024 13:17:57 +0200 Subject: [PATCH] Hide text results for events with passwords This is not a good solution as it relies on a frontend check. Ideally this would be done in backend. This same applies for thumbnails in search results. --- backend/src/api/model/search/event.rs | 20 +++++++++++--------- frontend/src/routes/Search.tsx | 19 +++++++++++++++---- frontend/src/schema.graphql | 21 +++++++++++---------- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/backend/src/api/model/search/event.rs b/backend/src/api/model/search/event.rs index 75cd9b9e4..4095a4956 100644 --- a/backend/src/api/model/search/event.rs +++ b/backend/src/api/model/search/event.rs @@ -29,6 +29,7 @@ pub(crate) struct SearchEvent { pub host_realms: Vec, pub text_matches: Vec, pub has_password: bool, + pub user_is_authorized: bool, } #[derive(Debug, GraphQLObject)] @@ -73,17 +74,17 @@ impl SearchEvent { let mut text_matches = Vec::new(); src.slide_texts.resolve_matches(slide_matches, &mut text_matches, TextAssetType::SlideText); src.caption_texts.resolve_matches(caption_matches, &mut text_matches, TextAssetType::Caption); + + let read_roles: Vec = src.read_roles.iter() + .map(|role| { + let bytes = hex::decode(role).expect("Failed to decode role"); + String::from_utf8(bytes).expect("Failed to convert bytes to string") + }) + .collect(); + let user_is_authorized = context.auth.overlaps_roles(read_roles); let thumbnail = { - let read_roles: Vec = src.read_roles.iter() - .map(|role| { - let bytes = hex::decode(role).expect("Failed to decode role"); - - String::from_utf8(bytes).expect("Failed to convert bytes to string") - }) - .collect(); - - if context.auth.overlaps_roles(read_roles) { + if user_is_authorized { src.thumbnail } else { None @@ -107,6 +108,7 @@ impl SearchEvent { host_realms: src.host_realms, text_matches, has_password: src.has_password, + user_is_authorized, } } } diff --git a/frontend/src/routes/Search.tsx b/frontend/src/routes/Search.tsx index 399bc9082..112424945 100644 --- a/frontend/src/routes/Search.tsx +++ b/frontend/src/routes/Search.tsx @@ -52,7 +52,7 @@ import { ellipsisOverflowCss, focusStyle } from "../ui"; import { COLORS } from "../color"; import { BREAKPOINT_MEDIUM, BREAKPOINT_SMALL } from "../GlobalStyle"; import { eventId, isExperimentalFlagSet, keyOfId, secondsToTimeString } from "../util"; -import { DirectVideoRoute, VideoRoute } from "./Video"; +import { DirectVideoRoute, getCredentials, VideoRoute } from "./Video"; import { DirectSeriesRoute } from "./Series"; import { PartOfSeriesLink } from "../ui/Blocks/VideoList"; import { SearchSlidePreviewQuery } from "./__generated__/SearchSlidePreviewQuery.graphql"; @@ -149,6 +149,8 @@ const query = graphql` startTime endTime created + hasPassword + userIsAuthorized hostRealms { path } textMatches { start @@ -402,6 +404,8 @@ const SearchResults: React.FC = ({ items }) => ( endTime: unwrapUndefined(item.endTime), hostRealms: unwrapUndefined(item.hostRealms), textMatches: unwrapUndefined(item.textMatches), + hasPassword: unwrapUndefined(item.hasPassword), + userIsAuthorized: unwrapUndefined(item.userIsAuthorized), }} />; } else if (item.__typename === "SearchSeries") { return ; + hasPassword: boolean; + userIsAuthorized: boolean; }; const SearchEvent: React.FC = ({ @@ -498,6 +504,8 @@ const SearchEvent: React.FC = ({ endTime, hostRealms, textMatches, + hasPassword, + userIsAuthorized, }) => { // TODO: decide what to do in the case of more than two host realms. Direct // link should be avoided. @@ -505,6 +513,9 @@ const SearchEvent: React.FC = ({ ? DirectVideoRoute.url({ videoId: id }) : VideoRoute.url({ realmPath: hostRealms[0].path, videoID: id }); + // TODO: This check should be done in backend. + const showMatches = userIsAuthorized || (hasPassword && getCredentials(keyOfId(id))); + return ( @@ -541,7 +552,7 @@ const SearchEvent: React.FC = ({ {seriesTitle && seriesId && } {/* Show timeline with matches if there are any */} - {textMatches.length > 0 && ( + {textMatches.length > 0 && showMatches && ( )} @@ -590,11 +601,11 @@ type TextMatchTimelineProps = Pick