@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 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").argument("[action]", "search | info | publish").argument("[query]", "search query or module name").action(async () => {
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();