@solongate/proxy 0.3.0 → 0.4.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/dist/index.js +1054 -703
- package/dist/pull-push.js +143 -0
- package/package.json +1 -1
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/pull-push.ts
|
|
4
|
+
import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync2 } from "fs";
|
|
5
|
+
import { resolve as resolve2 } from "path";
|
|
6
|
+
|
|
7
|
+
// src/config.ts
|
|
8
|
+
import { readFileSync, existsSync } from "fs";
|
|
9
|
+
import { resolve } from "path";
|
|
10
|
+
async function fetchCloudPolicy(apiKey, apiUrl, policyId) {
|
|
11
|
+
const url = `${apiUrl}/api/v1/policies/${policyId ?? "default"}`;
|
|
12
|
+
const res = await fetch(url, {
|
|
13
|
+
headers: { "Authorization": `Bearer ${apiKey}` }
|
|
14
|
+
});
|
|
15
|
+
if (!res.ok) {
|
|
16
|
+
const body = await res.text().catch(() => "");
|
|
17
|
+
throw new Error(`Failed to fetch policy from cloud (${res.status}): ${body}`);
|
|
18
|
+
}
|
|
19
|
+
const data = await res.json();
|
|
20
|
+
return {
|
|
21
|
+
id: String(data.id ?? "cloud"),
|
|
22
|
+
name: String(data.name ?? "Cloud Policy"),
|
|
23
|
+
version: Number(data._version ?? 1),
|
|
24
|
+
rules: data.rules ?? [],
|
|
25
|
+
createdAt: String(data._created_at ?? ""),
|
|
26
|
+
updatedAt: ""
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/pull-push.ts
|
|
31
|
+
var log = (...args) => process.stderr.write(`[SolonGate] ${args.map(String).join(" ")}
|
|
32
|
+
`);
|
|
33
|
+
function parseCliArgs() {
|
|
34
|
+
const args = process.argv.slice(2);
|
|
35
|
+
const command = args[0];
|
|
36
|
+
let apiKey = process.env.SOLONGATE_API_KEY || "";
|
|
37
|
+
let file = "policy.json";
|
|
38
|
+
let policyId;
|
|
39
|
+
for (let i = 1; i < args.length; i++) {
|
|
40
|
+
switch (args[i]) {
|
|
41
|
+
case "--api-key":
|
|
42
|
+
apiKey = args[++i];
|
|
43
|
+
break;
|
|
44
|
+
case "--policy":
|
|
45
|
+
case "--output":
|
|
46
|
+
case "--file":
|
|
47
|
+
case "-f":
|
|
48
|
+
case "-o":
|
|
49
|
+
file = args[++i];
|
|
50
|
+
break;
|
|
51
|
+
case "--policy-id":
|
|
52
|
+
case "--id":
|
|
53
|
+
policyId = args[++i];
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!apiKey) {
|
|
58
|
+
log("ERROR: API key required.");
|
|
59
|
+
log("");
|
|
60
|
+
log("Usage:");
|
|
61
|
+
log(` solongate-proxy ${command} --api-key sg_live_... --file policy.json`);
|
|
62
|
+
log(` SOLONGATE_API_KEY=sg_live_... solongate-proxy ${command}`);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
if (!apiKey.startsWith("sg_live_")) {
|
|
66
|
+
log("ERROR: Pull/push requires a live API key (sg_live_...).");
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
return { command, apiKey, file: resolve2(file), policyId };
|
|
70
|
+
}
|
|
71
|
+
async function pull(apiKey, file, policyId) {
|
|
72
|
+
const apiUrl = "https://api.solongate.com";
|
|
73
|
+
log(`Pulling policy from dashboard...`);
|
|
74
|
+
const policy = await fetchCloudPolicy(apiKey, apiUrl, policyId);
|
|
75
|
+
const json = JSON.stringify(policy, null, 2) + "\n";
|
|
76
|
+
writeFileSync(file, json, "utf-8");
|
|
77
|
+
log(`Saved: ${file}`);
|
|
78
|
+
log(` Name: ${policy.name}`);
|
|
79
|
+
log(` Version: ${policy.version}`);
|
|
80
|
+
log(` Rules: ${policy.rules.length}`);
|
|
81
|
+
log("");
|
|
82
|
+
log("Done. Policy pulled from dashboard to local file.");
|
|
83
|
+
}
|
|
84
|
+
async function push(apiKey, file) {
|
|
85
|
+
const apiUrl = "https://api.solongate.com";
|
|
86
|
+
if (!existsSync2(file)) {
|
|
87
|
+
log(`ERROR: File not found: ${file}`);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
const content = readFileSync2(file, "utf-8");
|
|
91
|
+
let policy;
|
|
92
|
+
try {
|
|
93
|
+
policy = JSON.parse(content);
|
|
94
|
+
} catch {
|
|
95
|
+
log(`ERROR: Invalid JSON in ${file}`);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
log(`Pushing policy to dashboard...`);
|
|
99
|
+
log(` File: ${file}`);
|
|
100
|
+
log(` Name: ${policy.name || "Unnamed"}`);
|
|
101
|
+
log(` Rules: ${(policy.rules || []).length}`);
|
|
102
|
+
const res = await fetch(`${apiUrl}/api/v1/policies`, {
|
|
103
|
+
method: "POST",
|
|
104
|
+
headers: {
|
|
105
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
106
|
+
"Content-Type": "application/json"
|
|
107
|
+
},
|
|
108
|
+
body: JSON.stringify({
|
|
109
|
+
id: policy.id || "default",
|
|
110
|
+
name: policy.name || "Local Policy",
|
|
111
|
+
description: policy.description || "Pushed from local file",
|
|
112
|
+
version: policy.version || 1,
|
|
113
|
+
rules: policy.rules || []
|
|
114
|
+
})
|
|
115
|
+
});
|
|
116
|
+
if (!res.ok) {
|
|
117
|
+
const body = await res.text().catch(() => "");
|
|
118
|
+
log(`ERROR: Push failed (${res.status}): ${body}`);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
const data = await res.json();
|
|
122
|
+
log(` Cloud version: ${data._version ?? "created"}`);
|
|
123
|
+
log("");
|
|
124
|
+
log("Done. Policy pushed from local file to dashboard.");
|
|
125
|
+
}
|
|
126
|
+
async function main() {
|
|
127
|
+
const { command, apiKey, file, policyId } = parseCliArgs();
|
|
128
|
+
try {
|
|
129
|
+
if (command === "pull") {
|
|
130
|
+
await pull(apiKey, file, policyId);
|
|
131
|
+
} else if (command === "push") {
|
|
132
|
+
await push(apiKey, file);
|
|
133
|
+
} else {
|
|
134
|
+
log(`Unknown command: ${command}`);
|
|
135
|
+
log("Usage: solongate-proxy pull|push --api-key sg_live_... --file policy.json");
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
} catch (err) {
|
|
139
|
+
log(`ERROR: ${err instanceof Error ? err.message : String(err)}`);
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "MCP security proxy — protect any MCP server with customizable policies, path/command constraints, rate limiting, and audit logging. Zero code changes required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|