diff --git a/common/views/components/UserProvider/UserProvider.tsx b/common/views/components/UserProvider/UserProvider.tsx index c8bf5bca68..2ce40007b4 100644 --- a/common/views/components/UserProvider/UserProvider.tsx +++ b/common/views/components/UserProvider/UserProvider.tsx @@ -16,13 +16,15 @@ import { export type State = 'initial' | 'loading' | 'signedin' | 'signedout' | 'failed'; type Props = { - user: UserInfo | undefined; + user?: UserInfo; + userIsStaffWithRestricted: boolean; state: State; reload: (abortSignal?: AbortSignal) => Promise; }; const defaultUserContext: Props = { user: undefined, + userIsStaffWithRestricted: false, state: 'initial', reload: async () => undefined, }; @@ -36,6 +38,8 @@ export function useUser(): Props { const UserProvider: FunctionComponent = ({ children }) => { const [user, setUser] = useState(); + const [userIsStaffWithRestricted, setUserIsStaffWithRestricted] = + useState(false); const [state, setState] = useState('initial'); const fetchUser = async (abortSignal?: AbortSignal, refetch = false) => { @@ -59,7 +63,11 @@ const UserProvider: FunctionComponent = ({ children }) => { // There is a race condition here where the cancel can happen // after the fetch has finished but before the response has been deserialised if (!abortSignal?.aborted) { - setUser(auth0UserProfileToUserInfo(data)); + const userData = auth0UserProfileToUserInfo(data); + setUser(userData); + setUserIsStaffWithRestricted( + userData?.role === 'StaffWithRestricted' + ); setState('signedin'); } } else { @@ -92,6 +100,7 @@ const UserProvider: FunctionComponent = ({ children }) => { fetchUser(abortSignal, true), }} diff --git a/content/webapp/components/IIIFViewer/IIIFCanvasThumbnail.tsx b/content/webapp/components/IIIFViewer/IIIFCanvasThumbnail.tsx index 83935a1d04..b53f9a6c18 100644 --- a/content/webapp/components/IIIFViewer/IIIFCanvasThumbnail.tsx +++ b/content/webapp/components/IIIFViewer/IIIFCanvasThumbnail.tsx @@ -76,8 +76,7 @@ const IIIFCanvasThumbnail: FunctionComponent = ({ highlightImage, }: IIIFCanvasThumbnailProps) => { const [thumbnailLoaded, setThumbnailLoaded] = useState(false); - const { user } = useUser(); - const role = user?.role; + const { userIsStaffWithRestricted } = useUser(); const isRestricted = canvas.hasRestrictedImage; const urlTemplate = canvas.imageServiceId ? iiifImageTemplate(canvas.imageServiceId) @@ -90,7 +89,7 @@ const IIIFCanvasThumbnail: FunctionComponent = ({ {!thumbnailLoaded && !isRestricted && ( )} - {isRestricted && role !== 'StaffWithRestricted' ? ( + {isRestricted && !userIsStaffWithRestricted ? ( <> diff --git a/content/webapp/components/IIIFViewer/MainViewer.tsx b/content/webapp/components/IIIFViewer/MainViewer.tsx index ed481611c8..9fb855244c 100644 --- a/content/webapp/components/IIIFViewer/MainViewer.tsx +++ b/content/webapp/components/IIIFViewer/MainViewer.tsx @@ -213,8 +213,7 @@ const ItemRenderer = memo(({ style, index, data }: ItemRendererProps) => { const { scrollVelocity, canvases, externalAccessService } = data; const [mainLoaded, setMainLoaded] = useState(false); const currentCanvas = canvases[index]; - const { user } = useUser(); - const role = user?.role; + const { userIsStaffWithRestricted } = useUser(); const urlTemplateMain = currentCanvas.imageServiceId ? iiifImageTemplate(currentCanvas.imageServiceId) : undefined; @@ -276,7 +275,7 @@ const ItemRenderer = memo(({ style, index, data }: ItemRendererProps) => {
- ) : isRestricted && role !== 'StaffWithRestricted' ? ( + ) : isRestricted && !userIsStaffWithRestricted ? ( // We always want to show the restricted message to users without a role of 'StaffWithRestricted' // If the user has the correct role then officially we should check the probe service repsonse before trying to load the image. // https://iiif.io/api/auth/2.0/#probe-service diff --git a/content/webapp/components/IIIFViewer/ViewerSidebar.tsx b/content/webapp/components/IIIFViewer/ViewerSidebar.tsx index 6b868bed5a..8189870ad1 100644 --- a/content/webapp/components/IIIFViewer/ViewerSidebar.tsx +++ b/content/webapp/components/IIIFViewer/ViewerSidebar.tsx @@ -162,7 +162,7 @@ const ViewerSidebar: FunctionComponent = ({ const { authV2 } = useToggles(); const { work, transformedManifest, parentManifest } = useContext(ItemViewerContext); - const { user } = useUser(); + const { userIsStaffWithRestricted } = useUser(); const matchingManifest = parentManifest && @@ -194,7 +194,7 @@ const ViewerSidebar: FunctionComponent = ({ const isWorkVisibleWithPermission = digitalLocationInfo?.accessCondition === 'restricted' && - user?.role === 'StaffWithRestricted'; + userIsStaffWithRestricted; const authServices = getAuthServices({ auth, authV2 }); diff --git a/content/webapp/components/WorkDetails/WorkDetails.AvailableOnline.tsx b/content/webapp/components/WorkDetails/WorkDetails.AvailableOnline.tsx index 734ecd284c..758f4e8cd1 100644 --- a/content/webapp/components/WorkDetails/WorkDetails.AvailableOnline.tsx +++ b/content/webapp/components/WorkDetails/WorkDetails.AvailableOnline.tsx @@ -139,7 +139,7 @@ const ItemPageLink = ({ digitalLocationInfo, authServices, }) => { - const { user } = useUser(); + const { userIsStaffWithRestricted } = useUser(); const isDownloadable = digitalLocationInfo?.accessCondition !== 'open-with-advisory' && @@ -147,7 +147,7 @@ const ItemPageLink = ({ const isWorkVisibleWithPermission = digitalLocationInfo?.accessCondition === 'restricted' && - user?.role === 'StaffWithRestricted'; + userIsStaffWithRestricted; const manifestNeedsRegeneration = authServices?.external?.id === @@ -271,8 +271,8 @@ const WorkDetailsAvailableOnline = ({ locationOfWork, transformedManifest, }: Props) => { - const { user } = useUser(); - const role = user?.role; + const { userIsStaffWithRestricted } = useUser(); + const { authV2 } = useToggles(); const { collectionManifestsCount, @@ -287,7 +287,7 @@ const WorkDetailsAvailableOnline = ({ const [origin, setOrigin] = useState(); const tokenService = getIframeTokenSrc({ - role, + userIsStaffWithRestricted, workId: work.id, origin, auth, diff --git a/content/webapp/components/WorkDetails/index.tsx b/content/webapp/components/WorkDetails/index.tsx index 9f00d6b222..3fedcebb07 100644 --- a/content/webapp/components/WorkDetails/index.tsx +++ b/content/webapp/components/WorkDetails/index.tsx @@ -62,7 +62,7 @@ const WorkDetails: FunctionComponent = ({ digitalLocationInfo, transformedManifest, }: Props) => { - const { user } = useUser(); + const { userIsStaffWithRestricted } = useUser(); const isArchive = useContext(IsArchiveContext); const transformedIIIFImage = useTransformedIIIFImage(toWorkBasic(work)); const { canvases, rendering, bornDigitalStatus } = { @@ -158,7 +158,7 @@ const WorkDetails: FunctionComponent = ({ const treatAsRestricted = digitalLocationInfo?.accessCondition === 'restricted' && - user?.role !== 'StaffWithRestricted'; + !userIsStaffWithRestricted; const showAvailableOnlineSection = ((digitalLocation && shouldShowItemLink) || diff --git a/content/webapp/pages/works/[workId]/index.tsx b/content/webapp/pages/works/[workId]/index.tsx index 22d30f85d2..9f3e35b715 100644 --- a/content/webapp/pages/works/[workId]/index.tsx +++ b/content/webapp/pages/works/[workId]/index.tsx @@ -72,8 +72,7 @@ export const WorkPage: NextPage = ({ transformedManifest, }) => { useHotjar(true); - const { user } = useUser(); - const role = user?.role; + const { userIsStaffWithRestricted } = useUser(); const isArchive = !!( work.parts.length || (work.partOf.length > 0 && work.partOf[0].totalParts) @@ -98,7 +97,7 @@ export const WorkPage: NextPage = ({ const allOriginalPdfs = isAllOriginalPdfs(canvases || []); const shouldShowItemLink = showItemLink({ - role, + userIsStaffWithRestricted, allOriginalPdfs, hasIIIFManifest: !!transformedManifest, digitalLocation, diff --git a/content/webapp/pages/works/[workId]/items.tsx b/content/webapp/pages/works/[workId]/items.tsx index c3ae641ee3..3de2d75198 100644 --- a/content/webapp/pages/works/[workId]/items.tsx +++ b/content/webapp/pages/works/[workId]/items.tsx @@ -127,8 +127,7 @@ const ItemPage: NextPage = ({ parentManifest, }) => { useHotjar(true); - const { user } = useUser(); - const role = user?.role; + const { userIsStaffWithRestricted } = useUser(); const { authV2 } = useToggles(); const transformedManifest = compressedTransformedManifest && @@ -143,7 +142,7 @@ const ItemPage: NextPage = ({ }; const needsModal = checkModalRequired({ - role, + userIsStaffWithRestricted, auth, isAnyImageOpen, authV2, @@ -167,7 +166,7 @@ const ItemPage: NextPage = ({ ((authV2 && auth?.v2.tokenService) || (!authV2 && auth?.v1.tokenService)) && origin; const tryAndGetRestrictedAuthCookie = - role === 'StaffWithRestricted' && + userIsStaffWithRestricted && authServices?.external?.id === 'https://iiif.wellcomecollection.org/auth/v2/access/restrictedlogin'; // showViewer is true by default, so the noScriptViewer is available without javascript @@ -203,7 +202,7 @@ const ItemPage: NextPage = ({ function receiveMessage(event: MessageEvent) { const data = event.data; const tokenService = getIframeTokenSrc({ - role, + userIsStaffWithRestricted, workId: work.id, origin: window.origin, auth, @@ -253,7 +252,7 @@ const ItemPage: NextPage = ({ id={iframeId} title="Authentication" src={getIframeTokenSrc({ - role, + userIsStaffWithRestricted, workId: work.id, origin, auth, diff --git a/content/webapp/utils/iiif/v3/index.ts b/content/webapp/utils/iiif/v3/index.ts index 1c6e0c9170..e0f397e154 100644 --- a/content/webapp/utils/iiif/v3/index.ts +++ b/content/webapp/utils/iiif/v3/index.ts @@ -368,13 +368,13 @@ export function getAuthServices({ } export function getIframeTokenSrc({ - role, + userIsStaffWithRestricted, workId, origin, auth, authV2, }: { - role?: string; + userIsStaffWithRestricted: boolean; workId: string; origin?: string; auth: Auth | undefined; @@ -387,7 +387,7 @@ export function getIframeTokenSrc({ const useV2TokenService = (authServices?.external?.id === 'https://iiif.wellcomecollection.org/auth/v2/access/restrictedlogin' && - role === 'StaffWithRestricted') || + userIsStaffWithRestricted) || authV2; if (useV2TokenService && auth?.v2.tokenService) { return `${auth.v2.tokenService.id}?messageId=${workId}&origin=${origin}`; @@ -397,19 +397,19 @@ export function getIframeTokenSrc({ } type checkModalParams = { - role?: string; + userIsStaffWithRestricted: boolean; auth?: Auth; isAnyImageOpen?: boolean; authV2?: boolean; }; export function checkModalRequired(params: checkModalParams): boolean { - const { role, auth, isAnyImageOpen, authV2 } = params; + const { userIsStaffWithRestricted, auth, isAnyImageOpen, authV2 } = params; const authServices = getAuthServices({ auth, authV2 }); if (authServices?.active) { return true; } else if (authServices?.external) { - if (isAnyImageOpen || role === 'StaffWithRestricted') { + if (isAnyImageOpen || userIsStaffWithRestricted) { return false; } else { return true; diff --git a/content/webapp/utils/works.ts b/content/webapp/utils/works.ts index e0c7f94006..94e1571d8f 100644 --- a/content/webapp/utils/works.ts +++ b/content/webapp/utils/works.ts @@ -359,7 +359,7 @@ export function getFirstAccessCondition( } export function showItemLink({ - role, + userIsStaffWithRestricted, allOriginalPdfs, hasIIIFManifest, digitalLocation, @@ -367,7 +367,7 @@ export function showItemLink({ canvases, bornDigitalStatus, }: { - role?: string; + userIsStaffWithRestricted: boolean; allOriginalPdfs: boolean; hasIIIFManifest: boolean; digitalLocation?: DigitalLocation; @@ -385,12 +385,12 @@ export function showItemLink({ const hasVideo = hasItemType(canvases, 'Video'); const hasSound = hasItemType(canvases, 'Sound') || hasItemType(canvases, 'Audio'); - if (accessCondition === 'restricted' && role === 'StaffWithRestricted') { + if (accessCondition === 'restricted' && userIsStaffWithRestricted) { return true; } if ( accessCondition === 'closed' || - (accessCondition === 'restricted' && role !== 'StaffWithRestricted') + (accessCondition === 'restricted' && !userIsStaffWithRestricted) ) { return false; } else if (