@payloadcms/figma 0.1.0-alpha.1 → 0.1.0-alpha.2
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.
|
@@ -18,6 +18,7 @@ import * as log from '../utils/log.js';
|
|
|
18
18
|
import { logMissingCliAuth } from './auth-preflight.js';
|
|
19
19
|
import { logMissingContentSystemId } from './bootstrap-preflight.js';
|
|
20
20
|
import { getDevCookieNames } from './dev-cookie-names.js';
|
|
21
|
+
import { createSandboxUploadFetchPlugin } from './sandbox-upload-fetch.js';
|
|
21
22
|
/**
|
|
22
23
|
* Worker-trusted marker injected by Figma's sites-worker after it validates the
|
|
23
24
|
* X-Figma-Job-Queues-Auth-Bypass secret on a Payload jobs endpoint. The default
|
|
@@ -392,7 +393,12 @@ export async function buildFigmaConfig(config) {
|
|
|
392
393
|
debug: !!process.env.DEBUG,
|
|
393
394
|
disabled: false
|
|
394
395
|
}),
|
|
395
|
-
scheduleExtractPlugin()
|
|
396
|
+
scheduleExtractPlugin(),
|
|
397
|
+
// Not folded into createStoragePlugin, which is skipped when
|
|
398
|
+
// figma.storage is false and would break remote uploads for those apps.
|
|
399
|
+
createSandboxUploadFetchPlugin({
|
|
400
|
+
userCollections: config.collections
|
|
401
|
+
})
|
|
396
402
|
]
|
|
397
403
|
};
|
|
398
404
|
// Inject figma fields into users collection
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Config } from 'payload';
|
|
2
|
+
/**
|
|
3
|
+
* True inside the Make sandbox. agentplat injects `FIGMA=1`, absent locally and
|
|
4
|
+
* in the deployed Lambda; `FIGMA=true` matches the app template's vite config.
|
|
5
|
+
*
|
|
6
|
+
* KEEP_IN_SYNC(services/agentplat/scriptrun/script_runner.go): EnvFigma
|
|
7
|
+
*/
|
|
8
|
+
export declare function isMakeSandbox(): boolean;
|
|
9
|
+
type SandboxUploadFetchOptions = {
|
|
10
|
+
/**
|
|
11
|
+
* The app's collections before any plugin runs. `plugin-cloud-storage` later
|
|
12
|
+
* rewrites `skipSafeFetch`, erasing whether the app set `false` or nothing, so
|
|
13
|
+
* intent must be read here.
|
|
14
|
+
*/
|
|
15
|
+
userCollections: Config['collections'];
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Defaults upload collections to skip `safeFetch` in the Make sandbox, where DNS
|
|
19
|
+
* maps external hostnames to unique-local IPv6 addresses (`fc00::/7`) that
|
|
20
|
+
* `safeFetch` rejects as non-unicast. A no-op elsewhere.
|
|
21
|
+
*
|
|
22
|
+
* Only a default: a collection that set `skipSafeFetch` itself keeps its value.
|
|
23
|
+
* `externalFileHeaderFilter` is left unset on purpose, since it would replace
|
|
24
|
+
* the cookie logic that forwards credentials for relative URLs.
|
|
25
|
+
*
|
|
26
|
+
* SSRF risks, bounded by the routes' auth gate and sandbox network limits:
|
|
27
|
+
* `getExternalFile` re-validates redirects only against `pasteURL.allowList`,
|
|
28
|
+
* any session can GET an arbitrary URL and read the body, and request cookies
|
|
29
|
+
* reach the target.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createSandboxUploadFetchPlugin({ userCollections }: SandboxUploadFetchOptions): (config: Config) => Config;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as log from '../utils/log.js';
|
|
2
|
+
/**
|
|
3
|
+
* True inside the Make sandbox. agentplat injects `FIGMA=1`, absent locally and
|
|
4
|
+
* in the deployed Lambda; `FIGMA=true` matches the app template's vite config.
|
|
5
|
+
*
|
|
6
|
+
* KEEP_IN_SYNC(services/agentplat/scriptrun/script_runner.go): EnvFigma
|
|
7
|
+
*/ export function isMakeSandbox() {
|
|
8
|
+
return process.env.FIGMA === '1' || process.env.FIGMA === 'true';
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Defaults upload collections to skip `safeFetch` in the Make sandbox, where DNS
|
|
12
|
+
* maps external hostnames to unique-local IPv6 addresses (`fc00::/7`) that
|
|
13
|
+
* `safeFetch` rejects as non-unicast. A no-op elsewhere.
|
|
14
|
+
*
|
|
15
|
+
* Only a default: a collection that set `skipSafeFetch` itself keeps its value.
|
|
16
|
+
* `externalFileHeaderFilter` is left unset on purpose, since it would replace
|
|
17
|
+
* the cookie logic that forwards credentials for relative URLs.
|
|
18
|
+
*
|
|
19
|
+
* SSRF risks, bounded by the routes' auth gate and sandbox network limits:
|
|
20
|
+
* `getExternalFile` re-validates redirects only against `pasteURL.allowList`,
|
|
21
|
+
* any session can GET an arbitrary URL and read the body, and request cookies
|
|
22
|
+
* reach the target.
|
|
23
|
+
*/ export function createSandboxUploadFetchPlugin({ userCollections }) {
|
|
24
|
+
const appOwnedSlugs = new Set((userCollections ?? []).filter((collection)=>typeof collection.upload === 'object' && 'skipSafeFetch' in collection.upload).map((collection)=>collection.slug));
|
|
25
|
+
return (config)=>{
|
|
26
|
+
if (!isMakeSandbox()) {
|
|
27
|
+
return config;
|
|
28
|
+
}
|
|
29
|
+
const modifiedSlugs = [];
|
|
30
|
+
const collections = (config.collections ?? []).map((collection)=>{
|
|
31
|
+
if (!collection.upload || appOwnedSlugs.has(collection.slug)) {
|
|
32
|
+
return collection;
|
|
33
|
+
}
|
|
34
|
+
modifiedSlugs.push(collection.slug);
|
|
35
|
+
const upload = collection.upload === true ? {} : collection.upload;
|
|
36
|
+
return {
|
|
37
|
+
...collection,
|
|
38
|
+
upload: {
|
|
39
|
+
...upload,
|
|
40
|
+
skipSafeFetch: true
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
if (modifiedSlugs.length === 0) {
|
|
45
|
+
return config;
|
|
46
|
+
}
|
|
47
|
+
log.debug(`Make sandbox detected: upload collections skip safeFetch (${modifiedSlugs.join(', ')})`);
|
|
48
|
+
return {
|
|
49
|
+
...config,
|
|
50
|
+
collections
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/figma",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.2",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
"generate:types": "tsx scripts/generate-types.ts",
|
|
98
98
|
"lint": "eslint .",
|
|
99
99
|
"lint:fix": "eslint . --fix",
|
|
100
|
+
"payload:cli": "tsx scripts/payload-cli.ts",
|
|
100
101
|
"start": "pnpm build && node ./bin/cli.js",
|
|
101
102
|
"test": "TEST_UNIT=true vitest run",
|
|
102
103
|
"test:int": "TEST_INT=true vitest run --config vitest.config.int.ts",
|