Remove multi auth error checking (#2018)
* Simplify state of selected account * Remove multi auth error checking
This commit is contained in:
		
							parent
							
								
									eaa15b3b43
								
							
						
					
					
						commit
						d7e01d0186
					
				@ -1,26 +1,21 @@
 | 
			
		||||
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'
 | 
			
		||||
import { useRouter } from 'next/router'
 | 
			
		||||
import * as cookie from 'cookie'
 | 
			
		||||
import { useMe } from '@/components/me'
 | 
			
		||||
import { USER_ID, SSR } from '@/lib/constants'
 | 
			
		||||
import { USER } from '@/fragments/users'
 | 
			
		||||
import { useQuery } from '@apollo/client'
 | 
			
		||||
import { UserListRow } from '@/components/user-list'
 | 
			
		||||
import Link from 'next/link'
 | 
			
		||||
import AddIcon from '@/svgs/add-fill.svg'
 | 
			
		||||
import { MultiAuthErrorBanner } from '@/components/banners'
 | 
			
		||||
import { cookieOptions, MULTI_AUTH_ANON, MULTI_AUTH_LIST, MULTI_AUTH_POINTER } from '@/lib/auth'
 | 
			
		||||
 | 
			
		||||
const AccountContext = createContext()
 | 
			
		||||
 | 
			
		||||
const CHECK_ERRORS_INTERVAL_MS = 5_000
 | 
			
		||||
 | 
			
		||||
const b64Decode = str => Buffer.from(str, 'base64').toString('utf-8')
 | 
			
		||||
 | 
			
		||||
export const AccountProvider = ({ children }) => {
 | 
			
		||||
  const [accounts, setAccounts] = useState([])
 | 
			
		||||
  const [meAnon, setMeAnon] = useState(true)
 | 
			
		||||
  const [errors, setErrors] = useState([])
 | 
			
		||||
  const [selected, setSelected] = useState(null)
 | 
			
		||||
 | 
			
		||||
  const updateAccountsFromCookie = useCallback(() => {
 | 
			
		||||
    const { [MULTI_AUTH_LIST]: listCookie } = cookie.parse(document.cookie)
 | 
			
		||||
@ -39,51 +34,29 @@ export const AccountProvider = ({ children }) => {
 | 
			
		||||
    return switchSuccess
 | 
			
		||||
  }, [updateAccountsFromCookie])
 | 
			
		||||
 | 
			
		||||
  const checkErrors = useCallback(() => {
 | 
			
		||||
    const {
 | 
			
		||||
      [MULTI_AUTH_LIST]: listCookie,
 | 
			
		||||
      [MULTI_AUTH_POINTER]: pointerCookie
 | 
			
		||||
    } = cookie.parse(document.cookie)
 | 
			
		||||
 | 
			
		||||
    const errors = []
 | 
			
		||||
 | 
			
		||||
    if (!listCookie) errors.push(`${MULTI_AUTH_LIST} cookie not found`)
 | 
			
		||||
    if (!pointerCookie) errors.push(`${MULTI_AUTH_POINTER} cookie not found`)
 | 
			
		||||
 | 
			
		||||
    setErrors(errors)
 | 
			
		||||
  }, [])
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (SSR) return
 | 
			
		||||
 | 
			
		||||
    updateAccountsFromCookie()
 | 
			
		||||
 | 
			
		||||
    const { [MULTI_AUTH_POINTER]: pointerCookie } = cookie.parse(document.cookie)
 | 
			
		||||
    setMeAnon(pointerCookie === 'anonymous')
 | 
			
		||||
 | 
			
		||||
    const interval = setInterval(checkErrors, CHECK_ERRORS_INTERVAL_MS)
 | 
			
		||||
    return () => clearInterval(interval)
 | 
			
		||||
  }, [updateAccountsFromCookie, checkErrors])
 | 
			
		||||
    setSelected(pointerCookie === MULTI_AUTH_ANON ? USER_ID.anon : Number(pointerCookie))
 | 
			
		||||
  }, [updateAccountsFromCookie])
 | 
			
		||||
 | 
			
		||||
  const value = useMemo(
 | 
			
		||||
    () => ({
 | 
			
		||||
      accounts,
 | 
			
		||||
      meAnon,
 | 
			
		||||
      setMeAnon,
 | 
			
		||||
      nextAccount,
 | 
			
		||||
      multiAuthErrors: errors
 | 
			
		||||
      selected,
 | 
			
		||||
      nextAccount
 | 
			
		||||
    }),
 | 
			
		||||
    [accounts, meAnon, setMeAnon, nextAccount])
 | 
			
		||||
    [accounts, selected, nextAccount])
 | 
			
		||||
  return <AccountContext.Provider value={value}>{children}</AccountContext.Provider>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const useAccounts = () => useContext(AccountContext)
 | 
			
		||||
 | 
			
		||||
