Skip to content

Commit

Permalink
Clean up usePanoptesUser
Browse files Browse the repository at this point in the history
- move `fetchPanoptesUser` into a helper.
- add explanatory comments.
- restore the missing `avatar_src` when getting the user object from a JWT.
  • Loading branch information
eatyourgreens committed Oct 16, 2023
1 parent c0a8128 commit 4d68293
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 31 deletions.
38 changes: 38 additions & 0 deletions packages/app-root/src/helpers/fetchPanoptesUser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import auth from 'panoptes-client/lib/auth'
import { auth as authHelpers } from '@zooniverse/panoptes-js'

/**
Get a Panoptes user from a Panoptes JSON Web Token (JWT), if we have one, or from
the Panoptes API otherwise.
*/
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 }
}
1 change: 1 addition & 0 deletions packages/app-root/src/helpers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as fetchPanoptesUser } from './fetchPanoptesUser.js'
44 changes: 13 additions & 31 deletions packages/app-root/src/hooks/usePanoptesUser.js
Original file line number Diff line number Diff line change
@@ -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
}
Expand All @@ -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')
Expand All @@ -60,7 +42,7 @@ export default function usePanoptesUser() {
setLoading(false)
}

if (typeof window !== 'undefined') {
if (isBrowser) {
checkUserSession()
}
auth.listen('change', checkUserSession)
Expand Down

0 comments on commit 4d68293

Please sign in to comment.