diff --git a/.github/workflows/ci-frontend.yml b/.github/workflows/ci-frontend.yml index 73ed1b1741b2..bfe6d9352890 100644 --- a/.github/workflows/ci-frontend.yml +++ b/.github/workflows/ci-frontend.yml @@ -132,6 +132,10 @@ jobs: # we only care if the toolbar will increase a lot minimum-change-threshold: 1000 + - name: Check toolbar for CSP eval violations + if: needs.changes.outputs.frontend == 'true' + run: pnpm --filter=@posthog/frontend check-toolbar-csp-eval + jest: runs-on: depot-ubuntu-24.04 needs: changes diff --git a/frontend/bin/check-toolbar-csp-eval.mjs b/frontend/bin/check-toolbar-csp-eval.mjs new file mode 100644 index 000000000000..cf14afffda62 --- /dev/null +++ b/frontend/bin/check-toolbar-csp-eval.mjs @@ -0,0 +1,102 @@ +import * as parser from "@babel/parser"; +import traverse from "@babel/traverse"; +import fs from "fs"; +import path from "path"; + +// Parse dist/toolbar.js and check for anything that might trigger CSP script-src violations + +// The threat model here is: +// * We're not trying to protect against an attacker hiding an eval like window["ev" + "al"]("..."). +// * This is OK because any actual violations will be caught by the customer's actual CSP rules. +// * We are just trying to prevent false positives in the CSP report. +// * This script is just meant to protect against us accidentally adding evals, which wouldn't be maliciously hidden. + + +// Identifiers that become code when the *first* argument is a string +const UNSAFE_TIMERS = new Set(["setTimeout", "setInterval", "setImmediate", "execScript"]); + +const FUNCTION_CTORS = new Set([ + "Function", + "AsyncFunction", + "GeneratorFunction", + "AsyncGeneratorFunction", +]); + +function main() { + const filePath = 'dist/toolbar.js'; + const absPath = path.resolve(process.cwd(), filePath); + const source = fs.readFileSync(absPath, "utf-8"); + + const ast = parser.parse(source, { + sourceType: "unambiguous", + }); + + const evals = []; + + traverse.default(ast, { + CallExpression(p) { + const callee = p.get("callee"); + + // eval(...) + if (callee.isIdentifier({name: "eval"})) { + if (p.node.loc) { + evals.push({ + type: 'eval()', + start: p.node.loc.start + }); + } + } + + // window['eval'](...) + else if ( + callee.isMemberExpression() && + callee.node.computed && + callee.get("object").isIdentifier({name: "window"}) && + callee.get("property").isStringLiteral({value: "eval"}) + ) { + if (p.node.loc) { + evals.push({type: 'window["eval"]()', start: p.node.loc.start}); + } + } + + // === 3. setTimeout + other functions with a string argument + else if ( + (callee.isIdentifier() && UNSAFE_TIMERS.has(callee.node.name)) || + (callee.isMemberExpression() && + !callee.node.computed && + callee.get("object").isIdentifier({name: "window"}) && + callee.get("property").isIdentifier() && + UNSAFE_TIMERS.has(callee.get("property").node.name)) + ) { + const firstArg = p.get("arguments")[0]; + if (firstArg?.isStringLiteral()) { + evals.push({type: `${callee.node.name}(string)`, start: p.node.loc}); + } + } + }, + + NewExpression(p) { + const callee = p.get("callee"); + + // new Function(...) + other Function constructors + if (callee.isIdentifier() && FUNCTION_CTORS.has(callee.node.name)) { + evals.push({ + type: `new ${callee.node.name}()`, + start: p.node.loc.start + }); + + } + }, + }); + + if (evals.length > 0) { + evals.forEach(({type, start: {line, column}}) => + console.log(`${type}: line ${line}:${column}`) + ); + + process.exit(1); + } +} + + +main() \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index 65227a0acf7c..534112ca51a6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -42,7 +42,8 @@ "lint:js": "eslint src ../cypress ../products", "lint:css": "stylelint \"../(frontend|products)/**/*.{css,scss}\" --ignore-path=frontend/.stylelintignore", "format": "pnpm lint:js --fix && pnpm lint:css --fix && pnpm prettier", - "visualize-toolbar-bundle": "pnpm exec esbuild-visualizer --metadata ./toolbar-esbuild-meta.json --filename=toolbar-esbuild-bundle-visualization.html" + "visualize-toolbar-bundle": "pnpm exec esbuild-visualizer --metadata ./toolbar-esbuild-meta.json --filename=toolbar-esbuild-bundle-visualization.html", + "check-toolbar-csp-eval": "node ./bin/check-toolbar-csp-eval.mjs" }, "dependencies": { "@babel/runtime": "^7.24.0", @@ -53,7 +54,7 @@ "@floating-ui/react": "^0.26.9", "@lottiefiles/react-lottie-player": "^3.4.7", "@medv/finder": "^3.1.0", - "@microlink/react-json-view": "^1.21.3", + "@microlink/react-json-view": "^1.26.2", "@microsoft/fetch-event-source": "^2.0.1", "@monaco-editor/react": "4.6.0", "@posthog/ee": "workspace:*", @@ -196,6 +197,8 @@ "zxcvbn": "^4.4.2" }, "devDependencies": { + "@babel/parser": "^7.24.0", + "@babel/traverse": "^7.24.0", "@parcel/packager-ts": "2.13.3", "@parcel/transformer-typescript-types": "2.13.3", "@storybook/addon-actions": "^7.6.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7530510e9912..021f40dce4ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -546,8 +546,8 @@ importers: specifier: ^3.1.0 version: 3.1.0 '@microlink/react-json-view': - specifier: ^1.21.3 - version: 1.22.2(@types/react@17.0.52)(encoding@0.1.13)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^1.26.2 + version: 1.26.2(@types/react@17.0.52)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@microsoft/fetch-event-source': specifier: ^2.0.1 version: 2.0.1 @@ -973,6 +973,12 @@ importers: specifier: ^2.3.2 version: 2.3.3 devDependencies: + '@babel/parser': + specifier: ^7.24.0 + version: 7.26.3 + '@babel/traverse': + specifier: ^7.24.0 + version: 7.26.4 '@parcel/packager-ts': specifier: 2.13.3 version: 2.13.3(@parcel/core@2.13.3(@swc/helpers@0.5.15)) @@ -4001,8 +4007,9 @@ packages: '@medv/finder@3.1.0': resolution: {integrity: sha512-ojkXjR3K0Zz3jnCR80tqPL+0yvbZk/lEodb6RIVjLz7W8RVA2wrw8ym/CzCpXO9SYVUIKHFUpc7jvf8UKfIM3w==} - '@microlink/react-json-view@1.22.2': - resolution: {integrity: sha512-liJzdlbspT5GbEuPffw4jzZfXOypKLK1Er9br03T31bAaIi/WptZqpcJaXPi7OmwC7v/YYczCkmAS7WaEfItPQ==} + '@microlink/react-json-view@1.26.2': + resolution: {integrity: sha512-NamaHDT21njvbg2RZQq+rnu+owlPyj5lnUdVH5ZtChfTX+75QD2EGnccB1gs0De42jdPj77UQHYLr7d4J46IYA==} + engines: {node: '>=17'} peerDependencies: react: '>= 15' react-dom: '>= 15' @@ -6469,6 +6476,9 @@ packages: '@types/babel__traverse@7.20.6': resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + '@types/base16@1.0.5': + resolution: {integrity: sha512-OzOWrTluG9cwqidEzC/Q6FAmIPcnZfm8BFRlIx0+UIUqnuAmi5OS88O0RpT3Yz6qdmqObvUhasrbNsCofE4W9A==} + '@types/bluebird@3.5.38': resolution: {integrity: sha512-yR/Kxc0dd4FfwtEoLZMoqJbM/VE/W7hXn/MIjb+axcwag0iFmSPK7OBUZq1YWLynJUoWQkfUrI7T0HDqGApNSg==} @@ -8165,10 +8175,16 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + color-support@1.1.3: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true + color@3.2.1: + resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} @@ -8394,9 +8410,6 @@ packages: resolution: {integrity: sha512-jbokKWGcyU4gl6jAfX97E1gDpY12DJ1cLJZmoDzaAln/shZ+S3KBFBuA2Q6WeUN4gJf/8klnV1EfvhA2lK5IRQ==} engines: {node: '>=12.0.0'} - cross-fetch@3.1.5: - resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} - cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -9700,15 +9713,6 @@ packages: fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - fbemitter@3.0.0: - resolution: {integrity: sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw==} - - fbjs-css-vars@1.0.2: - resolution: {integrity: sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==} - - fbjs@3.0.4: - resolution: {integrity: sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ==} - fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} @@ -9820,11 +9824,6 @@ packages: resolution: {integrity: sha512-RW1Dh6BuT14DA7+gtNRKzgzvG3GTPdrceHCi4ddZ9VFGQ9HtO5L8wzxMGsor7XtInIrbWZZCSak0oxnBF7tApw==} engines: {node: '>=0.4.0'} - flux@4.0.3: - resolution: {integrity: sha512-yKAbrp7JhZhj6uiT1FTuVMlIAT1J4jqEyBpFApi1kxpGZCvacMVc/t1pMQyotqHhAgvoE3bNvAykhCo2CLjnYw==} - peerDependencies: - react: ^15.0.2 || ^16.0.0 || ^17.0.0 - follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} @@ -10714,6 +10713,9 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + is-async-function@2.0.0: resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} engines: {node: '>= 0.4'} @@ -11759,9 +11761,6 @@ packages: lodash.flattendeep@4.4.0: resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} - lodash.flow@3.5.0: - resolution: {integrity: sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==} - lodash.isarguments@3.1.0: resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} @@ -12314,15 +12313,6 @@ packages: node-fetch-native@1.2.0: resolution: {integrity: sha512-5IAMBTl9p6PaAjYCnMv5FmqIF6GcZnawAVnzaCG0rX2aYZJ4CxEkZNtVPuTRug7fL7wyM5BQYTlAzcyMPi6oTQ==} - node-fetch@2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - node-fetch@2.6.9: resolution: {integrity: sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==} engines: {node: 4.x || >=6.0.0} @@ -13526,9 +13516,6 @@ packages: resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} engines: {node: '>=10'} - promise@7.3.1: - resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} - prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -13667,9 +13654,6 @@ packages: resolution: {integrity: sha512-n13AWriBMPYxnpbb6bnaY5YoY6rGj8vPLrz6CZF3o0qJNEwlcfJVxBzYZ0NJsQ21UbdJoijPCDrM++SUVEz7+w==} engines: {node: '>=8.16.0'} - pure-color@1.3.0: - resolution: {integrity: sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA==} - pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} @@ -13782,8 +13766,8 @@ packages: re2js@0.4.1: resolution: {integrity: sha512-Kxb+OKXrEPowP4bXAF07NDXtgYX07S8HeVGgadx5/D/R41LzWg1kgTD2szIv2iHJM3vrAPnDKaBzfUE/7QWX9w==} - react-base16-styling@0.6.0: - resolution: {integrity: sha512-yvh/7CArceR/jNATXOKDlvTnPKPmGZz7zsenQ3jUwLzHkNUR0CvY3yGYJbWJ/nnxsL8Sgmt5cO3/SILVuPO6TQ==} + react-base16-styling@0.9.1: + resolution: {integrity: sha512-1s0CY1zRBOQ5M3T61wetEpvQmsYSNtWEcdYzyZNxKa8t7oDvaOn9d21xrGezGAHFWLM7SHcktPuPTrvoqxSfKw==} react-colorful@5.6.1: resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==} @@ -13971,6 +13955,12 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-textarea-autosize@8.5.9: + resolution: {integrity: sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==} + engines: {node: '>=10'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-toastify@8.2.0: resolution: {integrity: sha512-Pg2Ju7NngAamarFvLwqrFomJ57u/Ay6i6zfLurt/qPynWkAkOthu6vxfqYpJCyNhHRhR4hu7+bySSeWWJu6PAg==} peerDependencies: @@ -14535,9 +14525,6 @@ packages: resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} engines: {node: '>=0.10.0'} - setimmediate@1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -14598,6 +14585,9 @@ packages: simple-concat@1.0.1: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + simple-update-notifier@1.1.0: resolution: {integrity: sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==} engines: {node: '>=8.10.0'} @@ -15526,9 +15516,6 @@ packages: typewise@1.0.3: resolution: {integrity: sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==} - ua-parser-js@0.7.32: - resolution: {integrity: sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==} - uc.micro@1.0.6: resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} @@ -15635,8 +15622,8 @@ packages: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} - unlayer-types@1.261.0: - resolution: {integrity: sha512-aSJTrqXQIClOSar5PENIrjRoHEiq5LRLLb9Z1k5D0g42FKiZVHQVolhPzN1ilw9FCl3lRNm1Ke000zDHiDSGGg==} + unlayer-types@1.263.0: + resolution: {integrity: sha512-dOpGPj8P6WkpR1lSRJqprPh8KzFTLdXN7TQAJWjPeSw+RwnIyGtiBRH80efV21S/gjBVT5UL7K1g12S3zTEL6w==} unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} @@ -18731,17 +18718,15 @@ snapshots: '@medv/finder@3.1.0': {} - '@microlink/react-json-view@1.22.2(@types/react@17.0.52)(encoding@0.1.13)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@microlink/react-json-view@1.26.2(@types/react@17.0.52)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: - flux: 4.0.3(encoding@0.1.13)(react@18.2.0) react: 18.2.0 - react-base16-styling: 0.6.0 + react-base16-styling: 0.9.1 react-dom: 18.2.0(react@18.2.0) react-lifecycles-compat: 3.0.4 - react-textarea-autosize: 8.3.4(@types/react@17.0.52)(react@18.2.0) + react-textarea-autosize: 8.5.9(@types/react@17.0.52)(react@18.2.0) transitivePeerDependencies: - '@types/react' - - encoding '@microsoft/fetch-event-source@2.0.1': {} @@ -22133,6 +22118,8 @@ snapshots: dependencies: '@babel/types': 7.26.3 + '@types/base16@1.0.5': {} + '@types/bluebird@3.5.38': {} '@types/body-parser@1.19.5': @@ -24173,8 +24160,18 @@ snapshots: color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + color-support@1.1.3: {} + color@3.2.1: + dependencies: + color-convert: 1.9.3 + color-string: 1.9.1 + colord@2.9.3: {} colorette@2.0.19: {} @@ -24422,12 +24419,6 @@ snapshots: dependencies: luxon: 3.5.0 - cross-fetch@3.1.5(encoding@0.1.13): - dependencies: - node-fetch: 2.6.7(encoding@0.1.13) - transitivePeerDependencies: - - encoding - cross-spawn@7.0.3: dependencies: path-key: 3.1.1 @@ -26228,26 +26219,6 @@ snapshots: dependencies: bser: 2.1.1 - fbemitter@3.0.0(encoding@0.1.13): - dependencies: - fbjs: 3.0.4(encoding@0.1.13) - transitivePeerDependencies: - - encoding - - fbjs-css-vars@1.0.2: {} - - fbjs@3.0.4(encoding@0.1.13): - dependencies: - cross-fetch: 3.1.5(encoding@0.1.13) - fbjs-css-vars: 1.0.2 - loose-envify: 1.4.0 - object-assign: 4.1.1 - promise: 7.3.1 - setimmediate: 1.0.5 - ua-parser-js: 0.7.32 - transitivePeerDependencies: - - encoding - fd-slicer@1.1.0: dependencies: pend: 1.2.0 @@ -26383,14 +26354,6 @@ snapshots: flow-parser@0.214.0: {} - flux@4.0.3(encoding@0.1.13)(react@18.2.0): - dependencies: - fbemitter: 3.0.0(encoding@0.1.13) - fbjs: 3.0.4(encoding@0.1.13) - react: 18.2.0 - transitivePeerDependencies: - - encoding - follow-redirects@1.15.9: {} for-each@0.3.3: @@ -27442,6 +27405,8 @@ snapshots: is-arrayish@0.2.1: {} + is-arrayish@0.3.2: {} + is-async-function@2.0.0: dependencies: has-tostringtag: 1.0.0 @@ -28804,8 +28769,6 @@ snapshots: lodash.flattendeep@4.4.0: {} - lodash.flow@3.5.0: {} - lodash.isarguments@3.1.0: {} lodash.isequal@4.5.0: {} @@ -29444,12 +29407,6 @@ snapshots: node-fetch-native@1.2.0: {} - node-fetch@2.6.7(encoding@0.1.13): - dependencies: - whatwg-url: 5.0.0 - optionalDependencies: - encoding: 0.1.13 - node-fetch@2.6.9(encoding@0.1.13): dependencies: whatwg-url: 5.0.0 @@ -30998,10 +30955,6 @@ snapshots: err-code: 2.0.3 retry: 0.12.0 - promise@7.3.1: - dependencies: - asap: 2.0.6 - prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -31227,8 +31180,6 @@ snapshots: - supports-color - utf-8-validate - pure-color@1.3.0: {} - pure-rand@6.1.0: {} qrcode.react@4.2.0(react@18.2.0): @@ -31348,12 +31299,15 @@ snapshots: re2js@0.4.1: {} - react-base16-styling@0.6.0: + react-base16-styling@0.9.1: dependencies: + '@babel/runtime': 7.24.0 + '@types/base16': 1.0.5 + '@types/lodash': 4.17.16 base16: 1.0.0 + color: 3.2.1 + csstype: 3.1.1 lodash.curry: 4.1.1 - lodash.flow: 3.5.0 - pure-color: 1.3.0 react-colorful@5.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: @@ -31409,7 +31363,7 @@ snapshots: react-email-editor@1.7.11(react@18.2.0): dependencies: react: 18.2.0 - unlayer-types: 1.261.0 + unlayer-types: 1.263.0 react-error-overlay@6.0.9: {} @@ -31572,6 +31526,15 @@ snapshots: transitivePeerDependencies: - '@types/react' + react-textarea-autosize@8.5.9(@types/react@17.0.52)(react@18.2.0): + dependencies: + '@babel/runtime': 7.24.0 + react: 18.2.0 + use-composed-ref: 1.3.0(react@18.2.0) + use-latest: 1.2.1(@types/react@17.0.52)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + react-toastify@8.2.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: clsx: 1.2.1 @@ -32216,8 +32179,6 @@ snapshots: is-plain-object: 2.0.4 split-string: 3.1.0 - setimmediate@1.0.5: {} - setprototypeof@1.2.0: {} sha.js@2.4.11: @@ -32285,6 +32246,10 @@ snapshots: simple-concat@1.0.1: {} + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + simple-update-notifier@1.1.0: dependencies: semver: 7.0.0 @@ -33420,8 +33385,6 @@ snapshots: dependencies: typewise-core: 1.2.0 - ua-parser-js@0.7.32: {} - uc.micro@1.0.6: {} uglify-js@3.19.3: {} @@ -33531,7 +33494,7 @@ snapshots: universalify@2.0.0: {} - unlayer-types@1.261.0: {} + unlayer-types@1.263.0: {} unpipe@1.0.0: {}