@profullstack/threatcrush 0.1.10 → 0.1.12
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/README.md +10 -0
- package/dist/index.js +114 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +130 -4
package/README.md
CHANGED
|
@@ -134,6 +134,16 @@ Pay once, access forever. All core modules, CLI, daemon, API, and lifetime updat
|
|
|
134
134
|
|
|
135
135
|
👉 [Get lifetime access at threatcrush.com](https://threatcrush.com)
|
|
136
136
|
|
|
137
|
+
## Browser Extension
|
|
138
|
+
|
|
139
|
+
Monitor security from your browser:
|
|
140
|
+
|
|
141
|
+
- **Chrome** — Chrome Web Store (coming soon)
|
|
142
|
+
- **Firefox** — Firefox Add-ons (coming soon)
|
|
143
|
+
- **Safari** — Coming soon
|
|
144
|
+
|
|
145
|
+
Features: scan any site, real-time alerts, security headers check, dashboard popup.
|
|
146
|
+
|
|
137
147
|
## Links
|
|
138
148
|
|
|
139
149
|
- 🌐 **Website:** [threatcrush.com](https://threatcrush.com)
|
package/dist/index.js
CHANGED
|
@@ -3843,6 +3843,7 @@ var import_readline = __toESM(require("readline"));
|
|
|
3843
3843
|
var import_node_child_process = require("child_process");
|
|
3844
3844
|
var import_node_fs = require("fs");
|
|
3845
3845
|
var import_node_path = require("path");
|
|
3846
|
+
var import_node_os2 = require("os");
|
|
3846
3847
|
var PKG_VERSION = "0.1.8";
|
|
3847
3848
|
try {
|
|
3848
3849
|
const pkg = JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.join)(__dirname, "..", "package.json"), "utf-8"));
|
|
@@ -4064,9 +4065,121 @@ program2.command("remove").description("Uninstall ThreatCrush CLI completely").a
|
|
|
4064
4065
|
program2.command("modules").description("Manage security modules").argument("[action]", "list | install | remove | available | update").argument("[name]", "module name").action(async () => {
|
|
4065
4066
|
await emailGate();
|
|
4066
4067
|
});
|
|
4067
|
-
program2.command("store").description("Browse the module marketplace").
|
|
4068
|
+
var storeCmd = program2.command("store").description("Browse the module marketplace").action(async () => {
|
|
4068
4069
|
await emailGate();
|
|
4069
4070
|
});
|
|
4071
|
+
storeCmd.command("search <query>").description("Search for modules in the store").action(async () => {
|
|
4072
|
+
await emailGate();
|
|
4073
|
+
});
|
|
4074
|
+
storeCmd.command("publish <url>").description("Publish a module from a git URL or web URL").action(async (url) => {
|
|
4075
|
+
console.log(LOGO);
|
|
4076
|
+
const configPath = (0, import_node_path.join)((0, import_node_os2.homedir)(), ".threatcrush", "config.json");
|
|
4077
|
+
let email = "";
|
|
4078
|
+
try {
|
|
4079
|
+
const config = JSON.parse((0, import_node_fs.readFileSync)(configPath, "utf-8"));
|
|
4080
|
+
email = config.email || "";
|
|
4081
|
+
} catch {
|
|
4082
|
+
}
|
|
4083
|
+
if (!email) {
|
|
4084
|
+
const rl2 = import_readline.default.createInterface({ input: process.stdin, output: process.stdout });
|
|
4085
|
+
email = await new Promise((resolve) => {
|
|
4086
|
+
rl2.question(source_default.green(" Enter your email: "), (answer) => {
|
|
4087
|
+
rl2.close();
|
|
4088
|
+
resolve(answer.trim());
|
|
4089
|
+
});
|
|
4090
|
+
});
|
|
4091
|
+
if (!email || !email.includes("@")) {
|
|
4092
|
+
console.log(source_default.red("\n Invalid email.\n"));
|
|
4093
|
+
return;
|
|
4094
|
+
}
|
|
4095
|
+
try {
|
|
4096
|
+
const dir = (0, import_node_path.join)((0, import_node_os2.homedir)(), ".threatcrush");
|
|
4097
|
+
if (!(0, import_node_fs.existsSync)(dir)) (0, import_node_fs.mkdirSync)(dir, { recursive: true });
|
|
4098
|
+
(0, import_node_fs.writeFileSync)(configPath, JSON.stringify({ email }, null, 2));
|
|
4099
|
+
console.log(source_default.dim(` Saved email to ${configPath}`));
|
|
4100
|
+
} catch {
|
|
4101
|
+
}
|
|
4102
|
+
}
|
|
4103
|
+
console.log(source_default.dim(`
|
|
4104
|
+
Fetching metadata from ${url}...
|
|
4105
|
+
`));
|
|
4106
|
+
let meta;
|
|
4107
|
+
try {
|
|
4108
|
+
const res = await fetch(`${API_URL}/api/modules/fetch-meta`, {
|
|
4109
|
+
method: "POST",
|
|
4110
|
+
headers: { "Content-Type": "application/json" },
|
|
4111
|
+
body: JSON.stringify({ url, git_url: url })
|
|
4112
|
+
});
|
|
4113
|
+
if (!res.ok) {
|
|
4114
|
+
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
4115
|
+
console.log(source_default.red(` \u2717 Failed to fetch metadata: ${err.error}
|
|
4116
|
+
`));
|
|
4117
|
+
return;
|
|
4118
|
+
}
|
|
4119
|
+
meta = await res.json();
|
|
4120
|
+
} catch (err) {
|
|
4121
|
+
console.log(source_default.red(` \u2717 Failed to fetch metadata: ${err instanceof Error ? err.message : err}
|
|
4122
|
+
`));
|
|
4123
|
+
return;
|
|
4124
|
+
}
|
|
4125
|
+
console.log(source_default.green(" \u2500\u2500 Module Preview \u2500\u2500\n"));
|
|
4126
|
+
console.log(` ${source_default.bold("Name:")} ${meta.name || source_default.dim("(none)")}`);
|
|
4127
|
+
console.log(` ${source_default.bold("Display:")} ${meta.display_name || source_default.dim("(none)")}`);
|
|
4128
|
+
console.log(` ${source_default.bold("Description:")} ${meta.description || source_default.dim("(none)")}`);
|
|
4129
|
+
console.log(` ${source_default.bold("Version:")} ${meta.version || "0.1.0"}`);
|
|
4130
|
+
console.log(` ${source_default.bold("License:")} ${meta.license || "MIT"}`);
|
|
4131
|
+
console.log(` ${source_default.bold("Author:")} ${meta.author_name || source_default.dim("(none)")}`);
|
|
4132
|
+
console.log(` ${source_default.bold("Homepage:")} ${meta.homepage_url || source_default.dim("(none)")}`);
|
|
4133
|
+
console.log(` ${source_default.bold("Git:")} ${meta.git_url || url}`);
|
|
4134
|
+
if (Array.isArray(meta.tags) && meta.tags.length > 0) {
|
|
4135
|
+
console.log(` ${source_default.bold("Tags:")} ${meta.tags.join(", ")}`);
|
|
4136
|
+
}
|
|
4137
|
+
if (meta.stars) {
|
|
4138
|
+
console.log(` ${source_default.bold("Stars:")} \u2B50 ${meta.stars}`);
|
|
4139
|
+
}
|
|
4140
|
+
console.log();
|
|
4141
|
+
const rl = import_readline.default.createInterface({ input: process.stdin, output: process.stdout });
|
|
4142
|
+
const confirm = await new Promise((resolve) => {
|
|
4143
|
+
rl.question(source_default.yellow(" Publish this module? (y/N): "), (answer) => {
|
|
4144
|
+
rl.close();
|
|
4145
|
+
resolve(answer.trim().toLowerCase());
|
|
4146
|
+
});
|
|
4147
|
+
});
|
|
4148
|
+
if (confirm !== "y" && confirm !== "yes") {
|
|
4149
|
+
console.log(source_default.dim("\n Cancelled.\n"));
|
|
4150
|
+
return;
|
|
4151
|
+
}
|
|
4152
|
+
console.log(source_default.dim("\n Publishing..."));
|
|
4153
|
+
try {
|
|
4154
|
+
const res = await fetch(`${API_URL}/api/modules`, {
|
|
4155
|
+
method: "POST",
|
|
4156
|
+
headers: { "Content-Type": "application/json" },
|
|
4157
|
+
body: JSON.stringify({
|
|
4158
|
+
...meta,
|
|
4159
|
+
author_email: email,
|
|
4160
|
+
git_url: meta.git_url || url,
|
|
4161
|
+
homepage_url: meta.homepage_url || url
|
|
4162
|
+
})
|
|
4163
|
+
});
|
|
4164
|
+
const result = await res.json();
|
|
4165
|
+
if (!res.ok) {
|
|
4166
|
+
console.log(source_default.red(`
|
|
4167
|
+
\u2717 Publish failed: ${result.error}
|
|
4168
|
+
`));
|
|
4169
|
+
return;
|
|
4170
|
+
}
|
|
4171
|
+
const mod = result.module;
|
|
4172
|
+
const slug = mod?.slug || meta.name;
|
|
4173
|
+
console.log(source_default.green(`
|
|
4174
|
+
\u2713 Module published!`));
|
|
4175
|
+
console.log(source_default.dim(` ${API_URL}/store/${slug}
|
|
4176
|
+
`));
|
|
4177
|
+
} catch (err) {
|
|
4178
|
+
console.log(source_default.red(`
|
|
4179
|
+
\u2717 Publish failed: ${err instanceof Error ? err.message : err}
|
|
4180
|
+
`));
|
|
4181
|
+
}
|
|
4182
|
+
});
|
|
4070
4183
|
program2.action(() => {
|
|
4071
4184
|
console.log(LOGO);
|
|
4072
4185
|
program2.help();
|