dh-remixer-sdk 0.0.32-bcfeba4 → 0.0.32
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/package.json +1 -1
- package/scripts/sdk-update/index.mjs +0 -3
- package/templates/base/filemap.json +1 -2
- package/templates/base/package.json +0 -1
- package/templates/base/vite.config.ts +22 -3
- package/scripts/sdk-update/manual-unlocked-file-update.mjs +0 -21
- package/templates/base/security/semgrep-build-guard.yml +0 -118
package/package.json
CHANGED
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
} from "./fs-utils.mjs";
|
|
11
11
|
import { getDeletionList, getExtractionList } from "./sdk-utils.mjs";
|
|
12
12
|
import { PROJECT_ROOT } from "./vars.mjs";
|
|
13
|
-
import { manualUnlockedFileUpdate } from "./manual-unlocked-file-update.mjs";
|
|
14
13
|
|
|
15
14
|
async function main() {
|
|
16
15
|
const targetPackageJson = await getTargetPackageJson();
|
|
@@ -35,8 +34,6 @@ async function main() {
|
|
|
35
34
|
const deletionList = await getDeletionList(templateType);
|
|
36
35
|
const extractionList = await getExtractionList(templateType);
|
|
37
36
|
|
|
38
|
-
await manualUnlockedFileUpdate();
|
|
39
|
-
|
|
40
37
|
// Delete old files
|
|
41
38
|
await Promise.all(
|
|
42
39
|
deletionList.map((relativePath) =>
|
|
@@ -20,6 +20,5 @@
|
|
|
20
20
|
"remixer/forms.ts": "lib/remixer/forms.ts",
|
|
21
21
|
"remixer/runtime.ts": "lib/remixer/runtime.ts",
|
|
22
22
|
"remixer/storage.ts": "lib/remixer/storage.ts",
|
|
23
|
-
"remixer/supabase.ts": "lib/remixer/supabase.ts"
|
|
24
|
-
"security/semgrep-build-guard.yml": "security/semgrep-build-guard.yml"
|
|
23
|
+
"remixer/supabase.ts": "lib/remixer/supabase.ts"
|
|
25
24
|
}
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
"start": "vite preview --host 0.0.0.0 --mode production --port ${PORT:-4173}",
|
|
9
9
|
"dev": "vite --host 0.0.0.0 --port ${PORT:-4173} --mode development",
|
|
10
10
|
"lint": "echo 'Linting not implemented!'",
|
|
11
|
-
"security-check": "semgrep --config security/semgrep-build-guard.yml --error .",
|
|
12
11
|
"remixer-sdk:update": "bun install dh-remixer-sdk@${REMIXER_SDK_TAG:-latest} && sdk-update"
|
|
13
12
|
},
|
|
14
13
|
"dependencies": {
|
|
@@ -2,14 +2,33 @@ import { defineConfig, Plugin } from "vite";
|
|
|
2
2
|
import react from "@vitejs/plugin-react";
|
|
3
3
|
import tailwindcss from "tailwindcss";
|
|
4
4
|
import autoprefixer from "autoprefixer";
|
|
5
|
-
import tailwindConfig from "./tailwind.config.
|
|
5
|
+
import tailwindConfig from "./tailwind.config.ts";
|
|
6
6
|
import path from "path";
|
|
7
|
+
import { execSync } from "node:child_process";
|
|
7
8
|
|
|
8
9
|
const PREVIEW_DOMAINS = [
|
|
9
10
|
'.remixer.ai',
|
|
10
11
|
'.dreamhosters.ai',
|
|
11
12
|
];
|
|
12
13
|
|
|
14
|
+
function ssgPostbuild(): Plugin {
|
|
15
|
+
let config;
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
name: "ssg-postbuild",
|
|
19
|
+
|
|
20
|
+
configResolved(resolvedConfig) {
|
|
21
|
+
config = resolvedConfig;
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
writeBundle() {
|
|
25
|
+
execSync(`BUILD_DIR=${config.build.outDir} npx ssg-helmet`, {
|
|
26
|
+
stdio: "inherit",
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
13
32
|
function injectRemixerMetaTagPlugin(): Plugin {
|
|
14
33
|
return {
|
|
15
34
|
name: "vite-plugin-inject-remixer-meta-tag",
|
|
@@ -28,13 +47,12 @@ function injectRemixerBadgePlugin(): Plugin {
|
|
|
28
47
|
|
|
29
48
|
transformIndexHtml(html) {
|
|
30
49
|
try {
|
|
31
|
-
const IS_SHOW_REMIXER_BADGE = process.env.IS_SHOW_REMIXER_BADGE === 'true';
|
|
32
50
|
const REMIXER_BADGE_TYPE: string = process.env.REMIXER_BADGE_TYPE || 'DEFAULT';
|
|
33
51
|
|
|
34
52
|
const domain = process.env.NEXT_PUBLIC_DOMAIN || '';
|
|
35
53
|
const isPreviewService = PREVIEW_DOMAINS.some(pd => domain.endsWith(pd));
|
|
36
54
|
|
|
37
|
-
if (!
|
|
55
|
+
if (!isPreviewService) return html
|
|
38
56
|
|
|
39
57
|
const DICTIONARY: Record<string, string> = {
|
|
40
58
|
UPGRADE_PLAN: 'https://unpkg.com/dh-remixer-badge@latest/dist/upgradeBadge.js',
|
|
@@ -184,6 +202,7 @@ export default defineConfig({
|
|
|
184
202
|
tailwindProdPlugin(),
|
|
185
203
|
react(),
|
|
186
204
|
injectRemixerMetaTagPlugin(),
|
|
205
|
+
// ssgPostbuild()
|
|
187
206
|
],
|
|
188
207
|
resolve: {
|
|
189
208
|
alias: {
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import fs from "node:fs/promises";
|
|
3
|
-
|
|
4
|
-
export async function manualUnlockedFileUpdate() {
|
|
5
|
-
const projectRoot = path.resolve(process.env.INIT_CWD ?? process.cwd());
|
|
6
|
-
const tailwindTsPath = path.join(projectRoot, "tailwind.config.ts");
|
|
7
|
-
const tailwindJsonPath = path.join(projectRoot, "tailwind.config.json");
|
|
8
|
-
const tailwindTs = await fs.readFile(tailwindTsPath, "utf8");
|
|
9
|
-
|
|
10
|
-
if (!tailwindTs) return;
|
|
11
|
-
|
|
12
|
-
const match = tailwindTs.match(/\{[\s\S]*\}/);
|
|
13
|
-
const extracted = match ? match[0] : null;
|
|
14
|
-
|
|
15
|
-
if (!extracted) return;
|
|
16
|
-
|
|
17
|
-
const obj = new Function(`return (${extracted})`)();
|
|
18
|
-
|
|
19
|
-
await fs.writeFile(tailwindJsonPath, JSON.stringify(obj, null, 2), "utf8");
|
|
20
|
-
await fs.unlink(tailwindTsPath);
|
|
21
|
-
}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
# Semgrep ruleset — build-time credential-exfiltration tripwires.
|
|
2
|
-
#
|
|
3
|
-
# Run from the project root, before `bun install` / `vite build`:
|
|
4
|
-
# semgrep --config security/semgrep-build-guard.yml --error .
|
|
5
|
-
#
|
|
6
|
-
# These rules are a pre-build GATE, not a guarantee — static analysis is
|
|
7
|
-
# evadable by obfuscation. Pair with the runtime controls in security/README.md
|
|
8
|
-
# (no ambient AWS creds, IMDS disabled, blocked link-local egress).
|
|
9
|
-
|
|
10
|
-
rules:
|
|
11
|
-
- id: shell-exec-in-build-config
|
|
12
|
-
languages: [typescript, javascript]
|
|
13
|
-
severity: ERROR
|
|
14
|
-
message: >
|
|
15
|
-
Shell / child_process execution found in a build config file. Config files
|
|
16
|
-
are executed by Node at build time and must never spawn processes.
|
|
17
|
-
paths:
|
|
18
|
-
include:
|
|
19
|
-
- "*.config.*"
|
|
20
|
-
- "*.config"
|
|
21
|
-
- ".*rc"
|
|
22
|
-
- ".*rc.*"
|
|
23
|
-
- "vite.config.*"
|
|
24
|
-
- "tailwind.config.*"
|
|
25
|
-
- "postcss.config.*"
|
|
26
|
-
exclude: &trusted_paths
|
|
27
|
-
# Locked, operator-authored files (enforced by the platform's
|
|
28
|
-
# filemap.json lock model) and this ruleset itself. Scanning them yields
|
|
29
|
-
# only false positives. Semgrep targets the USER-WRITABLE surface only.
|
|
30
|
-
- "vite.config.ts"
|
|
31
|
-
- "security/"
|
|
32
|
-
patterns:
|
|
33
|
-
- pattern-either:
|
|
34
|
-
- pattern: require('child_process')
|
|
35
|
-
- pattern: require("child_process")
|
|
36
|
-
- pattern: import 'child_process'
|
|
37
|
-
- pattern: import "child_process"
|
|
38
|
-
- pattern: import 'node:child_process'
|
|
39
|
-
- pattern: import "node:child_process"
|
|
40
|
-
- pattern: $X.execSync(...)
|
|
41
|
-
- pattern: $X.exec(...)
|
|
42
|
-
- pattern: $X.execFileSync(...)
|
|
43
|
-
- pattern: $X.spawnSync(...)
|
|
44
|
-
- pattern: $X.spawn(...)
|
|
45
|
-
|
|
46
|
-
- id: network-call-in-build-config
|
|
47
|
-
languages: [typescript, javascript]
|
|
48
|
-
severity: ERROR
|
|
49
|
-
message: >
|
|
50
|
-
Outbound network call (fetch/http/https/net) found in a build config file.
|
|
51
|
-
A build config has no legitimate reason to make network requests.
|
|
52
|
-
paths:
|
|
53
|
-
include:
|
|
54
|
-
- "*.config.*"
|
|
55
|
-
- "vite.config.*"
|
|
56
|
-
- "tailwind.config.*"
|
|
57
|
-
- "postcss.config.*"
|
|
58
|
-
exclude: *trusted_paths
|
|
59
|
-
patterns:
|
|
60
|
-
- pattern-either:
|
|
61
|
-
- pattern: fetch(...)
|
|
62
|
-
- pattern: require('http')
|
|
63
|
-
- pattern: require('https')
|
|
64
|
-
- pattern: require('net')
|
|
65
|
-
- pattern: require('dgram')
|
|
66
|
-
- pattern: import 'node:http'
|
|
67
|
-
- pattern: import 'node:https'
|
|
68
|
-
- pattern: import 'node:net'
|
|
69
|
-
|
|
70
|
-
- id: credential-path-or-imds-access
|
|
71
|
-
languages: [typescript, javascript]
|
|
72
|
-
severity: ERROR
|
|
73
|
-
message: >
|
|
74
|
-
Reference to AWS credential material (IMDS, container-credential endpoint,
|
|
75
|
-
~/.aws, or AWS_* container creds env). This is a credential-exfiltration
|
|
76
|
-
signature.
|
|
77
|
-
paths:
|
|
78
|
-
exclude: *trusted_paths
|
|
79
|
-
patterns:
|
|
80
|
-
- pattern-either:
|
|
81
|
-
- pattern-regex: "169\\.254\\.169\\.254"
|
|
82
|
-
- pattern-regex: "169\\.254\\.170\\.2"
|
|
83
|
-
- pattern-regex: "AWS_CONTAINER_CREDENTIALS"
|
|
84
|
-
- pattern-regex: "\\.aws/credentials"
|
|
85
|
-
- pattern-regex: "security-credentials"
|
|
86
|
-
|
|
87
|
-
- id: filesystem-read-in-build-config
|
|
88
|
-
languages: [typescript, javascript]
|
|
89
|
-
severity: WARNING
|
|
90
|
-
message: >
|
|
91
|
-
Filesystem read in a build config file. Verify it only reads project
|
|
92
|
-
assets and never credential/secret paths.
|
|
93
|
-
paths:
|
|
94
|
-
include:
|
|
95
|
-
- "*.config.*"
|
|
96
|
-
- "vite.config.*"
|
|
97
|
-
- "tailwind.config.*"
|
|
98
|
-
- "postcss.config.*"
|
|
99
|
-
exclude: *trusted_paths
|
|
100
|
-
patterns:
|
|
101
|
-
- pattern-either:
|
|
102
|
-
- pattern: $FS.readFileSync(...)
|
|
103
|
-
- pattern: $FS.readFile(...)
|
|
104
|
-
- pattern: require('fs')
|
|
105
|
-
- pattern: import 'node:fs'
|
|
106
|
-
|
|
107
|
-
- id: dynamic-code-eval
|
|
108
|
-
languages: [typescript, javascript]
|
|
109
|
-
severity: ERROR
|
|
110
|
-
message: >
|
|
111
|
-
Dynamic code evaluation (eval / Function constructor / dynamic require of a
|
|
112
|
-
computed name). Common obfuscation for build-time RCE.
|
|
113
|
-
paths:
|
|
114
|
-
exclude: *trusted_paths
|
|
115
|
-
patterns:
|
|
116
|
-
- pattern-either:
|
|
117
|
-
- pattern: eval(...)
|
|
118
|
-
- pattern: new Function(...)
|