@solongate/proxy 0.1.15 → 0.1.17
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 +62 -27
- package/dist/init.js +29 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -278,6 +278,35 @@ async function main() {
|
|
|
278
278
|
console.error(" \u2502 To undo: solongate-init --restore \u2502");
|
|
279
279
|
console.error(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
|
|
280
280
|
console.error("");
|
|
281
|
+
const envPath = resolve2(".env");
|
|
282
|
+
if (!existsSync2(envPath)) {
|
|
283
|
+
const envContent = `# SolonGate API Keys
|
|
284
|
+
# Get your keys from the dashboard: https://solongate.com
|
|
285
|
+
# IMPORTANT: Never commit this file to git!
|
|
286
|
+
|
|
287
|
+
# Live key \u2014 enables cloud policy sync + audit logging to dashboard
|
|
288
|
+
SOLONGATE_API_KEY=sg_live_your_key_here
|
|
289
|
+
|
|
290
|
+
# Test key \u2014 local-only, no cloud connection (for development)
|
|
291
|
+
# SOLONGATE_API_KEY=sg_test_your_key_here
|
|
292
|
+
`;
|
|
293
|
+
writeFileSync(envPath, envContent);
|
|
294
|
+
console.error(` Created .env with placeholder API keys`);
|
|
295
|
+
console.error(` \u2192 Edit .env and replace with your real keys from https://solongate.com`);
|
|
296
|
+
console.error("");
|
|
297
|
+
}
|
|
298
|
+
const gitignorePath = resolve2(".gitignore");
|
|
299
|
+
if (existsSync2(gitignorePath)) {
|
|
300
|
+
const gitignore = readFileSync2(gitignorePath, "utf-8");
|
|
301
|
+
if (!gitignore.includes(".env")) {
|
|
302
|
+
writeFileSync(gitignorePath, gitignore.trimEnd() + "\n.env\n.env.local\n");
|
|
303
|
+
console.error(` Added .env to .gitignore`);
|
|
304
|
+
}
|
|
305
|
+
} else {
|
|
306
|
+
writeFileSync(gitignorePath, ".env\n.env.local\nnode_modules/\n");
|
|
307
|
+
console.error(` Created .gitignore (with .env excluded)`);
|
|
308
|
+
}
|
|
309
|
+
console.error("");
|
|
281
310
|
for (const name of toProtect) {
|
|
282
311
|
console.error(` \u2713 ${name} \u2014 protected (${options.policy})`);
|
|
283
312
|
}
|
|
@@ -3149,35 +3178,41 @@ var SolonGateProxy = class {
|
|
|
3149
3178
|
log("Starting SolonGate Proxy...");
|
|
3150
3179
|
const apiUrl = this.config.apiUrl ?? "https://api.solongate.com";
|
|
3151
3180
|
if (this.config.apiKey) {
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3181
|
+
if (this.config.apiKey.startsWith("sg_test_")) {
|
|
3182
|
+
log("Using test API key \u2014 skipping online validation.");
|
|
3183
|
+
} else {
|
|
3184
|
+
log(`Validating license with ${apiUrl}...`);
|
|
3185
|
+
try {
|
|
3186
|
+
const res = await fetch(`${apiUrl}/api/v1/auth/me`, {
|
|
3187
|
+
headers: {
|
|
3188
|
+
"X-API-Key": this.config.apiKey,
|
|
3189
|
+
"Authorization": `Bearer ${this.config.apiKey}`
|
|
3190
|
+
},
|
|
3191
|
+
signal: AbortSignal.timeout(1e4)
|
|
3192
|
+
});
|
|
3193
|
+
if (res.status === 401) {
|
|
3194
|
+
log("ERROR: Invalid or expired API key.");
|
|
3195
|
+
process.exit(1);
|
|
3196
|
+
}
|
|
3197
|
+
if (res.status === 403) {
|
|
3198
|
+
log("ERROR: Your subscription is inactive. Renew at https://solongate.com");
|
|
3199
|
+
process.exit(1);
|
|
3200
|
+
}
|
|
3201
|
+
log("License validated.");
|
|
3202
|
+
} catch (err) {
|
|
3203
|
+
log(`ERROR: Unable to reach SolonGate license server. Check your internet connection.`);
|
|
3204
|
+
log(`Details: ${err instanceof Error ? err.message : String(err)}`);
|
|
3167
3205
|
process.exit(1);
|
|
3168
3206
|
}
|
|
3169
|
-
log("License validated.");
|
|
3170
|
-
} catch (err) {
|
|
3171
|
-
log(`ERROR: Unable to reach SolonGate license server. Check your internet connection.`);
|
|
3172
|
-
log(`Details: ${err instanceof Error ? err.message : String(err)}`);
|
|
3173
|
-
process.exit(1);
|
|
3174
3207
|
}
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3208
|
+
if (!this.config.apiKey.startsWith("sg_test_")) {
|
|
3209
|
+
try {
|
|
3210
|
+
const cloudPolicy = await fetchCloudPolicy(this.config.apiKey, apiUrl);
|
|
3211
|
+
this.config.policy = cloudPolicy;
|
|
3212
|
+
log(`Loaded cloud policy: ${cloudPolicy.name} (${cloudPolicy.rules.length} rules)`);
|
|
3213
|
+
} catch (err) {
|
|
3214
|
+
log(`Cloud policy fetch failed, using local policy: ${err instanceof Error ? err.message : String(err)}`);
|
|
3215
|
+
}
|
|
3181
3216
|
}
|
|
3182
3217
|
}
|
|
3183
3218
|
log(`Policy: ${this.config.policy.name} (${this.config.policy.rules.length} rules)`);
|
|
@@ -3296,7 +3331,7 @@ var SolonGateProxy = class {
|
|
|
3296
3331
|
const decision = result.isError ? "DENY" : "ALLOW";
|
|
3297
3332
|
const evaluationTimeMs = Date.now() - startTime;
|
|
3298
3333
|
log(`Result: ${decision} (${evaluationTimeMs}ms)`);
|
|
3299
|
-
if (this.config.apiKey) {
|
|
3334
|
+
if (this.config.apiKey && !this.config.apiKey.startsWith("sg_test_")) {
|
|
3300
3335
|
const apiUrl = this.config.apiUrl ?? "https://api.solongate.com";
|
|
3301
3336
|
sendAuditLog(this.config.apiKey, apiUrl, {
|
|
3302
3337
|
tool: name,
|
package/dist/init.js
CHANGED
|
@@ -280,6 +280,35 @@ async function main() {
|
|
|
280
280
|
console.error(" \u2502 To undo: solongate-init --restore \u2502");
|
|
281
281
|
console.error(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
|
|
282
282
|
console.error("");
|
|
283
|
+
const envPath = resolve(".env");
|
|
284
|
+
if (!existsSync(envPath)) {
|
|
285
|
+
const envContent = `# SolonGate API Keys
|
|
286
|
+
# Get your keys from the dashboard: https://solongate.com
|
|
287
|
+
# IMPORTANT: Never commit this file to git!
|
|
288
|
+
|
|
289
|
+
# Live key \u2014 enables cloud policy sync + audit logging to dashboard
|
|
290
|
+
SOLONGATE_API_KEY=sg_live_your_key_here
|
|
291
|
+
|
|
292
|
+
# Test key \u2014 local-only, no cloud connection (for development)
|
|
293
|
+
# SOLONGATE_API_KEY=sg_test_your_key_here
|
|
294
|
+
`;
|
|
295
|
+
writeFileSync(envPath, envContent);
|
|
296
|
+
console.error(` Created .env with placeholder API keys`);
|
|
297
|
+
console.error(` \u2192 Edit .env and replace with your real keys from https://solongate.com`);
|
|
298
|
+
console.error("");
|
|
299
|
+
}
|
|
300
|
+
const gitignorePath = resolve(".gitignore");
|
|
301
|
+
if (existsSync(gitignorePath)) {
|
|
302
|
+
const gitignore = readFileSync(gitignorePath, "utf-8");
|
|
303
|
+
if (!gitignore.includes(".env")) {
|
|
304
|
+
writeFileSync(gitignorePath, gitignore.trimEnd() + "\n.env\n.env.local\n");
|
|
305
|
+
console.error(` Added .env to .gitignore`);
|
|
306
|
+
}
|
|
307
|
+
} else {
|
|
308
|
+
writeFileSync(gitignorePath, ".env\n.env.local\nnode_modules/\n");
|
|
309
|
+
console.error(` Created .gitignore (with .env excluded)`);
|
|
310
|
+
}
|
|
311
|
+
console.error("");
|
|
283
312
|
for (const name of toProtect) {
|
|
284
313
|
console.error(` \u2713 ${name} \u2014 protected (${options.policy})`);
|
|
285
314
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "MCP security proxy
|
|
3
|
+
"version": "0.1.17",
|
|
4
|
+
"description": "MCP security proxy \u00e2\u20ac\u201d protect any MCP server with policies, input validation, rate limiting, and audit logging. Zero code changes required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"solongate-proxy": "./dist/index.js",
|