From 3367e6e431f3dafd815a6dcabfc0c422d5b656c6 Mon Sep 17 00:00:00 2001 From: Jim O'Donnell Date: Mon, 16 Oct 2023 09:47:06 +0100 Subject: [PATCH] Clean up usePanoptesUser - move `fetchPanoptesUser` into a helper. - add explanatory comments. - restore the missing `avatar_src` when getting the user object from a JWT. --- .../app-root/src/helpers/fetchPanoptesUser.js | 34 ++++++++++++++ packages/app-root/src/helpers/index.js | 1 + .../app-root/src/hooks/usePanoptesUser.js | 44 ++++++------------- 3 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 packages/app-root/src/helpers/fetchPanoptesUser.js create mode 100644 packages/app-root/src/helpers/index.js diff --git a/packages/app-root/src/helpers/fetchPanoptesUser.js b/packages/app-root/src/helpers/fetchPanoptesUser.js new file mode 100644 index 00000000000..cba2f87e47f --- /dev/null +++ b/packages/app-root/src/helpers/fetchPanoptesUser.js @@ -0,0 +1,34 @@ +import auth from 'panoptes-client/lib/auth' +import { auth as authHelpers } from '@zooniverse/panoptes-js' + +export default async function fetchPanoptesUser(storedUser) { + try { + const jwt = await auth.checkBearerToken() + /* + `crypto.subtle` is needed to decrypt the Panoptes JWT. + It will only exist for https:// URLs. + */ + const isSecure = crypto?.subtle + if (jwt && isSecure) { + /* + avatar_src isn't encoded in the Panoptes JWT, so we need to add it. + https://github.com/zooniverse/panoptes/issues/4217 + */ + const { user, error } = await authHelpers.decodeJWT(jwt) + if (user) { + const { admin, display_name, id, login } = user + return { + avatar_src: storedUser.avatar_src, + ...user + } + } + if (error) { + throw error + } + } + } catch (error) { + console.log(error) + } + const { admin, avatar_src, display_name, id, login } = await auth.checkCurrent() + return { admin, avatar_src, display_name, id, login } +} diff --git a/packages/app-root/src/helpers/index.js b/packages/app-root/src/helpers/index.js new file mode 100644 index 00000000000..025ab766d98 --- /dev/null +++ b/packages/app-root/src/helpers/index.js @@ -0,0 +1 @@ +export { default as fetchPanoptesUser } from './fetchPanoptesUser.js' diff --git a/packages/app-root/src/hooks/usePanoptesUser.js b/packages/app-root/src/hooks/usePanoptesUser.js index fb550c2595a..ed069c7cad1 100644 --- a/packages/app-root/src/hooks/usePanoptesUser.js +++ b/packages/app-root/src/hooks/usePanoptesUser.js @@ -1,38 +1,21 @@ import auth from 'panoptes-client/lib/auth' -import { auth as authHelpers } from '@zooniverse/panoptes-js' import { useEffect, useState } from 'react' -if (typeof window !== 'undefined') { - auth.checkCurrent() -} +import { fetchPanoptesUser } from '../helpers' -async function fetchPanoptesUser() { - try { - const authorization = await auth.checkBearerToken() - /* - Use crypto.subtle as a proxy for checking for SSL. - It will only exist for https:// URLs. - */ - const isSecure = crypto?.subtle - if (authorization && isSecure) { - const { user, error } = await authHelpers.decodeJWT(authorization) - if (user) { - return user - } - if (error) { - throw error - } - } - } catch (error) { - console.log(error) - } - return await auth.checkCurrent() +const isBrowser = typeof window !== 'undefined' + +if (isBrowser) { + auth.checkCurrent() } -const isBrowser = typeof window !== 'undefined' const localStorage = isBrowser ? window.localStorage : null const storedUserJSON = localStorage?.getItem('panoptes-user') let user = storedUserJSON && JSON.parse(storedUserJSON) +/* + Null users crash the ZooHeader component. + Set them to undefined for now. +*/ if (user === null) { user = undefined } @@ -45,11 +28,10 @@ export default function usePanoptesUser() { async function checkUserSession() { setLoading(true) try { - const panoptesUser = await fetchPanoptesUser() + const panoptesUser = await fetchPanoptesUser(user) if (panoptesUser) { - const { admin, avatar_src, display_name, id, login } = panoptesUser - user = { admin, avatar_src, display_name, id, login } - localStorage?.setItem('panoptes-user', JSON.stringify(user)) + localStorage?.setItem('panoptes-user', JSON.stringify(panoptesUser)) + user = panoptesUser } else { user = undefined localStorage?.removeItem('panoptes-user') @@ -60,7 +42,7 @@ export default function usePanoptesUser() { setLoading(false) } - if (typeof window !== 'undefined') { + if (isBrowser) { checkUserSession() } auth.listen('change', checkUserSession)