diff --git a/.changeset/fix-admin-meta-access.md b/.changeset/fix-admin-meta-access.md new file mode 100644 index 00000000000..4698edbb3eb --- /dev/null +++ b/.changeset/fix-admin-meta-access.md @@ -0,0 +1,5 @@ +--- +'@keystone-6/core': patch +--- + +Fixes `ui.isAccessAllowed` when `undefined`, to prevent access to the `adminMeta` GraphQL query, akin to the behaviour for the default AdminUI `pageMiddleware` diff --git a/packages/core/src/admin-ui/system/generateAdminUI.ts b/packages/core/src/admin-ui/system/generateAdminUI.ts index 1c22ccd8d8f..44ab0292a00 100644 --- a/packages/core/src/admin-ui/system/generateAdminUI.ts +++ b/packages/core/src/admin-ui/system/generateAdminUI.ts @@ -7,7 +7,7 @@ import { Entry, walk as _walk } from '@nodelib/fs.walk'; import type { KeystoneConfig, AdminFileToWrite } from '../../types'; import { writeAdminFiles } from '../templates'; import { serializePathForImport } from '../utils/serializePathForImport'; -import type { AdminMetaRootVal } from './createAdminMeta'; +import type { AdminMetaRootVal } from '../../lib/create-admin-meta'; const walk = promisify(_walk); diff --git a/packages/core/src/admin-ui/system/index.ts b/packages/core/src/admin-ui/system/index.ts index 73ca4fe2e14..40f22ecb86e 100644 --- a/packages/core/src/admin-ui/system/index.ts +++ b/packages/core/src/admin-ui/system/index.ts @@ -1,2 +1 @@ export { generateAdminUI } from './generateAdminUI'; -export { KeystoneMeta } from './adminMetaSchema'; diff --git a/packages/core/src/admin-ui/templates/app.ts b/packages/core/src/admin-ui/templates/app.ts index 9667af1134a..90ede20ae2c 100644 --- a/packages/core/src/admin-ui/templates/app.ts +++ b/packages/core/src/admin-ui/templates/app.ts @@ -12,7 +12,7 @@ import { Kind, } from 'graphql'; import { staticAdminMetaQuery, StaticAdminMetaQuery } from '../admin-meta-graphql'; -import type { AdminMetaRootVal } from '../system/createAdminMeta'; +import type { AdminMetaRootVal } from '../../lib/create-admin-meta'; type AppTemplateOptions = { configFileExists: boolean }; diff --git a/packages/core/src/admin-ui/templates/index.ts b/packages/core/src/admin-ui/templates/index.ts index d6e5164083b..05bfa8e9ff5 100644 --- a/packages/core/src/admin-ui/templates/index.ts +++ b/packages/core/src/admin-ui/templates/index.ts @@ -1,7 +1,7 @@ import * as Path from 'path'; import type { GraphQLSchema } from 'graphql'; import type { KeystoneConfig, AdminFileToWrite } from '../../types'; -import type { AdminMetaRootVal } from '../system/createAdminMeta'; +import type { AdminMetaRootVal } from '../../lib/create-admin-meta'; import { appTemplate } from './app'; import { homeTemplate } from './home'; import { listTemplate } from './list'; diff --git a/packages/core/src/fields/types/relationship/index.ts b/packages/core/src/fields/types/relationship/index.ts index 6d143ea7abb..c8e36c26233 100644 --- a/packages/core/src/fields/types/relationship/index.ts +++ b/packages/core/src/fields/types/relationship/index.ts @@ -1,6 +1,6 @@ import { BaseListTypeInfo, FieldTypeFunc, CommonFieldConfig, fieldType } from '../../../types'; import { graphql } from '../../..'; -import { getAdminMetaForRelationshipField } from '../../../admin-ui/system/createAdminMeta'; +import { getAdminMetaForRelationshipField } from '../../../lib/create-admin-meta'; // This is the default display mode for Relationships type SelectDisplayConfig = { diff --git a/packages/core/src/admin-ui/system/adminMetaSchema.ts b/packages/core/src/lib/admin-meta-resolver.ts similarity index 95% rename from packages/core/src/admin-ui/system/adminMetaSchema.ts rename to packages/core/src/lib/admin-meta-resolver.ts index 0f2800dc309..672a606e1b6 100644 --- a/packages/core/src/admin-ui/system/adminMetaSchema.ts +++ b/packages/core/src/lib/admin-meta-resolver.ts @@ -7,7 +7,7 @@ import type { ListMetaRootVal, AdminMetaRootVal, FieldGroupMeta, -} from './createAdminMeta'; +} from './create-admin-meta'; type Context = KeystoneContext | { isAdminUIBuildProcess: true }; @@ -228,19 +228,25 @@ const adminMeta = graphql.object()({ }, }); +function defaultIsAccessAllowed({ session, sessionStrategy }: KeystoneContext) { + if (!sessionStrategy) return true; + return session !== undefined; +} + export const KeystoneMeta = graphql.object<{ adminMeta: AdminMetaRootVal }>()({ name: 'KeystoneMeta', fields: { adminMeta: graphql.field({ type: graphql.nonNull(adminMeta), resolve({ adminMeta }, args, context) { - if ('isAdminUIBuildProcess' in context || adminMeta.isAccessAllowed === undefined) { + if ('isAdminUIBuildProcess' in context) { return adminMeta; } - return Promise.resolve(adminMeta.isAccessAllowed(context)).then(isAllowed => { - if (isAllowed) { - return adminMeta; - } + + const isAccessAllowed = adminMeta?.isAccessAllowed ?? defaultIsAccessAllowed; + return Promise.resolve(isAccessAllowed(context)).then(isAllowed => { + if (isAllowed) return adminMeta; + // TODO: ughhhhhh, we really need to talk about errors. // mostly unrelated to above: error or return null here(+ make field nullable)?s throw new Error('Access denied'); diff --git a/packages/core/src/admin-ui/system/createAdminMeta.ts b/packages/core/src/lib/create-admin-meta.ts similarity index 98% rename from packages/core/src/admin-ui/system/createAdminMeta.ts rename to packages/core/src/lib/create-admin-meta.ts index f15051fdd15..8b02b13206b 100644 --- a/packages/core/src/admin-ui/system/createAdminMeta.ts +++ b/packages/core/src/lib/create-admin-meta.ts @@ -8,9 +8,10 @@ import type { JSONValue, MaybeItemFunction, } from '../../types'; -import { humanize } from '../../lib/utils'; -import type { InitialisedList } from '../../lib/core/initialise-lists'; -import type { FilterOrderArgs } from '../../types/config/fields'; +import type { FilterOrderArgs } from '../types/config/fields'; + +import { humanize } from './utils'; +import type { InitialisedList } from './core/initialise-lists'; type ContextFunction = (context: KeystoneContext) => MaybePromise; diff --git a/packages/core/src/lib/createGraphQLSchema.ts b/packages/core/src/lib/createGraphQLSchema.ts index b38079f924a..685fae60af9 100644 --- a/packages/core/src/lib/createGraphQLSchema.ts +++ b/packages/core/src/lib/createGraphQLSchema.ts @@ -1,9 +1,9 @@ import { GraphQLNamedType, GraphQLSchema } from 'graphql'; -import type { KeystoneConfig } from '../types'; -import { KeystoneMeta } from '../admin-ui/system/adminMetaSchema'; import { graphql } from '../types/schema'; -import type { AdminMetaRootVal } from '../admin-ui/system/createAdminMeta'; +import type { KeystoneConfig } from '../types'; +import { KeystoneMeta } from './admin-meta-resolver'; +import type { AdminMetaRootVal } from './create-admin-meta'; import type { InitialisedList } from './core/initialise-lists'; import { getMutationsForList } from './core/mutations'; diff --git a/packages/core/src/lib/createSystem.ts b/packages/core/src/lib/createSystem.ts index 9b9d1d19221..f61226c74e2 100644 --- a/packages/core/src/lib/createSystem.ts +++ b/packages/core/src/lib/createSystem.ts @@ -2,9 +2,9 @@ import { randomBytes } from 'node:crypto'; import pLimit from 'p-limit'; import type { FieldData, KeystoneConfig } from '../types'; -import { createAdminMeta } from '../admin-ui/system/createAdminMeta'; import type { PrismaModule } from '../artifacts'; import { allowAll } from '../access'; +import { createAdminMeta } from './create-admin-meta'; import { createGraphQLSchema } from './createGraphQLSchema'; import { createContext } from './context/createContext'; import { initialiseLists, InitialisedList } from './core/initialise-lists'; diff --git a/packages/core/src/scripts/dev.ts b/packages/core/src/scripts/dev.ts index 60408ed6c8b..b4476e3f922 100644 --- a/packages/core/src/scripts/dev.ts +++ b/packages/core/src/scripts/dev.ts @@ -25,7 +25,7 @@ import { import type { KeystoneConfig } from '../types'; import { initialiseLists } from '../lib/core/initialise-lists'; import { printPrismaSchema } from '../lib/core/prisma-schema-printer'; -import type { AdminMetaRootVal } from '../admin-ui/system/createAdminMeta'; +import type { AdminMetaRootVal } from '../lib/create-admin-meta'; import { pkgDir } from '../pkg-dir'; import { ExitError } from './utils'; import type { Flags } from './cli';