eassist-mcp 1.0.3 → 1.0.5
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/build/auth.d.ts +0 -1
- package/build/auth.js +27 -76
- package/build/client.js +2 -1
- package/package.json +1 -1
package/build/auth.d.ts
CHANGED
package/build/auth.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import os from 'os';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import
|
|
5
|
-
import { URL } from 'url';
|
|
4
|
+
import crypto from 'crypto';
|
|
6
5
|
import axios from 'axios';
|
|
7
6
|
const CONFIG_DIR = path.join(os.homedir(), '.eassist-mcp');
|
|
8
7
|
const CONFIG_FILE = path.join(CONFIG_DIR, 'auth.json');
|
|
@@ -24,7 +23,6 @@ class AuthManager {
|
|
|
24
23
|
this.data = data;
|
|
25
24
|
}
|
|
26
25
|
isExpired(expiresAt) {
|
|
27
|
-
// Add 60s buffer so we refresh before actual expiry
|
|
28
26
|
return new Date(expiresAt).getTime() - 60_000 < Date.now();
|
|
29
27
|
}
|
|
30
28
|
getApiUrl() {
|
|
@@ -33,11 +31,9 @@ class AuthManager {
|
|
|
33
31
|
async getValidToken() {
|
|
34
32
|
if (!this.data)
|
|
35
33
|
this.data = this.load();
|
|
36
|
-
// Valid access token
|
|
37
34
|
if (this.data?.accessToken && !this.isExpired(this.data.expiresAt)) {
|
|
38
35
|
return this.data.accessToken;
|
|
39
36
|
}
|
|
40
|
-
// Try refresh
|
|
41
37
|
if (this.data?.refreshToken) {
|
|
42
38
|
try {
|
|
43
39
|
const apiUrl = this.getApiUrl();
|
|
@@ -50,82 +46,37 @@ class AuthManager {
|
|
|
50
46
|
// Refresh failed — fall through to OAuth
|
|
51
47
|
}
|
|
52
48
|
}
|
|
53
|
-
// Full OAuth flow
|
|
54
49
|
await this.triggerOAuthFlow();
|
|
55
50
|
return this.data.accessToken;
|
|
56
51
|
}
|
|
57
52
|
async triggerOAuthFlow() {
|
|
58
53
|
const apiUrl = this.getApiUrl();
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
h2{color:#34d399;margin-bottom:8px;}p{color:#64748b;margin:4px 0;}</style></head>
|
|
86
|
-
<body><div class="box"><h2>✓ Authenticated successfully</h2>
|
|
87
|
-
<p>Welcome, ${displayName}.</p><p>You can close this tab and return to Claude.</p>
|
|
88
|
-
</div></body></html>`);
|
|
89
|
-
server.close();
|
|
90
|
-
resolve();
|
|
91
|
-
}
|
|
92
|
-
catch (err) {
|
|
93
|
-
server.close();
|
|
94
|
-
reject(err);
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
server.listen(port, '127.0.0.1', async () => {
|
|
98
|
-
const authUrl = `${apiUrl}/api/auth/mcp?port=${port}`;
|
|
99
|
-
console.error(`\n[eassist-mcp] Opening browser for authentication...\n${authUrl}\n`);
|
|
100
|
-
try {
|
|
101
|
-
const { default: open } = await import('open');
|
|
102
|
-
await open(authUrl);
|
|
103
|
-
}
|
|
104
|
-
catch {
|
|
105
|
-
console.error('[eassist-mcp] Could not open browser automatically. Please open the URL above manually.');
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
server.on('error', reject);
|
|
109
|
-
// Timeout after 5 minutes
|
|
110
|
-
setTimeout(() => {
|
|
111
|
-
server.close();
|
|
112
|
-
reject(new Error('Authentication timed out. Please try again.'));
|
|
113
|
-
}, 5 * 60 * 1000);
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
findFreePort() {
|
|
117
|
-
return new Promise((resolve, reject) => {
|
|
118
|
-
const server = http.createServer();
|
|
119
|
-
server.listen(0, '127.0.0.1', () => {
|
|
120
|
-
const addr = server.address();
|
|
121
|
-
server.close(() => {
|
|
122
|
-
if (addr && typeof addr === 'object')
|
|
123
|
-
resolve(addr.port);
|
|
124
|
-
else
|
|
125
|
-
reject(new Error('Could not find free port'));
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
});
|
|
54
|
+
const sessionId = crypto.randomBytes(16).toString('hex');
|
|
55
|
+
const authUrl = `${apiUrl}/api/auth/mcp?session_id=${sessionId}`;
|
|
56
|
+
console.error(`\n[eassist-mcp] Opening browser for authentication...\n${authUrl}\n`);
|
|
57
|
+
try {
|
|
58
|
+
const { default: open } = await import('open');
|
|
59
|
+
await open(authUrl);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
console.error('[eassist-mcp] Could not open browser automatically. Please visit the URL above manually.');
|
|
63
|
+
}
|
|
64
|
+
// Poll the backend until it has the token (user completes OAuth in browser)
|
|
65
|
+
const pollUrl = `${apiUrl}/api/auth/mcp/result?session_id=${sessionId}`;
|
|
66
|
+
const deadline = Date.now() + 5 * 60 * 1000;
|
|
67
|
+
while (Date.now() < deadline) {
|
|
68
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
69
|
+
try {
|
|
70
|
+
const res = await axios.get(pollUrl);
|
|
71
|
+
const { token, refreshToken, expiresAt, name, email } = res.data;
|
|
72
|
+
this.store({ apiUrl, accessToken: token, refreshToken, expiresAt, name, email });
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// 404 = not ready yet, any other error = retry
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
throw new Error('Authentication timed out. Please try again.');
|
|
129
80
|
}
|
|
130
81
|
getStoredName() {
|
|
131
82
|
return this.data?.name ?? this.data?.email ?? 'Unknown';
|
package/build/client.js
CHANGED
|
@@ -2,7 +2,8 @@ import axios from 'axios';
|
|
|
2
2
|
import { auth } from './auth.js';
|
|
3
3
|
const DEFAULT_API_URL = 'https://eassist.forsysinc.com';
|
|
4
4
|
function getApiUrl() {
|
|
5
|
-
|
|
5
|
+
const base = (process.env.EASSIST_API_URL ?? DEFAULT_API_URL).replace(/\/$/, '');
|
|
6
|
+
return base.endsWith('/api') ? base : base + '/api';
|
|
6
7
|
}
|
|
7
8
|
async function headers() {
|
|
8
9
|
const token = await auth.getValidToken();
|