{"version":3,"file":"remove-restricted-relations.mjs","sources":["../../../src/sanitize/visitors/remove-restricted-relations.ts"],"sourcesContent":["import { isObject } from 'lodash';\nimport * as contentTypeUtils from '../../content-types';\nimport type { Model, RelationOrderingOptions } from '../../types';\nimport type { Visitor } from '../../traverse/factory';\nimport { VALID_RELATION_ORDERING_KEYS } from '../../relations';\n\nconst ACTIONS_TO_VERIFY = ['find'];\nconst { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = contentTypeUtils.constants;\n\ntype MorphArray = Array<{ __type: string }>;\ntype MorphElement = Record<string, unknown> & { __type: string };\ntype MorphMutationPayload = {\n  connect?: unknown;\n  set?: unknown;\n  disconnect?: unknown;\n  options?: Record<string, unknown> | null;\n};\ntype MorphPopulatePayload = {\n  on: Record<string, unknown>;\n  count?: unknown;\n};\n\nexport default (auth: unknown): Visitor =>\n  (visitorOptions, visitorUtils) => {\n    const { attribute } = visitorOptions;\n\n    // Deliberately not an `async` function. This visitor is invoked for every key of\n    // every node of every entity, and only relation attributes need any work at all.\n    // Declaring it `async` meant each of those keys allocated a promise purely to\n    // resolve it immediately, and the traversal then awaited it. Returning early\n    // without a promise lets the traversal stay synchronous for the common case.\n    if (!attribute || attribute.type !== 'relation') {\n      return;\n    }\n\n    return visitRelationAttribute(auth, visitorOptions, visitorUtils) as unknown as void;\n  };\n\nconst visitRelationAttribute = async (\n  auth: unknown,\n  { data, key, attribute, schema }: Parameters<Visitor>[0],\n  { remove, set }: Parameters<Visitor>[1]\n) => {\n  // Narrowing only; the caller reaches this for relation attributes exclusively.\n  if (!attribute) {\n    return;\n  }\n\n  const handleMorphRelation = async () => {\n    const elements = (data as Record<string, MorphArray | MorphElement | MorphMutationPayload>)[\n      key\n    ];\n\n    if (!elements) {\n      return;\n    }\n\n    if (isMorphMutationPayload(elements)) {\n      const newValue: Record<string, unknown> = {};\n\n      const connect = await handleMorphElements(elements.connect || []);\n      const relSet = await handleMorphElements(elements.set || []);\n      const disconnect = await handleMorphElements(elements.disconnect || []);\n\n      if (connect.length > 0) {\n        newValue.connect = connect;\n      }\n\n      if (relSet.length > 0) {\n        newValue.set = relSet;\n      }\n\n      if (disconnect.length > 0) {\n        newValue.disconnect = disconnect;\n      }\n\n      // TODO: this should technically be in its own visitor to check morph options, but for now we'll handle it here\n      const options = elements.options;\n      if (options && typeof options === 'object') {\n        const filteredOptions: RelationOrderingOptions = {};\n\n        Object.keys(options).forEach((key) => {\n          const optionKey = key as keyof RelationOrderingOptions;\n          const validator = VALID_RELATION_ORDERING_KEYS[optionKey];\n          const optionValue = options[key];\n\n          if (validator && validator(optionValue)) {\n            filteredOptions[optionKey] = optionValue as RelationOrderingOptions[typeof optionKey];\n          }\n        });\n\n        newValue.options = filteredOptions;\n      } else {\n        newValue.options = {};\n      }\n\n      set(key, newValue);\n    } else if (isMorphPopulatePayload(elements)) {\n      const newOn: Record<string, unknown> = {};\n\n      for (const [uid, subPopulate] of Object.entries(elements.on)) {\n        const scopes = ACTIONS_TO_VERIFY.map((action) => `${uid}.${action}`);\n        const isAllowed = await hasAccessToSomeScopes(scopes, auth);\n\n        if (isAllowed) {\n          newOn[uid] = subPopulate;\n        }\n      }\n\n      if (Object.keys(newOn).length === 0) {\n        remove(key);\n        return;\n      }\n\n      const count = isMorphPopulateCount(elements.count) ? true : elements.count;\n      set(key, { ...elements, count, on: newOn });\n    } else {\n      const newMorphValue = await handleMorphElements(elements);\n\n      if (!newMorphValue.length) {\n        if (Array.isArray(elements) && elements.length === 0) {\n          return;\n        }\n\n        remove(key);\n        return;\n      }\n\n      if (Array.isArray(elements)) {\n        set(key, newMorphValue);\n        return;\n      }\n\n      set(key, newMorphValue[0]);\n    }\n  };\n\n  const isMorphMutationPayload = (value: unknown): value is MorphMutationPayload => {\n    return isObject(value) && ('connect' in value || 'set' in value || 'disconnect' in value);\n  };\n\n  const isMorphPopulateCount = (value: unknown) => value === true || value === 'true';\n\n  const isMorphPopulatePayload = (value: unknown): value is MorphPopulatePayload => {\n    return isObject(value) && !('__type' in value) && 'on' in value && isObject(value.on);\n  };\n\n  const buildAllowedMorphPopulateFragment = async (subPopulate: unknown) => {\n    const newOn: Record<string, unknown> = {};\n\n    for (const uid of getRegisteredContentTypeUIDs()) {\n      const scopes = ACTIONS_TO_VERIFY.map((action) => `${uid}.${action}`);\n      const isAllowed = await hasAccessToSomeScopes(scopes, auth);\n\n      if (isAllowed) {\n        newOn[uid] = subPopulate;\n      }\n    }\n\n    return newOn;\n  };\n\n  const isMorphPopulateAllOrCount = (value: unknown): value is true | 'true' | { count: true } => {\n    return (\n      value === true ||\n      value === 'true' ||\n      (isObject(value) && 'count' in value && isMorphPopulateCount(value.count) && !('on' in value))\n    );\n  };\n\n  const isMorphCountOutput = (value: unknown): value is { count: number } => {\n    return (\n      isObject(value) &&\n      'count' in value &&\n      typeof value.count === 'number' &&\n      Object.keys(value).length === 1\n    );\n  };\n\n  const handleMorphElements = async (elements: unknown) => {\n    const allowedElements: Record<string, unknown>[] = [];\n    const elementsToCheck = Array.isArray(elements) ? elements : [elements];\n\n    for (const element of elementsToCheck) {\n      if (!isObject(element) || !('__type' in element) || typeof element.__type !== 'string') {\n        continue;\n      }\n\n      const scopes = ACTIONS_TO_VERIFY.map((action) => `${element.__type}.${action}`);\n      const isAllowed = await hasAccessToSomeScopes(scopes, auth);\n\n      if (isAllowed) {\n        allowedElements.push(element);\n      }\n    }\n\n    return allowedElements;\n  };\n\n  const handleRegularRelation = async () => {\n    const scopes = ACTIONS_TO_VERIFY.map((action) => `${attribute.target}.${action}`);\n    const isAllowed = await hasAccessToSomeScopes(scopes, auth);\n\n    if (!isAllowed) {\n      remove(key);\n    }\n  };\n\n  const isCreatorRelation = [CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE].includes(key);\n\n  if (contentTypeUtils.isMorphToRelationalAttribute(attribute)) {\n    const value = (data as Record<string, unknown>)[key];\n\n    if (isMorphPopulatePayload(value)) {\n      await handleMorphRelation();\n      return;\n    }\n\n    if (isMorphPopulateAllOrCount(value)) {\n      const newOn = await buildAllowedMorphPopulateFragment(true);\n\n      if (Object.keys(newOn).length === 0) {\n        remove(key);\n        return;\n      }\n\n      set(\n        key,\n        value === true || value === 'true' ? { on: newOn } : { ...value, count: true, on: newOn }\n      );\n      return;\n    }\n\n    if (isMorphCountOutput(value)) {\n      return;\n    }\n\n    await handleMorphRelation();\n    return;\n  }\n\n  if (isCreatorRelation && schema.options?.populateCreatorFields) {\n    return;\n  }\n\n  await handleRegularRelation();\n};\n\n/**\n * Per-`auth` memo of scope decisions.\n *\n * The decision for a given scope depends only on the ability carried by `auth`, which is\n * built once per request and not mutated while the response is sanitized. Sanitizing a\n * list re-asks the same question for every entity, so a 25-entity page with four\n * relations asked ~100 identical questions; each denial also constructed an Error, and\n * capturing a stack trace is by far the most expensive part of that.\n *\n * Keyed weakly on the `auth` object so entries are collected with the request.\n */\nconst scopeDecisionCache = new WeakMap<object, Map<string, boolean>>();\n\nconst canAccessScope = async (scope: string, auth: unknown): Promise<boolean> => {\n  const cacheable = typeof auth === 'object' && auth !== null;\n\n  let decisions: Map<string, boolean> | undefined;\n\n  if (cacheable) {\n    decisions = scopeDecisionCache.get(auth as object);\n\n    if (decisions === undefined) {\n      decisions = new Map();\n      scopeDecisionCache.set(auth as object, decisions);\n    } else {\n      const cached = decisions.get(scope);\n      if (cached !== undefined) {\n        return cached;\n      }\n    }\n  }\n\n  let allowed: boolean;\n  try {\n    await strapi.auth.verify(auth, { scope });\n    allowed = true;\n  } catch {\n    allowed = false;\n  }\n\n  decisions?.set(scope, allowed);\n\n  return allowed;\n};\n\nconst hasAccessToSomeScopes = async (scopes: string[], auth: unknown) => {\n  for (const scope of scopes) {\n    if (await canAccessScope(scope, auth)) {\n      return true;\n    }\n  }\n\n  return false;\n};\n\nconst getRegisteredContentTypeUIDs = () => {\n  return (Object.values(strapi.contentTypes ?? {}) as Model[])\n    .map((model) => model.uid)\n    .filter((uid): uid is string => typeof uid === 'string');\n};\n"],"names":["ACTIONS_TO_VERIFY","CREATED_BY_ATTRIBUTE","UPDATED_BY_ATTRIBUTE","contentTypeUtils","auth","visitorOptions","visitorUtils","attribute","type","visitRelationAttribute","data","key","schema","remove","set","handleMorphRelation","elements","isMorphMutationPayload","newValue","connect","handleMorphElements","relSet","disconnect","length","options","filteredOptions","Object","keys","forEach","optionKey","validator","VALID_RELATION_ORDERING_KEYS","optionValue","isMorphPopulatePayload","newOn","uid","subPopulate","entries","on","scopes","map","action","isAllowed","hasAccessToSomeScopes","count","isMorphPopulateCount","newMorphValue","Array","isArray","value","isObject","buildAllowedMorphPopulateFragment","getRegisteredContentTypeUIDs","isMorphPopulateAllOrCount","isMorphCountOutput","allowedElements","elementsToCheck","element","__type","push","handleRegularRelation","target","isCreatorRelation","includes","populateCreatorFields","scopeDecisionCache","WeakMap","canAccessScope","scope","cacheable","decisions","get","undefined","Map","cached","allowed","strapi","verify","values","contentTypes","model","filter"],"mappings":"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"}