fraim 2.0.177 → 2.0.180
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/src/ai-hub/desktop-main.js +2 -2
- package/dist/src/ai-hub/server.js +50 -1
- package/dist/src/api/admin/payments.js +33 -0
- package/dist/src/api/admin/sales-leads.js +21 -0
- package/dist/src/api/payment/create-session.js +338 -0
- package/dist/src/api/payment/dashboard-link.js +149 -0
- package/dist/src/api/payment/session-details.js +31 -0
- package/dist/src/api/payment/webhook.js +587 -0
- package/dist/src/api/personas/me.js +29 -0
- package/dist/src/api/pricing/get-config.js +25 -0
- package/dist/src/api/sales/contact.js +44 -0
- package/dist/src/cli/commands/add-provider.js +74 -61
- package/dist/src/cli/commands/add-surface.js +128 -0
- package/dist/src/cli/commands/login.js +5 -69
- package/dist/src/cli/commands/setup.js +27 -347
- package/dist/src/cli/distribution/marketplace-bundles.js +580 -0
- package/dist/src/cli/fraim.js +2 -0
- package/dist/src/cli/mcp/ide-formats.js +5 -3
- package/dist/src/cli/mcp/mcp-server-registry.js +10 -3
- package/dist/src/cli/providers/local-provider-registry.js +2 -3
- package/dist/src/cli/setup/auto-mcp-setup.js +9 -32
- package/dist/src/cli/setup/ide-detector.js +34 -14
- package/dist/src/config/persona-capability-bundles.js +17 -13
- package/dist/src/db/payment-repository.js +61 -0
- package/dist/src/first-run/session-service.js +2 -2
- package/dist/src/fraim/config-loader.js +11 -0
- package/dist/src/fraim/db-service.js +2387 -0
- package/dist/src/fraim/issues.js +152 -0
- package/dist/src/fraim/template-processor.js +184 -0
- package/dist/src/fraim/utils/request-utils.js +23 -0
- package/dist/src/local-mcp-server/stdio-server.js +28 -4
- package/dist/src/local-mcp-server/usage-collector.js +24 -0
- package/dist/src/middleware/auth.js +266 -0
- package/dist/src/middleware/cors-config.js +111 -0
- package/dist/src/middleware/logger.js +116 -0
- package/dist/src/middleware/rate-limit.js +110 -0
- package/dist/src/middleware/reject-query-api-key.js +45 -0
- package/dist/src/middleware/security-headers.js +41 -0
- package/dist/src/middleware/telemetry.js +134 -0
- package/dist/src/models/payment.js +2 -0
- package/dist/src/routes/analytics.js +1447 -0
- package/dist/src/routes/app-routes.js +32 -0
- package/dist/src/routes/auth-routes.js +505 -0
- package/dist/src/routes/oauth-routes.js +325 -0
- package/dist/src/routes/payment-routes.js +186 -0
- package/dist/src/routes/persona-catalog-routes.js +84 -0
- package/dist/src/services/admin-service.js +229 -0
- package/dist/src/services/audit-log-persistence.js +60 -0
- package/dist/src/services/audit-log.js +69 -0
- package/dist/src/services/cookie-service.js +129 -0
- package/dist/src/services/dashboard-access.js +27 -0
- package/dist/src/services/demo-seed-service.js +139 -0
- package/dist/src/services/email-code.js +23 -0
- package/dist/src/services/email-service-clean.js +782 -0
- package/dist/src/services/email-service.js +951 -0
- package/dist/src/services/installer-service.js +131 -0
- package/dist/src/services/mcp-oauth-store.js +33 -0
- package/dist/src/services/mcp-service.js +823 -0
- package/dist/src/services/oauth-helpers.js +127 -0
- package/dist/src/services/org-service.js +89 -0
- package/dist/src/services/persona-entitlement-service.js +288 -0
- package/dist/src/services/provider-service.js +215 -0
- package/dist/src/services/registry-service.js +628 -0
- package/dist/src/services/session-service.js +86 -0
- package/dist/src/services/trial-reminder-service.js +120 -0
- package/dist/src/services/usage-analytics-service.js +419 -0
- package/dist/src/services/workspace-identity.js +21 -0
- package/dist/src/types/analytics.js +2 -0
- package/dist/src/utils/payment-calculator.js +52 -0
- package/extensions/office-word/favicon.ico +0 -0
- package/extensions/office-word/icon-64.png +0 -0
- package/extensions/office-word/manifest.xml +33 -0
- package/extensions/office-word/taskpane.html +242 -0
- package/package.json +14 -3
- package/public/ai-hub/index.html +14 -2
- package/public/ai-hub/script.js +340 -66
- package/public/ai-hub/styles.css +83 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.securityHeaders = securityHeaders;
|
|
4
|
+
const DEFAULT_CSP = [
|
|
5
|
+
"default-src 'self'",
|
|
6
|
+
// Inline scripts are used by the analytics/installer dashboard; keep them.
|
|
7
|
+
// Third-party CDNs are explicitly listed rather than wildcarded.
|
|
8
|
+
"script-src 'self' 'unsafe-inline' https://js.stripe.com https://cdn.jsdelivr.net",
|
|
9
|
+
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
|
|
10
|
+
"img-src 'self' data: https:",
|
|
11
|
+
"font-src 'self' https://fonts.gstatic.com data:",
|
|
12
|
+
"connect-src 'self' https://api.stripe.com",
|
|
13
|
+
"frame-src 'self' https://js.stripe.com https://hooks.stripe.com",
|
|
14
|
+
"frame-ancestors 'self'",
|
|
15
|
+
"base-uri 'self'",
|
|
16
|
+
"form-action 'self' https://checkout.stripe.com"
|
|
17
|
+
].join('; ');
|
|
18
|
+
function securityHeaders(options = {}) {
|
|
19
|
+
const enableHsts = options.enableHsts !== false;
|
|
20
|
+
const csp = options.contentSecurityPolicy === undefined
|
|
21
|
+
? DEFAULT_CSP
|
|
22
|
+
: options.contentSecurityPolicy;
|
|
23
|
+
return function securityHeadersMiddleware(req, res, next) {
|
|
24
|
+
// Trust-proxy aware: req.secure is true if X-Forwarded-Proto is https
|
|
25
|
+
// and Express has been told to trust the upstream (see fraim-mcp-server.ts).
|
|
26
|
+
if (enableHsts && req.secure) {
|
|
27
|
+
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
|
|
28
|
+
}
|
|
29
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
30
|
+
res.setHeader('X-Frame-Options', 'SAMEORIGIN');
|
|
31
|
+
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
|
|
32
|
+
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
|
|
33
|
+
res.setHeader('Cross-Origin-Resource-Policy', 'same-site');
|
|
34
|
+
res.setHeader('X-Permitted-Cross-Domain-Policies', 'none');
|
|
35
|
+
res.setHeader('X-DNS-Prefetch-Control', 'off');
|
|
36
|
+
if (csp) {
|
|
37
|
+
res.setHeader('Content-Security-Policy', csp);
|
|
38
|
+
}
|
|
39
|
+
next();
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TelemetryMiddleware = void 0;
|
|
4
|
+
class TelemetryMiddleware {
|
|
5
|
+
constructor(sessionManager) {
|
|
6
|
+
this.sessionManager = sessionManager;
|
|
7
|
+
}
|
|
8
|
+
parseSessionId(req) {
|
|
9
|
+
const fromHeader = Array.isArray(req.headers['x-fraim-session-id'])
|
|
10
|
+
? req.headers['x-fraim-session-id'][0]
|
|
11
|
+
: req.headers['x-fraim-session-id'];
|
|
12
|
+
if (typeof fromHeader === 'string' && fromHeader.trim().length > 0) {
|
|
13
|
+
return fromHeader.trim();
|
|
14
|
+
}
|
|
15
|
+
const fromParams = req.body?.params?.sessionId;
|
|
16
|
+
if (typeof fromParams === 'string' && fromParams.trim().length > 0) {
|
|
17
|
+
return fromParams.trim();
|
|
18
|
+
}
|
|
19
|
+
const fromArgs = req.body?.params?.arguments?.sessionId;
|
|
20
|
+
if (typeof fromArgs === 'string' && fromArgs.trim().length > 0) {
|
|
21
|
+
return fromArgs.trim();
|
|
22
|
+
}
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Middleware to enforce Session Handshake and track activity
|
|
27
|
+
*/
|
|
28
|
+
async handle(req, res, next) {
|
|
29
|
+
try {
|
|
30
|
+
// 1. Standard MCP Lifecycle & Discovery methods (Initialize, List Tools/Resources/Prompts, etc.)
|
|
31
|
+
const exemptMethods = [
|
|
32
|
+
'initialize',
|
|
33
|
+
'notifications/initialized',
|
|
34
|
+
'tools/list',
|
|
35
|
+
'resources/list',
|
|
36
|
+
'prompts/list',
|
|
37
|
+
'prompts/get',
|
|
38
|
+
'logging/setLevel'
|
|
39
|
+
];
|
|
40
|
+
if (req.body && exemptMethods.includes(req.body.method)) {
|
|
41
|
+
return next();
|
|
42
|
+
}
|
|
43
|
+
// 2. FRAIM Bootstrap/Discovery Tools that don't need an active session
|
|
44
|
+
if (req.body && req.body.method === 'tools/call') {
|
|
45
|
+
const toolName = req.body.params?.name;
|
|
46
|
+
const safeTools = [
|
|
47
|
+
'fraim_connect',
|
|
48
|
+
'list_fraim_jobs'
|
|
49
|
+
];
|
|
50
|
+
if (toolName && safeTools.includes(toolName)) {
|
|
51
|
+
return next();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Skip for non-authenticated or exempt paths (GET only).
|
|
55
|
+
// Issue #359 - /api/auth/* and /api/account/* are human-session lifecycle
|
|
56
|
+
// endpoints (called by auth-bootstrap.js on every page load); they happen
|
|
57
|
+
// BEFORE any agent has fraim_connect'd, so they MUST be exempt from the
|
|
58
|
+
// telemetry session-active gate. Without this, /api/auth/session returns 400
|
|
59
|
+
// for every signed-in browser, which redirects users back to sign-in.
|
|
60
|
+
// Issue #563 - /api/org/* serves the org-cache sync performed by the
|
|
61
|
+
// `fraim sync` CLI, which runs outside any MCP session (same lifecycle
|
|
62
|
+
// position as /api/registry/sync). Auth still applies; only the
|
|
63
|
+
// session-active gate is exempted.
|
|
64
|
+
const exemptPaths = ['/health', '/admin', '/api/registry/sync', '/api/registry/github-workflows', '/api/registry/topology/personalized', '/api/registry/topology/usage-heatmap', '/api/org/', '/api/manager/', '/api/payment/', '/api/sales/', '/api/signup', '/api/providers', '/api/analytics', '/analytics', '/api/auth/', '/api/account/'];
|
|
65
|
+
if (exemptPaths.some(p => req.path.startsWith(p))) {
|
|
66
|
+
return next();
|
|
67
|
+
}
|
|
68
|
+
const apiKey = req.apiKeyData?.key;
|
|
69
|
+
if (!apiKey)
|
|
70
|
+
return next(); // Auth middleware handles 401 earlier
|
|
71
|
+
const sessionId = this.parseSessionId(req);
|
|
72
|
+
const localVersionFromHeader = Array.isArray(req.headers['x-fraim-local-version'])
|
|
73
|
+
? req.headers['x-fraim-local-version'][0]
|
|
74
|
+
: req.headers['x-fraim-local-version'];
|
|
75
|
+
const localVersion = req.localMcpVersion ||
|
|
76
|
+
(typeof localVersionFromHeader === 'string' ? localVersionFromHeader : 'unknown');
|
|
77
|
+
const isProxiedAgentCall = typeof localVersion === 'string' && localVersion !== 'unknown';
|
|
78
|
+
// Enforce explicit session id for local proxy agent traffic.
|
|
79
|
+
if (isProxiedAgentCall && !sessionId) {
|
|
80
|
+
return res.status(400).json({
|
|
81
|
+
jsonrpc: '2.0',
|
|
82
|
+
error: {
|
|
83
|
+
code: -32600,
|
|
84
|
+
message: `Missing Session ID. REQUIRED ACTION:
|
|
85
|
+
1. Call 'fraim_connect' first
|
|
86
|
+
2. Capture the returned sessionId
|
|
87
|
+
3. Include that sessionId on every subsequent FRAIM tool call (params.sessionId or params.arguments.sessionId).`
|
|
88
|
+
},
|
|
89
|
+
id: req.body?.id || null
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
// Check Session
|
|
93
|
+
const isActive = await this.sessionManager.updateActivity(apiKey, sessionId);
|
|
94
|
+
if (!isActive) {
|
|
95
|
+
const sessionStartGuidance = isProxiedAgentCall
|
|
96
|
+
? `Session Not Started. REQUIRED ACTION: Call 'fraim_connect' tool first, then include the returned sessionId on every subsequent FRAIM tool call.`
|
|
97
|
+
: `Session Not Started. REQUIRED ACTION: Call 'fraim_connect' tool first with these parameters:
|
|
98
|
+
|
|
99
|
+
{
|
|
100
|
+
"agent": {
|
|
101
|
+
"name": "YourAgentName",
|
|
102
|
+
"model": "your-model-name"
|
|
103
|
+
},
|
|
104
|
+
"machine": {
|
|
105
|
+
"hostname": "use os.hostname()",
|
|
106
|
+
"platform": "use process.platform"
|
|
107
|
+
},
|
|
108
|
+
"repo": {
|
|
109
|
+
"url": "git remote URL",
|
|
110
|
+
"owner": "repo owner",
|
|
111
|
+
"name": "repo name"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
After successful fraim_connect, all other FRAIM tools will work. This is required for telemetry and session management.`;
|
|
116
|
+
return res.status(400).json({
|
|
117
|
+
jsonrpc: '2.0',
|
|
118
|
+
error: {
|
|
119
|
+
code: -32600,
|
|
120
|
+
message: sessionStartGuidance
|
|
121
|
+
},
|
|
122
|
+
id: req.body?.id || null
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
console.log(`Telemetry active for ${apiKey}`);
|
|
126
|
+
return next();
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
console.error('Telemetry middleware error:', error);
|
|
130
|
+
return next(error);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
exports.TelemetryMiddleware = TelemetryMiddleware;
|