@nodatachat/guard 2.0.0 → 2.1.0

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/LICENSE.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # NoData Guard License
2
2
 
3
- Copyright (c) 2026 NoDataChat Ltd. All rights reserved.
3
+ Copyright (c) 2026 Capsule Ltd. All rights reserved.
4
4
 
5
5
  ## Terms
6
6
 
7
- This software is proprietary. You may use it under the terms of your NoDataChat subscription agreement.
7
+ This software is proprietary. You may use it under the terms of your Capsule subscription agreement.
8
8
 
9
9
  ### Permitted Uses
10
10
  - Running scans on your own projects with a valid license key
@@ -19,10 +19,10 @@ This software is proprietary. You may use it under the terms of your NoDataChat
19
19
 
20
20
  ### Data Privacy
21
21
  - Guard runs locally on your machine
22
- - Source code is never uploaded to NoDataChat servers
22
+ - Source code is never uploaded to Capsule servers
23
23
  - Only metadata reports (table names, counts, scores) are transmitted
24
24
  - You can opt out of metadata transmission with --skip-send
25
25
 
26
- For the full license agreement, visit: https://nodatachat.com/legal/guard-license
26
+ For the full license agreement, visit: https://nodatacapsule.com/legal/guard-license
27
27
 
28
- Contact: legal@nodatachat.com
28
+ Contact: legal@nodatacapsule.com
package/README.md CHANGED
@@ -79,7 +79,7 @@ npx nodata-guard --license-key $NDC_LICENSE --ci --fail-on critical
79
79
 
80
80
  ## Dashboard
81
81
 
