contrastapi 1.0.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.
Files changed (4) hide show
  1. package/README.md +126 -0
  2. package/index.d.ts +62 -0
  3. package/index.js +196 -0
  4. package/package.json +35 -0
package/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # ContrastAPI Node.js SDK
2
+
3
+ Official Node.js SDK for [ContrastAPI](https://api.contrastcyber.com) — security intelligence for developers and AI agents.
4
+
5
+ Zero dependencies. Works with Node.js 14+.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install contrastapi
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```javascript
16
+ const ContrastAPI = require("contrastapi");
17
+ const api = ContrastAPI();
18
+
19
+ async function main() {
20
+ // Domain intelligence
21
+ const report = await api.domain.report("example.com");
22
+
23
+ // CVE lookup
24
+ const cve = await api.cve.lookup("CVE-2024-3094");
25
+
26
+ // SSL certificate check
27
+ const ssl = await api.domain.ssl("example.com");
28
+
29
+ // Scan HTTP security headers (live)
30
+ const headers = await api.scan.headers("example.com");
31
+
32
+ // Check code for secrets
33
+ const secrets = await api.check.secrets("const key = 'AKIA...'", "javascript");
34
+ }
35
+
36
+ main();
37
+ ```
38
+
39
+ ## With API Key (Pro)
40
+
41
+ ```javascript
42
+ const api = ContrastAPI({ apiKey: "your-api-key" });
43
+ ```
44
+
45
+ ## All Methods
46
+
47
+ ### Domain Intelligence
48
+ ```javascript
49
+ api.domain.report("example.com") // Full domain report
50
+ api.domain.report("example.com", {lite: true}) // Fast lite report
51
+ api.domain.dns("example.com") // DNS records
52
+ api.domain.whois("example.com") // WHOIS data
53
+ api.domain.subdomains("example.com") // Subdomain enumeration
54
+ api.domain.certs("example.com") // Certificate transparency
55
+ api.domain.ssl("example.com") // SSL/TLS analysis
56
+ api.domain.tech("example.com") // Technology fingerprint
57
+ api.domain.threat("example.com") // Threat intelligence
58
+ api.domain.monitor("example.com") // Domain monitoring
59
+ api.domain.vulns("example.com") // Known vulnerabilities
60
+ api.domain.bulk(["a.com", "b.com"]) // Bulk domain reports
61
+ ```
62
+
63
+ ### IP & ASN
64
+ ```javascript
65
+ api.ip.lookup("8.8.8.8") // IP intelligence
66
+ api.asn.lookup("google.com") // ASN lookup
67
+ ```
68
+
69
+ ### CVE Intelligence
70
+ ```javascript
71
+ api.cve.lookup("CVE-2024-3094") // Single CVE
72
+ api.cve.search({product: "apache", severity: "critical"})
73
+ api.cve.recent() // Recently published
74
+ api.cve.kev() // Known exploited (CISA KEV)
75
+ api.cve.epss("CVE-2024-3094") // EPSS score
76
+ api.cve.exploit("CVE-2024-3094") // Public exploits
77
+ ```
78
+
79
+ ### Threat Intelligence
80
+ ```javascript
81
+ api.ioc.lookup("evil.com") // IOC enrichment (auto-detect type)
82
+ api.ioc.hash("abc123...") // Malware hash lookup
83
+ api.ioc.phishing("https://evil.com/login") // Phishing check
84
+ ```
85
+
86
+ ### Email & Phone
87
+ ```javascript
88
+ api.email.mx("example.com") // MX + SPF/DMARC/DKIM
89
+ api.email.disposable("user@tempmail.com") // Disposable email check
90
+ api.phone.lookup("+1234567890") // Phone validation
91
+ ```
92
+
93
+ ### Password
94
+ ```javascript
95
+ api.password.check("5baa61e4...") // HIBP breach check (SHA1)
96
+ ```
97
+
98
+ ### Code Security
99
+ ```javascript
100
+ api.check.secrets(code, "python") // Detect hardcoded secrets
101
+ api.check.injection(code, "javascript") // SQL/command injection
102
+ api.check.headers({"Content-Security-Policy": "..."}) // Header validation
103
+ api.check.dependencies([{name: "lodash", version: "4.17.0"}]) // CVE check
104
+ api.scan.headers("example.com") // Live header scan
105
+ ```
106
+
107
+ ### Meta
108
+ ```javascript
109
+ api.status() // API health
110
+ api.usage() // Usage stats (Pro)
111
+ ```
112
+
113
+ ## Error Handling
114
+
115
+ ```javascript
116
+ try {
117
+ const result = await api.cve.lookup("CVE-9999-0000");
118
+ } catch (err) {
119
+ console.log(err.status); // 404
120
+ console.log(err.message); // "CVE not found"
121
+ }
122
+ ```
123
+
124
+ ## License
125
+
126
+ MIT
package/index.d.ts ADDED
@@ -0,0 +1,62 @@
1
+ declare function ContrastAPI(options?: {
2
+ baseUrl?: string;
3
+ apiKey?: string;
4
+ timeout?: number;
5
+ allowInsecure?: boolean;
6
+ }): {
7
+ domain: {
8
+ report(domain: string, opts?: { lite?: boolean }): Promise<any>;
9
+ dns(domain: string): Promise<any>;
10
+ whois(domain: string): Promise<any>;
11
+ subdomains(domain: string): Promise<any>;
12
+ certs(domain: string): Promise<any>;
13
+ ssl(domain: string): Promise<any>;
14
+ tech(domain: string): Promise<any>;
15
+ threat(domain: string): Promise<any>;
16
+ monitor(domain: string): Promise<any>;
17
+ vulns(domain: string): Promise<any>;
18
+ bulk(domains: string[]): Promise<any>;
19
+ };
20
+ ip: {
21
+ lookup(ip: string): Promise<any>;
22
+ };
23
+ asn: {
24
+ lookup(target: string): Promise<any>;
25
+ };
26
+ cve: {
27
+ lookup(cveId: string): Promise<any>;
28
+ search(params?: { product?: string; severity?: string; days?: number; limit?: number }): Promise<any>;
29
+ recent(params?: { hours?: number; limit?: number }): Promise<any>;
30
+ kev(params?: { limit?: number }): Promise<any>;
31
+ epss(cveId: string): Promise<any>;
32
+ exploit(cveId: string): Promise<any>;
33
+ };
34
+ ioc: {
35
+ lookup(indicator: string): Promise<any>;
36
+ hash(fileHash: string): Promise<any>;
37
+ phishing(url: string): Promise<any>;
38
+ };
39
+ email: {
40
+ mx(domain: string): Promise<any>;
41
+ disposable(email: string): Promise<any>;
42
+ };
43
+ phone: {
44
+ lookup(number: string): Promise<any>;
45
+ };
46
+ password: {
47
+ check(sha1Hash: string): Promise<any>;
48
+ };
49
+ check: {
50
+ secrets(code: string, language: string): Promise<any>;
51
+ injection(code: string, language: string): Promise<any>;
52
+ headers(headers: Record<string, string>): Promise<any>;
53
+ dependencies(packages: Array<{ name: string; version?: string }>): Promise<any>;
54
+ };
55
+ scan: {
56
+ headers(domain: string): Promise<any>;
57
+ };
58
+ status(): Promise<any>;
59
+ usage(): Promise<any>;
60
+ };
61
+
62
+ export = ContrastAPI;
package/index.js ADDED
@@ -0,0 +1,196 @@
1
+ /**
2
+ * ContrastAPI — Security Intelligence SDK
3
+ * https://api.contrastcyber.com
4
+ */
5
+
6
+ const https = require("https");
7
+ const http = require("http");
8
+
9
+ const DEFAULT_BASE = "https://api.contrastcyber.com";
10
+ const MAX_BODY = 10 * 1024 * 1024; // 10 MB
11
+ const VERSION = require("./package.json").version;
12
+
13
+ function enc(v) {
14
+ if (!v && v !== 0) throw new Error("Missing required parameter");
15
+ return encodeURIComponent(String(v));
16
+ }
17
+
18
+ function encPath(v) {
19
+ if (!v) throw new Error("Missing required parameter");
20
+ return String(v).split("/").map(encodeURIComponent).join("/");
21
+ }
22
+
23
+ function ContrastAPI(options = {}) {
24
+ const baseUrl = (options.baseUrl || DEFAULT_BASE).replace(/\/$/, "");
25
+ const apiKey = options.apiKey || null;
26
+ const timeout = Math.max(1000, Math.min(options.timeout || 30000, 120000));
27
+
28
+ if (!baseUrl.startsWith("https://") && !options.allowInsecure) {
29
+ throw new Error("Only HTTPS is allowed. Pass { allowInsecure: true } to override.");
30
+ }
31
+
32
+ function request(method, path, body) {
33
+ return new Promise((resolve, reject) => {
34
+ const url = new URL(path, baseUrl);
35
+ if (url.origin !== new URL(baseUrl).origin) {
36
+ return reject(new Error("URL origin mismatch"));
37
+ }
38
+
39
+ const headers = {
40
+ "Accept": "application/json",
41
+ "User-Agent": `contrastapi-node/${VERSION}`,
42
+ };
43
+ if (apiKey) {
44
+ if (url.protocol !== "https:") {
45
+ return reject(new Error("Refusing to send API key over insecure connection"));
46
+ }
47
+ headers["X-API-Key"] = apiKey;
48
+ }
49
+
50
+ let payload;
51
+ if (body) {
52
+ payload = JSON.stringify(body);
53
+ headers["Content-Type"] = "application/json";
54
+ headers["Content-Length"] = Buffer.byteLength(payload);
55
+ }
56
+
57
+ const mod = url.protocol === "https:" ? https : http;
58
+ const req = mod.request(url, { method, headers, timeout }, (res) => {
59
+ let data = "";
60
+ let size = 0;
61
+ res.on("data", (chunk) => {
62
+ size += chunk.length;
63
+ if (size > MAX_BODY) {
64
+ req.destroy();
65
+ return reject(new Error("Response too large"));
66
+ }
67
+ data += chunk;
68
+ });
69
+ res.on("end", () => {
70
+ try {
71
+ const json = JSON.parse(data);
72
+ if (res.statusCode >= 400) {
73
+ const err = new Error(json.detail || json.message || `HTTP ${res.statusCode}`);
74
+ err.status = res.statusCode;
75
+ reject(err);
76
+ } else {
77
+ resolve(json);
78
+ }
79
+ } catch {
80
+ reject(new Error(`Invalid JSON response (HTTP ${res.statusCode})`));
81
+ }
82
+ });
83
+ });
84
+
85
+ req.on("error", reject);
86
+ req.on("timeout", () => { req.destroy(); reject(new Error("Request timed out")); });
87
+ if (payload) req.write(payload);
88
+ req.end();
89
+ });
90
+ }
91
+
92
+ function get(path) { return request("GET", path); }
93
+ function post(path, body) { return request("POST", path, body); }
94
+
95
+ return {
96
+ // --- Domain Intelligence ---
97
+ domain: {
98
+ report: (domain, opts = {}) => get(`/v1/domain/${enc(domain)}${opts.lite ? "?lite=true" : ""}`),
99
+ dns: (domain) => get(`/v1/dns/${enc(domain)}`),
100
+ whois: (domain) => get(`/v1/whois/${enc(domain)}`),
101
+ subdomains: (domain) => get(`/v1/subdomains/${enc(domain)}`),
102
+ certs: (domain) => get(`/v1/certs/${enc(domain)}`),
103
+ ssl: (domain) => get(`/v1/ssl/${enc(domain)}`),
104
+ tech: (domain) => get(`/v1/tech/${enc(domain)}`),
105
+ threat: (domain) => get(`/v1/threat/${enc(domain)}`),
106
+ monitor: (domain) => get(`/v1/monitor/${enc(domain)}`),
107
+ vulns: (domain) => get(`/v1/domain/${enc(domain)}/vulns`),
108
+ bulk: (domains) => {
109
+ if (!Array.isArray(domains) || !domains.every(d => typeof d === "string")) {
110
+ throw new Error("domains must be an array of strings");
111
+ }
112
+ return post("/v1/domains/bulk", { domains });
113
+ },
114
+ },
115
+
116
+ // --- IP Intelligence ---
117
+ ip: {
118
+ lookup: (ip) => get(`/v1/ip/${enc(ip)}`),
119
+ },
120
+
121
+ // --- ASN ---
122
+ asn: {
123
+ lookup: (target) => get(`/v1/asn/${enc(target)}`),
124
+ },
125
+
126
+ // --- CVE Intelligence ---
127
+ cve: {
128
+ lookup: (cveId) => get(`/v1/cve/${enc(cveId)}`),
129
+ search: (params = {}) => {
130
+ const q = new URLSearchParams();
131
+ if (params.product) q.set("product", params.product);
132
+ if (params.severity) q.set("severity", params.severity);
133
+ if (params.days) q.set("days", params.days);
134
+ if (params.limit) q.set("limit", params.limit);
135
+ return get(`/v1/cves?${q}`);
136
+ },
137
+ recent: (params = {}) => {
138
+ const q = new URLSearchParams();
139
+ if (params.hours) q.set("hours", params.hours);
140
+ if (params.limit) q.set("limit", params.limit);
141
+ const qs = q.toString();
142
+ return get(`/v1/cves/recent${qs ? "?" + qs : ""}`);
143
+ },
144
+ kev: (params = {}) => {
145
+ const q = new URLSearchParams();
146
+ if (params.limit) q.set("limit", params.limit);
147
+ const qs = q.toString();
148
+ return get(`/v1/cves/kev${qs ? "?" + qs : ""}`);
149
+ },
150
+ epss: (cveId) => get(`/v1/epss/${enc(cveId)}`),
151
+ exploit: (cveId) => get(`/v1/exploit/${enc(cveId)}`),
152
+ },
153
+
154
+ // --- Threat Intelligence / IOC ---
155
+ ioc: {
156
+ lookup: (indicator) => get(`/v1/ioc/${encPath(indicator)}`),
157
+ hash: (fileHash) => get(`/v1/hash/${enc(fileHash)}`),
158
+ phishing: (url) => get(`/v1/phishing/${encPath(url)}`),
159
+ },
160
+
161
+ // --- Email ---
162
+ email: {
163
+ mx: (domain) => get(`/v1/email/mx/${enc(domain)}`),
164
+ disposable: (email) => get(`/v1/email/disposable/${enc(email)}`),
165
+ },
166
+
167
+ // --- Phone ---
168
+ phone: {
169
+ lookup: (number) => get(`/v1/phone/${enc(number)}`),
170
+ },
171
+
172
+ // --- Password ---
173
+ password: {
174
+ check: (sha1Hash) => get(`/v1/password/${enc(sha1Hash)}`),
175
+ },
176
+
177
+ // --- Code Security ---
178
+ check: {
179
+ secrets: (code, language) => post("/v1/check/secrets", { code, language }),
180
+ injection: (code, language) => post("/v1/check/injection", { code, language }),
181
+ headers: (headers) => post("/v1/check/headers", { headers }),
182
+ dependencies: (packages) => post("/v1/check/dependencies", { packages }),
183
+ },
184
+
185
+ // --- Headers (live scan) ---
186
+ scan: {
187
+ headers: (domain) => get(`/v1/scan/headers/${enc(domain)}`),
188
+ },
189
+
190
+ // --- Meta ---
191
+ status: () => get("/v1/status"),
192
+ usage: () => get("/v1/usage"),
193
+ };
194
+ }
195
+
196
+ module.exports = ContrastAPI;
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "contrastapi",
3
+ "version": "1.0.0",
4
+ "description": "Official Node.js SDK for ContrastAPI — security intelligence for developers and AI agents",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "license": "MIT",
8
+ "author": "ContrastCyber <hello@contrastcyber.com>",
9
+ "homepage": "https://contrastcyber.com",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/UPinar/contrastapi"
13
+ },
14
+ "keywords": [
15
+ "security",
16
+ "cve",
17
+ "vulnerability",
18
+ "domain",
19
+ "dns",
20
+ "whois",
21
+ "ssl",
22
+ "threat-intelligence",
23
+ "mcp",
24
+ "osint",
25
+ "api"
26
+ ],
27
+ "files": [
28
+ "index.js",
29
+ "index.d.ts",
30
+ "README.md"
31
+ ],
32
+ "engines": {
33
+ "node": ">=14"
34
+ }
35
+ }