@payloadcms/payload-cloud 4.0.0-internal.688c4d0 → 4.0.0-internal.77191e5

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/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2018-2025 Payload CMS, Inc. <info@payloadcms.com>
3
+ Copyright (c) 2018-2026 Payload CMS, LLC <info@payloadcms.com>
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
@@ -1 +1 @@
1
- {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAGhE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAE1D,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE7D,eAAO,MAAM,iBAAiB,GAC5B,MAAM,wBAAwB,KAC7B,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAyDvC,CAAA"}
1
+ {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAGhE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAE1D,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAE7D,eAAO,MAAM,iBAAiB,SACtB,wBAAwB,KAC7B,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAyDvC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"afterDelete.d.ts","sourceRoot":"","sources":["../../src/hooks/afterDelete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEhG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAKjD,UAAU,IAAI;IACZ,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAED,eAAO,MAAM,kBAAkB,GAAI,iBAEhC,IAAI,KAAG,yBAAyB,CAAC,QAAQ,GAAG,UAAU,GAAG,cAAc,CA4BzE,CAAA"}
1
+ {"version":3,"file":"afterDelete.d.ts","sourceRoot":"","sources":["../../src/hooks/afterDelete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEhG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAKjD,UAAU,IAAI;IACZ,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAED,eAAO,MAAM,kBAAkB,oBAE5B,IAAI,KAAG,yBAAyB,CAAC,QAAQ,GAAG,UAAU,GAAG,cAAc,CA4BzE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"beforeChange.d.ts","sourceRoot":"","sources":["../../src/hooks/beforeChange.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAUjG,UAAU,IAAI;IACZ,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAID,eAAO,MAAM,mBAAmB,GAC7B,gBAAgB,IAAI,KAAG,0BAA0B,CAAC,QAAQ,GAAG,UAAU,CAuEvE,CAAA"}
1
+ {"version":3,"file":"beforeChange.d.ts","sourceRoot":"","sources":["../../src/hooks/beforeChange.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAUjG,UAAU,IAAI;IACZ,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAID,eAAO,MAAM,mBAAmB,mBACb,IAAI,KAAG,0BAA0B,CAAC,QAAQ,GAAG,UAAU,CAuEvE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"uploadCache.d.ts","sourceRoot":"","sources":["../../src/hooks/uploadCache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,yBAAyB,EAAkB,MAAM,SAAS,CAAA;AAEnG,UAAU,IAAI;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,eAAO,MAAM,8BAA8B,GACxC,cAAc,IAAI,KAAG,yBAgBrB,CAAA;AAEH,eAAO,MAAM,8BAA8B,GACxC,cAAc,IAAI,KAAG,yBAerB,CAAA"}
1
+ {"version":3,"file":"uploadCache.d.ts","sourceRoot":"","sources":["../../src/hooks/uploadCache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,yBAAyB,EAAkB,MAAM,SAAS,CAAA;AAEnG,UAAU,IAAI;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,eAAO,MAAM,8BAA8B,iBAC1B,IAAI,KAAG,yBAgBrB,CAAA;AAEH,eAAO,MAAM,8BAA8B,iBAC1B,IAAI,KAAG,yBAerB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,SAAS,CAAA;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAW/C,eAAO,MAAM,oBAAoB,QAAO,MAGvC,CAAA;AAUD,eAAO,MAAM,kBAAkB,GAC5B,gBAAgB,aAAa,MACvB,gBAAgB,MAAM,KAAG,OAAO,CAAC,MAAM,CAqJ7C,CAAA"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,SAAS,CAAA;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAW/C,eAAO,MAAM,oBAAoB,QAAO,MAGvC,CAAA;AAUD,eAAO,MAAM,kBAAkB,mBACZ,aAAa,sBACP,MAAM,KAAG,OAAO,CAAC,MAAM,CAwJ7C,CAAA"}
package/dist/plugin.js CHANGED
@@ -101,6 +101,11 @@ export const payloadCloudPlugin = (pluginOptions)=>async (incomingConfig)=>{
101
101
  ...config.globals || [],
102
102
  {
103
103
  slug: 'payload-cloud-instance',
104
+ access: {
105
+ read: ()=>false,
106
+ readVersions: ()=>false,
107
+ update: ()=>false
108
+ },
104
109
  admin: {
105
110
  hidden: true
106
111
  },
@@ -121,13 +126,10 @@ export const payloadCloudPlugin = (pluginOptions)=>async (incomingConfig)=>{
121
126
  const newShouldAutoRun = async (payload)=>{
122
127
  if (process.env.PAYLOAD_CLOUD_JOBS_INSTANCE) {
123
128
  const retrievedGlobal = await payload.findGlobal({
124
- slug: 'payload-cloud-instance'
129
+ slug: 'payload-cloud-instance',
130
+ overrideAccess: true
125
131
  });
126
- if (retrievedGlobal.instance === process.env.PAYLOAD_CLOUD_JOBS_INSTANCE) {
127
- return true;
128
- } else {
129
- process.env.PAYLOAD_CLOUD_JOBS_INSTANCE = '';
130
- }
132
+ return retrievedGlobal.instance === process.env.PAYLOAD_CLOUD_JOBS_INSTANCE;
131
133
  }
132
134
  return false;
133
135
  };
@@ -142,7 +144,8 @@ export const payloadCloudPlugin = (pluginOptions)=>async (incomingConfig)=>{
142
144
  slug: 'payload-cloud-instance',
143
145
  data: {
144
146
  instance
145
- }
147
+ },
148
+ overrideAccess: true
146
149
  });
147
150
  if (!hasExistingAutorun) {
148
151
  return [
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/plugin.ts"],"sourcesContent":["import type { Config, Payload } from 'payload'\n\nimport type { PluginOptions } from './types.js'\n\nimport { payloadCloudEmail } from './email.js'\nimport { getAfterDeleteHook } from './hooks/afterDelete.js'\nimport { getBeforeChangeHook } from './hooks/beforeChange.js'\nimport {\n getCacheUploadsAfterChangeHook,\n getCacheUploadsAfterDeleteHook,\n} from './hooks/uploadCache.js'\nimport { getStaticHandler } from './staticHandler.js'\n\nexport const generateRandomString = (): string => {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n return Array.from({ length: 24 }, () => chars[Math.floor(Math.random() * chars.length)]).join('')\n}\n\nconst DEFAULT_CRON = '* * * * *'\nconst DEFAULT_LIMIT = 10\nconst DEFAULT_CRON_JOB = {\n cron: DEFAULT_CRON,\n limit: DEFAULT_LIMIT,\n queue: 'default',\n}\n\nexport const payloadCloudPlugin =\n (pluginOptions?: PluginOptions) =>\n async (incomingConfig: Config): Promise<Config> => {\n let config = { ...incomingConfig }\n\n if (process.env.PAYLOAD_CLOUD !== 'true') {\n return config\n }\n\n const cachingEnabled =\n pluginOptions?.uploadCaching !== false && !!process.env.PAYLOAD_CLOUD_CACHE_KEY\n\n const apiEndpoint = pluginOptions?.endpoint || 'https://cloud-api.payloadcms.com'\n\n // Configure cloud storage\n if (pluginOptions?.storage !== false) {\n config = {\n ...config,\n collections: (config.collections || []).map((collection) => {\n if (collection.upload) {\n return {\n ...collection,\n hooks: {\n ...(collection.hooks || {}),\n afterChange: [\n ...(collection.hooks?.afterChange || []),\n ...(cachingEnabled\n ? [getCacheUploadsAfterChangeHook({ endpoint: apiEndpoint })]\n : []),\n ],\n afterDelete: [\n ...(collection.hooks?.afterDelete || []),\n getAfterDeleteHook({ collection }),\n ...(cachingEnabled\n ? [getCacheUploadsAfterDeleteHook({ endpoint: apiEndpoint })]\n : []),\n ],\n beforeChange: [\n ...(collection.hooks?.beforeChange || []),\n getBeforeChangeHook({ collection }),\n ],\n },\n upload: {\n ...(typeof collection.upload === 'object' ? collection.upload : {}),\n disableLocalStorage: true,\n handlers: [\n ...(typeof collection.upload === 'object' &&\n Array.isArray(collection.upload.handlers)\n ? collection.upload.handlers\n : []),\n getStaticHandler({\n cachingOptions: pluginOptions?.uploadCaching,\n collection,\n debug: pluginOptions?.debug,\n }),\n ],\n },\n }\n }\n\n return collection\n }),\n upload: {\n ...(config.upload || {}),\n useTempFiles: true,\n },\n }\n }\n\n // Configure cloud email\n const apiKey = process.env.PAYLOAD_CLOUD_EMAIL_API_KEY\n const defaultDomain = process.env.PAYLOAD_CLOUD_DEFAULT_DOMAIN\n if (pluginOptions?.email !== false && apiKey && defaultDomain) {\n config.email = await payloadCloudEmail({\n apiKey,\n config,\n defaultDomain,\n defaultFromAddress: pluginOptions?.email?.defaultFromAddress,\n defaultFromName: pluginOptions?.email?.defaultFromName,\n skipVerify: pluginOptions?.email?.skipVerify,\n })\n }\n\n // We make sure to only run cronjobs on one instance using a instance identifier stored in a global.\n config.globals = [\n ...(config.globals || []),\n {\n slug: 'payload-cloud-instance',\n admin: {\n hidden: true,\n },\n fields: [\n {\n name: 'instance',\n type: 'text',\n required: true,\n },\n ],\n },\n ]\n\n if (pluginOptions?.enableAutoRun === false) {\n return config\n }\n\n const oldAutoRunCopy = config.jobs?.autoRun ?? []\n\n const hasExistingAutorun = Boolean(config.jobs?.autoRun)\n\n const newShouldAutoRun = async (payload: Payload) => {\n if (process.env.PAYLOAD_CLOUD_JOBS_INSTANCE) {\n const retrievedGlobal = await payload.findGlobal({\n slug: 'payload-cloud-instance',\n })\n\n if (retrievedGlobal.instance === process.env.PAYLOAD_CLOUD_JOBS_INSTANCE) {\n return true\n } else {\n process.env.PAYLOAD_CLOUD_JOBS_INSTANCE = ''\n }\n }\n\n return false\n }\n\n if (!config.jobs?.shouldAutoRun) {\n ;(config.jobs ??= {}).shouldAutoRun = newShouldAutoRun\n }\n\n const newAutoRun = async (payload: Payload) => {\n const instance = generateRandomString()\n\n process.env.PAYLOAD_CLOUD_JOBS_INSTANCE = instance\n\n await payload.updateGlobal({\n slug: 'payload-cloud-instance',\n data: {\n instance,\n },\n })\n\n if (!hasExistingAutorun) {\n return [DEFAULT_CRON_JOB]\n }\n\n return typeof oldAutoRunCopy === 'function' ? await oldAutoRunCopy(payload) : oldAutoRunCopy\n }\n\n config.jobs.autoRun = newAutoRun\n\n return config\n }\n"],"names":["payloadCloudEmail","getAfterDeleteHook","getBeforeChangeHook","getCacheUploadsAfterChangeHook","getCacheUploadsAfterDeleteHook","getStaticHandler","generateRandomString","chars","Array","from","length","Math","floor","random","join","DEFAULT_CRON","DEFAULT_LIMIT","DEFAULT_CRON_JOB","cron","limit","queue","payloadCloudPlugin","pluginOptions","incomingConfig","config","process","env","PAYLOAD_CLOUD","cachingEnabled","uploadCaching","PAYLOAD_CLOUD_CACHE_KEY","apiEndpoint","endpoint","storage","collections","map","collection","upload","hooks","afterChange","afterDelete","beforeChange","disableLocalStorage","handlers","isArray","cachingOptions","debug","useTempFiles","apiKey","PAYLOAD_CLOUD_EMAIL_API_KEY","defaultDomain","PAYLOAD_CLOUD_DEFAULT_DOMAIN","email","defaultFromAddress","defaultFromName","skipVerify","globals","slug","admin","hidden","fields","name","type","required","enableAutoRun","oldAutoRunCopy","jobs","autoRun","hasExistingAutorun","Boolean","newShouldAutoRun","payload","PAYLOAD_CLOUD_JOBS_INSTANCE","retrievedGlobal","findGlobal","instance","shouldAutoRun","newAutoRun","updateGlobal","data"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/plugin.ts"],"sourcesContent":["import type { Config, Payload } from 'payload'\n\nimport type { PluginOptions } from './types.js'\n\nimport { payloadCloudEmail } from './email.js'\nimport { getAfterDeleteHook } from './hooks/afterDelete.js'\nimport { getBeforeChangeHook } from './hooks/beforeChange.js'\nimport {\n getCacheUploadsAfterChangeHook,\n getCacheUploadsAfterDeleteHook,\n} from './hooks/uploadCache.js'\nimport { getStaticHandler } from './staticHandler.js'\n\nexport const generateRandomString = (): string => {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n return Array.from({ length: 24 }, () => chars[Math.floor(Math.random() * chars.length)]).join('')\n}\n\nconst DEFAULT_CRON = '* * * * *'\nconst DEFAULT_LIMIT = 10\nconst DEFAULT_CRON_JOB = {\n cron: DEFAULT_CRON,\n limit: DEFAULT_LIMIT,\n queue: 'default',\n}\n\nexport const payloadCloudPlugin =\n (pluginOptions?: PluginOptions) =>\n async (incomingConfig: Config): Promise<Config> => {\n let config = { ...incomingConfig }\n\n if (process.env.PAYLOAD_CLOUD !== 'true') {\n return config\n }\n\n const cachingEnabled =\n pluginOptions?.uploadCaching !== false && !!process.env.PAYLOAD_CLOUD_CACHE_KEY\n\n const apiEndpoint = pluginOptions?.endpoint || 'https://cloud-api.payloadcms.com'\n\n // Configure cloud storage\n if (pluginOptions?.storage !== false) {\n config = {\n ...config,\n collections: (config.collections || []).map((collection) => {\n if (collection.upload) {\n return {\n ...collection,\n hooks: {\n ...(collection.hooks || {}),\n afterChange: [\n ...(collection.hooks?.afterChange || []),\n ...(cachingEnabled\n ? [getCacheUploadsAfterChangeHook({ endpoint: apiEndpoint })]\n : []),\n ],\n afterDelete: [\n ...(collection.hooks?.afterDelete || []),\n getAfterDeleteHook({ collection }),\n ...(cachingEnabled\n ? [getCacheUploadsAfterDeleteHook({ endpoint: apiEndpoint })]\n : []),\n ],\n beforeChange: [\n ...(collection.hooks?.beforeChange || []),\n getBeforeChangeHook({ collection }),\n ],\n },\n upload: {\n ...(typeof collection.upload === 'object' ? collection.upload : {}),\n disableLocalStorage: true,\n handlers: [\n ...(typeof collection.upload === 'object' &&\n Array.isArray(collection.upload.handlers)\n ? collection.upload.handlers\n : []),\n getStaticHandler({\n cachingOptions: pluginOptions?.uploadCaching,\n collection,\n debug: pluginOptions?.debug,\n }),\n ],\n },\n }\n }\n\n return collection\n }),\n upload: {\n ...(config.upload || {}),\n useTempFiles: true,\n },\n }\n }\n\n // Configure cloud email\n const apiKey = process.env.PAYLOAD_CLOUD_EMAIL_API_KEY\n const defaultDomain = process.env.PAYLOAD_CLOUD_DEFAULT_DOMAIN\n if (pluginOptions?.email !== false && apiKey && defaultDomain) {\n config.email = await payloadCloudEmail({\n apiKey,\n config,\n defaultDomain,\n defaultFromAddress: pluginOptions?.email?.defaultFromAddress,\n defaultFromName: pluginOptions?.email?.defaultFromName,\n skipVerify: pluginOptions?.email?.skipVerify,\n })\n }\n\n // We make sure to only run cronjobs on one instance using a instance identifier stored in a global.\n config.globals = [\n ...(config.globals || []),\n {\n slug: 'payload-cloud-instance',\n access: {\n read: () => false,\n readVersions: () => false,\n update: () => false,\n },\n admin: {\n hidden: true,\n },\n fields: [\n {\n name: 'instance',\n type: 'text',\n required: true,\n },\n ],\n },\n ]\n\n if (pluginOptions?.enableAutoRun === false) {\n return config\n }\n\n const oldAutoRunCopy = config.jobs?.autoRun ?? []\n\n const hasExistingAutorun = Boolean(config.jobs?.autoRun)\n\n const newShouldAutoRun = async (payload: Payload) => {\n if (process.env.PAYLOAD_CLOUD_JOBS_INSTANCE) {\n const retrievedGlobal = await payload.findGlobal({\n slug: 'payload-cloud-instance',\n overrideAccess: true,\n })\n\n return retrievedGlobal.instance === process.env.PAYLOAD_CLOUD_JOBS_INSTANCE\n }\n\n return false\n }\n\n if (!config.jobs?.shouldAutoRun) {\n ;(config.jobs ??= {}).shouldAutoRun = newShouldAutoRun\n }\n\n const newAutoRun = async (payload: Payload) => {\n const instance = generateRandomString()\n\n process.env.PAYLOAD_CLOUD_JOBS_INSTANCE = instance\n\n await payload.updateGlobal({\n slug: 'payload-cloud-instance',\n data: {\n instance,\n },\n overrideAccess: true,\n })\n\n if (!hasExistingAutorun) {\n return [DEFAULT_CRON_JOB]\n }\n\n return typeof oldAutoRunCopy === 'function' ? await oldAutoRunCopy(payload) : oldAutoRunCopy\n }\n\n config.jobs.autoRun = newAutoRun\n\n return config\n }\n"],"names":["payloadCloudEmail","getAfterDeleteHook","getBeforeChangeHook","getCacheUploadsAfterChangeHook","getCacheUploadsAfterDeleteHook","getStaticHandler","generateRandomString","chars","Array","from","length","Math","floor","random","join","DEFAULT_CRON","DEFAULT_LIMIT","DEFAULT_CRON_JOB","cron","limit","queue","payloadCloudPlugin","pluginOptions","incomingConfig","config","process","env","PAYLOAD_CLOUD","cachingEnabled","uploadCaching","PAYLOAD_CLOUD_CACHE_KEY","apiEndpoint","endpoint","storage","collections","map","collection","upload","hooks","afterChange","afterDelete","beforeChange","disableLocalStorage","handlers","isArray","cachingOptions","debug","useTempFiles","apiKey","PAYLOAD_CLOUD_EMAIL_API_KEY","defaultDomain","PAYLOAD_CLOUD_DEFAULT_DOMAIN","email","defaultFromAddress","defaultFromName","skipVerify","globals","slug","access","read","readVersions","update","admin","hidden","fields","name","type","required","enableAutoRun","oldAutoRunCopy","jobs","autoRun","hasExistingAutorun","Boolean","newShouldAutoRun","payload","PAYLOAD_CLOUD_JOBS_INSTANCE","retrievedGlobal","findGlobal","overrideAccess","instance","shouldAutoRun","newAutoRun","updateGlobal","data"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"staticHandler.d.ts","sourceRoot":"","sources":["../src/staticHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAG/C,OAAO,KAAK,EAA2B,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAKvF,UAAU,IAAI;IACZ,cAAc,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAA;IAC/C,UAAU,EAAE,gBAAgB,CAAA;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAuBD,eAAO,MAAM,gBAAgB,GAAI,uCAAuC,IAAI,KAAG,aA2G9E,CAAA"}
1
+ {"version":3,"file":"staticHandler.d.ts","sourceRoot":"","sources":["../src/staticHandler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAK/C,OAAO,KAAK,EAA2B,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAKvF,UAAU,IAAI;IACZ,cAAc,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAA;IAC/C,UAAU,EAAE,gBAAgB,CAAA;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAuBD,eAAO,MAAM,gBAAgB,0CAA2C,IAAI,KAAG,aAmH9E,CAAA"}
@@ -1,3 +1,4 @@
1
+ import { isXmlMimeType, uploadContentSecurityPolicy } from 'payload/internal';
1
2
  import { createKey } from './utilities/createKey.js';
2
3
  import { getStorageClient } from './utilities/getStorageClient.js';
3
4
  // Type guard for NodeJS.Readable streams
@@ -64,12 +65,18 @@ export const getStaticHandler = ({ cachingOptions, collection, debug })=>{
64
65
  },
65
66
  ETag: object.ETag
66
67
  };
67
- // Add Content-Security-Policy header for SVG files to prevent executable code
68
- if (object.ContentType === 'image/svg+xml') {
69
- responseHeaders['Content-Security-Policy'] = "script-src 'none'";
68
+ // Apply a restrictive policy to XML-family responses served through Payload.
69
+ if (isXmlMimeType(object.ContentType)) {
70
+ responseHeaders['Content-Security-Policy'] = uploadContentSecurityPolicy;
71
+ }
72
+ let headers = new Headers(responseHeaders);
73
+ if (typeof collection.upload === 'object' && typeof collection.upload.modifyResponseHeaders === 'function') {
74
+ headers = collection.upload.modifyResponseHeaders({
75
+ headers
76
+ }) || headers;
70
77
  }
71
78
  return new Response(bodyBuffer, {
72
- headers: new Headers(responseHeaders),
79
+ headers,
73
80
  status: 200
74
81
  });
75
82
  } catch (err) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/staticHandler.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\nimport type { Readable } from 'stream'\n\nimport type { CollectionCachingConfig, PluginOptions, StaticHandler } from './types.js'\n\nimport { createKey } from './utilities/createKey.js'\nimport { getStorageClient } from './utilities/getStorageClient.js'\n\ninterface Args {\n cachingOptions?: PluginOptions['uploadCaching']\n collection: CollectionConfig\n debug?: boolean\n}\n\n// Type guard for NodeJS.Readable streams\nconst isNodeReadableStream = (body: unknown): body is Readable => {\n return (\n typeof body === 'object' &&\n body !== null &&\n 'pipe' in body &&\n typeof (body as any).pipe === 'function' &&\n 'destroy' in body &&\n typeof (body as any).destroy === 'function'\n )\n}\n\n// Convert a stream into a promise that resolves with a Buffer\nconst streamToBuffer = async (readableStream: any) => {\n const chunks = []\n for await (const chunk of readableStream) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)\n }\n return Buffer.concat(chunks)\n}\n\nexport const getStaticHandler = ({ cachingOptions, collection, debug }: Args): StaticHandler => {\n let maxAge = 86400 // 24 hours default\n let collCacheConfig: CollectionCachingConfig | undefined\n if (cachingOptions !== false) {\n // Set custom maxAge for all collections\n maxAge = cachingOptions?.maxAge || maxAge\n collCacheConfig = cachingOptions?.collections?.[collection.slug] || {}\n }\n\n // Set maxAge using collection-specific override\n maxAge = collCacheConfig?.maxAge || maxAge\n\n const cachingEnabled =\n cachingOptions !== false &&\n !!process.env.PAYLOAD_CLOUD_CACHE_KEY &&\n collCacheConfig?.enabled !== false\n\n return async (req, { params }) => {\n let key = ''\n try {\n const { identityID, storageClient } = await getStorageClient()\n\n key = createKey({\n collection: collection.slug,\n filename: params.filename,\n identityID,\n })\n\n const object = await storageClient.getObject({\n Bucket: process.env.PAYLOAD_CLOUD_BUCKET,\n Key: key,\n })\n\n if (!object.Body || !object.ContentType || !object.ETag) {\n return new Response(null, { status: 404, statusText: 'Not Found' })\n }\n\n // On error, manually destroy stream to close socket\n if (object.Body && isNodeReadableStream(object.Body)) {\n const stream = object.Body\n stream.on('error', (err) => {\n req.payload.logger.error({\n err,\n key,\n msg: 'Error streaming S3 object, destroying stream',\n })\n stream.destroy()\n })\n }\n\n const bodyBuffer = await streamToBuffer(object.Body)\n\n const responseHeaders: Record<string, string> = {\n 'Content-Length': String(object.ContentLength),\n 'Content-Type': object.ContentType,\n ...(cachingEnabled && { 'Cache-Control': `public, max-age=${maxAge}` }),\n ETag: object.ETag,\n }\n\n // Add Content-Security-Policy header for SVG files to prevent executable code\n if (object.ContentType === 'image/svg+xml') {\n responseHeaders['Content-Security-Policy'] = \"script-src 'none'\"\n }\n\n return new Response(bodyBuffer, {\n headers: new Headers(responseHeaders),\n status: 200,\n })\n } catch (err: unknown) {\n // Handle each error explicitly\n if (err instanceof Error) {\n /**\n * Note: If AccessDenied comes back, it typically means that the object key is not found.\n * The AWS SDK throws this because it attempts an s3:ListBucket operation under the hood\n * if it does not find the object key, which we have disallowed in our bucket policy.\n */\n if (err.name === 'AccessDenied') {\n req.payload.logger.warn({\n awsErr: debug ? err : err.name,\n collectionSlug: collection.slug,\n msg: `Requested file not found in cloud storage: ${params.filename}`,\n params,\n requestedKey: key,\n })\n return new Response(null, { status: 404, statusText: 'Not Found' })\n } else if (err.name === 'NoSuchKey') {\n req.payload.logger.warn({\n awsErr: debug ? err : err.name,\n collectionSlug: collection.slug,\n msg: `Requested file not found in cloud storage: ${params.filename}`,\n params,\n requestedKey: key,\n })\n return new Response(null, { status: 404, statusText: 'Not Found' })\n }\n }\n\n req.payload.logger.error({\n collectionSlug: collection.slug,\n err,\n msg: `Error getting file from cloud storage: ${params.filename}`,\n params,\n requestedKey: key,\n })\n return new Response('Internal Server Error', { status: 500 })\n }\n }\n}\n"],"names":["createKey","getStorageClient","isNodeReadableStream","body","pipe","destroy","streamToBuffer","readableStream","chunks","chunk","push","Buffer","from","concat","getStaticHandler","cachingOptions","collection","debug","maxAge","collCacheConfig","collections","slug","cachingEnabled","process","env","PAYLOAD_CLOUD_CACHE_KEY","enabled","req","params","key","identityID","storageClient","filename","object","getObject","Bucket","PAYLOAD_CLOUD_BUCKET","Key","Body","ContentType","ETag","Response","status","statusText","stream","on","err","payload","logger","error","msg","bodyBuffer","responseHeaders","String","ContentLength","headers","Headers","Error","name","warn","awsErr","collectionSlug","requestedKey"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/staticHandler.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\nimport type { Readable } from 'stream'\n\nimport { isXmlMimeType, uploadContentSecurityPolicy } from 'payload/internal'\n\nimport type { CollectionCachingConfig, PluginOptions, StaticHandler } from './types.js'\n\nimport { createKey } from './utilities/createKey.js'\nimport { getStorageClient } from './utilities/getStorageClient.js'\n\ninterface Args {\n cachingOptions?: PluginOptions['uploadCaching']\n collection: CollectionConfig\n debug?: boolean\n}\n\n// Type guard for NodeJS.Readable streams\nconst isNodeReadableStream = (body: unknown): body is Readable => {\n return (\n typeof body === 'object' &&\n body !== null &&\n 'pipe' in body &&\n typeof (body as any).pipe === 'function' &&\n 'destroy' in body &&\n typeof (body as any).destroy === 'function'\n )\n}\n\n// Convert a stream into a promise that resolves with a Buffer\nconst streamToBuffer = async (readableStream: any) => {\n const chunks = []\n for await (const chunk of readableStream) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk)\n }\n return Buffer.concat(chunks)\n}\n\nexport const getStaticHandler = ({ cachingOptions, collection, debug }: Args): StaticHandler => {\n let maxAge = 86400 // 24 hours default\n let collCacheConfig: CollectionCachingConfig | undefined\n if (cachingOptions !== false) {\n // Set custom maxAge for all collections\n maxAge = cachingOptions?.maxAge || maxAge\n collCacheConfig = cachingOptions?.collections?.[collection.slug] || {}\n }\n\n // Set maxAge using collection-specific override\n maxAge = collCacheConfig?.maxAge || maxAge\n\n const cachingEnabled =\n cachingOptions !== false &&\n !!process.env.PAYLOAD_CLOUD_CACHE_KEY &&\n collCacheConfig?.enabled !== false\n\n return async (req, { params }) => {\n let key = ''\n try {\n const { identityID, storageClient } = await getStorageClient()\n\n key = createKey({\n collection: collection.slug,\n filename: params.filename,\n identityID,\n })\n\n const object = await storageClient.getObject({\n Bucket: process.env.PAYLOAD_CLOUD_BUCKET,\n Key: key,\n })\n\n if (!object.Body || !object.ContentType || !object.ETag) {\n return new Response(null, { status: 404, statusText: 'Not Found' })\n }\n\n // On error, manually destroy stream to close socket\n if (object.Body && isNodeReadableStream(object.Body)) {\n const stream = object.Body\n stream.on('error', (err) => {\n req.payload.logger.error({\n err,\n key,\n msg: 'Error streaming S3 object, destroying stream',\n })\n stream.destroy()\n })\n }\n\n const bodyBuffer = await streamToBuffer(object.Body)\n\n const responseHeaders: Record<string, string> = {\n 'Content-Length': String(object.ContentLength),\n 'Content-Type': object.ContentType,\n ...(cachingEnabled && { 'Cache-Control': `public, max-age=${maxAge}` }),\n ETag: object.ETag,\n }\n\n // Apply a restrictive policy to XML-family responses served through Payload.\n if (isXmlMimeType(object.ContentType)) {\n responseHeaders['Content-Security-Policy'] = uploadContentSecurityPolicy\n }\n\n let headers = new Headers(responseHeaders)\n if (\n typeof collection.upload === 'object' &&\n typeof collection.upload.modifyResponseHeaders === 'function'\n ) {\n headers = collection.upload.modifyResponseHeaders({ headers }) || headers\n }\n\n return new Response(bodyBuffer, {\n headers,\n status: 200,\n })\n } catch (err: unknown) {\n // Handle each error explicitly\n if (err instanceof Error) {\n /**\n * Note: If AccessDenied comes back, it typically means that the object key is not found.\n * The AWS SDK throws this because it attempts an s3:ListBucket operation under the hood\n * if it does not find the object key, which we have disallowed in our bucket policy.\n */\n if (err.name === 'AccessDenied') {\n req.payload.logger.warn({\n awsErr: debug ? err : err.name,\n collectionSlug: collection.slug,\n msg: `Requested file not found in cloud storage: ${params.filename}`,\n params,\n requestedKey: key,\n })\n return new Response(null, { status: 404, statusText: 'Not Found' })\n } else if (err.name === 'NoSuchKey') {\n req.payload.logger.warn({\n awsErr: debug ? err : err.name,\n collectionSlug: collection.slug,\n msg: `Requested file not found in cloud storage: ${params.filename}`,\n params,\n requestedKey: key,\n })\n return new Response(null, { status: 404, statusText: 'Not Found' })\n }\n }\n\n req.payload.logger.error({\n collectionSlug: collection.slug,\n err,\n msg: `Error getting file from cloud storage: ${params.filename}`,\n params,\n requestedKey: key,\n })\n return new Response('Internal Server Error', { status: 500 })\n }\n }\n}\n"],"names":["isXmlMimeType","uploadContentSecurityPolicy","createKey","getStorageClient","isNodeReadableStream","body","pipe","destroy","streamToBuffer","readableStream","chunks","chunk","push","Buffer","from","concat","getStaticHandler","cachingOptions","collection","debug","maxAge","collCacheConfig","collections","slug","cachingEnabled","process","env","PAYLOAD_CLOUD_CACHE_KEY","enabled","req","params","key","identityID","storageClient","filename","object","getObject","Bucket","PAYLOAD_CLOUD_BUCKET","Key","Body","ContentType","ETag","Response","status","statusText","stream","on","err","payload","logger","error","msg","bodyBuffer","responseHeaders","String","ContentLength","headers","Headers","upload","modifyResponseHeaders","Error","name","warn","awsErr","collectionSlug","requestedKey"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"authAsCognitoUser.d.ts","sourceRoot":"","sources":["../../src/utilities/authAsCognitoUser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAMpE,eAAO,MAAM,iBAAiB,GAC5B,UAAU,MAAM,EAChB,UAAU,MAAM,KACf,OAAO,CAAC,kBAAkB,CA0C5B,CAAA"}
1
+ {"version":3,"file":"authAsCognitoUser.d.ts","sourceRoot":"","sources":["../../src/utilities/authAsCognitoUser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAMpE,eAAO,MAAM,iBAAiB,aAClB,MAAM,YACN,MAAM,KACf,OAAO,CAAC,kBAAkB,CA0C5B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"createKey.d.ts","sourceRoot":"","sources":["../../src/utilities/createKey.ts"],"names":[],"mappings":"AAAA,UAAU,IAAI;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,SAAS,GAAI,sCAAsC,IAAI,KAAG,MACa,CAAA"}
1
+ {"version":3,"file":"createKey.d.ts","sourceRoot":"","sources":["../../src/utilities/createKey.ts"],"names":[],"mappings":"AAAA,UAAU,IAAI;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,SAAS,yCAA0C,IAAI,KAAG,MACa,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/payload-cloud",
3
- "version": "4.0.0-internal.688c4d0",
3
+ "version": "4.0.0-internal.77191e5",
4
4
  "description": "The official Payload Cloud plugin",
5
5
  "homepage": "https://payloadcms.com",
6
6
  "repository": {
@@ -37,15 +37,15 @@
37
37
  "@aws-sdk/credential-providers": "^3.614.0",
38
38
  "@aws-sdk/lib-storage": "^3.614.0",
39
39
  "amazon-cognito-identity-js": "^6.1.2",
40
- "nodemailer": "^8.0.5",
41
- "@payloadcms/email-nodemailer": "4.0.0-internal.688c4d0"
40
+ "nodemailer": "^9.1.1",
41
+ "@payloadcms/email-nodemailer": "4.0.0-internal.77191e5"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/nodemailer": "^8.0.0",
45
- "payload": "4.0.0-internal.688c4d0"
45
+ "payload": "4.0.0-internal.77191e5"
46
46
  },
47
47
  "peerDependencies": {
48
- "payload": "4.0.0-internal.688c4d0"
48
+ "payload": "4.0.0-internal.77191e5"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "pnpm build:types && pnpm build:swc",