@testany/hephos 0.3.18 → 0.4.0-dev.3
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/README.md +29 -0
- package/out/auth/AuthConfig.d.ts +54 -0
- package/out/auth/AuthConfig.d.ts.map +1 -0
- package/out/auth/AuthConfig.js +70 -0
- package/out/auth/AuthConfig.js.map +1 -0
- package/out/auth/AuthService.d.ts +74 -0
- package/out/auth/AuthService.d.ts.map +1 -0
- package/out/auth/AuthService.js +275 -0
- package/out/auth/AuthService.js.map +1 -0
- package/out/auth/CallbackServer.d.ts +15 -0
- package/out/auth/CallbackServer.d.ts.map +1 -0
- package/out/auth/CallbackServer.js +277 -0
- package/out/auth/CallbackServer.js.map +1 -0
- package/out/auth/TokenCache.d.ts +81 -0
- package/out/auth/TokenCache.d.ts.map +1 -0
- package/out/auth/TokenCache.js +191 -0
- package/out/auth/TokenCache.js.map +1 -0
- package/out/auth/index.d.ts +11 -0
- package/out/auth/index.d.ts.map +1 -0
- package/out/auth/index.js +13 -0
- package/out/auth/index.js.map +1 -0
- package/out/auth/types.d.ts +75 -0
- package/out/auth/types.d.ts.map +1 -0
- package/out/auth/types.js +15 -0
- package/out/auth/types.js.map +1 -0
- package/out/cli.d.ts.map +1 -1
- package/out/cli.js +223 -33
- package/out/cli.js.map +1 -1
- package/out/repl/ReplModeInk.d.ts +1 -0
- package/out/repl/ReplModeInk.d.ts.map +1 -1
- package/out/repl/ReplModeInk.js +96 -3
- package/out/repl/ReplModeInk.js.map +1 -1
- package/out/secure-config/BaseDirResolver.d.ts +5 -0
- package/out/secure-config/BaseDirResolver.d.ts.map +1 -0
- package/out/secure-config/BaseDirResolver.js +20 -0
- package/out/secure-config/BaseDirResolver.js.map +1 -0
- package/out/secure-config/DeviceKeyService.d.ts +13 -0
- package/out/secure-config/DeviceKeyService.d.ts.map +1 -0
- package/out/secure-config/DeviceKeyService.js +51 -0
- package/out/secure-config/DeviceKeyService.js.map +1 -0
- package/out/secure-config/DeviceStore.d.ts +13 -0
- package/out/secure-config/DeviceStore.d.ts.map +1 -0
- package/out/secure-config/DeviceStore.js +39 -0
- package/out/secure-config/DeviceStore.js.map +1 -0
- package/out/secure-config/InstructionNormalizer.d.ts +5 -0
- package/out/secure-config/InstructionNormalizer.d.ts.map +1 -0
- package/out/secure-config/InstructionNormalizer.js +20 -0
- package/out/secure-config/InstructionNormalizer.js.map +1 -0
- package/out/secure-config/KeysetService.d.ts +15 -0
- package/out/secure-config/KeysetService.d.ts.map +1 -0
- package/out/secure-config/KeysetService.js +88 -0
- package/out/secure-config/KeysetService.js.map +1 -0
- package/out/secure-config/SCPService.d.ts +14 -0
- package/out/secure-config/SCPService.d.ts.map +1 -0
- package/out/secure-config/SCPService.js +79 -0
- package/out/secure-config/SCPService.js.map +1 -0
- package/out/secure-config/SecureConfigClient.d.ts +30 -0
- package/out/secure-config/SecureConfigClient.d.ts.map +1 -0
- package/out/secure-config/SecureConfigClient.js +81 -0
- package/out/secure-config/SecureConfigClient.js.map +1 -0
- package/out/secure-config/errors.d.ts +8 -0
- package/out/secure-config/errors.d.ts.map +1 -0
- package/out/secure-config/errors.js +20 -0
- package/out/secure-config/errors.js.map +1 -0
- package/out/secure-config/index.d.ts +11 -0
- package/out/secure-config/index.d.ts.map +1 -0
- package/out/secure-config/index.js +11 -0
- package/out/secure-config/index.js.map +1 -0
- package/out/secure-config/rootKey.d.ts +3 -0
- package/out/secure-config/rootKey.d.ts.map +1 -0
- package/out/secure-config/rootKey.js +57 -0
- package/out/secure-config/rootKey.js.map +1 -0
- package/out/secure-config/signatureUtils.d.ts +3 -0
- package/out/secure-config/signatureUtils.d.ts.map +1 -0
- package/out/secure-config/signatureUtils.js +23 -0
- package/out/secure-config/signatureUtils.js.map +1 -0
- package/out/secure-config/types.d.ts +79 -0
- package/out/secure-config/types.d.ts.map +1 -0
- package/out/secure-config/types.js +2 -0
- package/out/secure-config/types.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local HTTP server to receive OAuth callback
|
|
3
|
+
* Listens on 127.0.0.1:8400 for security (localhost only)
|
|
4
|
+
*/
|
|
5
|
+
import * as http from 'http';
|
|
6
|
+
import { URL } from 'url';
|
|
7
|
+
import { CALLBACK_PORT, LOGIN_TIMEOUT_MS } from './AuthConfig.js';
|
|
8
|
+
import { AuthError } from './types.js';
|
|
9
|
+
/** HephOS favicon SVG (inline) */
|
|
10
|
+
const HEPHOS_ICON = `<svg width="48" height="48" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"><g transform="scale(1.4) translate(-28, -28)" fill="#ffd6c9"><path d="M85.627,84.217h28.746c11.232,0,20.369-9.137,20.369-20.441c0-11.231-9.137-20.369-20.369-20.369H104V40c0-2.209-1.791-4-4-4s-4,1.791-4,4v3.406H85.627c-11.232,0-20.369,9.138-20.369,20.442C65.258,75.08,74.395,84.217,85.627,84.217z M85.627,51.406h28.746c6.82,0,12.369,5.549,12.369,12.442c0,6.82-5.549,12.368-12.369,12.368H85.627c-6.82,0-12.369-5.548-12.369-12.441C73.258,56.955,78.807,51.406,85.627,51.406z"/><ellipse cx="86.421" cy="63.812" rx="5.636" ry="5.719"/><ellipse cx="113.579" cy="63.812" rx="5.636" ry="5.719"/><path d="M83.355,102.72c-2.209,0-4,1.791-4,4v16.725c0,2.209,1.791,4,4,4h33.291c2.209,0,4-1.791,4-4V106.72c0-2.209-1.791-4-4-4H83.355z M112.646,119.444H87.355v-8.725h25.291V119.444z"/><path d="M159.219,67.697c-2.209,0-4,1.791-4,4v4c0,2.481-2.02,4.5-4.5,4.5s-4.5-2.019-4.5-4.5v-4c0-2.209-1.791-4-4-4s-4,1.791-4,4v4c0,5.478,3.547,10.133,8.461,11.818c-0.407,8.45-7.389,15.205-15.938,15.205c-2.209,0-4,1.791-4,4v20.884c0,3.309-2.691,6-6,6h-12.834H92.092H79.258c-3.309,0-6-2.691-6-6v-0.884c0-2.209-1.791-4-4-4s-4,1.791-4,4v0.884c0,7.72,6.281,14,14,14h8.834v10.489C88.092,158.658,93.434,164,100,164s11.908-5.342,11.908-11.907v-10.489h8.834c7.719,0,14-6.28,14-14v-17.245c11.061-1.87,19.554-11.321,19.936-22.814c4.956-1.661,8.541-6.339,8.541-11.847v-4C163.219,69.488,161.428,67.697,159.219,67.697z M103.908,152.093c0,2.154-1.754,3.907-3.908,3.907s-3.908-1.753-3.908-3.907v-10.489h7.816V152.093z"/><path d="M73.258,106.72v-4.16c0-3.309,2.691-6,6-6h51.484c2.209,0,4-1.791,4-4s-1.791-4-4-4H79.258c-7.719,0-14,6.28-14,14v0.16H53.281V87.529c4.934-1.673,8.5-6.339,8.5-11.832v-4c0-2.209-1.791-4-4-4s-4,1.791-4,4v4c0,2.481-2.02,4.5-4.5,4.5s-4.5-2.019-4.5-4.5v-4c0-2.209-1.791-4-4-4s-4,1.791-4,4v4c0,5.493,3.566,10.159,8.5,11.832v19.191c0,2.209,1.791,4,4,4h19.977C71.467,110.72,73.258,108.929,73.258,106.72z"/></g></svg>`;
|
|
11
|
+
/** HTML response shown to user after successful login */
|
|
12
|
+
const SUCCESS_HTML = `
|
|
13
|
+
<!DOCTYPE html>
|
|
14
|
+
<html>
|
|
15
|
+
<head>
|
|
16
|
+
<meta charset="utf-8">
|
|
17
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
18
|
+
<title>Login Successful - HephOS</title>
|
|
19
|
+
<style>
|
|
20
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
21
|
+
body {
|
|
22
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
|
|
23
|
+
display: flex;
|
|
24
|
+
justify-content: center;
|
|
25
|
+
align-items: center;
|
|
26
|
+
min-height: 100vh;
|
|
27
|
+
background: #1c1a18;
|
|
28
|
+
color: #e8e4df;
|
|
29
|
+
}
|
|
30
|
+
.container {
|
|
31
|
+
text-align: center;
|
|
32
|
+
padding: 48px;
|
|
33
|
+
max-width: 400px;
|
|
34
|
+
}
|
|
35
|
+
.icon {
|
|
36
|
+
margin-bottom: 24px;
|
|
37
|
+
}
|
|
38
|
+
.status {
|
|
39
|
+
display: inline-flex;
|
|
40
|
+
align-items: center;
|
|
41
|
+
gap: 8px;
|
|
42
|
+
padding: 8px 16px;
|
|
43
|
+
background: rgba(74, 222, 128, 0.15);
|
|
44
|
+
border: 1px solid rgba(74, 222, 128, 0.3);
|
|
45
|
+
border-radius: 24px;
|
|
46
|
+
color: #4ade80;
|
|
47
|
+
font-size: 14px;
|
|
48
|
+
font-weight: 500;
|
|
49
|
+
margin-bottom: 24px;
|
|
50
|
+
}
|
|
51
|
+
.status svg {
|
|
52
|
+
width: 16px;
|
|
53
|
+
height: 16px;
|
|
54
|
+
}
|
|
55
|
+
h1 {
|
|
56
|
+
font-size: 24px;
|
|
57
|
+
font-weight: 600;
|
|
58
|
+
margin-bottom: 12px;
|
|
59
|
+
color: #ffd6c9;
|
|
60
|
+
}
|
|
61
|
+
p {
|
|
62
|
+
font-size: 15px;
|
|
63
|
+
color: #a39e98;
|
|
64
|
+
line-height: 1.5;
|
|
65
|
+
}
|
|
66
|
+
.hint {
|
|
67
|
+
margin-top: 32px;
|
|
68
|
+
padding-top: 24px;
|
|
69
|
+
border-top: 1px solid #2d2a27;
|
|
70
|
+
font-size: 13px;
|
|
71
|
+
color: #6b6560;
|
|
72
|
+
}
|
|
73
|
+
</style>
|
|
74
|
+
</head>
|
|
75
|
+
<body>
|
|
76
|
+
<div class="container">
|
|
77
|
+
<div class="icon">${HEPHOS_ICON}</div>
|
|
78
|
+
<div class="status">
|
|
79
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
|
80
|
+
<polyline points="20 6 9 17 4 12"></polyline>
|
|
81
|
+
</svg>
|
|
82
|
+
Login Successful
|
|
83
|
+
</div>
|
|
84
|
+
<h1>Welcome to HephOS</h1>
|
|
85
|
+
<p>You have been authenticated successfully. You can now close this window and return to the CLI.</p>
|
|
86
|
+
<div class="hint">This window can be closed safely.</div>
|
|
87
|
+
</div>
|
|
88
|
+
</body>
|
|
89
|
+
</html>
|
|
90
|
+
`;
|
|
91
|
+
/** HTML response shown on error */
|
|
92
|
+
const ERROR_HTML = (message) => `
|
|
93
|
+
<!DOCTYPE html>
|
|
94
|
+
<html>
|
|
95
|
+
<head>
|
|
96
|
+
<meta charset="utf-8">
|
|
97
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
98
|
+
<title>Login Failed - HephOS</title>
|
|
99
|
+
<style>
|
|
100
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
101
|
+
body {
|
|
102
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
|
|
103
|
+
display: flex;
|
|
104
|
+
justify-content: center;
|
|
105
|
+
align-items: center;
|
|
106
|
+
min-height: 100vh;
|
|
107
|
+
background: #1c1a18;
|
|
108
|
+
color: #e8e4df;
|
|
109
|
+
}
|
|
110
|
+
.container {
|
|
111
|
+
text-align: center;
|
|
112
|
+
padding: 48px;
|
|
113
|
+
max-width: 400px;
|
|
114
|
+
}
|
|
115
|
+
.icon {
|
|
116
|
+
margin-bottom: 24px;
|
|
117
|
+
}
|
|
118
|
+
.status {
|
|
119
|
+
display: inline-flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
gap: 8px;
|
|
122
|
+
padding: 8px 16px;
|
|
123
|
+
background: rgba(239, 68, 68, 0.15);
|
|
124
|
+
border: 1px solid rgba(239, 68, 68, 0.3);
|
|
125
|
+
border-radius: 24px;
|
|
126
|
+
color: #ef4444;
|
|
127
|
+
font-size: 14px;
|
|
128
|
+
font-weight: 500;
|
|
129
|
+
margin-bottom: 24px;
|
|
130
|
+
}
|
|
131
|
+
.status svg {
|
|
132
|
+
width: 16px;
|
|
133
|
+
height: 16px;
|
|
134
|
+
}
|
|
135
|
+
h1 {
|
|
136
|
+
font-size: 24px;
|
|
137
|
+
font-weight: 600;
|
|
138
|
+
margin-bottom: 12px;
|
|
139
|
+
color: #ffd6c9;
|
|
140
|
+
}
|
|
141
|
+
p {
|
|
142
|
+
font-size: 15px;
|
|
143
|
+
color: #a39e98;
|
|
144
|
+
line-height: 1.5;
|
|
145
|
+
}
|
|
146
|
+
.error-detail {
|
|
147
|
+
margin-top: 16px;
|
|
148
|
+
padding: 12px 16px;
|
|
149
|
+
background: rgba(239, 68, 68, 0.1);
|
|
150
|
+
border-radius: 8px;
|
|
151
|
+
font-size: 13px;
|
|
152
|
+
color: #ef4444;
|
|
153
|
+
word-break: break-word;
|
|
154
|
+
}
|
|
155
|
+
.hint {
|
|
156
|
+
margin-top: 32px;
|
|
157
|
+
padding-top: 24px;
|
|
158
|
+
border-top: 1px solid #2d2a27;
|
|
159
|
+
font-size: 13px;
|
|
160
|
+
color: #6b6560;
|
|
161
|
+
}
|
|
162
|
+
</style>
|
|
163
|
+
</head>
|
|
164
|
+
<body>
|
|
165
|
+
<div class="container">
|
|
166
|
+
<div class="icon">${HEPHOS_ICON}</div>
|
|
167
|
+
<div class="status">
|
|
168
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
|
169
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
170
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
171
|
+
</svg>
|
|
172
|
+
Login Failed
|
|
173
|
+
</div>
|
|
174
|
+
<h1>Authentication Error</h1>
|
|
175
|
+
<p>We couldn't complete the login process. Please try again.</p>
|
|
176
|
+
<div class="error-detail">${message}</div>
|
|
177
|
+
<div class="hint">Close this window and try again from the CLI.</div>
|
|
178
|
+
</div>
|
|
179
|
+
</body>
|
|
180
|
+
</html>
|
|
181
|
+
`;
|
|
182
|
+
/**
|
|
183
|
+
* Start a local HTTP server to receive OAuth callback
|
|
184
|
+
* Returns a promise that resolves with the authorization code and state
|
|
185
|
+
*/
|
|
186
|
+
export function startCallbackServer() {
|
|
187
|
+
return new Promise((resolve, reject) => {
|
|
188
|
+
let server = null;
|
|
189
|
+
let timeoutId = null;
|
|
190
|
+
const cleanup = () => {
|
|
191
|
+
if (timeoutId) {
|
|
192
|
+
clearTimeout(timeoutId);
|
|
193
|
+
timeoutId = null;
|
|
194
|
+
}
|
|
195
|
+
if (server) {
|
|
196
|
+
server.close();
|
|
197
|
+
server = null;
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
// Set timeout for login flow
|
|
201
|
+
timeoutId = setTimeout(() => {
|
|
202
|
+
cleanup();
|
|
203
|
+
reject(new AuthError('AUTH_CALLBACK_TIMEOUT', 'Login timed out. Please try again.'));
|
|
204
|
+
}, LOGIN_TIMEOUT_MS);
|
|
205
|
+
server = http.createServer((req, res) => {
|
|
206
|
+
// Only handle GET requests to /callback
|
|
207
|
+
if (req.method !== 'GET' || !req.url?.startsWith('/callback')) {
|
|
208
|
+
res.writeHead(404);
|
|
209
|
+
res.end('Not found');
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
try {
|
|
213
|
+
const url = new URL(req.url, `http://127.0.0.1:${CALLBACK_PORT}`);
|
|
214
|
+
const code = url.searchParams.get('code');
|
|
215
|
+
const state = url.searchParams.get('state');
|
|
216
|
+
const error = url.searchParams.get('error');
|
|
217
|
+
const errorDescription = url.searchParams.get('error_description');
|
|
218
|
+
// Handle OAuth error response
|
|
219
|
+
if (error) {
|
|
220
|
+
const message = errorDescription || error;
|
|
221
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
222
|
+
res.end(ERROR_HTML(message));
|
|
223
|
+
cleanup();
|
|
224
|
+
reject(new AuthError('AUTH_TOKEN_EXCHANGE_FAILED', `OAuth error: ${message}`));
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
// Validate required parameters
|
|
228
|
+
if (!code || !state) {
|
|
229
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
230
|
+
res.end(ERROR_HTML('Missing authorization code or state'));
|
|
231
|
+
cleanup();
|
|
232
|
+
reject(new AuthError('AUTH_TOKEN_EXCHANGE_FAILED', 'Missing authorization code or state in callback'));
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
// Success - send response and resolve
|
|
236
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
237
|
+
res.end(SUCCESS_HTML);
|
|
238
|
+
cleanup();
|
|
239
|
+
resolve({ code, state });
|
|
240
|
+
}
|
|
241
|
+
catch (err) {
|
|
242
|
+
res.writeHead(500);
|
|
243
|
+
res.end('Internal error');
|
|
244
|
+
cleanup();
|
|
245
|
+
reject(err);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
// Listen only on localhost for security
|
|
249
|
+
server.listen(CALLBACK_PORT, '127.0.0.1', () => {
|
|
250
|
+
// Server started successfully
|
|
251
|
+
});
|
|
252
|
+
server.on('error', (err) => {
|
|
253
|
+
cleanup();
|
|
254
|
+
if (err.code === 'EADDRINUSE') {
|
|
255
|
+
reject(new AuthError('AUTH_PORT_IN_USE', `Port ${CALLBACK_PORT} is already in use. Please close any application using this port and try again.`));
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
reject(new AuthError('AUTH_BROWSER_FAILED', `Failed to start callback server: ${err.message}`, err));
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Check if port is available
|
|
265
|
+
*/
|
|
266
|
+
export function isPortAvailable(port = CALLBACK_PORT) {
|
|
267
|
+
return new Promise((resolve) => {
|
|
268
|
+
const server = http.createServer();
|
|
269
|
+
server.listen(port, '127.0.0.1', () => {
|
|
270
|
+
server.close(() => resolve(true));
|
|
271
|
+
});
|
|
272
|
+
server.on('error', () => {
|
|
273
|
+
resolve(false);
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=CallbackServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallbackServer.js","sourceRoot":"","sources":["../../src/auth/CallbackServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token cache management
|
|
3
|
+
* Stores tokens in ~/.agent-chatter/auth/token-cache.json with 0600 permissions
|
|
4
|
+
*/
|
|
5
|
+
import type { AuthRegion, AuthEnvironment, TokenSet, UserInfo, CachedToken } from './types.js';
|
|
6
|
+
export declare class TokenCache {
|
|
7
|
+
private cachePath;
|
|
8
|
+
constructor(customPath?: string);
|
|
9
|
+
/**
|
|
10
|
+
* Ensure cache directory exists with proper permissions
|
|
11
|
+
*/
|
|
12
|
+
private ensureDirectory;
|
|
13
|
+
/**
|
|
14
|
+
* Read cache file
|
|
15
|
+
*/
|
|
16
|
+
private readCache;
|
|
17
|
+
/**
|
|
18
|
+
* Write cache file with 0600 permissions
|
|
19
|
+
*/
|
|
20
|
+
private writeCache;
|
|
21
|
+
/**
|
|
22
|
+
* Save tokens for a region
|
|
23
|
+
* Note: Only one region can be logged in at a time.
|
|
24
|
+
* Logging into a new region will automatically clear the other region's tokens.
|
|
25
|
+
*/
|
|
26
|
+
save(region: AuthRegion, tokens: TokenSet, userInfo: UserInfo, env?: AuthEnvironment): void;
|
|
27
|
+
/**
|
|
28
|
+
* Load tokens for a region
|
|
29
|
+
*/
|
|
30
|
+
load(region: AuthRegion): CachedToken | null;
|
|
31
|
+
/**
|
|
32
|
+
* Check if token for a region is valid (not expired)
|
|
33
|
+
*/
|
|
34
|
+
isValid(region: AuthRegion): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Check if token needs refresh (within threshold)
|
|
37
|
+
*/
|
|
38
|
+
needsRefresh(region: AuthRegion): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Clear tokens for a region
|
|
41
|
+
*/
|
|
42
|
+
clear(region: AuthRegion): void;
|
|
43
|
+
/**
|
|
44
|
+
* Clear all tokens
|
|
45
|
+
*/
|
|
46
|
+
clearAll(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Get the currently active region
|
|
49
|
+
*/
|
|
50
|
+
getActiveRegion(): AuthRegion | null;
|
|
51
|
+
/**
|
|
52
|
+
* Get the currently active environment
|
|
53
|
+
*/
|
|
54
|
+
getActiveEnv(): AuthEnvironment;
|
|
55
|
+
/**
|
|
56
|
+
* Set the active environment
|
|
57
|
+
*/
|
|
58
|
+
setActiveEnv(env: AuthEnvironment): void;
|
|
59
|
+
/**
|
|
60
|
+
* Set the active region
|
|
61
|
+
*/
|
|
62
|
+
setActiveRegion(region: AuthRegion): void;
|
|
63
|
+
/**
|
|
64
|
+
* Get access token for a region (if valid)
|
|
65
|
+
*/
|
|
66
|
+
getAccessToken(region: AuthRegion): string | null;
|
|
67
|
+
/**
|
|
68
|
+
* Get refresh token for a region
|
|
69
|
+
*/
|
|
70
|
+
getRefreshToken(region: AuthRegion): string | null;
|
|
71
|
+
/**
|
|
72
|
+
* Get user info for a region
|
|
73
|
+
*/
|
|
74
|
+
getUserInfo(region: AuthRegion): UserInfo | null;
|
|
75
|
+
/**
|
|
76
|
+
* Get cache file path (for display)
|
|
77
|
+
*/
|
|
78
|
+
getCachePath(): string;
|
|
79
|
+
}
|
|
80
|
+
export declare const tokenCache: TokenCache;
|
|
81
|
+
//# sourceMappingURL=TokenCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenCache.d.ts","sourceRoot":"","sources":["../../src/auth/TokenCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,WAAW,EAEZ,MAAM,YAAY,CAAC;AAQpB,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAS;gBAEd,UAAU,CAAC,EAAE,MAAM;IAI/B;;OAEG;IACH,OAAO,CAAC,eAAe;IAOvB;;OAEG;IACH,OAAO,CAAC,SAAS;IAoBjB;;OAEG;IACH,OAAO,CAAC,UAAU;IAQlB;;;;OAIG;IACH,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,CAAC,EAAE,eAAe,GAAG,IAAI;IAuB3F;;OAEG;IACH,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;IAK5C;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO;IAUpC;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO;IAWzC;;OAEG;IACH,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAa/B;;OAEG;IACH,QAAQ,IAAI,IAAI;IAIhB;;OAEG;IACH,eAAe,IAAI,UAAU,GAAG,IAAI;IAKpC;;OAEG;IACH,YAAY,IAAI,eAAe;IAK/B;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAMxC;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAMzC;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI;IAMjD;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI;IAKlD;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI;IAKhD;;OAEG;IACH,YAAY,IAAI,MAAM;CAGvB;AAGD,eAAO,MAAM,UAAU,YAAmB,CAAC"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token cache management
|
|
3
|
+
* Stores tokens in ~/.agent-chatter/auth/token-cache.json with 0600 permissions
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
import * as os from 'os';
|
|
8
|
+
import { TOKEN_CACHE_VERSION, REFRESH_THRESHOLD_MS, } from './AuthConfig.js';
|
|
9
|
+
/** Default cache directory */
|
|
10
|
+
const CACHE_DIR = path.join(os.homedir(), '.agent-chatter', 'auth');
|
|
11
|
+
/** Default cache file name */
|
|
12
|
+
const CACHE_FILE = 'token-cache.json';
|
|
13
|
+
export class TokenCache {
|
|
14
|
+
cachePath;
|
|
15
|
+
constructor(customPath) {
|
|
16
|
+
this.cachePath = customPath || path.join(CACHE_DIR, CACHE_FILE);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Ensure cache directory exists with proper permissions
|
|
20
|
+
*/
|
|
21
|
+
ensureDirectory() {
|
|
22
|
+
const dir = path.dirname(this.cachePath);
|
|
23
|
+
if (!fs.existsSync(dir)) {
|
|
24
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Read cache file
|
|
29
|
+
*/
|
|
30
|
+
readCache() {
|
|
31
|
+
try {
|
|
32
|
+
if (!fs.existsSync(this.cachePath)) {
|
|
33
|
+
return { version: TOKEN_CACHE_VERSION, tokens: {} };
|
|
34
|
+
}
|
|
35
|
+
const content = fs.readFileSync(this.cachePath, 'utf-8');
|
|
36
|
+
const cache = JSON.parse(content);
|
|
37
|
+
// Check version compatibility
|
|
38
|
+
if (cache.version !== TOKEN_CACHE_VERSION) {
|
|
39
|
+
// Future: handle migration
|
|
40
|
+
return { version: TOKEN_CACHE_VERSION, tokens: {} };
|
|
41
|
+
}
|
|
42
|
+
return cache;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return { version: TOKEN_CACHE_VERSION, tokens: {} };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Write cache file with 0600 permissions
|
|
50
|
+
*/
|
|
51
|
+
writeCache(cache) {
|
|
52
|
+
this.ensureDirectory();
|
|
53
|
+
const content = JSON.stringify(cache, null, 2);
|
|
54
|
+
// Write with restricted permissions (owner read/write only)
|
|
55
|
+
fs.writeFileSync(this.cachePath, content, { mode: 0o600 });
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Save tokens for a region
|
|
59
|
+
* Note: Only one region can be logged in at a time.
|
|
60
|
+
* Logging into a new region will automatically clear the other region's tokens.
|
|
61
|
+
*/
|
|
62
|
+
save(region, tokens, userInfo, env) {
|
|
63
|
+
const cache = this.readCache();
|
|
64
|
+
// Clear all existing tokens - only one region can be logged in at a time
|
|
65
|
+
cache.tokens = {};
|
|
66
|
+
const cachedToken = {
|
|
67
|
+
access_token: tokens.access_token,
|
|
68
|
+
id_token: tokens.id_token,
|
|
69
|
+
refresh_token: tokens.refresh_token,
|
|
70
|
+
token_type: tokens.token_type,
|
|
71
|
+
expires_in: tokens.expires_in,
|
|
72
|
+
obtained_at: Date.now(),
|
|
73
|
+
user_info: userInfo,
|
|
74
|
+
};
|
|
75
|
+
cache.tokens[region] = cachedToken;
|
|
76
|
+
cache.active_region = region;
|
|
77
|
+
cache.active_env = env ?? cache.active_env ?? 'prod';
|
|
78
|
+
this.writeCache(cache);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Load tokens for a region
|
|
82
|
+
*/
|
|
83
|
+
load(region) {
|
|
84
|
+
const cache = this.readCache();
|
|
85
|
+
return cache.tokens[region] || null;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Check if token for a region is valid (not expired)
|
|
89
|
+
*/
|
|
90
|
+
isValid(region) {
|
|
91
|
+
const token = this.load(region);
|
|
92
|
+
if (!token)
|
|
93
|
+
return false;
|
|
94
|
+
const age = Date.now() - token.obtained_at;
|
|
95
|
+
const expiresInMs = token.expires_in * 1000;
|
|
96
|
+
return age < expiresInMs;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Check if token needs refresh (within threshold)
|
|
100
|
+
*/
|
|
101
|
+
needsRefresh(region) {
|
|
102
|
+
const token = this.load(region);
|
|
103
|
+
if (!token)
|
|
104
|
+
return false;
|
|
105
|
+
const age = Date.now() - token.obtained_at;
|
|
106
|
+
const expiresInMs = token.expires_in * 1000;
|
|
107
|
+
const remaining = expiresInMs - age;
|
|
108
|
+
return remaining > 0 && remaining < REFRESH_THRESHOLD_MS;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Clear tokens for a region
|
|
112
|
+
*/
|
|
113
|
+
clear(region) {
|
|
114
|
+
const cache = this.readCache();
|
|
115
|
+
delete cache.tokens[region];
|
|
116
|
+
// Clear active region if it was the cleared region
|
|
117
|
+
if (cache.active_region === region) {
|
|
118
|
+
cache.active_region = undefined;
|
|
119
|
+
cache.active_env = undefined;
|
|
120
|
+
}
|
|
121
|
+
this.writeCache(cache);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Clear all tokens
|
|
125
|
+
*/
|
|
126
|
+
clearAll() {
|
|
127
|
+
this.writeCache({ version: TOKEN_CACHE_VERSION, tokens: {} });
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get the currently active region
|
|
131
|
+
*/
|
|
132
|
+
getActiveRegion() {
|
|
133
|
+
const cache = this.readCache();
|
|
134
|
+
return cache.active_region || null;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get the currently active environment
|
|
138
|
+
*/
|
|
139
|
+
getActiveEnv() {
|
|
140
|
+
const cache = this.readCache();
|
|
141
|
+
return cache.active_env || 'prod';
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Set the active environment
|
|
145
|
+
*/
|
|
146
|
+
setActiveEnv(env) {
|
|
147
|
+
const cache = this.readCache();
|
|
148
|
+
cache.active_env = env;
|
|
149
|
+
this.writeCache(cache);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Set the active region
|
|
153
|
+
*/
|
|
154
|
+
setActiveRegion(region) {
|
|
155
|
+
const cache = this.readCache();
|
|
156
|
+
cache.active_region = region;
|
|
157
|
+
this.writeCache(cache);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get access token for a region (if valid)
|
|
161
|
+
*/
|
|
162
|
+
getAccessToken(region) {
|
|
163
|
+
if (!this.isValid(region))
|
|
164
|
+
return null;
|
|
165
|
+
const token = this.load(region);
|
|
166
|
+
return token?.access_token || null;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Get refresh token for a region
|
|
170
|
+
*/
|
|
171
|
+
getRefreshToken(region) {
|
|
172
|
+
const token = this.load(region);
|
|
173
|
+
return token?.refresh_token || null;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get user info for a region
|
|
177
|
+
*/
|
|
178
|
+
getUserInfo(region) {
|
|
179
|
+
const token = this.load(region);
|
|
180
|
+
return token?.user_info || null;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get cache file path (for display)
|
|
184
|
+
*/
|
|
185
|
+
getCachePath() {
|
|
186
|
+
return this.cachePath;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// Export singleton instance
|
|
190
|
+
export const tokenCache = new TokenCache();
|
|
191
|
+
//# sourceMappingURL=TokenCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenCache.js","sourceRoot":"","sources":["../../src/auth/TokenCache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth module exports
|
|
3
|
+
*/
|
|
4
|
+
export type { AuthRegion, AuthEnvironment, TokenSet, UserInfo, CachedToken, TokenCacheFile, PKCEParams, AuthUrlResult, CallbackResult, LoginResult, AuthErrorCode, } from './types.js';
|
|
5
|
+
export { AuthError } from './types.js';
|
|
6
|
+
export { AUTH_CONFIG, REDIRECT_URI, CALLBACK_PORT, SCOPES, LOGIN_TIMEOUT_MS, REFRESH_THRESHOLD_MS, TOKEN_CACHE_VERSION, getOIDCEndpoints, isValidRegion, isValidEnvironment, getApiBaseUrl, DEFAULT_ENVIRONMENT, } from './AuthConfig.js';
|
|
7
|
+
export type { RegionConfig } from './AuthConfig.js';
|
|
8
|
+
export { TokenCache, tokenCache } from './TokenCache.js';
|
|
9
|
+
export { startCallbackServer, isPortAvailable } from './CallbackServer.js';
|
|
10
|
+
export { AuthService, createAuthService, maskToken } from './AuthService.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,UAAU,EACV,eAAe,EACf,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,cAAc,EACd,UAAU,EACV,aAAa,EACb,cAAc,EACd,WAAW,EACX,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EACL,WAAW,EACX,YAAY,EACZ,aAAa,EACb,MAAM,EACN,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGpD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGzD,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG3E,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth module exports
|
|
3
|
+
*/
|
|
4
|
+
export { AuthError } from './types.js';
|
|
5
|
+
// Config
|
|
6
|
+
export { AUTH_CONFIG, REDIRECT_URI, CALLBACK_PORT, SCOPES, LOGIN_TIMEOUT_MS, REFRESH_THRESHOLD_MS, TOKEN_CACHE_VERSION, getOIDCEndpoints, isValidRegion, isValidEnvironment, getApiBaseUrl, DEFAULT_ENVIRONMENT, } from './AuthConfig.js';
|
|
7
|
+
// Token cache
|
|
8
|
+
export { TokenCache, tokenCache } from './TokenCache.js';
|
|
9
|
+
// Callback server
|
|
10
|
+
export { startCallbackServer, isPortAvailable } from './CallbackServer.js';
|
|
11
|
+
// Auth service
|
|
12
|
+
export { AuthService, createAuthService, maskToken } from './AuthService.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAiBH,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,SAAS;AACT,OAAO,EACL,WAAW,EACX,YAAY,EACZ,aAAa,EACb,MAAM,EACN,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAIzB,cAAc;AACd,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEzD,kBAAkB;AAClB,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3E,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth module type definitions
|
|
3
|
+
*/
|
|
4
|
+
/** Supported authentication regions */
|
|
5
|
+
export type AuthRegion = 'cn' | 'us';
|
|
6
|
+
/** Supported environments */
|
|
7
|
+
export type AuthEnvironment = 'prod' | 'staging';
|
|
8
|
+
/** OAuth token set returned from Authing */
|
|
9
|
+
export interface TokenSet {
|
|
10
|
+
access_token: string;
|
|
11
|
+
id_token: string;
|
|
12
|
+
refresh_token?: string;
|
|
13
|
+
token_type: string;
|
|
14
|
+
expires_in: number;
|
|
15
|
+
}
|
|
16
|
+
/** User information from Authing userInfo endpoint */
|
|
17
|
+
export interface UserInfo {
|
|
18
|
+
sub: string;
|
|
19
|
+
email?: string;
|
|
20
|
+
email_verified?: boolean;
|
|
21
|
+
name?: string;
|
|
22
|
+
nickname?: string;
|
|
23
|
+
picture?: string;
|
|
24
|
+
preferred_username?: string;
|
|
25
|
+
}
|
|
26
|
+
/** Cached token with metadata */
|
|
27
|
+
export interface CachedToken {
|
|
28
|
+
access_token: string;
|
|
29
|
+
id_token: string;
|
|
30
|
+
refresh_token?: string;
|
|
31
|
+
token_type: string;
|
|
32
|
+
expires_in: number;
|
|
33
|
+
obtained_at: number;
|
|
34
|
+
user_info: UserInfo;
|
|
35
|
+
}
|
|
36
|
+
/** Token cache file structure */
|
|
37
|
+
export interface TokenCacheFile {
|
|
38
|
+
version: number;
|
|
39
|
+
tokens: Partial<Record<AuthRegion, CachedToken>>;
|
|
40
|
+
active_region?: AuthRegion;
|
|
41
|
+
active_env?: AuthEnvironment;
|
|
42
|
+
}
|
|
43
|
+
/** PKCE parameters */
|
|
44
|
+
export interface PKCEParams {
|
|
45
|
+
verifier: string;
|
|
46
|
+
challenge: string;
|
|
47
|
+
state: string;
|
|
48
|
+
}
|
|
49
|
+
/** Authorization URL result */
|
|
50
|
+
export interface AuthUrlResult {
|
|
51
|
+
url: string;
|
|
52
|
+
state: string;
|
|
53
|
+
verifier: string;
|
|
54
|
+
}
|
|
55
|
+
/** OAuth callback result */
|
|
56
|
+
export interface CallbackResult {
|
|
57
|
+
code: string;
|
|
58
|
+
state: string;
|
|
59
|
+
}
|
|
60
|
+
/** Login result */
|
|
61
|
+
export interface LoginResult {
|
|
62
|
+
tokens: TokenSet;
|
|
63
|
+
userInfo: UserInfo;
|
|
64
|
+
region: AuthRegion;
|
|
65
|
+
environment?: AuthEnvironment;
|
|
66
|
+
}
|
|
67
|
+
/** Auth error codes */
|
|
68
|
+
export type AuthErrorCode = 'AUTH_BROWSER_FAILED' | 'AUTH_CALLBACK_TIMEOUT' | 'AUTH_STATE_MISMATCH' | 'AUTH_TOKEN_EXCHANGE_FAILED' | 'AUTH_USER_SYNC_FAILED' | 'AUTH_REFRESH_FAILED' | 'AUTH_INVALID_REGION' | 'AUTH_PORT_IN_USE';
|
|
69
|
+
/** Custom auth error */
|
|
70
|
+
export declare class AuthError extends Error {
|
|
71
|
+
code: AuthErrorCode;
|
|
72
|
+
cause?: Error | undefined;
|
|
73
|
+
constructor(code: AuthErrorCode, message: string, cause?: Error | undefined);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=types.d.ts.map
|