payload 3.64.0-internal.9a6b44a → 3.64.0-internal.deef021
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/sanitize.d.ts.map +1 -1
- package/dist/config/sanitize.js +0 -29
- package/dist/config/sanitize.js.map +1 -1
- package/dist/uploads/checkFileRestrictions.d.ts.map +1 -1
- package/dist/uploads/checkFileRestrictions.js +10 -0
- package/dist/uploads/checkFileRestrictions.js.map +1 -1
- package/dist/utilities/validatePDF.d.ts +2 -0
- package/dist/utilities/validatePDF.d.ts.map +1 -0
- package/dist/utilities/validatePDF.js +16 -0
- package/dist/utilities/validatePDF.js.map +1 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/config/sanitize.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,MAAM,EAGN,eAAe,EAEhB,MAAM,YAAY,CAAA;AA6FnB,eAAO,MAAM,cAAc,mBAA0B,MAAM,KAAG,OAAO,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/config/sanitize.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,MAAM,EAGN,eAAe,EAEhB,MAAM,YAAY,CAAA;AA6FnB,eAAO,MAAM,cAAc,mBAA0B,MAAM,KAAG,OAAO,CAAC,eAAe,CAiXpF,CAAA"}
|
package/dist/config/sanitize.js
CHANGED
|
@@ -122,35 +122,6 @@ export const sanitizeConfig = async (incomingConfig)=>{
|
|
|
122
122
|
i18nConfig.fallbackLanguage = supportedLangKeys.includes(fallbackLang) ? fallbackLang : supportedLangKeys[0];
|
|
123
123
|
i18nConfig.translations = incomingConfig.i18n?.translations || i18nConfig.translations;
|
|
124
124
|
}
|
|
125
|
-
// Inject custom translations from i18n.translations into supportedLanguages
|
|
126
|
-
// This allows label functions like ({ t }) => t('namespace:key') to work with custom translations
|
|
127
|
-
// that users define in their config, not just the default translations from @payloadcms/translations
|
|
128
|
-
if (i18nConfig.translations && typeof i18nConfig.translations === 'object') {
|
|
129
|
-
Object.keys(i18nConfig.translations).forEach((lang)=>{
|
|
130
|
-
const langKey = lang;
|
|
131
|
-
const customTranslations = i18nConfig.translations[langKey];
|
|
132
|
-
if (customTranslations && typeof customTranslations === 'object') {
|
|
133
|
-
const existingLang = i18nConfig.supportedLanguages[langKey];
|
|
134
|
-
if (existingLang) {
|
|
135
|
-
// Language exists - merge custom translations with existing
|
|
136
|
-
const merged = deepMergeSimple(existingLang.translations || {}, customTranslations);
|
|
137
|
-
// @ts-expect-error - merging custom translations into language config
|
|
138
|
-
i18nConfig.supportedLanguages[langKey] = {
|
|
139
|
-
...existingLang,
|
|
140
|
-
translations: merged
|
|
141
|
-
};
|
|
142
|
-
} else {
|
|
143
|
-
// Language doesn't exist - create it using 'en' as template
|
|
144
|
-
// Merge en.translations (general, authentication, etc.) with custom translations
|
|
145
|
-
const mergedTranslations = deepMergeSimple(en.translations, customTranslations);
|
|
146
|
-
i18nConfig.supportedLanguages[langKey] = {
|
|
147
|
-
...en,
|
|
148
|
-
translations: mergedTranslations
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
125
|
config.i18n = i18nConfig;
|
|
155
126
|
const richTextSanitizationPromises = [];
|
|
156
127
|
const schedulePublishCollections = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config/sanitize.ts"],"sourcesContent":["import type { AcceptedLanguages, Language } from '@payloadcms/translations'\n\nimport { en } from '@payloadcms/translations/languages/en'\nimport { deepMergeSimple } from '@payloadcms/translations/utilities'\n\nimport type { CollectionSlug, GlobalSlug, SanitizedCollectionConfig } from '../index.js'\nimport type { SanitizedJobsConfig } from '../queues/config/types/index.js'\nimport type {\n Config,\n LocalizationConfigWithLabels,\n LocalizationConfigWithNoLabels,\n SanitizedConfig,\n Timezone,\n} from './types.js'\n\nimport { defaultUserCollection } from '../auth/defaultUser.js'\nimport { authRootEndpoints } from '../auth/endpoints/index.js'\nimport { sanitizeCollection } from '../collections/config/sanitize.js'\nimport { migrationsCollection } from '../database/migrations/migrationsCollection.js'\nimport { DuplicateCollection, InvalidConfiguration } from '../errors/index.js'\nimport { defaultTimezones } from '../fields/baseFields/timezone/defaultTimezones.js'\nimport { addFolderCollection } from '../folders/addFolderCollection.js'\nimport { addFolderFieldToCollection } from '../folders/addFolderFieldToCollection.js'\nimport { sanitizeGlobal } from '../globals/config/sanitize.js'\nimport { baseBlockFields, formatLabels, sanitizeFields } from '../index.js'\nimport {\n getLockedDocumentsCollection,\n lockedDocumentsCollectionSlug,\n} from '../locked-documents/config.js'\nimport { getPreferencesCollection, preferencesCollectionSlug } from '../preferences/config.js'\nimport { getQueryPresetsConfig, queryPresetsCollectionSlug } from '../query-presets/config.js'\nimport { getDefaultJobsCollection, jobsCollectionSlug } from '../queues/config/collection.js'\nimport { getJobStatsGlobal } from '../queues/config/global.js'\nimport { flattenBlock } from '../utilities/flattenAllFields.js'\nimport { getSchedulePublishTask } from '../versions/schedule/job.js'\nimport { addDefaultsToConfig } from './defaults.js'\nimport { setupOrderable } from './orderable/index.js'\n\nconst sanitizeAdminConfig = (configToSanitize: Config): Partial<SanitizedConfig> => {\n const sanitizedConfig = { ...configToSanitize }\n\n if (configToSanitize?.compatibility?.allowLocalizedWithinLocalized) {\n process.env.NEXT_PUBLIC_PAYLOAD_COMPATIBILITY_allowLocalizedWithinLocalized = 'true'\n }\n\n // default logging level will be 'error' if not provided\n sanitizedConfig.loggingLevels = {\n Forbidden: 'info',\n Locked: 'info',\n MissingFile: 'info',\n NotFound: 'info',\n ValidationError: 'info',\n ...(sanitizedConfig.loggingLevels || {}),\n }\n\n // add default user collection if none provided\n if (!sanitizedConfig?.admin?.user) {\n const firstCollectionWithAuth = sanitizedConfig.collections!.find(({ auth }) => Boolean(auth))\n\n if (firstCollectionWithAuth) {\n sanitizedConfig.admin!.user = firstCollectionWithAuth.slug\n } else {\n sanitizedConfig.admin!.user = defaultUserCollection.slug\n sanitizedConfig.collections!.push(defaultUserCollection)\n }\n }\n\n const userCollection = sanitizedConfig.collections!.find(\n ({ slug }) => slug === sanitizedConfig.admin!.user,\n )\n\n if (!userCollection || !userCollection.auth) {\n throw new InvalidConfiguration(\n `${sanitizedConfig.admin!.user} is not a valid admin user collection`,\n )\n }\n\n if (sanitizedConfig?.admin?.timezones) {\n if (typeof sanitizedConfig?.admin?.timezones?.supportedTimezones === 'function') {\n sanitizedConfig.admin.timezones.supportedTimezones =\n sanitizedConfig.admin.timezones.supportedTimezones({ defaultTimezones })\n }\n\n if (!sanitizedConfig?.admin?.timezones?.supportedTimezones) {\n sanitizedConfig.admin.timezones.supportedTimezones = defaultTimezones\n }\n } else {\n sanitizedConfig.admin!.timezones = {\n supportedTimezones: defaultTimezones,\n }\n }\n // Timezones supported by the Intl API\n const _internalSupportedTimezones = Intl.supportedValuesOf('timeZone')\n\n // We're casting here because it's already been sanitised above but TS still thinks it could be a function\n ;(sanitizedConfig.admin!.timezones.supportedTimezones as Timezone[]).forEach((timezone) => {\n if (!_internalSupportedTimezones.includes(timezone.value)) {\n throw new InvalidConfiguration(\n `Timezone ${timezone.value} is not supported by the current runtime via the Intl API.`,\n )\n }\n })\n\n return sanitizedConfig as unknown as Partial<SanitizedConfig>\n}\n\nexport const sanitizeConfig = async (incomingConfig: Config): Promise<SanitizedConfig> => {\n const configWithDefaults = addDefaultsToConfig(incomingConfig)\n\n const config: Partial<SanitizedConfig> = sanitizeAdminConfig(configWithDefaults)\n\n // Add orderable fields\n setupOrderable(config as SanitizedConfig)\n\n if (!config.endpoints) {\n config.endpoints = []\n }\n\n for (const endpoint of authRootEndpoints) {\n config.endpoints.push(endpoint)\n }\n\n if (config.localization && config.localization.locales?.length > 0) {\n // clone localization config so to not break everything\n const firstLocale = config.localization.locales[0]\n if (typeof firstLocale === 'string') {\n config.localization.localeCodes = [\n ...(config.localization as unknown as LocalizationConfigWithNoLabels).locales,\n ]\n\n // is string[], so convert to Locale[]\n config.localization.locales = (\n config.localization as unknown as LocalizationConfigWithNoLabels\n ).locales.map((locale) => ({\n code: locale,\n label: locale,\n rtl: false,\n toString: () => locale,\n }))\n } else {\n // is Locale[], so convert to string[] for localeCodes\n config.localization.localeCodes = config.localization.locales.map((locale) => locale.code)\n\n config.localization.locales = (\n config.localization as LocalizationConfigWithLabels\n ).locales.map((locale) => ({\n ...locale,\n toString: () => locale.code,\n }))\n }\n\n // Default fallback to true if not provided\n config.localization.fallback = config.localization?.fallback ?? true\n }\n\n const i18nConfig: SanitizedConfig['i18n'] = {\n fallbackLanguage: 'en',\n supportedLanguages: {\n en,\n },\n translations: {},\n }\n\n if (incomingConfig?.i18n) {\n i18nConfig.supportedLanguages =\n incomingConfig.i18n?.supportedLanguages || i18nConfig.supportedLanguages\n\n const supportedLangKeys = <AcceptedLanguages[]>Object.keys(i18nConfig.supportedLanguages)\n const fallbackLang = incomingConfig.i18n?.fallbackLanguage || i18nConfig.fallbackLanguage\n\n i18nConfig.fallbackLanguage = supportedLangKeys.includes(fallbackLang)\n ? fallbackLang\n : supportedLangKeys[0]!\n i18nConfig.translations =\n (incomingConfig.i18n?.translations as SanitizedConfig['i18n']['translations']) ||\n i18nConfig.translations\n }\n\n // Inject custom translations from i18n.translations into supportedLanguages\n // This allows label functions like ({ t }) => t('namespace:key') to work with custom translations\n // that users define in their config, not just the default translations from @payloadcms/translations\n if (i18nConfig.translations && typeof i18nConfig.translations === 'object') {\n Object.keys(i18nConfig.translations).forEach((lang) => {\n const langKey = lang as AcceptedLanguages\n const customTranslations = i18nConfig.translations[langKey]\n\n if (customTranslations && typeof customTranslations === 'object') {\n const existingLang = i18nConfig.supportedLanguages[langKey]\n\n if (existingLang) {\n // Language exists - merge custom translations with existing\n const merged = deepMergeSimple(existingLang.translations || {}, customTranslations)\n // @ts-expect-error - merging custom translations into language config\n i18nConfig.supportedLanguages[langKey] = { ...existingLang, translations: merged }\n } else {\n // Language doesn't exist - create it using 'en' as template\n // Merge en.translations (general, authentication, etc.) with custom translations\n const mergedTranslations = deepMergeSimple(en.translations, customTranslations)\n i18nConfig.supportedLanguages[langKey] = {\n ...en,\n translations: mergedTranslations,\n } as Language<typeof en.translations>\n }\n }\n })\n }\n\n config.i18n = i18nConfig\n\n const richTextSanitizationPromises: Array<(config: SanitizedConfig) => Promise<void>> = []\n\n const schedulePublishCollections: CollectionSlug[] = []\n\n const queryPresetsCollections: CollectionSlug[] = []\n\n const schedulePublishGlobals: GlobalSlug[] = []\n\n const collectionSlugs = new Set<CollectionSlug>()\n\n const validRelationships = [\n ...(config.collections?.map((c) => c.slug) ?? []),\n jobsCollectionSlug,\n lockedDocumentsCollectionSlug,\n preferencesCollectionSlug,\n ]\n\n if (config.folders !== false) {\n validRelationships.push(config.folders!.slug)\n }\n\n /**\n * Blocks sanitization needs to happen before collections, as collection/global join field sanitization needs config.blocks\n * to be populated with the sanitized blocks\n */\n config.blocks = []\n\n if (incomingConfig.blocks?.length) {\n for (const block of incomingConfig.blocks) {\n const sanitizedBlock = block\n\n if (sanitizedBlock._sanitized === true) {\n continue\n }\n sanitizedBlock._sanitized = true\n\n sanitizedBlock.fields = sanitizedBlock.fields.concat(baseBlockFields)\n\n sanitizedBlock.labels = !sanitizedBlock.labels\n ? formatLabels(sanitizedBlock.slug)\n : sanitizedBlock.labels\n\n sanitizedBlock.fields = await sanitizeFields({\n config: config as unknown as Config,\n existingFieldNames: new Set(),\n fields: sanitizedBlock.fields,\n parentIsLocalized: false,\n richTextSanitizationPromises,\n validRelationships,\n })\n\n const flattenedSanitizedBlock = flattenBlock({ block })\n\n config.blocks.push(flattenedSanitizedBlock)\n }\n }\n\n const folderEnabledCollections: SanitizedCollectionConfig[] = []\n\n for (let i = 0; i < config.collections!.length; i++) {\n if (collectionSlugs.has(config.collections![i]!.slug)) {\n throw new DuplicateCollection('slug', config.collections![i]!.slug)\n }\n\n collectionSlugs.add(config.collections![i]!.slug)\n\n const draftsConfig = config.collections![i]?.versions?.drafts\n\n if (typeof draftsConfig === 'object' && draftsConfig.schedulePublish) {\n schedulePublishCollections.push(config.collections![i]!.slug)\n }\n\n if (config.collections![i]!.enableQueryPresets) {\n queryPresetsCollections.push(config.collections![i]!.slug)\n\n if (!validRelationships.includes(queryPresetsCollectionSlug)) {\n validRelationships.push(queryPresetsCollectionSlug)\n }\n }\n\n if (config.folders !== false && config.collections![i]!.folders) {\n addFolderFieldToCollection({\n collection: config.collections![i]!,\n collectionSpecific: config.folders!.collectionSpecific,\n folderFieldName: config.folders!.fieldName,\n folderSlug: config.folders!.slug,\n })\n }\n\n config.collections![i] = await sanitizeCollection(\n config as unknown as Config,\n config.collections![i]!,\n richTextSanitizationPromises,\n validRelationships,\n )\n\n if (config.folders !== false && config.collections![i]!.folders) {\n folderEnabledCollections.push(config.collections![i]!)\n }\n }\n\n if (config.globals!.length > 0) {\n for (let i = 0; i < config.globals!.length; i++) {\n const draftsConfig = config.globals![i]?.versions?.drafts\n\n if (typeof draftsConfig === 'object' && draftsConfig.schedulePublish) {\n schedulePublishGlobals.push(config.globals![i]!.slug)\n }\n\n config.globals![i] = await sanitizeGlobal(\n config as unknown as Config,\n config.globals![i]!,\n richTextSanitizationPromises,\n validRelationships,\n )\n }\n }\n\n if (schedulePublishCollections.length || schedulePublishGlobals.length) {\n ;((config.jobs ??= {} as SanitizedJobsConfig).tasks ??= []).push(\n getSchedulePublishTask({\n adminUserSlug: config.admin!.user,\n collections: schedulePublishCollections,\n globals: schedulePublishGlobals,\n }),\n )\n }\n\n ;(config.jobs ??= {} as SanitizedJobsConfig).enabled = Boolean(\n (Array.isArray(configWithDefaults.jobs?.tasks) && configWithDefaults.jobs?.tasks?.length) ||\n (Array.isArray(configWithDefaults.jobs?.workflows) &&\n configWithDefaults.jobs?.workflows?.length),\n )\n\n // Need to add default jobs collection before locked documents collections\n if (config.jobs.enabled) {\n // Check for schedule property in both tasks and workflows\n const hasScheduleProperty =\n (config?.jobs?.tasks?.length && config.jobs.tasks.some((task) => task.schedule)) ||\n (config?.jobs?.workflows?.length &&\n config.jobs.workflows.some((workflow) => workflow.schedule))\n\n if (hasScheduleProperty) {\n config.jobs.scheduling = true\n // Add payload-jobs-stats global for tracking when a job of a specific slug was last run\n ;(config.globals ??= []).push(\n await sanitizeGlobal(\n config as unknown as Config,\n getJobStatsGlobal(config as unknown as Config),\n richTextSanitizationPromises,\n validRelationships,\n ),\n )\n\n config.jobs.stats = true\n }\n\n let defaultJobsCollection = getDefaultJobsCollection(config.jobs)\n\n if (typeof config.jobs.jobsCollectionOverrides === 'function') {\n defaultJobsCollection = config.jobs.jobsCollectionOverrides({\n defaultJobsCollection,\n })\n\n const hooks = defaultJobsCollection?.hooks\n // @todo - delete this check in 4.0\n if (hooks && config?.jobs?.runHooks !== true) {\n for (const [hookKey, hook] of Object.entries(hooks)) {\n const defaultAmount = hookKey === 'afterRead' || hookKey === 'beforeChange' ? 1 : 0\n if (hook.length > defaultAmount) {\n // eslint-disable-next-line no-console\n console.warn(\n `The jobsCollectionOverrides function is returning a collection with an additional ${hookKey} hook defined. These hooks will not run unless the jobs.runHooks option is set to true. Setting this option to true will negatively impact performance.`,\n )\n break\n }\n }\n }\n }\n const sanitizedJobsCollection = await sanitizeCollection(\n config as unknown as Config,\n defaultJobsCollection,\n richTextSanitizationPromises,\n validRelationships,\n )\n\n ;(config.collections ??= []).push(sanitizedJobsCollection)\n }\n\n if (config.folders !== false && folderEnabledCollections.length) {\n await addFolderCollection({\n collectionSpecific: config.folders!.collectionSpecific,\n config: config as unknown as Config,\n folderEnabledCollections,\n richTextSanitizationPromises,\n validRelationships,\n })\n }\n\n configWithDefaults.collections!.push(\n await sanitizeCollection(\n config as unknown as Config,\n getLockedDocumentsCollection(config as unknown as Config),\n richTextSanitizationPromises,\n validRelationships,\n ),\n )\n\n configWithDefaults.collections!.push(\n await sanitizeCollection(\n config as unknown as Config,\n getPreferencesCollection(config as unknown as Config),\n richTextSanitizationPromises,\n validRelationships,\n ),\n )\n\n const migrations = await sanitizeCollection(\n config as unknown as Config,\n migrationsCollection,\n richTextSanitizationPromises,\n validRelationships,\n )\n\n // @ts-expect-error indexSortableFields is only valid for @payloadcms/db-mongodb\n if (config?.db?.indexSortableFields) {\n migrations.indexes = [\n {\n fields: ['batch', 'name'],\n unique: false,\n },\n ]\n }\n configWithDefaults.collections!.push(migrations)\n\n if (queryPresetsCollections.length > 0) {\n configWithDefaults.collections!.push(\n await sanitizeCollection(\n config as unknown as Config,\n getQueryPresetsConfig(config as unknown as Config),\n richTextSanitizationPromises,\n validRelationships,\n ),\n )\n }\n\n if (config.serverURL !== '') {\n config.csrf!.push(config.serverURL!)\n }\n\n const uploadAdapters = new Set<string>()\n // interact with all collections\n for (const collection of config.collections!) {\n // deduped upload adapters\n if (collection.upload?.adapter) {\n uploadAdapters.add(collection.upload.adapter)\n }\n }\n\n if (!config.upload) {\n config.upload = { adapters: [] }\n }\n\n config.upload.adapters = Array.from(\n new Set(config.collections!.map((c) => c.upload?.adapter).filter(Boolean) as string[]),\n )\n\n // Pass through the email config as is so adapters don't break\n if (incomingConfig.email) {\n config.email = incomingConfig.email\n }\n\n /*\n Execute richText sanitization\n */\n if (typeof incomingConfig.editor === 'function') {\n config.editor = await incomingConfig.editor({\n config: config as SanitizedConfig,\n isRoot: true,\n parentIsLocalized: false,\n })\n if (config.editor.i18n && Object.keys(config.editor.i18n).length >= 0) {\n config.i18n.translations = deepMergeSimple(config.i18n.translations, config.editor.i18n)\n }\n }\n\n const promises: Promise<void>[] = []\n\n for (const sanitizeFunction of richTextSanitizationPromises) {\n promises.push(sanitizeFunction(config as SanitizedConfig))\n }\n\n await Promise.all(promises)\n\n return config as SanitizedConfig\n}\n"],"names":["en","deepMergeSimple","defaultUserCollection","authRootEndpoints","sanitizeCollection","migrationsCollection","DuplicateCollection","InvalidConfiguration","defaultTimezones","addFolderCollection","addFolderFieldToCollection","sanitizeGlobal","baseBlockFields","formatLabels","sanitizeFields","getLockedDocumentsCollection","lockedDocumentsCollectionSlug","getPreferencesCollection","preferencesCollectionSlug","getQueryPresetsConfig","queryPresetsCollectionSlug","getDefaultJobsCollection","jobsCollectionSlug","getJobStatsGlobal","flattenBlock","getSchedulePublishTask","addDefaultsToConfig","setupOrderable","sanitizeAdminConfig","configToSanitize","sanitizedConfig","compatibility","allowLocalizedWithinLocalized","process","env","NEXT_PUBLIC_PAYLOAD_COMPATIBILITY_allowLocalizedWithinLocalized","loggingLevels","Forbidden","Locked","MissingFile","NotFound","ValidationError","admin","user","firstCollectionWithAuth","collections","find","auth","Boolean","slug","push","userCollection","timezones","supportedTimezones","_internalSupportedTimezones","Intl","supportedValuesOf","forEach","timezone","includes","value","sanitizeConfig","incomingConfig","configWithDefaults","config","endpoints","endpoint","localization","locales","length","firstLocale","localeCodes","map","locale","code","label","rtl","toString","fallback","i18nConfig","fallbackLanguage","supportedLanguages","translations","i18n","supportedLangKeys","Object","keys","fallbackLang","lang","langKey","customTranslations","existingLang","merged","mergedTranslations","richTextSanitizationPromises","schedulePublishCollections","queryPresetsCollections","schedulePublishGlobals","collectionSlugs","Set","validRelationships","c","folders","blocks","block","sanitizedBlock","_sanitized","fields","concat","labels","existingFieldNames","parentIsLocalized","flattenedSanitizedBlock","folderEnabledCollections","i","has","add","draftsConfig","versions","drafts","schedulePublish","enableQueryPresets","collection","collectionSpecific","folderFieldName","fieldName","folderSlug","globals","jobs","tasks","adminUserSlug","enabled","Array","isArray","workflows","hasScheduleProperty","some","task","schedule","workflow","scheduling","stats","defaultJobsCollection","jobsCollectionOverrides","hooks","runHooks","hookKey","hook","entries","defaultAmount","console","warn","sanitizedJobsCollection","migrations","db","indexSortableFields","indexes","unique","serverURL","csrf","uploadAdapters","upload","adapter","adapters","from","filter","email","editor","isRoot","promises","sanitizeFunction","Promise","all"],"mappings":"AAEA,SAASA,EAAE,QAAQ,wCAAuC;AAC1D,SAASC,eAAe,QAAQ,qCAAoC;AAYpE,SAASC,qBAAqB,QAAQ,yBAAwB;AAC9D,SAASC,iBAAiB,QAAQ,6BAA4B;AAC9D,SAASC,kBAAkB,QAAQ,oCAAmC;AACtE,SAASC,oBAAoB,QAAQ,iDAAgD;AACrF,SAASC,mBAAmB,EAAEC,oBAAoB,QAAQ,qBAAoB;AAC9E,SAASC,gBAAgB,QAAQ,oDAAmD;AACpF,SAASC,mBAAmB,QAAQ,oCAAmC;AACvE,SAASC,0BAA0B,QAAQ,2CAA0C;AACrF,SAASC,cAAc,QAAQ,gCAA+B;AAC9D,SAASC,eAAe,EAAEC,YAAY,EAAEC,cAAc,QAAQ,cAAa;AAC3E,SACEC,4BAA4B,EAC5BC,6BAA6B,QACxB,gCAA+B;AACtC,SAASC,wBAAwB,EAAEC,yBAAyB,QAAQ,2BAA0B;AAC9F,SAASC,qBAAqB,EAAEC,0BAA0B,QAAQ,6BAA4B;AAC9F,SAASC,wBAAwB,EAAEC,kBAAkB,QAAQ,iCAAgC;AAC7F,SAASC,iBAAiB,QAAQ,6BAA4B;AAC9D,SAASC,YAAY,QAAQ,mCAAkC;AAC/D,SAASC,sBAAsB,QAAQ,8BAA6B;AACpE,SAASC,mBAAmB,QAAQ,gBAAe;AACnD,SAASC,cAAc,QAAQ,uBAAsB;AAErD,MAAMC,sBAAsB,CAACC;IAC3B,MAAMC,kBAAkB;QAAE,GAAGD,gBAAgB;IAAC;IAE9C,IAAIA,kBAAkBE,eAAeC,+BAA+B;QAClEC,QAAQC,GAAG,CAACC,+DAA+D,GAAG;IAChF;IAEA,wDAAwD;IACxDL,gBAAgBM,aAAa,GAAG;QAC9BC,WAAW;QACXC,QAAQ;QACRC,aAAa;QACbC,UAAU;QACVC,iBAAiB;QACjB,GAAIX,gBAAgBM,aAAa,IAAI,CAAC,CAAC;IACzC;IAEA,+CAA+C;IAC/C,IAAI,CAACN,iBAAiBY,OAAOC,MAAM;QACjC,MAAMC,0BAA0Bd,gBAAgBe,WAAW,CAAEC,IAAI,CAAC,CAAC,EAAEC,IAAI,EAAE,GAAKC,QAAQD;QAExF,IAAIH,yBAAyB;YAC3Bd,gBAAgBY,KAAK,CAAEC,IAAI,GAAGC,wBAAwBK,IAAI;QAC5D,OAAO;YACLnB,gBAAgBY,KAAK,CAAEC,IAAI,GAAGzC,sBAAsB+C,IAAI;YACxDnB,gBAAgBe,WAAW,CAAEK,IAAI,CAAChD;QACpC;IACF;IAEA,MAAMiD,iBAAiBrB,gBAAgBe,WAAW,CAAEC,IAAI,CACtD,CAAC,EAAEG,IAAI,EAAE,GAAKA,SAASnB,gBAAgBY,KAAK,CAAEC,IAAI;IAGpD,IAAI,CAACQ,kBAAkB,CAACA,eAAeJ,IAAI,EAAE;QAC3C,MAAM,IAAIxC,qBACR,GAAGuB,gBAAgBY,KAAK,CAAEC,IAAI,CAAC,qCAAqC,CAAC;IAEzE;IAEA,IAAIb,iBAAiBY,OAAOU,WAAW;QACrC,IAAI,OAAOtB,iBAAiBY,OAAOU,WAAWC,uBAAuB,YAAY;YAC/EvB,gBAAgBY,KAAK,CAACU,SAAS,CAACC,kBAAkB,GAChDvB,gBAAgBY,KAAK,CAACU,SAAS,CAACC,kBAAkB,CAAC;gBAAE7C;YAAiB;QAC1E;QAEA,IAAI,CAACsB,iBAAiBY,OAAOU,WAAWC,oBAAoB;YAC1DvB,gBAAgBY,KAAK,CAACU,SAAS,CAACC,kBAAkB,GAAG7C;QACvD;IACF,OAAO;QACLsB,gBAAgBY,KAAK,CAAEU,SAAS,GAAG;YACjCC,oBAAoB7C;QACtB;IACF;IACA,sCAAsC;IACtC,MAAM8C,8BAA8BC,KAAKC,iBAAiB,CAAC;IAGzD1B,gBAAgBY,KAAK,CAAEU,SAAS,CAACC,kBAAkB,CAAgBI,OAAO,CAAC,CAACC;QAC5E,IAAI,CAACJ,4BAA4BK,QAAQ,CAACD,SAASE,KAAK,GAAG;YACzD,MAAM,IAAIrD,qBACR,CAAC,SAAS,EAAEmD,SAASE,KAAK,CAAC,0DAA0D,CAAC;QAE1F;IACF;IAEA,OAAO9B;AACT;AAEA,OAAO,MAAM+B,iBAAiB,OAAOC;IACnC,MAAMC,qBAAqBrC,oBAAoBoC;IAE/C,MAAME,SAAmCpC,oBAAoBmC;IAE7D,uBAAuB;IACvBpC,eAAeqC;IAEf,IAAI,CAACA,OAAOC,SAAS,EAAE;QACrBD,OAAOC,SAAS,GAAG,EAAE;IACvB;IAEA,KAAK,MAAMC,YAAY/D,kBAAmB;QACxC6D,OAAOC,SAAS,CAACf,IAAI,CAACgB;IACxB;IAEA,IAAIF,OAAOG,YAAY,IAAIH,OAAOG,YAAY,CAACC,OAAO,EAAEC,SAAS,GAAG;QAClE,uDAAuD;QACvD,MAAMC,cAAcN,OAAOG,YAAY,CAACC,OAAO,CAAC,EAAE;QAClD,IAAI,OAAOE,gBAAgB,UAAU;YACnCN,OAAOG,YAAY,CAACI,WAAW,GAAG;mBAC7B,AAACP,OAAOG,YAAY,CAA+CC,OAAO;aAC9E;YAED,sCAAsC;YACtCJ,OAAOG,YAAY,CAACC,OAAO,GAAG,AAC5BJ,OAAOG,YAAY,CACnBC,OAAO,CAACI,GAAG,CAAC,CAACC,SAAY,CAAA;oBACzBC,MAAMD;oBACNE,OAAOF;oBACPG,KAAK;oBACLC,UAAU,IAAMJ;gBAClB,CAAA;QACF,OAAO;YACL,sDAAsD;YACtDT,OAAOG,YAAY,CAACI,WAAW,GAAGP,OAAOG,YAAY,CAACC,OAAO,CAACI,GAAG,CAAC,CAACC,SAAWA,OAAOC,IAAI;YAEzFV,OAAOG,YAAY,CAACC,OAAO,GAAG,AAC5BJ,OAAOG,YAAY,CACnBC,OAAO,CAACI,GAAG,CAAC,CAACC,SAAY,CAAA;oBACzB,GAAGA,MAAM;oBACTI,UAAU,IAAMJ,OAAOC,IAAI;gBAC7B,CAAA;QACF;QAEA,2CAA2C;QAC3CV,OAAOG,YAAY,CAACW,QAAQ,GAAGd,OAAOG,YAAY,EAAEW,YAAY;IAClE;IAEA,MAAMC,aAAsC;QAC1CC,kBAAkB;QAClBC,oBAAoB;YAClBjF;QACF;QACAkF,cAAc,CAAC;IACjB;IAEA,IAAIpB,gBAAgBqB,MAAM;QACxBJ,WAAWE,kBAAkB,GAC3BnB,eAAeqB,IAAI,EAAEF,sBAAsBF,WAAWE,kBAAkB;QAE1E,MAAMG,oBAAyCC,OAAOC,IAAI,CAACP,WAAWE,kBAAkB;QACxF,MAAMM,eAAezB,eAAeqB,IAAI,EAAEH,oBAAoBD,WAAWC,gBAAgB;QAEzFD,WAAWC,gBAAgB,GAAGI,kBAAkBzB,QAAQ,CAAC4B,gBACrDA,eACAH,iBAAiB,CAAC,EAAE;QACxBL,WAAWG,YAAY,GACrB,AAACpB,eAAeqB,IAAI,EAAED,gBACtBH,WAAWG,YAAY;IAC3B;IAEA,4EAA4E;IAC5E,kGAAkG;IAClG,qGAAqG;IACrG,IAAIH,WAAWG,YAAY,IAAI,OAAOH,WAAWG,YAAY,KAAK,UAAU;QAC1EG,OAAOC,IAAI,CAACP,WAAWG,YAAY,EAAEzB,OAAO,CAAC,CAAC+B;YAC5C,MAAMC,UAAUD;YAChB,MAAME,qBAAqBX,WAAWG,YAAY,CAACO,QAAQ;YAE3D,IAAIC,sBAAsB,OAAOA,uBAAuB,UAAU;gBAChE,MAAMC,eAAeZ,WAAWE,kBAAkB,CAACQ,QAAQ;gBAE3D,IAAIE,cAAc;oBAChB,4DAA4D;oBAC5D,MAAMC,SAAS3F,gBAAgB0F,aAAaT,YAAY,IAAI,CAAC,GAAGQ;oBAChE,sEAAsE;oBACtEX,WAAWE,kBAAkB,CAACQ,QAAQ,GAAG;wBAAE,GAAGE,YAAY;wBAAET,cAAcU;oBAAO;gBACnF,OAAO;oBACL,4DAA4D;oBAC5D,iFAAiF;oBACjF,MAAMC,qBAAqB5F,gBAAgBD,GAAGkF,YAAY,EAAEQ;oBAC5DX,WAAWE,kBAAkB,CAACQ,QAAQ,GAAG;wBACvC,GAAGzF,EAAE;wBACLkF,cAAcW;oBAChB;gBACF;YACF;QACF;IACF;IAEA7B,OAAOmB,IAAI,GAAGJ;IAEd,MAAMe,+BAAkF,EAAE;IAE1F,MAAMC,6BAA+C,EAAE;IAEvD,MAAMC,0BAA4C,EAAE;IAEpD,MAAMC,yBAAuC,EAAE;IAE/C,MAAMC,kBAAkB,IAAIC;IAE5B,MAAMC,qBAAqB;WACrBpC,OAAOnB,WAAW,EAAE2B,IAAI,CAAC6B,IAAMA,EAAEpD,IAAI,KAAK,EAAE;QAChD3B;QACAN;QACAE;KACD;IAED,IAAI8C,OAAOsC,OAAO,KAAK,OAAO;QAC5BF,mBAAmBlD,IAAI,CAACc,OAAOsC,OAAO,CAAErD,IAAI;IAC9C;IAEA;;;GAGC,GACDe,OAAOuC,MAAM,GAAG,EAAE;IAElB,IAAIzC,eAAeyC,MAAM,EAAElC,QAAQ;QACjC,KAAK,MAAMmC,SAAS1C,eAAeyC,MAAM,CAAE;YACzC,MAAME,iBAAiBD;YAEvB,IAAIC,eAAeC,UAAU,KAAK,MAAM;gBACtC;YACF;YACAD,eAAeC,UAAU,GAAG;YAE5BD,eAAeE,MAAM,GAAGF,eAAeE,MAAM,CAACC,MAAM,CAAChG;YAErD6F,eAAeI,MAAM,GAAG,CAACJ,eAAeI,MAAM,GAC1ChG,aAAa4F,eAAexD,IAAI,IAChCwD,eAAeI,MAAM;YAEzBJ,eAAeE,MAAM,GAAG,MAAM7F,eAAe;gBAC3CkD,QAAQA;gBACR8C,oBAAoB,IAAIX;gBACxBQ,QAAQF,eAAeE,MAAM;gBAC7BI,mBAAmB;gBACnBjB;gBACAM;YACF;YAEA,MAAMY,0BAA0BxF,aAAa;gBAAEgF;YAAM;YAErDxC,OAAOuC,MAAM,CAACrD,IAAI,CAAC8D;QACrB;IACF;IAEA,MAAMC,2BAAwD,EAAE;IAEhE,IAAK,IAAIC,IAAI,GAAGA,IAAIlD,OAAOnB,WAAW,CAAEwB,MAAM,EAAE6C,IAAK;QACnD,IAAIhB,gBAAgBiB,GAAG,CAACnD,OAAOnB,WAAW,AAAC,CAACqE,EAAE,CAAEjE,IAAI,GAAG;YACrD,MAAM,IAAI3C,oBAAoB,QAAQ0D,OAAOnB,WAAW,AAAC,CAACqE,EAAE,CAAEjE,IAAI;QACpE;QAEAiD,gBAAgBkB,GAAG,CAACpD,OAAOnB,WAAW,AAAC,CAACqE,EAAE,CAAEjE,IAAI;QAEhD,MAAMoE,eAAerD,OAAOnB,WAAW,AAAC,CAACqE,EAAE,EAAEI,UAAUC;QAEvD,IAAI,OAAOF,iBAAiB,YAAYA,aAAaG,eAAe,EAAE;YACpEzB,2BAA2B7C,IAAI,CAACc,OAAOnB,WAAW,AAAC,CAACqE,EAAE,CAAEjE,IAAI;QAC9D;QAEA,IAAIe,OAAOnB,WAAW,AAAC,CAACqE,EAAE,CAAEO,kBAAkB,EAAE;YAC9CzB,wBAAwB9C,IAAI,CAACc,OAAOnB,WAAW,AAAC,CAACqE,EAAE,CAAEjE,IAAI;YAEzD,IAAI,CAACmD,mBAAmBzC,QAAQ,CAACvC,6BAA6B;gBAC5DgF,mBAAmBlD,IAAI,CAAC9B;YAC1B;QACF;QAEA,IAAI4C,OAAOsC,OAAO,KAAK,SAAStC,OAAOnB,WAAW,AAAC,CAACqE,EAAE,CAAEZ,OAAO,EAAE;YAC/D5F,2BAA2B;gBACzBgH,YAAY1D,OAAOnB,WAAW,AAAC,CAACqE,EAAE;gBAClCS,oBAAoB3D,OAAOsC,OAAO,CAAEqB,kBAAkB;gBACtDC,iBAAiB5D,OAAOsC,OAAO,CAAEuB,SAAS;gBAC1CC,YAAY9D,OAAOsC,OAAO,CAAErD,IAAI;YAClC;QACF;QAEAe,OAAOnB,WAAW,AAAC,CAACqE,EAAE,GAAG,MAAM9G,mBAC7B4D,QACAA,OAAOnB,WAAW,AAAC,CAACqE,EAAE,EACtBpB,8BACAM;QAGF,IAAIpC,OAAOsC,OAAO,KAAK,SAAStC,OAAOnB,WAAW,AAAC,CAACqE,EAAE,CAAEZ,OAAO,EAAE;YAC/DW,yBAAyB/D,IAAI,CAACc,OAAOnB,WAAW,AAAC,CAACqE,EAAE;QACtD;IACF;IAEA,IAAIlD,OAAO+D,OAAO,CAAE1D,MAAM,GAAG,GAAG;QAC9B,IAAK,IAAI6C,IAAI,GAAGA,IAAIlD,OAAO+D,OAAO,CAAE1D,MAAM,EAAE6C,IAAK;YAC/C,MAAMG,eAAerD,OAAO+D,OAAO,AAAC,CAACb,EAAE,EAAEI,UAAUC;YAEnD,IAAI,OAAOF,iBAAiB,YAAYA,aAAaG,eAAe,EAAE;gBACpEvB,uBAAuB/C,IAAI,CAACc,OAAO+D,OAAO,AAAC,CAACb,EAAE,CAAEjE,IAAI;YACtD;YAEAe,OAAO+D,OAAO,AAAC,CAACb,EAAE,GAAG,MAAMvG,eACzBqD,QACAA,OAAO+D,OAAO,AAAC,CAACb,EAAE,EAClBpB,8BACAM;QAEJ;IACF;IAEA,IAAIL,2BAA2B1B,MAAM,IAAI4B,uBAAuB5B,MAAM,EAAE;;QACpE,CAAA,AAACL,CAAAA,OAAOgE,IAAI,KAAK,CAAC,CAAuB,EAAGC,KAAK,KAAK,EAAE,AAAD,EAAG/E,IAAI,CAC9DzB,uBAAuB;YACrByG,eAAelE,OAAOtB,KAAK,CAAEC,IAAI;YACjCE,aAAakD;YACbgC,SAAS9B;QACX;IAEJ;;IAEEjC,CAAAA,OAAOgE,IAAI,KAAK,CAAC,CAAuB,EAAGG,OAAO,GAAGnF,QACrD,AAACoF,MAAMC,OAAO,CAACtE,mBAAmBiE,IAAI,EAAEC,UAAUlE,mBAAmBiE,IAAI,EAAEC,OAAO5D,UAC/E+D,MAAMC,OAAO,CAACtE,mBAAmBiE,IAAI,EAAEM,cACtCvE,mBAAmBiE,IAAI,EAAEM,WAAWjE;IAG1C,0EAA0E;IAC1E,IAAIL,OAAOgE,IAAI,CAACG,OAAO,EAAE;QACvB,0DAA0D;QAC1D,MAAMI,sBACJ,AAACvE,QAAQgE,MAAMC,OAAO5D,UAAUL,OAAOgE,IAAI,CAACC,KAAK,CAACO,IAAI,CAAC,CAACC,OAASA,KAAKC,QAAQ,KAC7E1E,QAAQgE,MAAMM,WAAWjE,UACxBL,OAAOgE,IAAI,CAACM,SAAS,CAACE,IAAI,CAAC,CAACG,WAAaA,SAASD,QAAQ;QAE9D,IAAIH,qBAAqB;YACvBvE,OAAOgE,IAAI,CAACY,UAAU,GAAG;YAEvB5E,CAAAA,OAAO+D,OAAO,KAAK,EAAE,AAAD,EAAG7E,IAAI,CAC3B,MAAMvC,eACJqD,QACAzC,kBAAkByC,SAClB8B,8BACAM;YAIJpC,OAAOgE,IAAI,CAACa,KAAK,GAAG;QACtB;QAEA,IAAIC,wBAAwBzH,yBAAyB2C,OAAOgE,IAAI;QAEhE,IAAI,OAAOhE,OAAOgE,IAAI,CAACe,uBAAuB,KAAK,YAAY;YAC7DD,wBAAwB9E,OAAOgE,IAAI,CAACe,uBAAuB,CAAC;gBAC1DD;YACF;YAEA,MAAME,QAAQF,uBAAuBE;YACrC,mCAAmC;YACnC,IAAIA,SAAShF,QAAQgE,MAAMiB,aAAa,MAAM;gBAC5C,KAAK,MAAM,CAACC,SAASC,KAAK,IAAI9D,OAAO+D,OAAO,CAACJ,OAAQ;oBACnD,MAAMK,gBAAgBH,YAAY,eAAeA,YAAY,iBAAiB,IAAI;oBAClF,IAAIC,KAAK9E,MAAM,GAAGgF,eAAe;wBAC/B,sCAAsC;wBACtCC,QAAQC,IAAI,CACV,CAAC,kFAAkF,EAAEL,QAAQ,uJAAuJ,CAAC;wBAEvP;oBACF;gBACF;YACF;QACF;QACA,MAAMM,0BAA0B,MAAMpJ,mBACpC4D,QACA8E,uBACAhD,8BACAM;QAGApC,CAAAA,OAAOnB,WAAW,KAAK,EAAE,AAAD,EAAGK,IAAI,CAACsG;IACpC;IAEA,IAAIxF,OAAOsC,OAAO,KAAK,SAASW,yBAAyB5C,MAAM,EAAE;QAC/D,MAAM5D,oBAAoB;YACxBkH,oBAAoB3D,OAAOsC,OAAO,CAAEqB,kBAAkB;YACtD3D,QAAQA;YACRiD;YACAnB;YACAM;QACF;IACF;IAEArC,mBAAmBlB,WAAW,CAAEK,IAAI,CAClC,MAAM9C,mBACJ4D,QACAjD,6BAA6BiD,SAC7B8B,8BACAM;IAIJrC,mBAAmBlB,WAAW,CAAEK,IAAI,CAClC,MAAM9C,mBACJ4D,QACA/C,yBAAyB+C,SACzB8B,8BACAM;IAIJ,MAAMqD,aAAa,MAAMrJ,mBACvB4D,QACA3D,sBACAyF,8BACAM;IAGF,gFAAgF;IAChF,IAAIpC,QAAQ0F,IAAIC,qBAAqB;QACnCF,WAAWG,OAAO,GAAG;YACnB;gBACEjD,QAAQ;oBAAC;oBAAS;iBAAO;gBACzBkD,QAAQ;YACV;SACD;IACH;IACA9F,mBAAmBlB,WAAW,CAAEK,IAAI,CAACuG;IAErC,IAAIzD,wBAAwB3B,MAAM,GAAG,GAAG;QACtCN,mBAAmBlB,WAAW,CAAEK,IAAI,CAClC,MAAM9C,mBACJ4D,QACA7C,sBAAsB6C,SACtB8B,8BACAM;IAGN;IAEA,IAAIpC,OAAO8F,SAAS,KAAK,IAAI;QAC3B9F,OAAO+F,IAAI,CAAE7G,IAAI,CAACc,OAAO8F,SAAS;IACpC;IAEA,MAAME,iBAAiB,IAAI7D;IAC3B,gCAAgC;IAChC,KAAK,MAAMuB,cAAc1D,OAAOnB,WAAW,CAAG;QAC5C,0BAA0B;QAC1B,IAAI6E,WAAWuC,MAAM,EAAEC,SAAS;YAC9BF,eAAe5C,GAAG,CAACM,WAAWuC,MAAM,CAACC,OAAO;QAC9C;IACF;IAEA,IAAI,CAAClG,OAAOiG,MAAM,EAAE;QAClBjG,OAAOiG,MAAM,GAAG;YAAEE,UAAU,EAAE;QAAC;IACjC;IAEAnG,OAAOiG,MAAM,CAACE,QAAQ,GAAG/B,MAAMgC,IAAI,CACjC,IAAIjE,IAAInC,OAAOnB,WAAW,CAAE2B,GAAG,CAAC,CAAC6B,IAAMA,EAAE4D,MAAM,EAAEC,SAASG,MAAM,CAACrH;IAGnE,8DAA8D;IAC9D,IAAIc,eAAewG,KAAK,EAAE;QACxBtG,OAAOsG,KAAK,GAAGxG,eAAewG,KAAK;IACrC;IAEA;;GAEC,GACD,IAAI,OAAOxG,eAAeyG,MAAM,KAAK,YAAY;QAC/CvG,OAAOuG,MAAM,GAAG,MAAMzG,eAAeyG,MAAM,CAAC;YAC1CvG,QAAQA;YACRwG,QAAQ;YACRzD,mBAAmB;QACrB;QACA,IAAI/C,OAAOuG,MAAM,CAACpF,IAAI,IAAIE,OAAOC,IAAI,CAACtB,OAAOuG,MAAM,CAACpF,IAAI,EAAEd,MAAM,IAAI,GAAG;YACrEL,OAAOmB,IAAI,CAACD,YAAY,GAAGjF,gBAAgB+D,OAAOmB,IAAI,CAACD,YAAY,EAAElB,OAAOuG,MAAM,CAACpF,IAAI;QACzF;IACF;IAEA,MAAMsF,WAA4B,EAAE;IAEpC,KAAK,MAAMC,oBAAoB5E,6BAA8B;QAC3D2E,SAASvH,IAAI,CAACwH,iBAAiB1G;IACjC;IAEA,MAAM2G,QAAQC,GAAG,CAACH;IAElB,OAAOzG;AACT,EAAC"}
|
|
1
|
+
{"version":3,"sources":["../../src/config/sanitize.ts"],"sourcesContent":["import type { AcceptedLanguages } from '@payloadcms/translations'\n\nimport { en } from '@payloadcms/translations/languages/en'\nimport { deepMergeSimple } from '@payloadcms/translations/utilities'\n\nimport type { CollectionSlug, GlobalSlug, SanitizedCollectionConfig } from '../index.js'\nimport type { SanitizedJobsConfig } from '../queues/config/types/index.js'\nimport type {\n Config,\n LocalizationConfigWithLabels,\n LocalizationConfigWithNoLabels,\n SanitizedConfig,\n Timezone,\n} from './types.js'\n\nimport { defaultUserCollection } from '../auth/defaultUser.js'\nimport { authRootEndpoints } from '../auth/endpoints/index.js'\nimport { sanitizeCollection } from '../collections/config/sanitize.js'\nimport { migrationsCollection } from '../database/migrations/migrationsCollection.js'\nimport { DuplicateCollection, InvalidConfiguration } from '../errors/index.js'\nimport { defaultTimezones } from '../fields/baseFields/timezone/defaultTimezones.js'\nimport { addFolderCollection } from '../folders/addFolderCollection.js'\nimport { addFolderFieldToCollection } from '../folders/addFolderFieldToCollection.js'\nimport { sanitizeGlobal } from '../globals/config/sanitize.js'\nimport { baseBlockFields, formatLabels, sanitizeFields } from '../index.js'\nimport {\n getLockedDocumentsCollection,\n lockedDocumentsCollectionSlug,\n} from '../locked-documents/config.js'\nimport { getPreferencesCollection, preferencesCollectionSlug } from '../preferences/config.js'\nimport { getQueryPresetsConfig, queryPresetsCollectionSlug } from '../query-presets/config.js'\nimport { getDefaultJobsCollection, jobsCollectionSlug } from '../queues/config/collection.js'\nimport { getJobStatsGlobal } from '../queues/config/global.js'\nimport { flattenBlock } from '../utilities/flattenAllFields.js'\nimport { getSchedulePublishTask } from '../versions/schedule/job.js'\nimport { addDefaultsToConfig } from './defaults.js'\nimport { setupOrderable } from './orderable/index.js'\n\nconst sanitizeAdminConfig = (configToSanitize: Config): Partial<SanitizedConfig> => {\n const sanitizedConfig = { ...configToSanitize }\n\n if (configToSanitize?.compatibility?.allowLocalizedWithinLocalized) {\n process.env.NEXT_PUBLIC_PAYLOAD_COMPATIBILITY_allowLocalizedWithinLocalized = 'true'\n }\n\n // default logging level will be 'error' if not provided\n sanitizedConfig.loggingLevels = {\n Forbidden: 'info',\n Locked: 'info',\n MissingFile: 'info',\n NotFound: 'info',\n ValidationError: 'info',\n ...(sanitizedConfig.loggingLevels || {}),\n }\n\n // add default user collection if none provided\n if (!sanitizedConfig?.admin?.user) {\n const firstCollectionWithAuth = sanitizedConfig.collections!.find(({ auth }) => Boolean(auth))\n\n if (firstCollectionWithAuth) {\n sanitizedConfig.admin!.user = firstCollectionWithAuth.slug\n } else {\n sanitizedConfig.admin!.user = defaultUserCollection.slug\n sanitizedConfig.collections!.push(defaultUserCollection)\n }\n }\n\n const userCollection = sanitizedConfig.collections!.find(\n ({ slug }) => slug === sanitizedConfig.admin!.user,\n )\n\n if (!userCollection || !userCollection.auth) {\n throw new InvalidConfiguration(\n `${sanitizedConfig.admin!.user} is not a valid admin user collection`,\n )\n }\n\n if (sanitizedConfig?.admin?.timezones) {\n if (typeof sanitizedConfig?.admin?.timezones?.supportedTimezones === 'function') {\n sanitizedConfig.admin.timezones.supportedTimezones =\n sanitizedConfig.admin.timezones.supportedTimezones({ defaultTimezones })\n }\n\n if (!sanitizedConfig?.admin?.timezones?.supportedTimezones) {\n sanitizedConfig.admin.timezones.supportedTimezones = defaultTimezones\n }\n } else {\n sanitizedConfig.admin!.timezones = {\n supportedTimezones: defaultTimezones,\n }\n }\n // Timezones supported by the Intl API\n const _internalSupportedTimezones = Intl.supportedValuesOf('timeZone')\n\n // We're casting here because it's already been sanitised above but TS still thinks it could be a function\n ;(sanitizedConfig.admin!.timezones.supportedTimezones as Timezone[]).forEach((timezone) => {\n if (!_internalSupportedTimezones.includes(timezone.value)) {\n throw new InvalidConfiguration(\n `Timezone ${timezone.value} is not supported by the current runtime via the Intl API.`,\n )\n }\n })\n\n return sanitizedConfig as unknown as Partial<SanitizedConfig>\n}\n\nexport const sanitizeConfig = async (incomingConfig: Config): Promise<SanitizedConfig> => {\n const configWithDefaults = addDefaultsToConfig(incomingConfig)\n\n const config: Partial<SanitizedConfig> = sanitizeAdminConfig(configWithDefaults)\n\n // Add orderable fields\n setupOrderable(config as SanitizedConfig)\n\n if (!config.endpoints) {\n config.endpoints = []\n }\n\n for (const endpoint of authRootEndpoints) {\n config.endpoints.push(endpoint)\n }\n\n if (config.localization && config.localization.locales?.length > 0) {\n // clone localization config so to not break everything\n const firstLocale = config.localization.locales[0]\n if (typeof firstLocale === 'string') {\n config.localization.localeCodes = [\n ...(config.localization as unknown as LocalizationConfigWithNoLabels).locales,\n ]\n\n // is string[], so convert to Locale[]\n config.localization.locales = (\n config.localization as unknown as LocalizationConfigWithNoLabels\n ).locales.map((locale) => ({\n code: locale,\n label: locale,\n rtl: false,\n toString: () => locale,\n }))\n } else {\n // is Locale[], so convert to string[] for localeCodes\n config.localization.localeCodes = config.localization.locales.map((locale) => locale.code)\n\n config.localization.locales = (\n config.localization as LocalizationConfigWithLabels\n ).locales.map((locale) => ({\n ...locale,\n toString: () => locale.code,\n }))\n }\n\n // Default fallback to true if not provided\n config.localization.fallback = config.localization?.fallback ?? true\n }\n\n const i18nConfig: SanitizedConfig['i18n'] = {\n fallbackLanguage: 'en',\n supportedLanguages: {\n en,\n },\n translations: {},\n }\n\n if (incomingConfig?.i18n) {\n i18nConfig.supportedLanguages =\n incomingConfig.i18n?.supportedLanguages || i18nConfig.supportedLanguages\n\n const supportedLangKeys = <AcceptedLanguages[]>Object.keys(i18nConfig.supportedLanguages)\n const fallbackLang = incomingConfig.i18n?.fallbackLanguage || i18nConfig.fallbackLanguage\n\n i18nConfig.fallbackLanguage = supportedLangKeys.includes(fallbackLang)\n ? fallbackLang\n : supportedLangKeys[0]!\n i18nConfig.translations =\n (incomingConfig.i18n?.translations as SanitizedConfig['i18n']['translations']) ||\n i18nConfig.translations\n }\n\n config.i18n = i18nConfig\n\n const richTextSanitizationPromises: Array<(config: SanitizedConfig) => Promise<void>> = []\n\n const schedulePublishCollections: CollectionSlug[] = []\n\n const queryPresetsCollections: CollectionSlug[] = []\n\n const schedulePublishGlobals: GlobalSlug[] = []\n\n const collectionSlugs = new Set<CollectionSlug>()\n\n const validRelationships = [\n ...(config.collections?.map((c) => c.slug) ?? []),\n jobsCollectionSlug,\n lockedDocumentsCollectionSlug,\n preferencesCollectionSlug,\n ]\n\n if (config.folders !== false) {\n validRelationships.push(config.folders!.slug)\n }\n\n /**\n * Blocks sanitization needs to happen before collections, as collection/global join field sanitization needs config.blocks\n * to be populated with the sanitized blocks\n */\n config.blocks = []\n\n if (incomingConfig.blocks?.length) {\n for (const block of incomingConfig.blocks) {\n const sanitizedBlock = block\n\n if (sanitizedBlock._sanitized === true) {\n continue\n }\n sanitizedBlock._sanitized = true\n\n sanitizedBlock.fields = sanitizedBlock.fields.concat(baseBlockFields)\n\n sanitizedBlock.labels = !sanitizedBlock.labels\n ? formatLabels(sanitizedBlock.slug)\n : sanitizedBlock.labels\n\n sanitizedBlock.fields = await sanitizeFields({\n config: config as unknown as Config,\n existingFieldNames: new Set(),\n fields: sanitizedBlock.fields,\n parentIsLocalized: false,\n richTextSanitizationPromises,\n validRelationships,\n })\n\n const flattenedSanitizedBlock = flattenBlock({ block })\n\n config.blocks.push(flattenedSanitizedBlock)\n }\n }\n\n const folderEnabledCollections: SanitizedCollectionConfig[] = []\n\n for (let i = 0; i < config.collections!.length; i++) {\n if (collectionSlugs.has(config.collections![i]!.slug)) {\n throw new DuplicateCollection('slug', config.collections![i]!.slug)\n }\n\n collectionSlugs.add(config.collections![i]!.slug)\n\n const draftsConfig = config.collections![i]?.versions?.drafts\n\n if (typeof draftsConfig === 'object' && draftsConfig.schedulePublish) {\n schedulePublishCollections.push(config.collections![i]!.slug)\n }\n\n if (config.collections![i]!.enableQueryPresets) {\n queryPresetsCollections.push(config.collections![i]!.slug)\n\n if (!validRelationships.includes(queryPresetsCollectionSlug)) {\n validRelationships.push(queryPresetsCollectionSlug)\n }\n }\n\n if (config.folders !== false && config.collections![i]!.folders) {\n addFolderFieldToCollection({\n collection: config.collections![i]!,\n collectionSpecific: config.folders!.collectionSpecific,\n folderFieldName: config.folders!.fieldName,\n folderSlug: config.folders!.slug,\n })\n }\n\n config.collections![i] = await sanitizeCollection(\n config as unknown as Config,\n config.collections![i]!,\n richTextSanitizationPromises,\n validRelationships,\n )\n\n if (config.folders !== false && config.collections![i]!.folders) {\n folderEnabledCollections.push(config.collections![i]!)\n }\n }\n\n if (config.globals!.length > 0) {\n for (let i = 0; i < config.globals!.length; i++) {\n const draftsConfig = config.globals![i]?.versions?.drafts\n\n if (typeof draftsConfig === 'object' && draftsConfig.schedulePublish) {\n schedulePublishGlobals.push(config.globals![i]!.slug)\n }\n\n config.globals![i] = await sanitizeGlobal(\n config as unknown as Config,\n config.globals![i]!,\n richTextSanitizationPromises,\n validRelationships,\n )\n }\n }\n\n if (schedulePublishCollections.length || schedulePublishGlobals.length) {\n ;((config.jobs ??= {} as SanitizedJobsConfig).tasks ??= []).push(\n getSchedulePublishTask({\n adminUserSlug: config.admin!.user,\n collections: schedulePublishCollections,\n globals: schedulePublishGlobals,\n }),\n )\n }\n\n ;(config.jobs ??= {} as SanitizedJobsConfig).enabled = Boolean(\n (Array.isArray(configWithDefaults.jobs?.tasks) && configWithDefaults.jobs?.tasks?.length) ||\n (Array.isArray(configWithDefaults.jobs?.workflows) &&\n configWithDefaults.jobs?.workflows?.length),\n )\n\n // Need to add default jobs collection before locked documents collections\n if (config.jobs.enabled) {\n // Check for schedule property in both tasks and workflows\n const hasScheduleProperty =\n (config?.jobs?.tasks?.length && config.jobs.tasks.some((task) => task.schedule)) ||\n (config?.jobs?.workflows?.length &&\n config.jobs.workflows.some((workflow) => workflow.schedule))\n\n if (hasScheduleProperty) {\n config.jobs.scheduling = true\n // Add payload-jobs-stats global for tracking when a job of a specific slug was last run\n ;(config.globals ??= []).push(\n await sanitizeGlobal(\n config as unknown as Config,\n getJobStatsGlobal(config as unknown as Config),\n richTextSanitizationPromises,\n validRelationships,\n ),\n )\n\n config.jobs.stats = true\n }\n\n let defaultJobsCollection = getDefaultJobsCollection(config.jobs)\n\n if (typeof config.jobs.jobsCollectionOverrides === 'function') {\n defaultJobsCollection = config.jobs.jobsCollectionOverrides({\n defaultJobsCollection,\n })\n\n const hooks = defaultJobsCollection?.hooks\n // @todo - delete this check in 4.0\n if (hooks && config?.jobs?.runHooks !== true) {\n for (const [hookKey, hook] of Object.entries(hooks)) {\n const defaultAmount = hookKey === 'afterRead' || hookKey === 'beforeChange' ? 1 : 0\n if (hook.length > defaultAmount) {\n // eslint-disable-next-line no-console\n console.warn(\n `The jobsCollectionOverrides function is returning a collection with an additional ${hookKey} hook defined. These hooks will not run unless the jobs.runHooks option is set to true. Setting this option to true will negatively impact performance.`,\n )\n break\n }\n }\n }\n }\n const sanitizedJobsCollection = await sanitizeCollection(\n config as unknown as Config,\n defaultJobsCollection,\n richTextSanitizationPromises,\n validRelationships,\n )\n\n ;(config.collections ??= []).push(sanitizedJobsCollection)\n }\n\n if (config.folders !== false && folderEnabledCollections.length) {\n await addFolderCollection({\n collectionSpecific: config.folders!.collectionSpecific,\n config: config as unknown as Config,\n folderEnabledCollections,\n richTextSanitizationPromises,\n validRelationships,\n })\n }\n\n configWithDefaults.collections!.push(\n await sanitizeCollection(\n config as unknown as Config,\n getLockedDocumentsCollection(config as unknown as Config),\n richTextSanitizationPromises,\n validRelationships,\n ),\n )\n\n configWithDefaults.collections!.push(\n await sanitizeCollection(\n config as unknown as Config,\n getPreferencesCollection(config as unknown as Config),\n richTextSanitizationPromises,\n validRelationships,\n ),\n )\n\n const migrations = await sanitizeCollection(\n config as unknown as Config,\n migrationsCollection,\n richTextSanitizationPromises,\n validRelationships,\n )\n\n // @ts-expect-error indexSortableFields is only valid for @payloadcms/db-mongodb\n if (config?.db?.indexSortableFields) {\n migrations.indexes = [\n {\n fields: ['batch', 'name'],\n unique: false,\n },\n ]\n }\n configWithDefaults.collections!.push(migrations)\n\n if (queryPresetsCollections.length > 0) {\n configWithDefaults.collections!.push(\n await sanitizeCollection(\n config as unknown as Config,\n getQueryPresetsConfig(config as unknown as Config),\n richTextSanitizationPromises,\n validRelationships,\n ),\n )\n }\n\n if (config.serverURL !== '') {\n config.csrf!.push(config.serverURL!)\n }\n\n const uploadAdapters = new Set<string>()\n // interact with all collections\n for (const collection of config.collections!) {\n // deduped upload adapters\n if (collection.upload?.adapter) {\n uploadAdapters.add(collection.upload.adapter)\n }\n }\n\n if (!config.upload) {\n config.upload = { adapters: [] }\n }\n\n config.upload.adapters = Array.from(\n new Set(config.collections!.map((c) => c.upload?.adapter).filter(Boolean) as string[]),\n )\n\n // Pass through the email config as is so adapters don't break\n if (incomingConfig.email) {\n config.email = incomingConfig.email\n }\n\n /*\n Execute richText sanitization\n */\n if (typeof incomingConfig.editor === 'function') {\n config.editor = await incomingConfig.editor({\n config: config as SanitizedConfig,\n isRoot: true,\n parentIsLocalized: false,\n })\n if (config.editor.i18n && Object.keys(config.editor.i18n).length >= 0) {\n config.i18n.translations = deepMergeSimple(config.i18n.translations, config.editor.i18n)\n }\n }\n\n const promises: Promise<void>[] = []\n\n for (const sanitizeFunction of richTextSanitizationPromises) {\n promises.push(sanitizeFunction(config as SanitizedConfig))\n }\n\n await Promise.all(promises)\n\n return config as SanitizedConfig\n}\n"],"names":["en","deepMergeSimple","defaultUserCollection","authRootEndpoints","sanitizeCollection","migrationsCollection","DuplicateCollection","InvalidConfiguration","defaultTimezones","addFolderCollection","addFolderFieldToCollection","sanitizeGlobal","baseBlockFields","formatLabels","sanitizeFields","getLockedDocumentsCollection","lockedDocumentsCollectionSlug","getPreferencesCollection","preferencesCollectionSlug","getQueryPresetsConfig","queryPresetsCollectionSlug","getDefaultJobsCollection","jobsCollectionSlug","getJobStatsGlobal","flattenBlock","getSchedulePublishTask","addDefaultsToConfig","setupOrderable","sanitizeAdminConfig","configToSanitize","sanitizedConfig","compatibility","allowLocalizedWithinLocalized","process","env","NEXT_PUBLIC_PAYLOAD_COMPATIBILITY_allowLocalizedWithinLocalized","loggingLevels","Forbidden","Locked","MissingFile","NotFound","ValidationError","admin","user","firstCollectionWithAuth","collections","find","auth","Boolean","slug","push","userCollection","timezones","supportedTimezones","_internalSupportedTimezones","Intl","supportedValuesOf","forEach","timezone","includes","value","sanitizeConfig","incomingConfig","configWithDefaults","config","endpoints","endpoint","localization","locales","length","firstLocale","localeCodes","map","locale","code","label","rtl","toString","fallback","i18nConfig","fallbackLanguage","supportedLanguages","translations","i18n","supportedLangKeys","Object","keys","fallbackLang","richTextSanitizationPromises","schedulePublishCollections","queryPresetsCollections","schedulePublishGlobals","collectionSlugs","Set","validRelationships","c","folders","blocks","block","sanitizedBlock","_sanitized","fields","concat","labels","existingFieldNames","parentIsLocalized","flattenedSanitizedBlock","folderEnabledCollections","i","has","add","draftsConfig","versions","drafts","schedulePublish","enableQueryPresets","collection","collectionSpecific","folderFieldName","fieldName","folderSlug","globals","jobs","tasks","adminUserSlug","enabled","Array","isArray","workflows","hasScheduleProperty","some","task","schedule","workflow","scheduling","stats","defaultJobsCollection","jobsCollectionOverrides","hooks","runHooks","hookKey","hook","entries","defaultAmount","console","warn","sanitizedJobsCollection","migrations","db","indexSortableFields","indexes","unique","serverURL","csrf","uploadAdapters","upload","adapter","adapters","from","filter","email","editor","isRoot","promises","sanitizeFunction","Promise","all"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkFileRestrictions.d.ts","sourceRoot":"","sources":["../../src/uploads/checkFileRestrictions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,2BAA2B,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"checkFileRestrictions.d.ts","sourceRoot":"","sources":["../../src/uploads/checkFileRestrictions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,2BAA2B,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAO5E;;GAEG;AACH,eAAO,MAAM,6BAA6B,EAAE,aAgC3C,CAAA;AAED,eAAO,MAAM,qBAAqB,+BAI/B,2BAA2B,KAAG,OAAO,CAAC,IAAI,CAuE5C,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { fileTypeFromBuffer } from 'file-type';
|
|
2
2
|
import { ValidationError } from '../errors/index.js';
|
|
3
3
|
import { validateMimeType } from '../utilities/validateMimeType.js';
|
|
4
|
+
import { validatePDF } from '../utilities/validatePDF.js';
|
|
4
5
|
import { detectSvgFromXml } from './detectSvgFromXml.js';
|
|
5
6
|
/**
|
|
6
7
|
* Restricted file types and their extensions.
|
|
@@ -227,6 +228,9 @@ export const checkFileRestrictions = async ({ collection, file, req })=>{
|
|
|
227
228
|
// Secondary mimetype check to assess file type from buffer
|
|
228
229
|
if (configMimeTypes.length > 0) {
|
|
229
230
|
let detected = await fileTypeFromBuffer(file.data);
|
|
231
|
+
if (!detected) {
|
|
232
|
+
errors.push(`File buffer returned no detectable MIME type.`);
|
|
233
|
+
}
|
|
230
234
|
// Handle SVG files that are detected as XML due to <?xml declarations
|
|
231
235
|
if (detected?.mime === 'application/xml' && configMimeTypes.some((type)=>type.includes('image/') && (type.includes('svg') || type === 'image/*')) && detectSvgFromXml(file.data)) {
|
|
232
236
|
detected = {
|
|
@@ -235,6 +239,12 @@ export const checkFileRestrictions = async ({ collection, file, req })=>{
|
|
|
235
239
|
};
|
|
236
240
|
}
|
|
237
241
|
const passesMimeTypeCheck = detected?.mime && validateMimeType(detected.mime, configMimeTypes);
|
|
242
|
+
if (passesMimeTypeCheck && detected?.mime === 'application/pdf') {
|
|
243
|
+
const isValidPDF = validatePDF(file?.data);
|
|
244
|
+
if (!isValidPDF) {
|
|
245
|
+
errors.push('Invalid PDF file.');
|
|
246
|
+
}
|
|
247
|
+
}
|
|
238
248
|
if (detected && !passesMimeTypeCheck) {
|
|
239
249
|
errors.push(`Invalid MIME type: ${detected.mime}.`);
|
|
240
250
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/uploads/checkFileRestrictions.ts"],"sourcesContent":["import { fileTypeFromBuffer } from 'file-type'\n\nimport type { checkFileRestrictionsParams, FileAllowList } from './types.js'\n\nimport { ValidationError } from '../errors/index.js'\nimport { validateMimeType } from '../utilities/validateMimeType.js'\nimport { detectSvgFromXml } from './detectSvgFromXml.js'\n\n/**\n * Restricted file types and their extensions.\n */\nexport const RESTRICTED_FILE_EXT_AND_TYPES: FileAllowList = [\n { extensions: ['exe', 'dll'], mimeType: 'application/x-msdownload' },\n { extensions: ['exe', 'com', 'app', 'action'], mimeType: 'application/x-executable' },\n { extensions: ['bat', 'cmd'], mimeType: 'application/x-msdos-program' },\n { extensions: ['exe', 'com'], mimeType: 'application/x-ms-dos-executable' },\n { extensions: ['dmg'], mimeType: 'application/x-apple-diskimage' },\n { extensions: ['deb'], mimeType: 'application/x-debian-package' },\n { extensions: ['rpm'], mimeType: 'application/x-redhat-package-manager' },\n { extensions: ['exe', 'dll'], mimeType: 'application/vnd.microsoft.portable-executable' },\n { extensions: ['msi'], mimeType: 'application/x-msi' },\n { extensions: ['jar', 'ear', 'war'], mimeType: 'application/java-archive' },\n { extensions: ['desktop'], mimeType: 'application/x-desktop' },\n { extensions: ['cpl'], mimeType: 'application/x-cpl' },\n { extensions: ['lnk'], mimeType: 'application/x-ms-shortcut' },\n { extensions: ['pkg'], mimeType: 'application/x-apple-installer' },\n { extensions: ['htm', 'html', 'shtml', 'xhtml'], mimeType: 'text/html' },\n { extensions: ['php', 'phtml'], mimeType: 'application/x-httpd-php' },\n { extensions: ['js', 'jse'], mimeType: 'text/javascript' },\n { extensions: ['jsp'], mimeType: 'application/x-jsp' },\n { extensions: ['py'], mimeType: 'text/x-python' },\n { extensions: ['rb'], mimeType: 'text/x-ruby' },\n { extensions: ['pl'], mimeType: 'text/x-perl' },\n { extensions: ['ps1', 'psc1', 'psd1', 'psh', 'psm1'], mimeType: 'application/x-powershell' },\n { extensions: ['vbe', 'vbs'], mimeType: 'application/x-vbscript' },\n { extensions: ['ws', 'wsc', 'wsf', 'wsh'], mimeType: 'application/x-ms-wsh' },\n { extensions: ['scr'], mimeType: 'application/x-msdownload' },\n { extensions: ['asp', 'aspx'], mimeType: 'application/x-asp' },\n { extensions: ['hta'], mimeType: 'application/x-hta' },\n { extensions: ['reg'], mimeType: 'application/x-registry' },\n { extensions: ['url'], mimeType: 'application/x-url' },\n { extensions: ['workflow'], mimeType: 'application/x-workflow' },\n { extensions: ['command'], mimeType: 'application/x-command' },\n]\n\nexport const checkFileRestrictions = async ({\n collection,\n file,\n req,\n}: checkFileRestrictionsParams): Promise<void> => {\n const errors: string[] = []\n const { upload: uploadConfig } = collection\n const configMimeTypes =\n uploadConfig &&\n typeof uploadConfig === 'object' &&\n 'mimeTypes' in uploadConfig &&\n Array.isArray(uploadConfig.mimeTypes)\n ? uploadConfig.mimeTypes\n : []\n\n const allowRestrictedFileTypes =\n uploadConfig && typeof uploadConfig === 'object' && 'allowRestrictedFileTypes' in uploadConfig\n ? (uploadConfig as { allowRestrictedFileTypes?: boolean }).allowRestrictedFileTypes\n : false\n\n // Skip validation if `allowRestrictedFileTypes` is true\n if (allowRestrictedFileTypes) {\n return\n }\n\n // Secondary mimetype check to assess file type from buffer\n if (configMimeTypes.length > 0) {\n let detected = await fileTypeFromBuffer(file.data)\n\n // Handle SVG files that are detected as XML due to <?xml declarations\n if (\n detected?.mime === 'application/xml' &&\n configMimeTypes.some(\n (type) => type.includes('image/') && (type.includes('svg') || type === 'image/*'),\n ) &&\n detectSvgFromXml(file.data)\n ) {\n detected = { ext: 'svg' as any, mime: 'image/svg+xml' as any }\n }\n\n const passesMimeTypeCheck = detected?.mime && validateMimeType(detected.mime, configMimeTypes)\n\n if (detected && !passesMimeTypeCheck) {\n errors.push(`Invalid MIME type: ${detected.mime}.`)\n }\n } else {\n const isRestricted = RESTRICTED_FILE_EXT_AND_TYPES.some((type) => {\n const hasRestrictedExt = type.extensions.some((ext) => file.name.toLowerCase().endsWith(ext))\n const hasRestrictedMime = type.mimeType === file.mimetype\n return hasRestrictedExt || hasRestrictedMime\n })\n if (isRestricted) {\n errors.push(\n `File type '${file.mimetype}' not allowed ${file.name}: Restricted file type detected -- set 'allowRestrictedFileTypes' to true to skip this check for this Collection.`,\n )\n }\n }\n\n if (errors.length > 0) {\n req.payload.logger.error(errors.join(', '))\n throw new ValidationError({\n errors: [{ message: errors.join(', '), path: 'file' }],\n })\n }\n}\n"],"names":["fileTypeFromBuffer","ValidationError","validateMimeType","detectSvgFromXml","RESTRICTED_FILE_EXT_AND_TYPES","extensions","mimeType","checkFileRestrictions","collection","file","req","errors","upload","uploadConfig","configMimeTypes","Array","isArray","mimeTypes","allowRestrictedFileTypes","length","detected","data","mime","some","type","includes","ext","passesMimeTypeCheck","
|
|
1
|
+
{"version":3,"sources":["../../src/uploads/checkFileRestrictions.ts"],"sourcesContent":["import { fileTypeFromBuffer } from 'file-type'\n\nimport type { checkFileRestrictionsParams, FileAllowList } from './types.js'\n\nimport { ValidationError } from '../errors/index.js'\nimport { validateMimeType } from '../utilities/validateMimeType.js'\nimport { validatePDF } from '../utilities/validatePDF.js'\nimport { detectSvgFromXml } from './detectSvgFromXml.js'\n\n/**\n * Restricted file types and their extensions.\n */\nexport const RESTRICTED_FILE_EXT_AND_TYPES: FileAllowList = [\n { extensions: ['exe', 'dll'], mimeType: 'application/x-msdownload' },\n { extensions: ['exe', 'com', 'app', 'action'], mimeType: 'application/x-executable' },\n { extensions: ['bat', 'cmd'], mimeType: 'application/x-msdos-program' },\n { extensions: ['exe', 'com'], mimeType: 'application/x-ms-dos-executable' },\n { extensions: ['dmg'], mimeType: 'application/x-apple-diskimage' },\n { extensions: ['deb'], mimeType: 'application/x-debian-package' },\n { extensions: ['rpm'], mimeType: 'application/x-redhat-package-manager' },\n { extensions: ['exe', 'dll'], mimeType: 'application/vnd.microsoft.portable-executable' },\n { extensions: ['msi'], mimeType: 'application/x-msi' },\n { extensions: ['jar', 'ear', 'war'], mimeType: 'application/java-archive' },\n { extensions: ['desktop'], mimeType: 'application/x-desktop' },\n { extensions: ['cpl'], mimeType: 'application/x-cpl' },\n { extensions: ['lnk'], mimeType: 'application/x-ms-shortcut' },\n { extensions: ['pkg'], mimeType: 'application/x-apple-installer' },\n { extensions: ['htm', 'html', 'shtml', 'xhtml'], mimeType: 'text/html' },\n { extensions: ['php', 'phtml'], mimeType: 'application/x-httpd-php' },\n { extensions: ['js', 'jse'], mimeType: 'text/javascript' },\n { extensions: ['jsp'], mimeType: 'application/x-jsp' },\n { extensions: ['py'], mimeType: 'text/x-python' },\n { extensions: ['rb'], mimeType: 'text/x-ruby' },\n { extensions: ['pl'], mimeType: 'text/x-perl' },\n { extensions: ['ps1', 'psc1', 'psd1', 'psh', 'psm1'], mimeType: 'application/x-powershell' },\n { extensions: ['vbe', 'vbs'], mimeType: 'application/x-vbscript' },\n { extensions: ['ws', 'wsc', 'wsf', 'wsh'], mimeType: 'application/x-ms-wsh' },\n { extensions: ['scr'], mimeType: 'application/x-msdownload' },\n { extensions: ['asp', 'aspx'], mimeType: 'application/x-asp' },\n { extensions: ['hta'], mimeType: 'application/x-hta' },\n { extensions: ['reg'], mimeType: 'application/x-registry' },\n { extensions: ['url'], mimeType: 'application/x-url' },\n { extensions: ['workflow'], mimeType: 'application/x-workflow' },\n { extensions: ['command'], mimeType: 'application/x-command' },\n]\n\nexport const checkFileRestrictions = async ({\n collection,\n file,\n req,\n}: checkFileRestrictionsParams): Promise<void> => {\n const errors: string[] = []\n const { upload: uploadConfig } = collection\n const configMimeTypes =\n uploadConfig &&\n typeof uploadConfig === 'object' &&\n 'mimeTypes' in uploadConfig &&\n Array.isArray(uploadConfig.mimeTypes)\n ? uploadConfig.mimeTypes\n : []\n\n const allowRestrictedFileTypes =\n uploadConfig && typeof uploadConfig === 'object' && 'allowRestrictedFileTypes' in uploadConfig\n ? (uploadConfig as { allowRestrictedFileTypes?: boolean }).allowRestrictedFileTypes\n : false\n\n // Skip validation if `allowRestrictedFileTypes` is true\n if (allowRestrictedFileTypes) {\n return\n }\n\n // Secondary mimetype check to assess file type from buffer\n if (configMimeTypes.length > 0) {\n let detected = await fileTypeFromBuffer(file.data)\n\n if (!detected) {\n errors.push(`File buffer returned no detectable MIME type.`)\n }\n\n // Handle SVG files that are detected as XML due to <?xml declarations\n if (\n detected?.mime === 'application/xml' &&\n configMimeTypes.some(\n (type) => type.includes('image/') && (type.includes('svg') || type === 'image/*'),\n ) &&\n detectSvgFromXml(file.data)\n ) {\n detected = { ext: 'svg' as any, mime: 'image/svg+xml' as any }\n }\n\n const passesMimeTypeCheck = detected?.mime && validateMimeType(detected.mime, configMimeTypes)\n\n if (passesMimeTypeCheck && detected?.mime === 'application/pdf') {\n const isValidPDF = validatePDF(file?.data)\n if (!isValidPDF) {\n errors.push('Invalid PDF file.')\n }\n }\n\n if (detected && !passesMimeTypeCheck) {\n errors.push(`Invalid MIME type: ${detected.mime}.`)\n }\n } else {\n const isRestricted = RESTRICTED_FILE_EXT_AND_TYPES.some((type) => {\n const hasRestrictedExt = type.extensions.some((ext) => file.name.toLowerCase().endsWith(ext))\n const hasRestrictedMime = type.mimeType === file.mimetype\n return hasRestrictedExt || hasRestrictedMime\n })\n if (isRestricted) {\n errors.push(\n `File type '${file.mimetype}' not allowed ${file.name}: Restricted file type detected -- set 'allowRestrictedFileTypes' to true to skip this check for this Collection.`,\n )\n }\n }\n\n if (errors.length > 0) {\n req.payload.logger.error(errors.join(', '))\n throw new ValidationError({\n errors: [{ message: errors.join(', '), path: 'file' }],\n })\n }\n}\n"],"names":["fileTypeFromBuffer","ValidationError","validateMimeType","validatePDF","detectSvgFromXml","RESTRICTED_FILE_EXT_AND_TYPES","extensions","mimeType","checkFileRestrictions","collection","file","req","errors","upload","uploadConfig","configMimeTypes","Array","isArray","mimeTypes","allowRestrictedFileTypes","length","detected","data","push","mime","some","type","includes","ext","passesMimeTypeCheck","isValidPDF","isRestricted","hasRestrictedExt","name","toLowerCase","endsWith","hasRestrictedMime","mimetype","payload","logger","error","join","message","path"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validatePDF.d.ts","sourceRoot":"","sources":["../../src/utilities/validatePDF.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,WAgBzC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function validatePDF(buffer) {
|
|
2
|
+
// Check for PDF header
|
|
3
|
+
const header = buffer.subarray(0, 8).toString('latin1');
|
|
4
|
+
if (!header.startsWith('%PDF-')) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
// Check for EOF marker and xref table
|
|
8
|
+
const endSize = Math.min(1024, buffer.length);
|
|
9
|
+
const end = buffer.subarray(buffer.length - endSize).toString('latin1');
|
|
10
|
+
if (!end.includes('%%EOF') || !end.includes('xref')) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=validatePDF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utilities/validatePDF.ts"],"sourcesContent":["export function validatePDF(buffer: Buffer) {\n // Check for PDF header\n const header = buffer.subarray(0, 8).toString('latin1')\n if (!header.startsWith('%PDF-')) {\n return false\n }\n\n // Check for EOF marker and xref table\n const endSize = Math.min(1024, buffer.length)\n const end = buffer.subarray(buffer.length - endSize).toString('latin1')\n\n if (!end.includes('%%EOF') || !end.includes('xref')) {\n return false\n }\n\n return true\n}\n"],"names":["validatePDF","buffer","header","subarray","toString","startsWith","endSize","Math","min","length","end","includes"],"mappings":"AAAA,OAAO,SAASA,YAAYC,MAAc;IACxC,uBAAuB;IACvB,MAAMC,SAASD,OAAOE,QAAQ,CAAC,GAAG,GAAGC,QAAQ,CAAC;IAC9C,IAAI,CAACF,OAAOG,UAAU,CAAC,UAAU;QAC/B,OAAO;IACT;IAEA,sCAAsC;IACtC,MAAMC,UAAUC,KAAKC,GAAG,CAAC,MAAMP,OAAOQ,MAAM;IAC5C,MAAMC,MAAMT,OAAOE,QAAQ,CAACF,OAAOQ,MAAM,GAAGH,SAASF,QAAQ,CAAC;IAE9D,IAAI,CAACM,IAAIC,QAAQ,CAAC,YAAY,CAACD,IAAIC,QAAQ,CAAC,SAAS;QACnD,OAAO;IACT;IAEA,OAAO;AACT"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payload",
|
|
3
|
-
"version": "3.64.0-internal.
|
|
3
|
+
"version": "3.64.0-internal.deef021",
|
|
4
4
|
"description": "Node, React, Headless CMS and Application Framework built on Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"admin panel",
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"undici": "7.10.0",
|
|
102
102
|
"uuid": "10.0.0",
|
|
103
103
|
"ws": "^8.16.0",
|
|
104
|
-
"@payloadcms/translations": "3.64.0-internal.
|
|
104
|
+
"@payloadcms/translations": "3.64.0-internal.deef021"
|
|
105
105
|
},
|
|
106
106
|
"devDependencies": {
|
|
107
107
|
"@hyrious/esbuild-plugin-commonjs": "0.2.6",
|