fix(plugin-multi-tenant): remove tenant cookie on logout (#10761)
### What? - Removes the tenant cookie when the user logs out - Prevents double redirect to globals when no tenant is selected ### Why? There were a couple scenarios where the cookie and the tenant did not match, ie if you logged into 1 tenant, and then out and then into another tenant.
This commit is contained in:
@@ -25,14 +25,16 @@ const Context = createContext<ContextType>({
|
||||
export const TenantSelectionProviderClient = ({
|
||||
children,
|
||||
initialValue,
|
||||
tenantCookie,
|
||||
tenantOptions,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
initialValue?: string
|
||||
initialValue?: number | string
|
||||
tenantCookie?: string
|
||||
tenantOptions: OptionObject[]
|
||||
}) => {
|
||||
const [selectedTenantID, setSelectedTenantID] = React.useState<number | string>(
|
||||
initialValue || SELECT_ALL,
|
||||
const [selectedTenantID, setSelectedTenantID] = React.useState<number | string | undefined>(
|
||||
initialValue,
|
||||
)
|
||||
const [preventRefreshOnChange, setPreventRefreshOnChange] = React.useState(false)
|
||||
const { user } = useAuth()
|
||||
@@ -49,11 +51,20 @@ export const TenantSelectionProviderClient = ({
|
||||
document.cookie = 'payload-tenant=' + (value || '') + expires + '; path=/'
|
||||
}, [])
|
||||
|
||||
const deleteCookie = React.useCallback(() => {
|
||||
document.cookie = 'payload-tenant=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'
|
||||
}, [])
|
||||
|
||||
const setTenant = React.useCallback<ContextType['setTenant']>(
|
||||
({ id, refresh }) => {
|
||||
if (id === undefined) {
|
||||
setSelectedTenantID(SELECT_ALL)
|
||||
setCookie(SELECT_ALL)
|
||||
if (tenantOptions.length > 1) {
|
||||
setSelectedTenantID(SELECT_ALL)
|
||||
setCookie(SELECT_ALL)
|
||||
} else {
|
||||
setSelectedTenantID(tenantOptions[0]?.value)
|
||||
setCookie(String(tenantOptions[0]?.value))
|
||||
}
|
||||
} else {
|
||||
setSelectedTenantID(id)
|
||||
setCookie(String(id))
|
||||
@@ -62,7 +73,7 @@ export const TenantSelectionProviderClient = ({
|
||||
router.refresh()
|
||||
}
|
||||
},
|
||||
[setSelectedTenantID, setCookie, router, preventRefreshOnChange],
|
||||
[setSelectedTenantID, setCookie, router, preventRefreshOnChange, tenantOptions],
|
||||
)
|
||||
|
||||
React.useEffect(() => {
|
||||
@@ -77,11 +88,26 @@ export const TenantSelectionProviderClient = ({
|
||||
setTenant({ id: undefined, refresh: true })
|
||||
}
|
||||
}
|
||||
}, [initialValue, setTenant, selectedTenantID, tenantOptions])
|
||||
}, [tenantCookie, setTenant, selectedTenantID, tenantOptions, initialValue, setCookie])
|
||||
|
||||
React.useEffect(() => {
|
||||
router.refresh()
|
||||
}, [userID, router])
|
||||
if (userID && !tenantCookie) {
|
||||
// User is logged in, but does not have a tenant cookie, set it
|
||||
setSelectedTenantID(initialValue)
|
||||
setCookie(String(initialValue))
|
||||
}
|
||||
}, [userID, tenantCookie, initialValue, setCookie, router])
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!userID && tenantCookie) {
|
||||
// User is not logged in, but has a tenant cookie, delete it
|
||||
deleteCookie()
|
||||
setSelectedTenantID(undefined)
|
||||
} else if (userID) {
|
||||
// User changed, refresh
|
||||
router.refresh()
|
||||
}
|
||||
}, [userID, tenantCookie, deleteCookie, router])
|
||||
|
||||
return (
|
||||
<span
|
||||
|
||||
@@ -2,6 +2,8 @@ import type { OptionObject, Payload, User } from 'payload'
|
||||
|
||||
import { cookies as getCookies } from 'next/headers.js'
|
||||
|
||||
import { SELECT_ALL } from '../../constants.js'
|
||||
import { findTenantOptions } from '../../queries/findTenantOptions.js'
|
||||
import { TenantSelectionProviderClient } from './index.client.js'
|
||||
|
||||
type Args = {
|
||||
@@ -22,16 +24,14 @@ export const TenantSelectionProvider = async ({
|
||||
let tenantOptions: OptionObject[] = []
|
||||
|
||||
try {
|
||||
const { docs: userTenants } = await payload.find({
|
||||
collection: tenantsCollectionSlug,
|
||||
depth: 0,
|
||||
limit: 1000,
|
||||
overrideAccess: false,
|
||||
sort: useAsTitle,
|
||||
const { docs } = await findTenantOptions({
|
||||
limit: 0,
|
||||
payload,
|
||||
tenantsCollectionSlug,
|
||||
useAsTitle,
|
||||
user,
|
||||
})
|
||||
|
||||
tenantOptions = userTenants.map((doc) => ({
|
||||
tenantOptions = docs.map((doc) => ({
|
||||
label: String(doc[useAsTitle]),
|
||||
value: String(doc.id),
|
||||
}))
|
||||
@@ -40,10 +40,25 @@ export const TenantSelectionProvider = async ({
|
||||
}
|
||||
|
||||
const cookies = await getCookies()
|
||||
const tenantCookie = cookies.get('payload-tenant')?.value
|
||||
let tenantCookie = cookies.get('payload-tenant')?.value
|
||||
let initialValue = undefined
|
||||
const isValidTenantCookie =
|
||||
(tenantOptions.length > 1 && tenantCookie === SELECT_ALL) ||
|
||||
tenantOptions.some((option) => option.value === tenantCookie)
|
||||
|
||||
if (isValidTenantCookie) {
|
||||
initialValue = tenantCookie
|
||||
} else {
|
||||
tenantCookie = undefined
|
||||
initialValue = tenantOptions.length > 1 ? SELECT_ALL : tenantOptions[0]?.value
|
||||
}
|
||||
|
||||
return (
|
||||
<TenantSelectionProviderClient initialValue={tenantCookie} tenantOptions={tenantOptions}>
|
||||
<TenantSelectionProviderClient
|
||||
initialValue={initialValue}
|
||||
tenantCookie={tenantCookie}
|
||||
tenantOptions={tenantOptions}
|
||||
>
|
||||
{children}
|
||||
</TenantSelectionProviderClient>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user