82
- After running Guard, log in at [nodatachat.com/guard](https://nodatachat.com/guard) with your license key to see:
82
+ After running Guard, log in at [nodatacapsule.com/guard](https://nodatacapsule.com/guard) with your license key to see:
83
83
 
84
84
  - Score trends over time
85
85
  - Scan history with comparison
@@ -114,7 +114,7 @@ Proprietary — see [LICENSE.md](LICENSE.md)
114
114
 
115
115
  ## Links
116
116
 
117
- - [Website](https://nodatachat.com)
118
- - [Guard Dashboard](https://nodatachat.com/guard)
119
- - [Getting Started](https://nodatachat.com/guard/onboarding)
120
- - [Pricing](https://nodatachat.com/pricing)
117
+ - [Website](https://nodatacapsule.com)
118
+ - [Guard Dashboard](https://nodatacapsule.com/guard)
119
+ - [Getting Started](https://nodatacapsule.com/guard/onboarding)
120
+ - [Pricing](https://nodatacapsule.com/pricing)
@@ -18,7 +18,7 @@ const crypto_1 = require("crypto");
18
18
  const fs_1 = require("fs");
19
19
  const path_1 = require("path");
20
20
  const GUARD_VERSION = "2.0.0";
21
- const API_BASE = process.env.GUARD_API_BASE || "https://nodatachat.com/api/guard";
21
+ const API_BASE = process.env.GUARD_API_BASE || "https://nodatacapsule.com/api/guard";
22
22
  // Dev license keys that work without server (for development and demos)
23
23
  const DEV_LICENSES = new Set(["NDC-DEV", "NDC-DEMO", "NDC-TEST"]);
24
24
  // ── Project fingerprint (directory structure only, no file contents) ──
package/dist/cli.js CHANGED
@@ -87,12 +87,44 @@ async function main() {
87
87
  }
88
88
  // Env fallbacks
89
89
  if (!licenseKey)
90
- licenseKey = process.env.NDC_LICENSE || process.env.NODATA_LICENSE_KEY;
90
+ licenseKey = process.env.NDC_LICENSE || process.env.NODATA_LICENSE_KEY || process.env.NODATA_API_KEY || process.env.NDC_API_KEY;
91
91
  if (!dbUrl)
92
92
  dbUrl = process.env.DATABASE_URL;
93
+ // Shared Protect config fallback (~/.nodata/config.json)
93
94
  if (!licenseKey) {
94
- console.error("\n Error: --license-key required (or set NDC_LICENSE env var)\n");
95
- printHelp();
95
+ try {
96
+ const home = process.env.HOME || process.env.USERPROFILE || "";
97
+ const configPath = require("path").join(home, ".nodata", "config.json");
98
+ if (require("fs").existsSync(configPath)) {
99
+ const config = JSON.parse(require("fs").readFileSync(configPath, "utf-8"));
100
+ if (config.api_key) {
101
+ licenseKey = config.api_key;
102
+ console.log(`\n \x1b[32m✓\x1b[0m Using API key from NoData Protect (~/.nodata/config.json)\n`);
103
+ }
104
+ }
105
+ }
106
+ catch { /* ignore */ }
107
+ }
108
+ // Capsule config fallback (.capsule.json)
109
+ if (!licenseKey) {
110
+ try {
111
+ const capsulePath = require("path").join(projectDir, ".capsule.json");
112
+ if (require("fs").existsSync(capsulePath)) {
113
+ const config = JSON.parse(require("fs").readFileSync(capsulePath, "utf-8"));
114
+ if (config.licenseKey) {
115
+ licenseKey = config.licenseKey;
116
+ console.log(`\n \x1b[32m✓\x1b[0m Using API key from Capsule config (.capsule.json)\n`);
117
+ }
118
+ }
119
+ }
120
+ catch { /* ignore */ }
121
+ }
122
+ if (!licenseKey) {
123
+ console.error("\n \x1b[31m✗\x1b[0m No API key found.\n");
124
+ console.error(" Options:");
125
+ console.error(" 1. Run \x1b[36mnpx @nodatachat/protect init\x1b[0m first (creates key automatically)");
126
+ console.error(" 2. Pass \x1b[36m--license-key YOUR_KEY\x1b[0m");
127
+ console.error(" 3. Set \x1b[36mNDC_LICENSE=YOUR_KEY\x1b[0m in environment\n");
96
128
  process.exit(1);
97
129
  }
98
130
  // ── Schedule setup (no scan needed) ──
@@ -204,12 +236,13 @@ async function main() {
204
236
  if (!skipSend) {
205
237
  log(ciMode, "Sending metadata to NoData...");
206
238
  try {
207
- const res = await fetch("https://nodatachat.com/api/guard/report", {
239
+ const res = await fetch("https://nodatacapsule.com/api/guard/report", {
208
240
  method: "POST",
209
241
  headers: {
210
242
  "Content-Type": "application/json",
211
243
  "X-Scan-Id": activation.scan_id,
212
244
  "X-Activation-Key": activation.activation_key,
245
+ "X-License-Key": licenseKey || "",
213
246
  },
214
247
  body: JSON.stringify(metadata),
215
248
  signal: AbortSignal.timeout(10000),
@@ -449,7 +482,7 @@ function printHelp() {
449
482
  # CI pipeline
450
483
  npx nodata-guard --ci --fail-on critical
451
484
 
452
- Documentation: https://nodatachat.com/guard
485
+ Documentation: https://nodatacapsule.com/guard
453
486
  `);
454
487
  }
455
488
  main().catch((err) => {
@@ -156,7 +156,7 @@ async function sendNotifications(config, event, payload, onLog) {
156
156
  if (config.notify.email?.length) {
157
157
  for (const email of config.notify.email) {
158
158
  try {
159
- await fetch("https://nodatachat.com/api/guard/notify", {
159
+ await fetch("https://nodatacapsule.com/api/guard/notify", {
160
160
  method: "POST",
161
161
  headers: { "Content-Type": "application/json" },
162
162
  body: JSON.stringify({ channel: "email", to: email, payload }),
package/dist/reporter.js CHANGED
@@ -125,6 +125,33 @@ function generateReports(input) {
125
125
  medium: medSecrets,
126
126
  fixes_available: plaintextPII, // each plaintext field has a migration fix
127
127
  },
128
+ // Fix suggestions — safe to send (just recommendation text, no code/values)
129
+ findings: [
130
+ ...allPII.filter(f => !f.encrypted).map(f => ({
131
+ severity: "high",
132
+ category: "pii",
133
+ rule_id: `PII_${f.pii_type.toUpperCase()}`,
134
+ title: `${f.table}.${f.column} — ${f.pii_type} stored in plaintext`,
135
+ fix_suggestion: `Add AES-256-GCM encryption to ${f.table}.${f.column} via Capsule field permissions`,
136
+ soc_control: "CC6.7",
137
+ })),
138
+ ...(input.code?.secrets.filter(s => !s.is_env_interpolated) || []).map(s => ({
139
+ severity: s.severity,
140
+ category: "secrets",
141
+ rule_id: `SECRET_${s.type.toUpperCase().replace(/-/g, "_")}`,
142
+ title: `Hardcoded ${s.type} in ${s.file}:${s.line}`,
143
+ fix_suggestion: `Move to .env and encrypt with @nodatachat/protect`,
144
+ soc_control: "CC6.1",
145
+ })),
146
+ ...(input.code?.routes.filter(r => !r.has_auth) || []).slice(0, 20).map(r => ({
147
+ severity: "high",
148
+ category: "auth",
149
+ rule_id: "ROUTE_NO_AUTH",
150
+ title: `Unprotected route: ${r.path}`,
151
+ fix_suggestion: `Add authentication middleware (withAuth or API key check)`,
152
+ soc_control: "CC6.3",
153
+ })),
154
+ ],
128
155
  proof_hash: proofHash,
129
156
  privacy: {
130
157
  contains_data_values: false,
package/dist/types.d.ts CHANGED
@@ -142,6 +142,14 @@ export interface MetadataReport {
142
142
  medium: number;
143
143
  fixes_available: number;
144
144
  };
145
+ findings: Array<{
146
+ severity: "critical" | "high" | "medium" | "low";
147
+ category: string;
148
+ rule_id: string;
149
+ title: string;
150
+ fix_suggestion: string;
151
+ soc_control: string;
152
+ }>;
145
153
  proof_hash: string;
146
154
  privacy: {
147
155
  contains_data_values: false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodatachat/guard",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "NoData Guard — continuous security scanner. Runs locally, reports only metadata. Your data never leaves your machine.",
5
5
  "main": "./dist/cli.js",
6
6
  "types": "./dist/cli.d.ts",
@@ -49,7 +49,7 @@
49
49
  "devsecops"
50
50
  ],
51
51
  "license": "SEE LICENSE IN LICENSE.md",
52
- "homepage": "https://nodatachat.com/guard",
52
+ "homepage": "https://nodatacapsule.com/guard",
53
53
  "repository": {
54
54
  "type": "git",
55
55
  "url": "https://github.com/nodatachat/guard"
@@ -57,5 +57,5 @@
57
57
  "bugs": {
58
58
  "url": "https://github.com/nodatachat/guard/issues"
59
59
  },
60
- "author": "NoDataChat <support@nodatachat.com>"
60
+ "author": "Capsule <support@nodatacapsule.com>"
61
61
  }