@payloadcms/plugin-multi-tenant
Version:
Multi Tenant plugin for Payload
133 lines (132 loc) • 5.52 kB
JavaScript
import { unauthorized } from 'next/navigation.js';
import { formatAdminURL } from 'payload/shared';
import { getCollectionIDType } from './getCollectionIDType.js';
import { getTenantFromCookie } from './getTenantFromCookie.js';
import { getTenantOptions } from './getTenantOptions.js';
export async function getGlobalViewRedirect({ slug: collectionSlug, basePath, docID, headers, payload, tenantFieldName, tenantsArrayFieldName, tenantsArrayTenantFieldName, tenantsCollectionSlug, useAsTitle, user, userHasAccessToAllTenants, view }) {
const idType = getCollectionIDType({
collectionSlug: tenantsCollectionSlug,
payload
});
let tenant = getTenantFromCookie(headers, idType);
let redirectRoute = undefined;
if (!user) {
return unauthorized();
}
if (!tenant) {
const tenantOptions = await getTenantOptions({
payload,
tenantsArrayFieldName,
tenantsArrayTenantFieldName,
tenantsCollectionSlug,
useAsTitle,
user,
userHasAccessToAllTenants
});
tenant = tenantOptions[0]?.value || null;
}
if (tenant) {
try {
const globalTenantDocQuery = await payload.find({
collection: collectionSlug,
depth: 0,
limit: 1,
pagination: false,
select: {
id: true
},
where: {
[tenantFieldName]: {
in: [
tenant
]
}
}
});
const globalTenantDocID = globalTenantDocQuery?.docs?.[0]?.id;
if (view === 'document') {
// global tenant document edit view
if (globalTenantDocID && docID !== globalTenantDocID) {
// tenant document already exists but does not match current route docID
// redirect to matching tenant docID from query
redirectRoute = `/collections/${collectionSlug}/${globalTenantDocID}`;
} else if (docID && !globalTenantDocID) {
// a docID was found in the route but no global document with this tenant exists
// so we need to generate a redirect to the create route
redirectRoute = await generateCreateRedirect({
collectionSlug,
payload,
tenantID: tenant
});
}
} else if (view === 'list') {
// global tenant document list view
if (globalTenantDocID) {
// tenant document exists, redirect from list view to the document edit view
redirectRoute = `/collections/${collectionSlug}/${globalTenantDocID}`;
} else {
// no matching document was found for the current tenant
// so we need to generate a redirect to the create route
redirectRoute = await generateCreateRedirect({
collectionSlug,
payload,
tenantID: tenant
});
}
}
} catch (e) {
const prefix = `${e && typeof e === 'object' && 'message' in e && typeof e.message === 'string' ? `${e.message} - ` : ''}`;
payload.logger.error(e, `${prefix}Multi Tenant Redirect Error`);
}
} else {
// no tenants were found, redirect to the admin view
return formatAdminURL({
adminRoute: payload.config.routes.admin,
basePath,
path: '',
serverURL: payload.config.serverURL
});
}
if (redirectRoute) {
return formatAdminURL({
adminRoute: payload.config.routes.admin,
basePath,
path: redirectRoute,
serverURL: payload.config.serverURL
});
}
// no redirect is needed
// the current route is valid
return undefined;
}
/**
* Generate a redirect URL for creating a new document in a multi-tenant collection.
*
* If autosave is enabled on the collection, we need to create the document and then redirect to it.
* Otherwise we can redirect to the default create route.
*/ async function generateCreateRedirect({ collectionSlug, payload, tenantID }) {
const collection = payload.collections[collectionSlug];
if (collection?.config.versions?.drafts && typeof collection.config.versions.drafts === 'object' && collection.config.versions.drafts.autosave) {
// Autosave is enabled, create a document first
try {
const doc = await payload.create({
collection: collectionSlug,
data: {
tenant: tenantID
},
depth: 0,
draft: true,
select: {
id: true
}
});
return `/collections/${collectionSlug}/${doc.id}`;
} catch (error) {
payload.logger.error(error, `Error creating autosave global multi tenant document for ${collectionSlug}`);
}
return '/';
}
// Autosave is not enabled, redirect to default create route
return `/collections/${collectionSlug}/create`;
}
//# sourceMappingURL=getGlobalViewRedirect.js.map