const AccountListRow = ({ account, ...props }) => {
 | 
			
		||||
  const { meAnon, setMeAnon } = useAccounts()
 | 
			
		||||
  const { me, refreshMe } = useMe()
 | 
			
		||||
  const anonRow = account.id === USER_ID.anon
 | 
			
		||||
  const selected = (meAnon && anonRow) || Number(me?.id) === Number(account.id)
 | 
			
		||||
  const { selected } = useAccounts()
 | 
			
		||||
  const router = useRouter()
 | 
			
		||||
 | 
			
		||||
  // fetch updated names and photo ids since they might have changed since we were issued the JWTs
 | 
			
		||||
@ -103,18 +76,8 @@ const AccountListRow = ({ account, ...props }) => {
 | 
			
		||||
 | 
			
		||||
    // update pointer cookie
 | 
			
		||||
    const options = cookieOptions({ httpOnly: false })
 | 
			
		||||
    document.cookie = cookie.serialize(MULTI_AUTH_POINTER, anonRow ? MULTI_AUTH_ANON : account.id, options)
 | 
			
		||||
 | 
			
		||||
    // update state
 | 
			
		||||
    if (anonRow) {
 | 
			
		||||
      // order is important to prevent flashes of no session
 | 
			
		||||
      setMeAnon(true)
 | 
			
		||||
      await refreshMe()
 | 
			
		||||
    } else {
 | 
			
		||||
      await refreshMe()
 | 
			
		||||
      // order is important to prevent flashes of inconsistent data in switch account dialog
 | 
			
		||||
      setMeAnon(account.id === USER_ID.anon)
 | 
			
		||||
    }
 | 
			
		||||
    const anon = account.id === USER_ID.anon
 | 
			
		||||
    document.cookie = cookie.serialize(MULTI_AUTH_POINTER, anon ? MULTI_AUTH_ANON : account.id, options)
 | 
			
		||||
 | 
			
		||||
    // reload whatever page we're on to avoid any bugs due to missing authorization etc.
 | 
			
		||||
    router.reload()
 | 
			
		||||
@ -127,30 +90,16 @@ const AccountListRow = ({ account, ...props }) => {
 | 
			
		||||
        className='d-flex align-items-center me-2'
 | 
			
		||||
        {...props}
 | 
			
		||||
        onNymClick={onClick}
 | 
			
		||||
        selected={selected}
 | 
			
		||||
        selected={selected === account.id}
 | 
			
		||||
      />
 | 
			
		||||
    </div>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default function SwitchAccountList () {
 | 
			
		||||
  const { accounts, multiAuthErrors } = useAccounts()
 | 
			
		||||
  const { accounts } = useAccounts()
 | 
			
		||||
  const router = useRouter()
 | 
			
		||||
 | 
			
		||||
  const hasError = multiAuthErrors.length > 0
 | 
			
		||||
 | 
			
		||||
  if (hasError) {
 | 
			
		||||
    return (
 | 
			
		||||
      <>
 | 
			
		||||
        <div className='my-2'>
 | 
			
		||||
          <div className='d-flex flex-column flex-wrap mt-2 mb-3'>
 | 
			
		||||
            <MultiAuthErrorBanner errors={multiAuthErrors} />
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </>
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // can't show hat since the streak is not included in the JWT payload
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,6 @@ import { useMutation } from '@apollo/client'
 | 
			
		||||
import { WELCOME_BANNER_MUTATION } from '@/fragments/users'
 | 
			
		||||
import { useToast } from '@/components/toast'
 | 
			
		||||
import Link from 'next/link'
 | 
			
		||||
import AccordianItem from '@/components/accordian-item'
 | 
			
		||||
 | 
			
		||||
export function WelcomeBanner ({ Banner }) {
 | 
			
		||||
  const { me } = useMe()
 | 
			
		||||
@ -124,24 +123,3 @@ export function AuthBanner () {
 | 
			
		||||
    </Alert>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function MultiAuthErrorBanner ({ errors }) {
 | 
			
		||||
  return (
 | 
			
		||||
    <Alert className={styles.banner} key='info' variant='danger'>
 | 
			
		||||
      <div className='fw-bold mb-3'>Account switching is currently unavailable</div>
 | 
			
		||||
      <AccordianItem
 | 
			
		||||
        className='my-3'
 | 
			
		||||
        header='We have detected the following issues:'
 | 
			
		||||
        headerColor='var(--bs-danger-text-emphasis)'
 | 
			
		||||
        body={
 | 
			
		||||
          <ul>
 | 
			
		||||
            {errors.map((err, i) => (
 | 
			
		||||
              <li key={i}>{err}</li>
 | 
			
		||||
            ))}
 | 
			
		||||
          </ul>
 | 
			
		||||
      }
 | 
			
		||||
      />
 | 
			
		||||
      <div className='mt-3'>To resolve these issues, please sign out and sign in again.</div>
 | 
			
		||||
    </Alert>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user