import { createContext, useCallback, useContext, useEffect, useState } from 'react'
import { useRouter } from 'next/router'
import cookie from 'cookie'
import { useMe } from './me'
import { ANON_USER_ID, SSR } from '../lib/constants'
import { USER } from '../fragments/users'
import { useApolloClient, useQuery } from '@apollo/client'
import { UserListRow } from './user-list'
const AccountContext = createContext()
const b64Decode = str => Buffer.from(str, 'base64').toString('utf-8')
const b64Encode = obj => Buffer.from(JSON.stringify(obj)).toString('base64')
export const AccountProvider = ({ children }) => {
const { me } = useMe()
const [accounts, setAccounts] = useState([])
const [isAnon, setIsAnon] = useState(true)
const updateAccountsFromCookie = useCallback(() => {
try {
const { multi_auth: multiAuthCookie } = cookie.parse(document.cookie)
const accounts = multiAuthCookie
? JSON.parse(b64Decode(multiAuthCookie))
: me ? [{ id: Number(me.id), name: me.name, photoId: me.photoId }] : []
setAccounts(accounts)
// required for backwards compatibility: sync cookie with accounts if no multi auth cookie exists
// this is the case for sessions that existed before we deployed account switching
if (!multiAuthCookie && !!me) {
document.cookie = `multi_auth=${b64Encode(accounts)}; Path=/; Secure`
}
} catch (err) {
console.error('error parsing cookies:', err)
}
}, [setAccounts])
useEffect(() => {
updateAccountsFromCookie()
}, [])
const addAccount = useCallback(user => {
setAccounts(accounts => [...accounts, user])
}, [setAccounts])
const removeAccount = useCallback(userId => {
setAccounts(accounts => accounts.filter(({ id }) => id !== userId))
}, [setAccounts])
const multiAuthSignout = useCallback(async () => {
// switch to next available account
const { status } = await fetch('/api/signout', { credentials: 'include' })
// if status is 201, this mean the server was able to switch us to the next available account
// and the current account was simply removed from the list of available accounts including the corresponding JWT.
// -> update needed to sync state with cookies
if (status === 201) updateAccountsFromCookie()
return status
}, [updateAccountsFromCookie])
useEffect(() => {
// document not defined on server
if (SSR) return
const { 'multi_auth.user-id': multiAuthUserIdCookie } = cookie.parse(document.cookie)
setIsAnon(multiAuthUserIdCookie === 'anonymous')
}, [])
return