@bodhiapp/bodhi-js-ext 0.0.39 → 0.0.40
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/bodhi-ext.cjs.js +1 -1
- package/dist/bodhi-ext.esm.js +479 -531
- package/dist/direct-client.d.ts +2 -1
- package/dist/ext-client.d.ts +1 -6
- package/dist/ext2ext-client.d.ts +3 -7
- package/package.json +4 -4
package/dist/bodhi-ext.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { DirectClientBase as
|
|
2
|
-
import { InMemoryStorage as
|
|
3
|
-
import { isExtError as
|
|
4
|
-
const
|
|
1
|
+
import { DirectClientBase as V, createStoragePrefixWithNamespace as X, STORAGE_PREFIXES as N, generateCodeVerifier as w, generateCodeChallenge as z, buildAuthorizeUrl as v, BASE_OAUTH_SCOPE as L, buildErrorUrl as b, AccessRequestBuilder as P, unwrapResponse as k, buildReviewUrl as O, createOperationError as d, throwAccessRequestDenialError as M, PENDING_EXTENSION_READY as f, Logger as x, NOOP_STATE_CALLBACK as Q, createExtensionStateNotInitialized as G, BACKEND_SERVER_NOT_REACHABLE as K, createExtensionStateNotFound as F, BodhiError as T, INITIAL_AUTH_STATE as H, BodhiApiError as W, Chat as J, Models as Y, Embeddings as j, Mcps as Z, isAuthError as ee, BaseFacadeClient as te, refreshAccessToken as re } from "@bodhiapp/bodhi-js-core";
|
|
2
|
+
import { InMemoryStorage as Ae } from "@bodhiapp/bodhi-js-core";
|
|
3
|
+
import { isExtError as y, isApiSuccessResponse as se, MESSAGE_TYPES as _, EXT_ACTIONS as oe, BODHI_STREAM_PORT as ie, isStreamChunk as ne, isStreamApiError as ae, isStreamError as ce, BODHI_STREAM_TEXT_PORT as he } from "@bodhiapp/bodhi-browser-types";
|
|
4
|
+
const a = {
|
|
5
5
|
EXT2EXT_CLIENT_REQUEST: "EXT2EXT_CLIENT_REQUEST",
|
|
6
6
|
EXT2EXT_CLIENT_RESPONSE: "EXT2EXT_CLIENT_RESPONSE",
|
|
7
7
|
EXT2EXT_CLIENT_BROADCAST: "EXT2EXT_CLIENT_BROADCAST",
|
|
@@ -19,18 +19,18 @@ const c = {
|
|
|
19
19
|
EXT2EXT_CLIENT_STREAM_TEXT_CHUNK: "EXT2EXT_CLIENT_STREAM_TEXT_CHUNK",
|
|
20
20
|
EXT2EXT_CLIENT_STREAM_TEXT_DONE: "EXT2EXT_CLIENT_STREAM_TEXT_DONE",
|
|
21
21
|
EXT2EXT_CLIENT_STREAM_TEXT_ERROR: "EXT2EXT_CLIENT_STREAM_TEXT_ERROR"
|
|
22
|
-
},
|
|
22
|
+
}, U = "ext2ext-client-stream", D = "ext2ext-client-stream-text", m = {
|
|
23
23
|
LOGIN: "login",
|
|
24
24
|
LOGOUT: "logout",
|
|
25
25
|
GET_AUTH_STATE: "getAuthState",
|
|
26
26
|
DISCOVER_EXTENSION: "discoverBodhiExtension",
|
|
27
27
|
GET_EXTENSION_ID: "get_extension_id",
|
|
28
28
|
SET_EXTENSION_ID: "setExtensionId"
|
|
29
|
-
},
|
|
30
|
-
function
|
|
29
|
+
}, Ee = 5e3, ue = 3, de = 500, le = 500, Te = 3e4;
|
|
30
|
+
function ge(R) {
|
|
31
31
|
return "error" in R;
|
|
32
32
|
}
|
|
33
|
-
class
|
|
33
|
+
class _e {
|
|
34
34
|
async get(e) {
|
|
35
35
|
const r = (await chrome.storage.session.get(e))[e];
|
|
36
36
|
return r !== void 0 ? String(r) : null;
|
|
@@ -42,22 +42,22 @@ class Te {
|
|
|
42
42
|
await chrome.storage.session.remove(e);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
class
|
|
45
|
+
class me extends V {
|
|
46
46
|
constructor(e, t) {
|
|
47
47
|
const r = X(
|
|
48
48
|
e.basePath,
|
|
49
49
|
N.EXT_DIRECT
|
|
50
|
-
),
|
|
50
|
+
), i = {
|
|
51
51
|
authClientId: e.authClientId,
|
|
52
52
|
authServerUrl: e.authServerUrl,
|
|
53
53
|
storagePrefix: r,
|
|
54
54
|
logLevel: e.logLevel,
|
|
55
55
|
loggerPrefix: "DirectExtClient",
|
|
56
56
|
apiTimeoutMs: e.apiTimeoutMs,
|
|
57
|
-
storage: e.storage ?? new
|
|
57
|
+
storage: e.storage ?? new _e(),
|
|
58
58
|
initialTokens: e.initialTokens
|
|
59
59
|
};
|
|
60
|
-
super(
|
|
60
|
+
super(i, t);
|
|
61
61
|
}
|
|
62
62
|
// ============================================================================
|
|
63
63
|
// Authentication (chrome.identity OAuth)
|
|
@@ -66,75 +66,68 @@ class ge extends $ {
|
|
|
66
66
|
const t = await this.getAuthState();
|
|
67
67
|
if (t.status === "authenticated")
|
|
68
68
|
return t;
|
|
69
|
-
e?.
|
|
70
|
-
const r = e?.userRole ?? "scope_user_user";
|
|
69
|
+
const r = e?.userRole ?? "scope_user_user", i = this._getRedirectUri();
|
|
71
70
|
e?.onProgress?.("requesting");
|
|
72
|
-
const
|
|
73
|
-
e?.requested && n.requested(e.requested);
|
|
74
|
-
const o = n.build(), s = await this.requestAccess(o), { id: i, review_url: h } = L(s);
|
|
75
|
-
e?.onProgress?.("reviewing"), await chrome.tabs.create({ url: h });
|
|
76
|
-
const a = await this.pollAccessRequestStatus(i, {
|
|
77
|
-
intervalMs: e?.pollIntervalMs ?? b,
|
|
78
|
-
timeoutMs: e?.pollTimeoutMs ?? P
|
|
79
|
-
});
|
|
80
|
-
if (a.status !== "approved")
|
|
81
|
-
throw l("auth_error", `Access request ${a.status}`);
|
|
82
|
-
const E = a.access_request_scope;
|
|
83
|
-
return e?.onProgress?.("authenticating"), this.performOAuthPkce(`openid profile email roles ${E ?? ""}`.trim());
|
|
84
|
-
}
|
|
85
|
-
async performOAuthPkce(e) {
|
|
86
|
-
const t = A(), r = await B(t), n = A();
|
|
71
|
+
const s = w(), o = await z(s), n = w();
|
|
87
72
|
await this._storageSet({
|
|
88
|
-
[this.storageKeys.CODE_VERIFIER]:
|
|
73
|
+
[this.storageKeys.CODE_VERIFIER]: s,
|
|
89
74
|
[this.storageKeys.STATE]: n
|
|
90
75
|
});
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (!d) {
|
|
111
|
-
await this._storageRemove([this.storageKeys.CODE_VERIFIER, this.storageKeys.STATE]), h(l("oauth_error", "No authorization code"));
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
await this.exchangeCodeForTokens(d);
|
|
115
|
-
const m = await this.getAuthState();
|
|
116
|
-
if (m.status !== "authenticated")
|
|
117
|
-
throw l("oauth_error", "Login failed");
|
|
118
|
-
this.setAuthState(m), await this._storageRemove([this.storageKeys.CODE_VERIFIER, this.storageKeys.STATE]), i(m);
|
|
119
|
-
} catch (E) {
|
|
120
|
-
await this._storageRemove([this.storageKeys.CODE_VERIFIER, this.storageKeys.STATE]), h(E);
|
|
121
|
-
}
|
|
76
|
+
const h = v(this.authEndpoints, {
|
|
77
|
+
clientId: this.authClientId,
|
|
78
|
+
redirectUri: i,
|
|
79
|
+
scope: L,
|
|
80
|
+
state: n,
|
|
81
|
+
codeChallenge: o
|
|
82
|
+
}), c = b(i), E = new P(this.authClientId).requestedRole(r);
|
|
83
|
+
e?.requested && E.requested(e.requested);
|
|
84
|
+
const l = await this.requestAccess(E.build()), { review_url: u } = k(l), g = O(u, h, c);
|
|
85
|
+
e?.onProgress?.("reviewing");
|
|
86
|
+
const S = await this.launchReview(g);
|
|
87
|
+
return e?.onProgress?.("authenticating"), this.completeOAuthRedirect(S);
|
|
88
|
+
}
|
|
89
|
+
launchReview(e) {
|
|
90
|
+
return new Promise((t, r) => {
|
|
91
|
+
chrome.identity.launchWebAuthFlow({ url: e, interactive: !0 }, (i) => {
|
|
92
|
+
if (chrome.runtime.lastError) {
|
|
93
|
+
r(chrome.runtime.lastError);
|
|
94
|
+
return;
|
|
122
95
|
}
|
|
123
|
-
|
|
96
|
+
if (!i) {
|
|
97
|
+
r(d("oauth_error", "No redirect URL received"));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
t(i);
|
|
101
|
+
});
|
|
124
102
|
});
|
|
125
103
|
}
|
|
104
|
+
async completeOAuthRedirect(e) {
|
|
105
|
+
const t = new URL(e), r = t.searchParams.get("error");
|
|
106
|
+
if (r)
|
|
107
|
+
throw await this._storageRemove([this.storageKeys.CODE_VERIFIER, this.storageKeys.STATE]), t.searchParams.get("error_source") === "bodhi" && M(r === "access_denied" ? "denied" : r), d("oauth_error", t.searchParams.get("error_description") ?? r);
|
|
108
|
+
const i = t.searchParams.get("code"), s = t.searchParams.get("state"), o = await this._storageGet(this.storageKeys.STATE);
|
|
109
|
+
if (!s || s !== o)
|
|
110
|
+
throw await this._storageRemove([this.storageKeys.CODE_VERIFIER, this.storageKeys.STATE]), d("oauth_error", "State mismatch");
|
|
111
|
+
if (!i)
|
|
112
|
+
throw await this._storageRemove([this.storageKeys.CODE_VERIFIER, this.storageKeys.STATE]), d("oauth_error", "No authorization code");
|
|
113
|
+
await this.exchangeCodeForTokens(i);
|
|
114
|
+
const n = await this.getAuthState();
|
|
115
|
+
if (n.status !== "authenticated")
|
|
116
|
+
throw await this._storageRemove([this.storageKeys.CODE_VERIFIER, this.storageKeys.STATE]), d("oauth_error", "Login failed");
|
|
117
|
+
return this.setAuthState(n), n;
|
|
118
|
+
}
|
|
126
119
|
_getRedirectUri() {
|
|
127
120
|
return chrome.identity.getRedirectURL("callback");
|
|
128
121
|
}
|
|
129
122
|
}
|
|
130
|
-
class
|
|
123
|
+
class pe {
|
|
131
124
|
constructor(e = {}, t) {
|
|
132
125
|
this.state = {
|
|
133
126
|
type: "extension",
|
|
134
127
|
extension: "not-initialized",
|
|
135
128
|
extensionId: null,
|
|
136
129
|
server: f
|
|
137
|
-
}, this.extensionId = null, this.broadcastListenerActive = !1, this.config = e, this.logger = new x("ExtClient", e?.logLevel || "warn"), this.onStateChange = t ??
|
|
130
|
+
}, this.extensionId = null, this.broadcastListenerActive = !1, this.config = e, this.logger = new x("ExtClient", e?.logLevel || "warn"), this.onStateChange = t ?? Q, this.apiTimeoutMs = e.apiTimeoutMs ?? Te, this.authClientId = e.authClientId ?? "";
|
|
138
131
|
}
|
|
139
132
|
/**
|
|
140
133
|
* Set client state and notify callback
|
|
@@ -161,7 +154,7 @@ class _e {
|
|
|
161
154
|
setupBroadcastListener() {
|
|
162
155
|
this.broadcastListenerActive || (this.broadcastListenerActive = !0, chrome.runtime.onMessage.addListener((e) => {
|
|
163
156
|
const t = e;
|
|
164
|
-
return t?.type ===
|
|
157
|
+
return t?.type === a.EXT2EXT_CLIENT_BROADCAST && t.event === "authStateChanged" && this.handleAuthStateChangedBroadcast(), !1;
|
|
165
158
|
}), this.logger.debug("Broadcast listener setup complete"));
|
|
166
159
|
}
|
|
167
160
|
/**
|
|
@@ -202,63 +195,63 @@ class _e {
|
|
|
202
195
|
async init(e = {}) {
|
|
203
196
|
if (!e.testConnection && !e.selectedConnection) {
|
|
204
197
|
this.logger.info("No testConnection or selectedConnection, returning not-initialized state");
|
|
205
|
-
const
|
|
206
|
-
return this.setState(
|
|
198
|
+
const i = G();
|
|
199
|
+
return this.setState(i), i;
|
|
207
200
|
}
|
|
208
201
|
if (this.extensionId && !e.testConnection)
|
|
209
202
|
return this.logger.debug("Already initialized with extensionId, skipping discovery"), this.state;
|
|
210
|
-
const t = e.timeoutMs ?? this.config.initParams?.extension?.timeoutMs ??
|
|
203
|
+
const t = e.timeoutMs ?? this.config.initParams?.extension?.timeoutMs ?? Ee, r = e.savedState?.extensionId;
|
|
211
204
|
try {
|
|
212
205
|
if (!this.extensionId) {
|
|
213
206
|
if (r)
|
|
214
207
|
this.logger.info("Restoring with known extensionId:", r), await this.sendExtMessageWithTimeout(
|
|
215
|
-
|
|
208
|
+
m.SET_EXTENSION_ID,
|
|
216
209
|
{ extensionId: r },
|
|
217
210
|
t
|
|
218
211
|
), this.extensionId = r;
|
|
219
212
|
else {
|
|
220
213
|
this.logger.info("Discovering bodhi-browser extension...");
|
|
221
|
-
const
|
|
214
|
+
const o = {
|
|
222
215
|
attempts: this.config.initParams?.extension?.attempts,
|
|
223
216
|
attemptWaitMs: this.config.initParams?.extension?.attemptWaitMs,
|
|
224
217
|
attemptTimeout: this.config.initParams?.extension?.attemptTimeout
|
|
225
|
-
},
|
|
226
|
-
|
|
227
|
-
|
|
218
|
+
}, n = await this.sendExtMessageWithTimeout(
|
|
219
|
+
m.DISCOVER_EXTENSION,
|
|
220
|
+
o,
|
|
228
221
|
t
|
|
229
222
|
);
|
|
230
|
-
this.extensionId =
|
|
223
|
+
this.extensionId = n.extensionId, this.logger.info("Extension discovered:", this.extensionId);
|
|
231
224
|
}
|
|
232
225
|
this.setupBroadcastListener();
|
|
233
226
|
}
|
|
234
|
-
const
|
|
227
|
+
const i = {
|
|
235
228
|
type: "extension",
|
|
236
229
|
extension: "ready",
|
|
237
230
|
extensionId: this.extensionId,
|
|
238
231
|
server: f
|
|
239
232
|
};
|
|
240
|
-
let
|
|
233
|
+
let s = f;
|
|
241
234
|
if (e.testConnection)
|
|
242
235
|
try {
|
|
243
|
-
|
|
244
|
-
} catch (
|
|
245
|
-
this.logger.error("Failed to get server state:",
|
|
236
|
+
s = await this.getServerState(), this.logger.info("Server connectivity tested, state:", s.status);
|
|
237
|
+
} catch (o) {
|
|
238
|
+
this.logger.error("Failed to get server state:", o), s = K;
|
|
246
239
|
}
|
|
247
|
-
return this.setState({ ...
|
|
248
|
-
} catch (
|
|
249
|
-
this.logger.error("Failed to initialize extension:",
|
|
250
|
-
const
|
|
251
|
-
return this.setState(
|
|
240
|
+
return this.setState({ ...i, server: s }), this.state;
|
|
241
|
+
} catch (i) {
|
|
242
|
+
this.logger.error("Failed to initialize extension:", i), this.extensionId = null;
|
|
243
|
+
const s = F();
|
|
244
|
+
return this.setState(s), this.state;
|
|
252
245
|
}
|
|
253
246
|
}
|
|
254
247
|
/**
|
|
255
248
|
* Helper method to send ext message with timeout support
|
|
256
249
|
*/
|
|
257
250
|
async sendExtMessageWithTimeout(e, t, r = 1e4) {
|
|
258
|
-
const
|
|
259
|
-
(
|
|
251
|
+
const i = new Promise(
|
|
252
|
+
(s, o) => setTimeout(() => o(new Error("Timeout")), r)
|
|
260
253
|
);
|
|
261
|
-
return Promise.race([this.sendExtRequest(e, t),
|
|
254
|
+
return Promise.race([this.sendExtRequest(e, t), i]);
|
|
262
255
|
}
|
|
263
256
|
/**
|
|
264
257
|
* Send an EXT2EXT_CLIENT_REQUEST message and await EXT2EXT_CLIENT_RESPONSE
|
|
@@ -266,29 +259,29 @@ class _e {
|
|
|
266
259
|
*/
|
|
267
260
|
async sendExtRequest(e, t) {
|
|
268
261
|
try {
|
|
269
|
-
const r = this.generateRequestId(),
|
|
270
|
-
type:
|
|
262
|
+
const r = this.generateRequestId(), i = await chrome.runtime.sendMessage({
|
|
263
|
+
type: a.EXT2EXT_CLIENT_REQUEST,
|
|
271
264
|
requestId: r,
|
|
272
265
|
request: {
|
|
273
266
|
action: e,
|
|
274
267
|
params: t
|
|
275
268
|
}
|
|
276
269
|
});
|
|
277
|
-
if (!
|
|
278
|
-
throw
|
|
279
|
-
if (
|
|
280
|
-
throw
|
|
270
|
+
if (!i)
|
|
271
|
+
throw d("extension_error", "No response from background script");
|
|
272
|
+
if (i.type !== a.EXT2EXT_CLIENT_RESPONSE)
|
|
273
|
+
throw d(
|
|
281
274
|
"extension_error",
|
|
282
275
|
"Invalid response type from background script"
|
|
283
276
|
);
|
|
284
|
-
const
|
|
285
|
-
if (
|
|
286
|
-
const
|
|
287
|
-
throw
|
|
277
|
+
const s = i.response;
|
|
278
|
+
if (y(s)) {
|
|
279
|
+
const o = s.error.type || "extension_error";
|
|
280
|
+
throw d(o, s.error.message);
|
|
288
281
|
}
|
|
289
|
-
return
|
|
282
|
+
return s;
|
|
290
283
|
} catch (r) {
|
|
291
|
-
throw r instanceof T ? r :
|
|
284
|
+
throw r instanceof T ? r : d(
|
|
292
285
|
"extension_error",
|
|
293
286
|
r instanceof Error ? r.message : "Unknown error occurred"
|
|
294
287
|
);
|
|
@@ -298,17 +291,17 @@ class _e {
|
|
|
298
291
|
* Send an API_REQUEST message and await API_RESPONSE (internal)
|
|
299
292
|
* Returns ext2ext-specific ExtClientApiResponseMessage
|
|
300
293
|
*/
|
|
301
|
-
async sendRawApiMessage(e, t, r,
|
|
302
|
-
const
|
|
294
|
+
async sendRawApiMessage(e, t, r, i, s) {
|
|
295
|
+
const o = this.generateRequestId();
|
|
303
296
|
return await chrome.runtime.sendMessage({
|
|
304
|
-
type:
|
|
305
|
-
requestId:
|
|
297
|
+
type: a.EXT2EXT_CLIENT_API_REQUEST,
|
|
298
|
+
requestId: o,
|
|
306
299
|
request: {
|
|
307
300
|
method: e,
|
|
308
301
|
endpoint: t,
|
|
309
302
|
body: r,
|
|
310
|
-
headers:
|
|
311
|
-
authenticated:
|
|
303
|
+
headers: i,
|
|
304
|
+
authenticated: s
|
|
312
305
|
}
|
|
313
306
|
});
|
|
314
307
|
}
|
|
@@ -316,31 +309,31 @@ class _e {
|
|
|
316
309
|
* Send an API message and return ApiResponse
|
|
317
310
|
* @throws BodhiError on operational errors (network, timeout, extension-level)
|
|
318
311
|
*/
|
|
319
|
-
async sendApiRequest(e, t, r,
|
|
312
|
+
async sendApiRequest(e, t, r, i, s) {
|
|
320
313
|
try {
|
|
321
|
-
const
|
|
322
|
-
(h,
|
|
323
|
-
() =>
|
|
314
|
+
const o = new Promise(
|
|
315
|
+
(h, c) => setTimeout(
|
|
316
|
+
() => c(
|
|
324
317
|
new Error(
|
|
325
318
|
`[bodhi-js-sdk/ext] network timeout: api request not completed within configured/default timeout of ${this.apiTimeoutMs}ms`
|
|
326
319
|
)
|
|
327
320
|
),
|
|
328
321
|
this.apiTimeoutMs
|
|
329
322
|
)
|
|
330
|
-
),
|
|
331
|
-
this.sendRawApiMessage(e, t, r,
|
|
332
|
-
|
|
323
|
+
), n = await Promise.race([
|
|
324
|
+
this.sendRawApiMessage(e, t, r, i, s),
|
|
325
|
+
o
|
|
333
326
|
]);
|
|
334
|
-
if (
|
|
335
|
-
const h =
|
|
336
|
-
throw new T(h,
|
|
327
|
+
if (ge(n)) {
|
|
328
|
+
const h = n.error.type || "extension_error";
|
|
329
|
+
throw new T(h, n.error.message);
|
|
337
330
|
}
|
|
338
|
-
return
|
|
339
|
-
} catch (
|
|
340
|
-
if (
|
|
341
|
-
throw
|
|
342
|
-
const
|
|
343
|
-
throw new T("network_error",
|
|
331
|
+
return n.response;
|
|
332
|
+
} catch (o) {
|
|
333
|
+
if (o instanceof T)
|
|
334
|
+
throw o;
|
|
335
|
+
const n = o instanceof Error ? o.message : String(o);
|
|
336
|
+
throw new T("network_error", n);
|
|
344
337
|
}
|
|
345
338
|
}
|
|
346
339
|
/**
|
|
@@ -351,29 +344,29 @@ class _e {
|
|
|
351
344
|
*/
|
|
352
345
|
async login(e) {
|
|
353
346
|
return new Promise((t, r) => {
|
|
354
|
-
const
|
|
355
|
-
if (
|
|
356
|
-
chrome.runtime.onMessage.removeListener(
|
|
347
|
+
const i = async (s) => {
|
|
348
|
+
if (s && typeof s == "object" && "type" in s && s.type === "EXT2EXT_CLIENT_BROADCAST" && "event" in s && s.event === "authStateChanged") {
|
|
349
|
+
chrome.runtime.onMessage.removeListener(i);
|
|
357
350
|
try {
|
|
358
|
-
const
|
|
359
|
-
if (
|
|
351
|
+
const o = await this.getAuthState();
|
|
352
|
+
if (ee(o)) {
|
|
360
353
|
r(
|
|
361
|
-
|
|
354
|
+
d("auth_error", `Login failed: ${o.error?.message}`)
|
|
362
355
|
);
|
|
363
356
|
return;
|
|
364
357
|
}
|
|
365
|
-
if (
|
|
366
|
-
r(
|
|
358
|
+
if (o.status !== "authenticated") {
|
|
359
|
+
r(d("auth_error", "Login failed: User is not logged in"));
|
|
367
360
|
return;
|
|
368
361
|
}
|
|
369
|
-
this.setAuthState(
|
|
370
|
-
} catch (
|
|
371
|
-
r(
|
|
362
|
+
this.setAuthState(o), t(o);
|
|
363
|
+
} catch (o) {
|
|
364
|
+
r(o);
|
|
372
365
|
}
|
|
373
366
|
}
|
|
374
367
|
};
|
|
375
|
-
chrome.runtime.onMessage.addListener(
|
|
376
|
-
chrome.runtime.onMessage.removeListener(
|
|
368
|
+
chrome.runtime.onMessage.addListener(i), this.sendExtRequest(m.LOGIN, e).catch((s) => {
|
|
369
|
+
chrome.runtime.onMessage.removeListener(i), r(s);
|
|
377
370
|
});
|
|
378
371
|
});
|
|
379
372
|
}
|
|
@@ -383,7 +376,7 @@ class _e {
|
|
|
383
376
|
* @returns AuthLoggedOut with logged out state
|
|
384
377
|
*/
|
|
385
378
|
async logout() {
|
|
386
|
-
await this.sendExtRequest(
|
|
379
|
+
await this.sendExtRequest(m.LOGOUT);
|
|
387
380
|
const e = {
|
|
388
381
|
status: "unauthenticated",
|
|
389
382
|
user: null,
|
|
@@ -402,8 +395,8 @@ class _e {
|
|
|
402
395
|
*/
|
|
403
396
|
async getAuthState() {
|
|
404
397
|
return this.isClientInitialized() ? (await this.sendExtRequest(
|
|
405
|
-
|
|
406
|
-
)).authState :
|
|
398
|
+
m.GET_AUTH_STATE
|
|
399
|
+
)).authState : H;
|
|
407
400
|
}
|
|
408
401
|
/**
|
|
409
402
|
* Ping bodhi-browser-ext API via /ping endpoint
|
|
@@ -419,12 +412,12 @@ class _e {
|
|
|
419
412
|
let e;
|
|
420
413
|
try {
|
|
421
414
|
e = await this.sendApiRequest("GET", "/bodhi/v1/info");
|
|
422
|
-
} catch (
|
|
423
|
-
const
|
|
415
|
+
} catch (s) {
|
|
416
|
+
const o = s instanceof Error ? s.message : "Connection failed", n = s instanceof T ? s.code : "extension_error";
|
|
424
417
|
return {
|
|
425
418
|
status: "not-reachable",
|
|
426
419
|
version: null,
|
|
427
|
-
error: { message:
|
|
420
|
+
error: { message: o, type: n }
|
|
428
421
|
};
|
|
429
422
|
}
|
|
430
423
|
if (e.status >= 400)
|
|
@@ -433,30 +426,30 @@ class _e {
|
|
|
433
426
|
version: null,
|
|
434
427
|
error: { message: "API error from server", type: "extension_error" }
|
|
435
428
|
};
|
|
436
|
-
const t = e.body, r = t.version || "unknown",
|
|
429
|
+
const t = e.body, r = t.version || "unknown", i = { deployment: t.deployment ?? null, client_id: t.client_id ?? null };
|
|
437
430
|
switch (t.status) {
|
|
438
431
|
case "ready":
|
|
439
|
-
return { status: "ready", version: r, error: null, ...
|
|
432
|
+
return { status: "ready", version: r, error: null, ...i };
|
|
440
433
|
case "setup":
|
|
441
434
|
return {
|
|
442
435
|
status: "setup",
|
|
443
436
|
version: r,
|
|
444
437
|
error: t.error ? { message: t.error.message, type: t.error.type } : { message: "Setup required", type: "extension_error" },
|
|
445
|
-
...
|
|
438
|
+
...i
|
|
446
439
|
};
|
|
447
440
|
case "resource_admin":
|
|
448
441
|
return {
|
|
449
442
|
status: "resource_admin",
|
|
450
443
|
version: r,
|
|
451
444
|
error: t.error ? { message: t.error.message, type: t.error.type } : { message: "Resource admin required", type: "extension_error" },
|
|
452
|
-
...
|
|
445
|
+
...i
|
|
453
446
|
};
|
|
454
447
|
case "error":
|
|
455
448
|
return {
|
|
456
449
|
status: "error",
|
|
457
450
|
version: r,
|
|
458
451
|
error: t.error ? { message: t.error.message, type: t.error.type } : { message: "Server error", type: "extension_error" },
|
|
459
|
-
...
|
|
452
|
+
...i
|
|
460
453
|
};
|
|
461
454
|
default:
|
|
462
455
|
return {
|
|
@@ -472,141 +465,141 @@ class _e {
|
|
|
472
465
|
/**
|
|
473
466
|
* Generic streaming method
|
|
474
467
|
*/
|
|
475
|
-
async *stream(e, t, r,
|
|
476
|
-
const
|
|
468
|
+
async *stream(e, t, r, i, s = !0) {
|
|
469
|
+
const o = this.generateRequestId();
|
|
477
470
|
this.logger.debug("Starting stream", {
|
|
478
471
|
method: e,
|
|
479
472
|
endpoint: t,
|
|
480
|
-
requestId:
|
|
473
|
+
requestId: o
|
|
481
474
|
});
|
|
482
|
-
const
|
|
475
|
+
const n = chrome.runtime.connect({ name: U }), c = new ReadableStream({
|
|
483
476
|
start: (E) => {
|
|
484
|
-
|
|
485
|
-
if (
|
|
486
|
-
switch (
|
|
487
|
-
case
|
|
488
|
-
this.logger.debug("Stream complete", { requestId:
|
|
477
|
+
n.onMessage.addListener((l) => {
|
|
478
|
+
if (l.requestId === o)
|
|
479
|
+
switch (l.type) {
|
|
480
|
+
case a.EXT2EXT_CLIENT_STREAM_DONE:
|
|
481
|
+
this.logger.debug("Stream complete", { requestId: o }), E.close(), n.disconnect();
|
|
489
482
|
break;
|
|
490
|
-
case
|
|
483
|
+
case a.EXT2EXT_CLIENT_STREAM_ERROR:
|
|
491
484
|
this.logger.error("Stream error", {
|
|
492
|
-
requestId:
|
|
493
|
-
error: JSON.stringify(
|
|
485
|
+
requestId: o,
|
|
486
|
+
error: JSON.stringify(l.error)
|
|
494
487
|
}), E.error(
|
|
495
488
|
new T(
|
|
496
489
|
"extension_error",
|
|
497
|
-
|
|
490
|
+
l.error.message
|
|
498
491
|
)
|
|
499
|
-
),
|
|
492
|
+
), n.disconnect();
|
|
500
493
|
break;
|
|
501
|
-
case
|
|
502
|
-
const u =
|
|
494
|
+
case a.EXT2EXT_CLIENT_STREAM_API_ERROR: {
|
|
495
|
+
const u = l;
|
|
503
496
|
this.logger.error("Stream API error", {
|
|
504
|
-
requestId:
|
|
497
|
+
requestId: o,
|
|
505
498
|
error: u.response.body?.error
|
|
506
499
|
}), E.error(
|
|
507
|
-
new
|
|
500
|
+
new W(
|
|
508
501
|
u.response.status,
|
|
509
502
|
u.response.body,
|
|
510
503
|
u.response.body?.error?.message || "API error"
|
|
511
504
|
)
|
|
512
|
-
),
|
|
505
|
+
), n.disconnect();
|
|
513
506
|
break;
|
|
514
507
|
}
|
|
515
|
-
case
|
|
516
|
-
const u =
|
|
517
|
-
|
|
508
|
+
case a.EXT2EXT_CLIENT_STREAM_CHUNK: {
|
|
509
|
+
const u = l;
|
|
510
|
+
se(u.response) && E.enqueue(u.response.body);
|
|
518
511
|
break;
|
|
519
512
|
}
|
|
520
513
|
}
|
|
521
|
-
}),
|
|
522
|
-
this.logger.debug("Port disconnected", { requestId:
|
|
514
|
+
}), n.onDisconnect.addListener(() => {
|
|
515
|
+
this.logger.debug("Port disconnected", { requestId: o });
|
|
523
516
|
try {
|
|
524
517
|
E.error(new T("connection_closed", "Connection closed unexpectedly"));
|
|
525
518
|
} catch {
|
|
526
519
|
}
|
|
527
|
-
}),
|
|
528
|
-
type:
|
|
529
|
-
requestId:
|
|
530
|
-
request: { method: e, endpoint: t, body: r, headers:
|
|
520
|
+
}), n.postMessage({
|
|
521
|
+
type: a.EXT2EXT_CLIENT_STREAM_REQUEST,
|
|
522
|
+
requestId: o,
|
|
523
|
+
request: { method: e, endpoint: t, body: r, headers: i, authenticated: s }
|
|
531
524
|
});
|
|
532
525
|
}
|
|
533
526
|
}).getReader();
|
|
534
527
|
try {
|
|
535
528
|
for (; ; ) {
|
|
536
|
-
const { done: E, value:
|
|
529
|
+
const { done: E, value: l } = await c.read();
|
|
537
530
|
if (E) {
|
|
538
531
|
this.logger.debug("Stream iteration complete");
|
|
539
532
|
break;
|
|
540
533
|
}
|
|
541
|
-
yield
|
|
534
|
+
yield l;
|
|
542
535
|
}
|
|
543
536
|
} finally {
|
|
544
|
-
|
|
537
|
+
c.releaseLock();
|
|
545
538
|
}
|
|
546
539
|
}
|
|
547
540
|
/**
|
|
548
541
|
* Raw text streaming method - no SSE/JSON parsing
|
|
549
542
|
* Returns status, headers, and async generator of raw text chunks
|
|
550
543
|
*/
|
|
551
|
-
async streamText(e, t, r,
|
|
552
|
-
const
|
|
553
|
-
return new Promise((
|
|
554
|
-
let
|
|
555
|
-
const
|
|
544
|
+
async streamText(e, t, r, i, s = !0) {
|
|
545
|
+
const o = this.generateRequestId();
|
|
546
|
+
return new Promise((n, h) => {
|
|
547
|
+
let c, E = !1;
|
|
548
|
+
const l = new ReadableStream({
|
|
556
549
|
start: (g) => {
|
|
557
|
-
|
|
550
|
+
c = g;
|
|
558
551
|
}
|
|
559
|
-
}), u = chrome.runtime.connect({ name:
|
|
552
|
+
}), u = chrome.runtime.connect({ name: D });
|
|
560
553
|
u.onMessage.addListener((g) => {
|
|
561
|
-
if (g.requestId ===
|
|
554
|
+
if (g.requestId === o)
|
|
562
555
|
switch (g.type) {
|
|
563
|
-
case
|
|
556
|
+
case a.EXT2EXT_CLIENT_STREAM_TEXT_START: {
|
|
564
557
|
E = !0;
|
|
565
|
-
async function*
|
|
566
|
-
const C =
|
|
558
|
+
async function* S(q) {
|
|
559
|
+
const C = q.getReader();
|
|
567
560
|
try {
|
|
568
561
|
for (; ; ) {
|
|
569
|
-
const { done:
|
|
570
|
-
if (
|
|
571
|
-
yield
|
|
562
|
+
const { done: $, value: B } = await C.read();
|
|
563
|
+
if ($) break;
|
|
564
|
+
yield B;
|
|
572
565
|
}
|
|
573
566
|
} finally {
|
|
574
567
|
C.releaseLock();
|
|
575
568
|
}
|
|
576
569
|
}
|
|
577
|
-
|
|
570
|
+
n({
|
|
578
571
|
status: g.status,
|
|
579
572
|
headers: g.headers,
|
|
580
|
-
body:
|
|
573
|
+
body: S(l)
|
|
581
574
|
});
|
|
582
575
|
break;
|
|
583
576
|
}
|
|
584
|
-
case
|
|
585
|
-
|
|
577
|
+
case a.EXT2EXT_CLIENT_STREAM_TEXT_CHUNK:
|
|
578
|
+
c.enqueue(g.chunk);
|
|
586
579
|
break;
|
|
587
|
-
case
|
|
588
|
-
|
|
580
|
+
case a.EXT2EXT_CLIENT_STREAM_TEXT_DONE:
|
|
581
|
+
c.close(), u.disconnect();
|
|
589
582
|
break;
|
|
590
|
-
case
|
|
591
|
-
const
|
|
592
|
-
E ?
|
|
583
|
+
case a.EXT2EXT_CLIENT_STREAM_TEXT_ERROR: {
|
|
584
|
+
const S = d("extension_error", g.error.message);
|
|
585
|
+
E ? c.error(S) : h(S), u.disconnect();
|
|
593
586
|
break;
|
|
594
587
|
}
|
|
595
588
|
}
|
|
596
589
|
}), u.onDisconnect.addListener(() => {
|
|
597
590
|
if (!E)
|
|
598
|
-
h(
|
|
591
|
+
h(d("extension_error", "Connection closed unexpectedly"));
|
|
599
592
|
else
|
|
600
593
|
try {
|
|
601
|
-
|
|
602
|
-
|
|
594
|
+
c.error(
|
|
595
|
+
d("extension_error", "Connection closed unexpectedly")
|
|
603
596
|
);
|
|
604
597
|
} catch {
|
|
605
598
|
}
|
|
606
599
|
}), u.postMessage({
|
|
607
|
-
type:
|
|
608
|
-
requestId:
|
|
609
|
-
request: { method: e, endpoint: t, body: r, headers:
|
|
600
|
+
type: a.EXT2EXT_CLIENT_STREAM_TEXT_REQUEST,
|
|
601
|
+
requestId: o,
|
|
602
|
+
request: { method: e, endpoint: t, body: r, headers: i, authenticated: s }
|
|
610
603
|
});
|
|
611
604
|
});
|
|
612
605
|
}
|
|
@@ -614,16 +607,16 @@ class _e {
|
|
|
614
607
|
// OpenAI-Compatible Namespaced API
|
|
615
608
|
// ============================================================================
|
|
616
609
|
get chat() {
|
|
617
|
-
return this._chat ??= new
|
|
610
|
+
return this._chat ??= new J(this);
|
|
618
611
|
}
|
|
619
612
|
get models() {
|
|
620
|
-
return this._models ??= new
|
|
613
|
+
return this._models ??= new Y(this);
|
|
621
614
|
}
|
|
622
615
|
get embeddings() {
|
|
623
|
-
return this._embeddings ??= new
|
|
616
|
+
return this._embeddings ??= new j(this);
|
|
624
617
|
}
|
|
625
618
|
get mcps() {
|
|
626
|
-
return this._mcps ??= new
|
|
619
|
+
return this._mcps ??= new Z(this);
|
|
627
620
|
}
|
|
628
621
|
// ============================================================================
|
|
629
622
|
// Access Request Methods
|
|
@@ -637,22 +630,6 @@ class _e {
|
|
|
637
630
|
!1
|
|
638
631
|
);
|
|
639
632
|
}
|
|
640
|
-
async getAccessRequestStatus(e) {
|
|
641
|
-
return this.sendApiRequest(
|
|
642
|
-
"GET",
|
|
643
|
-
`/bodhi/v1/apps/access-requests/${e}?app_client_id=${encodeURIComponent(this.authClientId)}`,
|
|
644
|
-
void 0,
|
|
645
|
-
{},
|
|
646
|
-
!1
|
|
647
|
-
);
|
|
648
|
-
}
|
|
649
|
-
async pollAccessRequestStatus(e, t) {
|
|
650
|
-
return k(
|
|
651
|
-
(r) => this.getAccessRequestStatus(r),
|
|
652
|
-
e,
|
|
653
|
-
t
|
|
654
|
-
);
|
|
655
|
-
}
|
|
656
633
|
/**
|
|
657
634
|
* Serialize ext2ext client state for persistence
|
|
658
635
|
*/
|
|
@@ -670,18 +647,18 @@ class _e {
|
|
|
670
647
|
};
|
|
671
648
|
}
|
|
672
649
|
}
|
|
673
|
-
class
|
|
650
|
+
class ye extends te {
|
|
674
651
|
constructor(e, t, r) {
|
|
675
|
-
const
|
|
676
|
-
basePath:
|
|
677
|
-
authServerUrl:
|
|
678
|
-
logLevel:
|
|
679
|
-
apiTimeoutMs:
|
|
680
|
-
storage:
|
|
681
|
-
initialTokens:
|
|
682
|
-
initParams:
|
|
652
|
+
const i = t || {}, s = {
|
|
653
|
+
basePath: i.basePath || "/",
|
|
654
|
+
authServerUrl: i.authServerUrl || "https://id.getbodhi.app/realms/bodhi",
|
|
655
|
+
logLevel: i.logLevel || "warn",
|
|
656
|
+
apiTimeoutMs: i.apiTimeoutMs,
|
|
657
|
+
storage: i.storage,
|
|
658
|
+
initialTokens: i.initialTokens,
|
|
659
|
+
initParams: i.initParams
|
|
683
660
|
};
|
|
684
|
-
super(e,
|
|
661
|
+
super(e, s, r);
|
|
685
662
|
}
|
|
686
663
|
createLogger(e) {
|
|
687
664
|
return new x("ExtUIClient", e.logLevel);
|
|
@@ -690,7 +667,7 @@ class fe extends j {
|
|
|
690
667
|
return X(e.basePath, N.EXT);
|
|
691
668
|
}
|
|
692
669
|
createExtClient(e, t) {
|
|
693
|
-
return new
|
|
670
|
+
return new pe(
|
|
694
671
|
{
|
|
695
672
|
authClientId: this.authClientId,
|
|
696
673
|
logLevel: e.logLevel,
|
|
@@ -701,7 +678,7 @@ class fe extends j {
|
|
|
701
678
|
);
|
|
702
679
|
}
|
|
703
680
|
createDirectClient(e, t, r) {
|
|
704
|
-
return new
|
|
681
|
+
return new me(
|
|
705
682
|
{
|
|
706
683
|
authClientId: e,
|
|
707
684
|
authServerUrl: t.authServerUrl,
|
|
@@ -715,12 +692,12 @@ class fe extends j {
|
|
|
715
692
|
);
|
|
716
693
|
}
|
|
717
694
|
}
|
|
718
|
-
const
|
|
695
|
+
const Se = ["ggedphdcbekjlomjaidbajglgihbeaon"], Re = ["bjdjhiombmfbcoeojijpfckljjghmjbf"], I = "production", p = class p {
|
|
719
696
|
// ============================================================================
|
|
720
697
|
// Constructor
|
|
721
698
|
// ============================================================================
|
|
722
699
|
constructor(e, t) {
|
|
723
|
-
this.isAuthenticating = !1, this.state = "setup", this.listenersInitialized = !1, this.refreshPromise = null, this.activeStreamPorts = /* @__PURE__ */ new Map(), this.authClientId = e, this.authServerUrl = t?.authServerUrl || "https://id.getbodhi.app/realms/bodhi", this.extensionId = t?.extensionId, this.logger = new x("BodhiExtClient", t?.logLevel || "warn"), this.attempts = t?.attempts ??
|
|
700
|
+
this.isAuthenticating = !1, this.state = "setup", this.listenersInitialized = !1, this.refreshPromise = null, this.activeStreamPorts = /* @__PURE__ */ new Map(), this.authClientId = e, this.authServerUrl = t?.authServerUrl || "https://id.getbodhi.app/realms/bodhi", this.extensionId = t?.extensionId, this.logger = new x("BodhiExtClient", t?.logLevel || "warn"), this.attempts = t?.attempts ?? ue, this.attemptWaitMs = t?.attemptWaitMs ?? de, this.attemptTimeout = t?.attemptTimeout ?? le, this.authEndpoints = {
|
|
724
701
|
authorize: `${this.authServerUrl}/protocol/openid-connect/auth`,
|
|
725
702
|
token: `${this.authServerUrl}/protocol/openid-connect/token`,
|
|
726
703
|
userinfo: `${this.authServerUrl}/protocol/openid-connect/userinfo`,
|
|
@@ -738,11 +715,11 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
738
715
|
}
|
|
739
716
|
static generateCodeVerifier() {
|
|
740
717
|
const e = new Uint8Array(32);
|
|
741
|
-
return crypto.getRandomValues(e),
|
|
718
|
+
return crypto.getRandomValues(e), p.base64UrlEncode(e.buffer);
|
|
742
719
|
}
|
|
743
720
|
static async generateCodeChallenge(e) {
|
|
744
|
-
const r = new TextEncoder().encode(e),
|
|
745
|
-
return
|
|
721
|
+
const r = new TextEncoder().encode(e), i = await crypto.subtle.digest("SHA-256", r);
|
|
722
|
+
return p.base64UrlEncode(i);
|
|
746
723
|
}
|
|
747
724
|
// ============================================================================
|
|
748
725
|
// State Management
|
|
@@ -761,7 +738,7 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
761
738
|
* Get extension IDs for current environment
|
|
762
739
|
*/
|
|
763
740
|
getExtensionIdsForEnvironment() {
|
|
764
|
-
const t =
|
|
741
|
+
const t = I !== "production" ? Se : Re;
|
|
765
742
|
return this.logger.info("[Ext2Ext/Registry] Environment: production"), this.logger.debug("[Ext2Ext/Registry] Using extension IDs:", t), t;
|
|
766
743
|
}
|
|
767
744
|
/**
|
|
@@ -771,34 +748,34 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
771
748
|
return this.logger.debug(
|
|
772
749
|
`[Ext2Ext/Discovery] Pinging extension: ${e} with timeout ${this.attemptTimeout}ms`
|
|
773
750
|
), new Promise((t, r) => {
|
|
774
|
-
const
|
|
751
|
+
const i = setTimeout(() => {
|
|
775
752
|
this.logger.debug(`[Ext2Ext/Discovery] Timeout waiting for extension ${e}`), r(new Error("Timeout"));
|
|
776
753
|
}, this.attemptTimeout);
|
|
777
754
|
try {
|
|
778
|
-
const
|
|
755
|
+
const s = {
|
|
779
756
|
type: _.EXT_REQUEST,
|
|
780
757
|
requestId: crypto.randomUUID(),
|
|
781
758
|
request: {
|
|
782
759
|
action: "get_extension_id"
|
|
783
760
|
}
|
|
784
761
|
};
|
|
785
|
-
this.logger.debug(`[Ext2Ext/Discovery] Sending message to ${e}:`,
|
|
786
|
-
if (clearTimeout(
|
|
762
|
+
this.logger.debug(`[Ext2Ext/Discovery] Sending message to ${e}:`, s), chrome.runtime.sendMessage(e, s, (o) => {
|
|
763
|
+
if (clearTimeout(i), chrome.runtime.lastError) {
|
|
787
764
|
this.logger.error(
|
|
788
765
|
`[Ext2Ext/Discovery] Error from extension ${e}:`,
|
|
789
766
|
chrome.runtime.lastError.message
|
|
790
767
|
), r(new Error(chrome.runtime.lastError.message));
|
|
791
768
|
return;
|
|
792
769
|
}
|
|
793
|
-
this.logger.debug(`[Ext2Ext/Discovery] Response from ${e}:`,
|
|
794
|
-
const
|
|
795
|
-
|
|
770
|
+
this.logger.debug(`[Ext2Ext/Discovery] Response from ${e}:`, o);
|
|
771
|
+
const n = o;
|
|
772
|
+
n && n.type === _.EXT_RESPONSE ? (this.logger.debug(`[Ext2Ext/Discovery] ✓ Extension ${e} responded`), t(!0)) : (this.logger.error(
|
|
796
773
|
`[Ext2Ext/Discovery] Invalid response from ${e}:`,
|
|
797
|
-
|
|
774
|
+
o
|
|
798
775
|
), r(new Error("Invalid response")));
|
|
799
776
|
});
|
|
800
|
-
} catch (
|
|
801
|
-
this.logger.error(`[Ext2Ext/Discovery] Exception pinging ${e}:`,
|
|
777
|
+
} catch (s) {
|
|
778
|
+
this.logger.error(`[Ext2Ext/Discovery] Exception pinging ${e}:`, s), clearTimeout(i), r(s);
|
|
802
779
|
}
|
|
803
780
|
});
|
|
804
781
|
}
|
|
@@ -813,39 +790,39 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
813
790
|
* @param params Resolved discovery params
|
|
814
791
|
*/
|
|
815
792
|
async discoverBodhiExtension(e) {
|
|
816
|
-
const { attempts: t, attemptWaitMs: r, attemptTimeout:
|
|
793
|
+
const { attempts: t, attemptWaitMs: r, attemptTimeout: i } = e;
|
|
817
794
|
this.logger.info(
|
|
818
|
-
`[Ext2Ext/Discovery] Starting discovery: ${t} attempts per ID, ${
|
|
795
|
+
`[Ext2Ext/Discovery] Starting discovery: ${t} attempts per ID, ${i}ms timeout, ${r}ms between attempts`
|
|
819
796
|
);
|
|
820
|
-
const
|
|
797
|
+
const s = this.getExtensionIdsForEnvironment();
|
|
821
798
|
this.logger.debug(
|
|
822
|
-
`[Ext2Ext/Discovery] Will try ${
|
|
823
|
-
|
|
799
|
+
`[Ext2Ext/Discovery] Will try ${s.length} extension(s):`,
|
|
800
|
+
s
|
|
824
801
|
);
|
|
825
|
-
for (const h of
|
|
826
|
-
for (let
|
|
802
|
+
for (const h of s) {
|
|
803
|
+
for (let c = 1; c <= t; c++) {
|
|
827
804
|
this.logger.debug(
|
|
828
|
-
`[Ext2Ext/Discovery] Trying ${h} - attempt ${
|
|
805
|
+
`[Ext2Ext/Discovery] Trying ${h} - attempt ${c}/${t}`
|
|
829
806
|
);
|
|
830
807
|
try {
|
|
831
|
-
return await this.pingExtension(h), this.logger.info(`[Ext2Ext/Discovery] ✓ Found: ${h} on attempt ${
|
|
808
|
+
return await this.pingExtension(h), this.logger.info(`[Ext2Ext/Discovery] ✓ Found: ${h} on attempt ${c}`), {
|
|
832
809
|
success: !0,
|
|
833
810
|
extensionId: h
|
|
834
811
|
};
|
|
835
812
|
} catch (E) {
|
|
836
813
|
this.logger.debug(
|
|
837
|
-
`[Ext2Ext/Discovery] Attempt ${
|
|
838
|
-
),
|
|
814
|
+
`[Ext2Ext/Discovery] Attempt ${c} failed for ${h}: ${E instanceof Error ? E.message : "Unknown error"}`
|
|
815
|
+
), c < t && await this.sleep(r);
|
|
839
816
|
}
|
|
840
817
|
}
|
|
841
818
|
this.logger.warn(
|
|
842
819
|
`[Ext2Ext/Discovery] ✗ Not found: ${h} after ${t} attempts`
|
|
843
820
|
);
|
|
844
821
|
}
|
|
845
|
-
const
|
|
846
|
-
return this.logger.error(`[Ext2Ext/Discovery] ${
|
|
822
|
+
const o = s.join(", "), n = `Extension not found. Tried ${s.length} IDs with ${t} attempts each: ${o}`;
|
|
823
|
+
return this.logger.error(`[Ext2Ext/Discovery] ${n}`), {
|
|
847
824
|
success: !1,
|
|
848
|
-
error:
|
|
825
|
+
error: n
|
|
849
826
|
};
|
|
850
827
|
}
|
|
851
828
|
// ============================================================================
|
|
@@ -859,8 +836,8 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
859
836
|
this.logger.debug("[BodhiExtClient] Listeners already initialized, skipping");
|
|
860
837
|
return;
|
|
861
838
|
}
|
|
862
|
-
this.listenersInitialized = !0, chrome.runtime.onMessage.addListener((e, t, r) => e.type !==
|
|
863
|
-
type:
|
|
839
|
+
this.listenersInitialized = !0, chrome.runtime.onMessage.addListener((e, t, r) => e.type !== a.EXT2EXT_CLIENT_REQUEST && e.type !== a.EXT2EXT_CLIENT_API_REQUEST ? !1 : this.state !== "ready" && !(e.type === a.EXT2EXT_CLIENT_REQUEST && e.request.action === m.DISCOVER_EXTENSION) ? (e.type === a.EXT2EXT_CLIENT_REQUEST ? r({
|
|
840
|
+
type: a.EXT2EXT_CLIENT_RESPONSE,
|
|
864
841
|
requestId: e.requestId,
|
|
865
842
|
response: {
|
|
866
843
|
error: {
|
|
@@ -869,24 +846,24 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
869
846
|
}
|
|
870
847
|
}
|
|
871
848
|
}) : r({
|
|
872
|
-
type:
|
|
849
|
+
type: a.EXT2EXT_CLIENT_API_RESPONSE,
|
|
873
850
|
requestId: e.requestId,
|
|
874
851
|
error: {
|
|
875
852
|
message: `Client not initialized. Extension discovery not complete, cannot handle type:${e.type}, message:${JSON.stringify(e)}`,
|
|
876
853
|
type: "NOT_INITIALIZED"
|
|
877
854
|
}
|
|
878
855
|
}), !0) : (this.logger.debug(`[BodhiExtClient] Processing message.type=${e.type}`), (async () => {
|
|
879
|
-
const
|
|
880
|
-
r(
|
|
856
|
+
const i = await this.handleAction(e);
|
|
857
|
+
r(i);
|
|
881
858
|
})(), !0)), this.registerStreamPortListener(
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
859
|
+
U,
|
|
860
|
+
a.EXT2EXT_CLIENT_STREAM_REQUEST,
|
|
861
|
+
a.EXT2EXT_CLIENT_STREAM_ERROR,
|
|
885
862
|
(e, t) => this.handleStreamRequest(e, t)
|
|
886
863
|
), this.registerStreamPortListener(
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
864
|
+
D,
|
|
865
|
+
a.EXT2EXT_CLIENT_STREAM_TEXT_REQUEST,
|
|
866
|
+
a.EXT2EXT_CLIENT_STREAM_TEXT_ERROR,
|
|
890
867
|
(e, t) => this.handleStreamTextRequest(e, t)
|
|
891
868
|
), this.logger.info("[BodhiExtClient] Streaming listeners initialized");
|
|
892
869
|
}
|
|
@@ -918,7 +895,7 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
918
895
|
*/
|
|
919
896
|
broadcastAuthStateChange() {
|
|
920
897
|
chrome.runtime.sendMessage({
|
|
921
|
-
type:
|
|
898
|
+
type: a.EXT2EXT_CLIENT_BROADCAST,
|
|
922
899
|
event: "authStateChanged"
|
|
923
900
|
}).catch((e) => {
|
|
924
901
|
this.logger.debug("[BodhiExtClient] No listeners for broadcast:", e.message);
|
|
@@ -945,10 +922,10 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
945
922
|
try {
|
|
946
923
|
let r = e.request.headers || {};
|
|
947
924
|
if (e.request.authenticated) {
|
|
948
|
-
const
|
|
949
|
-
if (!
|
|
925
|
+
const s = await this._getAccessTokenRaw();
|
|
926
|
+
if (!s)
|
|
950
927
|
return {
|
|
951
|
-
type:
|
|
928
|
+
type: a.EXT2EXT_CLIENT_API_RESPONSE,
|
|
952
929
|
requestId: t,
|
|
953
930
|
error: {
|
|
954
931
|
message: "Not authenticated. Please log in first.",
|
|
@@ -957,23 +934,23 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
957
934
|
};
|
|
958
935
|
r = {
|
|
959
936
|
...r,
|
|
960
|
-
Authorization: `Bearer ${
|
|
937
|
+
Authorization: `Bearer ${s}`
|
|
961
938
|
}, this.logger.debug("[BodhiExtClient] Injected auth token for authenticated request");
|
|
962
939
|
}
|
|
963
|
-
const
|
|
940
|
+
const i = await this.sendApiRequest(
|
|
964
941
|
e.request.method,
|
|
965
942
|
e.request.endpoint,
|
|
966
943
|
e.request.body,
|
|
967
944
|
r
|
|
968
945
|
);
|
|
969
946
|
return {
|
|
970
|
-
type:
|
|
947
|
+
type: a.EXT2EXT_CLIENT_API_RESPONSE,
|
|
971
948
|
requestId: t,
|
|
972
|
-
response:
|
|
949
|
+
response: i
|
|
973
950
|
};
|
|
974
951
|
} catch (r) {
|
|
975
952
|
return this.logger.error("[BodhiExtClient] API request failed:", r), {
|
|
976
|
-
type:
|
|
953
|
+
type: a.EXT2EXT_CLIENT_API_RESPONSE,
|
|
977
954
|
requestId: t,
|
|
978
955
|
error: {
|
|
979
956
|
message: r instanceof Error ? r.message : "Unknown error",
|
|
@@ -989,76 +966,76 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
989
966
|
* @returns Action response message (success or error)
|
|
990
967
|
*/
|
|
991
968
|
async handleExtClientRequest(e) {
|
|
992
|
-
const { requestId: t, request: r } = e, { action:
|
|
993
|
-
this.logger.debug(`[BodhiExtClient] Handling action: ${
|
|
969
|
+
const { requestId: t, request: r } = e, { action: i, params: s } = r;
|
|
970
|
+
this.logger.debug(`[BodhiExtClient] Handling action: ${i}`);
|
|
994
971
|
try {
|
|
995
|
-
let
|
|
996
|
-
switch (
|
|
997
|
-
case
|
|
998
|
-
const
|
|
999
|
-
await this.init(
|
|
972
|
+
let o = {};
|
|
973
|
+
switch (i) {
|
|
974
|
+
case m.DISCOVER_EXTENSION: {
|
|
975
|
+
const n = s;
|
|
976
|
+
await this.init(n), this.logger.info("[BodhiExtClient] Discovery successful:", {
|
|
1000
977
|
extensionId: this.extensionId,
|
|
1001
|
-
environment:
|
|
1002
|
-
}),
|
|
978
|
+
environment: I
|
|
979
|
+
}), o = {
|
|
1003
980
|
extensionId: this.extensionId,
|
|
1004
|
-
environment:
|
|
981
|
+
environment: I
|
|
1005
982
|
};
|
|
1006
983
|
break;
|
|
1007
984
|
}
|
|
1008
|
-
case
|
|
1009
|
-
const { extensionId:
|
|
1010
|
-
this.extensionId =
|
|
985
|
+
case m.SET_EXTENSION_ID: {
|
|
986
|
+
const { extensionId: n } = s;
|
|
987
|
+
this.extensionId = n, this.state = "ready", this.logger.info("[BodhiExtClient] Extension ID set:", { extensionId: n }), o = { success: !0 };
|
|
1011
988
|
break;
|
|
1012
989
|
}
|
|
1013
|
-
case
|
|
1014
|
-
const
|
|
1015
|
-
return
|
|
1016
|
-
type:
|
|
990
|
+
case m.GET_EXTENSION_ID: {
|
|
991
|
+
const n = await this.sendExtRequestRaw(oe.GET_EXTENSION_ID, s);
|
|
992
|
+
return y(n.response) ? {
|
|
993
|
+
type: a.EXT2EXT_CLIENT_RESPONSE,
|
|
1017
994
|
requestId: t,
|
|
1018
995
|
response: {
|
|
1019
996
|
error: {
|
|
1020
|
-
message:
|
|
1021
|
-
type:
|
|
997
|
+
message: n.response.error.message || `Extension request failed to get extension ID: ${JSON.stringify(n.response)}`,
|
|
998
|
+
type: n.response.error.type
|
|
1022
999
|
}
|
|
1023
1000
|
}
|
|
1024
1001
|
} : {
|
|
1025
|
-
type:
|
|
1002
|
+
type: a.EXT2EXT_CLIENT_RESPONSE,
|
|
1026
1003
|
requestId: t,
|
|
1027
|
-
response:
|
|
1004
|
+
response: n.response
|
|
1028
1005
|
};
|
|
1029
1006
|
}
|
|
1030
|
-
case
|
|
1031
|
-
const
|
|
1032
|
-
await this.login(
|
|
1007
|
+
case m.LOGIN: {
|
|
1008
|
+
const n = s;
|
|
1009
|
+
await this.login(n), this.broadcastAuthStateChange();
|
|
1033
1010
|
break;
|
|
1034
1011
|
}
|
|
1035
|
-
case
|
|
1012
|
+
case m.LOGOUT:
|
|
1036
1013
|
await this.logout(), this.broadcastAuthStateChange();
|
|
1037
1014
|
break;
|
|
1038
|
-
case
|
|
1039
|
-
|
|
1015
|
+
case m.GET_AUTH_STATE:
|
|
1016
|
+
o = { authState: await this.getAuthState() };
|
|
1040
1017
|
break;
|
|
1041
1018
|
default:
|
|
1042
1019
|
return {
|
|
1043
|
-
type:
|
|
1020
|
+
type: a.EXT2EXT_CLIENT_RESPONSE,
|
|
1044
1021
|
requestId: t,
|
|
1045
1022
|
response: {
|
|
1046
|
-
error: { message: `Unknown action: ${
|
|
1023
|
+
error: { message: `Unknown action: ${i}`, type: "UNKNOWN_ACTION" }
|
|
1047
1024
|
}
|
|
1048
1025
|
};
|
|
1049
1026
|
}
|
|
1050
1027
|
return {
|
|
1051
|
-
type:
|
|
1028
|
+
type: a.EXT2EXT_CLIENT_RESPONSE,
|
|
1052
1029
|
requestId: t,
|
|
1053
|
-
response:
|
|
1030
|
+
response: o
|
|
1054
1031
|
};
|
|
1055
|
-
} catch (
|
|
1056
|
-
return this.logger.error("[BodhiExtClient] Unexpected error:",
|
|
1057
|
-
type:
|
|
1032
|
+
} catch (o) {
|
|
1033
|
+
return this.logger.error("[BodhiExtClient] Unexpected error:", o), {
|
|
1034
|
+
type: a.EXT2EXT_CLIENT_RESPONSE,
|
|
1058
1035
|
requestId: t,
|
|
1059
1036
|
response: {
|
|
1060
1037
|
error: {
|
|
1061
|
-
message:
|
|
1038
|
+
message: o instanceof Error ? o.message : `Unexpected error: ${JSON.stringify(o)}`
|
|
1062
1039
|
}
|
|
1063
1040
|
}
|
|
1064
1041
|
};
|
|
@@ -1067,14 +1044,14 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1067
1044
|
// Implementation signature (must be compatible with all overloads)
|
|
1068
1045
|
async handleAction(e) {
|
|
1069
1046
|
switch (e.type) {
|
|
1070
|
-
case
|
|
1047
|
+
case a.EXT2EXT_CLIENT_API_REQUEST:
|
|
1071
1048
|
return this.handleApiRequest(e);
|
|
1072
|
-
case
|
|
1049
|
+
case a.EXT2EXT_CLIENT_REQUEST:
|
|
1073
1050
|
return this.handleExtClientRequest(e);
|
|
1074
1051
|
default: {
|
|
1075
1052
|
const { requestId: t } = e;
|
|
1076
1053
|
return this.logger.error("[BodhiExtClient] Unknown message type:", e.type), {
|
|
1077
|
-
type:
|
|
1054
|
+
type: a.EXT2EXT_CLIENT_RESPONSE,
|
|
1078
1055
|
requestId: t,
|
|
1079
1056
|
response: {
|
|
1080
1057
|
error: {
|
|
@@ -1100,19 +1077,18 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1100
1077
|
try {
|
|
1101
1078
|
if (!this.extensionId)
|
|
1102
1079
|
throw new Error("Extension not discovered. Please detect Bodhi extension before login.");
|
|
1103
|
-
e?.
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
});
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
await this.performOAuthPkce(d);
|
|
1080
|
+
const r = e?.userRole ?? "scope_user_user", i = chrome.identity.getRedirectURL("callback"), s = p.generateCodeVerifier(), o = await p.generateCodeChallenge(s), n = p.generateCodeVerifier();
|
|
1081
|
+
await chrome.storage.session.set({ codeVerifier: s, state: n, authInProgress: !0 });
|
|
1082
|
+
const h = v(this.authEndpoints, {
|
|
1083
|
+
clientId: this.authClientId,
|
|
1084
|
+
redirectUri: i,
|
|
1085
|
+
scope: L,
|
|
1086
|
+
state: n,
|
|
1087
|
+
codeChallenge: o
|
|
1088
|
+
}), c = b(i), E = new P(this.authClientId).requestedRole(r);
|
|
1089
|
+
e?.requested && E.requested(e.requested);
|
|
1090
|
+
const l = await this.requestAccess(E.build()), { review_url: u } = k(l), g = O(u, h, c), S = await this.launchReview(g);
|
|
1091
|
+
await this.completeOAuthRedirect(S);
|
|
1116
1092
|
} finally {
|
|
1117
1093
|
this.isAuthenticating = !1;
|
|
1118
1094
|
}
|
|
@@ -1125,7 +1101,7 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1125
1101
|
async exchangeCodeForTokens(e) {
|
|
1126
1102
|
if ((await this.getAuthState()).status === "authenticated")
|
|
1127
1103
|
return;
|
|
1128
|
-
const { codeVerifier: r } = await chrome.storage.session.get("codeVerifier"),
|
|
1104
|
+
const { codeVerifier: r } = await chrome.storage.session.get("codeVerifier"), i = chrome.identity.getRedirectURL("callback"), s = await fetch(this.authEndpoints.token, {
|
|
1129
1105
|
method: "POST",
|
|
1130
1106
|
headers: {
|
|
1131
1107
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
@@ -1133,21 +1109,21 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1133
1109
|
body: new URLSearchParams({
|
|
1134
1110
|
grant_type: "authorization_code",
|
|
1135
1111
|
code: e,
|
|
1136
|
-
redirect_uri:
|
|
1112
|
+
redirect_uri: i,
|
|
1137
1113
|
client_id: this.authClientId,
|
|
1138
1114
|
code_verifier: r
|
|
1139
1115
|
})
|
|
1140
1116
|
});
|
|
1141
|
-
if (!
|
|
1142
|
-
const
|
|
1143
|
-
throw new Error(`Token exchange failed: ${
|
|
1117
|
+
if (!s.ok) {
|
|
1118
|
+
const n = await s.text();
|
|
1119
|
+
throw new Error(`Token exchange failed: ${s.status} ${n}`);
|
|
1144
1120
|
}
|
|
1145
|
-
const
|
|
1121
|
+
const o = await s.json();
|
|
1146
1122
|
await this.storeTokens({
|
|
1147
|
-
accessToken:
|
|
1148
|
-
refreshToken:
|
|
1149
|
-
idToken:
|
|
1150
|
-
expiresIn:
|
|
1123
|
+
accessToken: o.access_token,
|
|
1124
|
+
refreshToken: o.refresh_token,
|
|
1125
|
+
idToken: o.id_token,
|
|
1126
|
+
expiresIn: o.expires_in
|
|
1151
1127
|
});
|
|
1152
1128
|
}
|
|
1153
1129
|
/**
|
|
@@ -1230,61 +1206,33 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1230
1206
|
e
|
|
1231
1207
|
);
|
|
1232
1208
|
}
|
|
1233
|
-
|
|
1234
|
-
return
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
async pollAccessRequestStatus(e, t) {
|
|
1240
|
-
return k(
|
|
1241
|
-
(r) => this.getAccessRequestStatus(r),
|
|
1242
|
-
e,
|
|
1243
|
-
t
|
|
1244
|
-
);
|
|
1245
|
-
}
|
|
1246
|
-
async performOAuthPkce(e) {
|
|
1247
|
-
const t = S.generateCodeVerifier(), r = await S.generateCodeChallenge(t), n = S.generateCodeVerifier();
|
|
1248
|
-
await chrome.storage.session.set({
|
|
1249
|
-
codeVerifier: t,
|
|
1250
|
-
state: n,
|
|
1251
|
-
authInProgress: !0
|
|
1252
|
-
});
|
|
1253
|
-
const o = chrome.identity.getRedirectURL("callback"), s = new URL(this.authEndpoints.authorize);
|
|
1254
|
-
return s.searchParams.set("client_id", this.authClientId), s.searchParams.set("response_type", "code"), s.searchParams.set("redirect_uri", o), s.searchParams.set("scope", e), s.searchParams.set("code_challenge", r), s.searchParams.set("code_challenge_method", "S256"), s.searchParams.set("state", n), new Promise((i, h) => {
|
|
1255
|
-
chrome.identity.launchWebAuthFlow(
|
|
1256
|
-
{ url: s.toString(), interactive: !0 },
|
|
1257
|
-
async (a) => {
|
|
1258
|
-
if (await chrome.storage.session.set({ authInProgress: !1 }), chrome.runtime.lastError) {
|
|
1259
|
-
await chrome.storage.session.remove(["codeVerifier", "state"]), h(chrome.runtime.lastError);
|
|
1260
|
-
return;
|
|
1261
|
-
}
|
|
1262
|
-
if (!a) {
|
|
1263
|
-
await chrome.storage.session.remove(["codeVerifier", "state"]), h(l("oauth_error", "No redirect URL received"));
|
|
1264
|
-
return;
|
|
1265
|
-
}
|
|
1266
|
-
try {
|
|
1267
|
-
const E = new URL(a), d = E.searchParams.get("code"), u = E.searchParams.get("state"), { state: g } = await chrome.storage.session.get("state");
|
|
1268
|
-
if (u !== g) {
|
|
1269
|
-
await chrome.storage.session.remove(["codeVerifier", "state"]), h(l("oauth_error", "State mismatch"));
|
|
1270
|
-
return;
|
|
1271
|
-
}
|
|
1272
|
-
if (!d) {
|
|
1273
|
-
await chrome.storage.session.remove(["codeVerifier", "state"]), h(l("oauth_error", "No authorization code"));
|
|
1274
|
-
return;
|
|
1275
|
-
}
|
|
1276
|
-
await this.exchangeCodeForTokens(d), await chrome.storage.session.remove(["codeVerifier", "state"]);
|
|
1277
|
-
const m = await this.getAuthState();
|
|
1278
|
-
if (m.status !== "authenticated")
|
|
1279
|
-
throw l("oauth_error", "Login failed");
|
|
1280
|
-
i(m);
|
|
1281
|
-
} catch (E) {
|
|
1282
|
-
await chrome.storage.session.remove(["codeVerifier", "state"]), h(E);
|
|
1283
|
-
}
|
|
1209
|
+
launchReview(e) {
|
|
1210
|
+
return new Promise((t, r) => {
|
|
1211
|
+
chrome.identity.launchWebAuthFlow({ url: e, interactive: !0 }, async (i) => {
|
|
1212
|
+
if (await chrome.storage.session.set({ authInProgress: !1 }), chrome.runtime.lastError) {
|
|
1213
|
+
await chrome.storage.session.remove(["codeVerifier", "state"]), r(chrome.runtime.lastError);
|
|
1214
|
+
return;
|
|
1284
1215
|
}
|
|
1285
|
-
|
|
1216
|
+
if (!i) {
|
|
1217
|
+
await chrome.storage.session.remove(["codeVerifier", "state"]), r(d("oauth_error", "No redirect URL received"));
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
t(i);
|
|
1221
|
+
});
|
|
1286
1222
|
});
|
|
1287
1223
|
}
|
|
1224
|
+
async completeOAuthRedirect(e) {
|
|
1225
|
+
const t = new URL(e), r = t.searchParams.get("error");
|
|
1226
|
+
if (r)
|
|
1227
|
+
throw await chrome.storage.session.remove(["codeVerifier", "state"]), t.searchParams.get("error_source") === "bodhi" && M(r === "access_denied" ? "denied" : r), d("oauth_error", t.searchParams.get("error_description") ?? r);
|
|
1228
|
+
const i = t.searchParams.get("code"), s = t.searchParams.get("state"), { state: o } = await chrome.storage.session.get("state");
|
|
1229
|
+
if (!s || s !== o)
|
|
1230
|
+
throw await chrome.storage.session.remove(["codeVerifier", "state"]), d("oauth_error", "State mismatch");
|
|
1231
|
+
if (!i)
|
|
1232
|
+
throw await chrome.storage.session.remove(["codeVerifier", "state"]), d("oauth_error", "No authorization code");
|
|
1233
|
+
if (await this.exchangeCodeForTokens(i), await chrome.storage.session.remove(["codeVerifier", "state"]), (await this.getAuthState()).status !== "authenticated")
|
|
1234
|
+
throw d("oauth_error", "Login failed");
|
|
1235
|
+
}
|
|
1288
1236
|
// Ext2Ext Communication (Private Methods)
|
|
1289
1237
|
// ============================================================================
|
|
1290
1238
|
/**
|
|
@@ -1295,7 +1243,7 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1295
1243
|
*/
|
|
1296
1244
|
async sendExtRequest(e, t) {
|
|
1297
1245
|
const r = await this.sendExtRequestRaw(e, t);
|
|
1298
|
-
if (
|
|
1246
|
+
if (y(r.response))
|
|
1299
1247
|
throw this.logger.error("[BodhiExtClient] Extension error:", r.response.error), new Error(
|
|
1300
1248
|
r.response.error.message || `Extension request failed: ${JSON.stringify(r.response)}`
|
|
1301
1249
|
);
|
|
@@ -1309,7 +1257,7 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1309
1257
|
* @param headers Optional headers
|
|
1310
1258
|
* @returns API response from LLM server via bodhi-browser-ext
|
|
1311
1259
|
*/
|
|
1312
|
-
async sendApiRequest(e, t, r,
|
|
1260
|
+
async sendApiRequest(e, t, r, i) {
|
|
1313
1261
|
if (!this.extensionId)
|
|
1314
1262
|
throw new T(
|
|
1315
1263
|
"not_initialized",
|
|
@@ -1319,22 +1267,22 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1319
1267
|
`[BodhiExtClient] Sending API_REQUEST: method=${e}, endpoint=${t}`,
|
|
1320
1268
|
r ? { body: r } : ""
|
|
1321
1269
|
);
|
|
1322
|
-
const
|
|
1270
|
+
const s = crypto.randomUUID(), o = {
|
|
1323
1271
|
type: _.API_REQUEST,
|
|
1324
|
-
requestId:
|
|
1272
|
+
requestId: s,
|
|
1325
1273
|
request: {
|
|
1326
1274
|
method: e,
|
|
1327
1275
|
endpoint: t,
|
|
1328
1276
|
body: r,
|
|
1329
|
-
headers:
|
|
1277
|
+
headers: i
|
|
1330
1278
|
}
|
|
1331
1279
|
};
|
|
1332
|
-
return this.logger.debug(`[BodhiExtClient] Request ID: ${
|
|
1280
|
+
return this.logger.debug(`[BodhiExtClient] Request ID: ${s}, Extension: ${this.extensionId}`), new Promise((n, h) => {
|
|
1333
1281
|
try {
|
|
1334
|
-
chrome.runtime.sendMessage(this.extensionId,
|
|
1282
|
+
chrome.runtime.sendMessage(this.extensionId, o, (c) => {
|
|
1335
1283
|
if (chrome.runtime.lastError) {
|
|
1336
1284
|
this.logger.error(
|
|
1337
|
-
`[BodhiExtClient] Chrome runtime error for request ${
|
|
1285
|
+
`[BodhiExtClient] Chrome runtime error for request ${s}:`,
|
|
1338
1286
|
chrome.runtime.lastError
|
|
1339
1287
|
), h(
|
|
1340
1288
|
new T(
|
|
@@ -1344,19 +1292,19 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1344
1292
|
);
|
|
1345
1293
|
return;
|
|
1346
1294
|
}
|
|
1347
|
-
if (this.logger.debug(`[BodhiExtClient] Response for request ${
|
|
1348
|
-
this.logger.error(`[BodhiExtClient] No response received for request ${
|
|
1295
|
+
if (this.logger.debug(`[BodhiExtClient] Response for request ${s}:`, c), !c) {
|
|
1296
|
+
this.logger.error(`[BodhiExtClient] No response received for request ${s}`), h(new T("extension_error", "No response from extension"));
|
|
1349
1297
|
return;
|
|
1350
1298
|
}
|
|
1351
|
-
|
|
1352
|
-
new T(
|
|
1353
|
-
)) : (this.logger.debug(`[BodhiExtClient] ✓ Valid API_RESPONSE for ${
|
|
1354
|
-
`[BodhiExtClient] Invalid response format for ${
|
|
1355
|
-
|
|
1299
|
+
c.type === _.API_RESPONSE && c.requestId === s ? "error" in c ? (this.logger.error(`[BodhiExtClient] API error for ${s}:`, c.error), h(
|
|
1300
|
+
new T(c.error.type || "extension_error", c.error.message)
|
|
1301
|
+
)) : (this.logger.debug(`[BodhiExtClient] ✓ Valid API_RESPONSE for ${s}`), n(c.response)) : (this.logger.error(
|
|
1302
|
+
`[BodhiExtClient] Invalid response format for ${s}:`,
|
|
1303
|
+
c
|
|
1356
1304
|
), h(new T("extension_error", "Invalid response format")));
|
|
1357
1305
|
});
|
|
1358
|
-
} catch (
|
|
1359
|
-
this.logger.error(`[BodhiExtClient] Exception sending message for ${
|
|
1306
|
+
} catch (c) {
|
|
1307
|
+
this.logger.error(`[BodhiExtClient] Exception sending message for ${s}:`, c), h(c);
|
|
1360
1308
|
}
|
|
1361
1309
|
});
|
|
1362
1310
|
}
|
|
@@ -1376,7 +1324,7 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1376
1324
|
`[BodhiExtClient] Sending EXT_REQUEST (raw): action=${e}`,
|
|
1377
1325
|
t ? { params: t } : ""
|
|
1378
1326
|
);
|
|
1379
|
-
const r = crypto.randomUUID(),
|
|
1327
|
+
const r = crypto.randomUUID(), i = {
|
|
1380
1328
|
type: _.EXT_REQUEST,
|
|
1381
1329
|
requestId: r,
|
|
1382
1330
|
request: {
|
|
@@ -1384,27 +1332,27 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1384
1332
|
params: t
|
|
1385
1333
|
}
|
|
1386
1334
|
};
|
|
1387
|
-
return this.logger.debug(`[BodhiExtClient] Request ID: ${r}, Extension: ${this.extensionId}`), new Promise((
|
|
1335
|
+
return this.logger.debug(`[BodhiExtClient] Request ID: ${r}, Extension: ${this.extensionId}`), new Promise((s, o) => {
|
|
1388
1336
|
try {
|
|
1389
|
-
chrome.runtime.sendMessage(this.extensionId,
|
|
1337
|
+
chrome.runtime.sendMessage(this.extensionId, i, (n) => {
|
|
1390
1338
|
if (chrome.runtime.lastError) {
|
|
1391
1339
|
this.logger.error(
|
|
1392
1340
|
`[BodhiExtClient] Chrome runtime error for request ${r}:`,
|
|
1393
1341
|
chrome.runtime.lastError
|
|
1394
|
-
),
|
|
1342
|
+
), o(new Error(chrome.runtime.lastError.message));
|
|
1395
1343
|
return;
|
|
1396
1344
|
}
|
|
1397
|
-
if (this.logger.debug(`[BodhiExtClient] Response for request ${r}:`,
|
|
1398
|
-
this.logger.error(`[BodhiExtClient] No response received for request ${r}`),
|
|
1345
|
+
if (this.logger.debug(`[BodhiExtClient] Response for request ${r}:`, n), !n) {
|
|
1346
|
+
this.logger.error(`[BodhiExtClient] No response received for request ${r}`), o(new Error("No response from extension"));
|
|
1399
1347
|
return;
|
|
1400
1348
|
}
|
|
1401
|
-
|
|
1349
|
+
n.type === _.EXT_RESPONSE && n.requestId === r ? (this.logger.debug(`[BodhiExtClient] ✓ Valid EXT_RESPONSE for ${r}`), s(n)) : (this.logger.error(
|
|
1402
1350
|
`[BodhiExtClient] Invalid response format for ${r}:`,
|
|
1403
|
-
|
|
1404
|
-
),
|
|
1351
|
+
n
|
|
1352
|
+
), o(new T("extension_error", "Invalid response format")));
|
|
1405
1353
|
});
|
|
1406
|
-
} catch (
|
|
1407
|
-
this.logger.error(`[BodhiExtClient] Exception sending message for ${r}:`,
|
|
1354
|
+
} catch (n) {
|
|
1355
|
+
this.logger.error(`[BodhiExtClient] Exception sending message for ${r}:`, n), o(n);
|
|
1408
1356
|
}
|
|
1409
1357
|
});
|
|
1410
1358
|
}
|
|
@@ -1412,19 +1360,19 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1412
1360
|
* Register a chrome.runtime.onConnect listener for a streaming port.
|
|
1413
1361
|
* Validates port name and message type, then delegates to handler.
|
|
1414
1362
|
*/
|
|
1415
|
-
registerStreamPortListener(e, t, r,
|
|
1416
|
-
chrome.runtime.onConnect.addListener((
|
|
1417
|
-
|
|
1418
|
-
if (
|
|
1419
|
-
this.logger.warn(`[BodhiExtClient] Unknown message type on ${e}:`,
|
|
1363
|
+
registerStreamPortListener(e, t, r, i) {
|
|
1364
|
+
chrome.runtime.onConnect.addListener((s) => {
|
|
1365
|
+
s.name === e && (this.logger.info(`[BodhiExtClient] Port connected: ${e}`), s.onMessage.addListener(async (o) => {
|
|
1366
|
+
if (o.type !== t) {
|
|
1367
|
+
this.logger.warn(`[BodhiExtClient] Unknown message type on ${e}:`, o.type), s.postMessage({
|
|
1420
1368
|
type: r,
|
|
1421
|
-
requestId:
|
|
1369
|
+
requestId: o.requestId,
|
|
1422
1370
|
error: { message: "Unknown message type", type: "extension_error" }
|
|
1423
1371
|
});
|
|
1424
1372
|
return;
|
|
1425
1373
|
}
|
|
1426
|
-
await
|
|
1427
|
-
}),
|
|
1374
|
+
await i(s, o);
|
|
1375
|
+
}), s.onDisconnect.addListener(() => {
|
|
1428
1376
|
this.logger.info(`[BodhiExtClient] Port disconnected: ${e}`);
|
|
1429
1377
|
}));
|
|
1430
1378
|
});
|
|
@@ -1437,15 +1385,15 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1437
1385
|
* @param onBodhiMessage Called for each message from bodhi-browser-ext.
|
|
1438
1386
|
* Returns true if the stream is complete (triggers cleanup).
|
|
1439
1387
|
*/
|
|
1440
|
-
async handleGenericStreamRelay(e, t, r,
|
|
1388
|
+
async handleGenericStreamRelay(e, t, r, i, s, o, n) {
|
|
1441
1389
|
if (this.logger.debug("[BodhiExtClient] Processing stream relay:", {
|
|
1442
1390
|
requestId: t,
|
|
1443
1391
|
method: r.method,
|
|
1444
1392
|
endpoint: r.endpoint,
|
|
1445
|
-
bodhiPortName:
|
|
1393
|
+
bodhiPortName: i
|
|
1446
1394
|
}), !this.extensionId) {
|
|
1447
1395
|
e.postMessage({
|
|
1448
|
-
type:
|
|
1396
|
+
type: o,
|
|
1449
1397
|
requestId: t,
|
|
1450
1398
|
error: { message: "Client not initialized (no extensionId)", type: "extension_error" }
|
|
1451
1399
|
});
|
|
@@ -1457,7 +1405,7 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1457
1405
|
const u = await this._getAccessTokenRaw();
|
|
1458
1406
|
if (!u) {
|
|
1459
1407
|
e.postMessage({
|
|
1460
|
-
type:
|
|
1408
|
+
type: o,
|
|
1461
1409
|
requestId: t,
|
|
1462
1410
|
error: { message: "Not authenticated. Please log in first.", type: "extension_error" }
|
|
1463
1411
|
});
|
|
@@ -1465,20 +1413,20 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1465
1413
|
}
|
|
1466
1414
|
h = { ...h, Authorization: `Bearer ${u}` }, this.logger.debug("[BodhiExtClient] Injected auth token for stream relay");
|
|
1467
1415
|
}
|
|
1468
|
-
const
|
|
1469
|
-
this.activeStreamPorts.set(t,
|
|
1416
|
+
const c = chrome.runtime.connect(this.extensionId, { name: i });
|
|
1417
|
+
this.activeStreamPorts.set(t, c);
|
|
1470
1418
|
const E = setTimeout(() => {
|
|
1471
1419
|
this.activeStreamPorts.has(t) && (this.logger.error(`[BodhiExtClient] Stream timeout for ${t}`), e.postMessage({
|
|
1472
|
-
type:
|
|
1420
|
+
type: o,
|
|
1473
1421
|
requestId: t,
|
|
1474
1422
|
error: { message: "Stream request timed out", type: "timeout_error" }
|
|
1475
1423
|
}), this.cleanupStreamPort(t));
|
|
1476
|
-
},
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
}),
|
|
1424
|
+
}, p.STREAM_TIMEOUT);
|
|
1425
|
+
c.onMessage.addListener((u) => {
|
|
1426
|
+
n(u, e, t) && (clearTimeout(E), this.cleanupStreamPort(t));
|
|
1427
|
+
}), c.onDisconnect.addListener(() => {
|
|
1480
1428
|
clearTimeout(E), this.activeStreamPorts.has(t) && (this.logger.error(`[BodhiExtClient] Bodhi port disconnected for ${t}`), e.postMessage({
|
|
1481
|
-
type:
|
|
1429
|
+
type: o,
|
|
1482
1430
|
requestId: t,
|
|
1483
1431
|
error: {
|
|
1484
1432
|
message: "Connection to Bodhi extension closed unexpectedly",
|
|
@@ -1486,8 +1434,8 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1486
1434
|
}
|
|
1487
1435
|
}), this.activeStreamPorts.delete(t));
|
|
1488
1436
|
});
|
|
1489
|
-
const
|
|
1490
|
-
type:
|
|
1437
|
+
const l = {
|
|
1438
|
+
type: s,
|
|
1491
1439
|
requestId: t,
|
|
1492
1440
|
request: {
|
|
1493
1441
|
method: r.method,
|
|
@@ -1496,14 +1444,14 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1496
1444
|
headers: h
|
|
1497
1445
|
}
|
|
1498
1446
|
};
|
|
1499
|
-
this.logger.debug("[BodhiExtClient] Sending stream request to bodhi port:",
|
|
1447
|
+
this.logger.debug("[BodhiExtClient] Sending stream request to bodhi port:", l), c.postMessage(l);
|
|
1500
1448
|
} catch (h) {
|
|
1501
|
-
const
|
|
1502
|
-
this.logger.error("[BodhiExtClient] Stream relay error:", JSON.stringify(
|
|
1503
|
-
type:
|
|
1449
|
+
const c = h;
|
|
1450
|
+
this.logger.error("[BodhiExtClient] Stream relay error:", JSON.stringify(c.message)), e.postMessage({
|
|
1451
|
+
type: o,
|
|
1504
1452
|
requestId: t,
|
|
1505
1453
|
error: {
|
|
1506
|
-
message: `uncaught error: ${JSON.stringify({ error:
|
|
1454
|
+
message: `uncaught error: ${JSON.stringify({ error: c, message: c.message })}`,
|
|
1507
1455
|
type: "extension_error"
|
|
1508
1456
|
}
|
|
1509
1457
|
});
|
|
@@ -1526,47 +1474,47 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1526
1474
|
* Handle SSE-parsed streaming request — translates STREAM_* messages to EXT2EXT_CLIENT_STREAM_*
|
|
1527
1475
|
*/
|
|
1528
1476
|
async handleStreamRequest(e, t) {
|
|
1529
|
-
const { requestId: r, request:
|
|
1477
|
+
const { requestId: r, request: i } = t;
|
|
1530
1478
|
await this.handleGenericStreamRelay(
|
|
1531
1479
|
e,
|
|
1532
1480
|
r,
|
|
1533
|
-
|
|
1534
|
-
|
|
1481
|
+
i,
|
|
1482
|
+
ie,
|
|
1535
1483
|
_.STREAM_REQUEST,
|
|
1536
|
-
|
|
1537
|
-
(
|
|
1538
|
-
if (
|
|
1539
|
-
const h =
|
|
1540
|
-
return h.status >= 400 ? (
|
|
1541
|
-
type:
|
|
1542
|
-
requestId:
|
|
1484
|
+
a.EXT2EXT_CLIENT_STREAM_ERROR,
|
|
1485
|
+
(s, o, n) => {
|
|
1486
|
+
if (ne(s)) {
|
|
1487
|
+
const h = s.response, c = h.body;
|
|
1488
|
+
return h.status >= 400 ? (o.postMessage({
|
|
1489
|
+
type: a.EXT2EXT_CLIENT_STREAM_API_ERROR,
|
|
1490
|
+
requestId: n,
|
|
1543
1491
|
response: h
|
|
1544
|
-
}), !1) :
|
|
1545
|
-
type:
|
|
1546
|
-
requestId:
|
|
1547
|
-
}), this.logger.info(`[BodhiExtClient] Stream complete for ${
|
|
1548
|
-
type:
|
|
1549
|
-
requestId:
|
|
1492
|
+
}), !1) : c?.done ? (o.postMessage({
|
|
1493
|
+
type: a.EXT2EXT_CLIENT_STREAM_DONE,
|
|
1494
|
+
requestId: n
|
|
1495
|
+
}), this.logger.info(`[BodhiExtClient] Stream complete for ${n}`), !0) : (o.postMessage({
|
|
1496
|
+
type: a.EXT2EXT_CLIENT_STREAM_CHUNK,
|
|
1497
|
+
requestId: n,
|
|
1550
1498
|
response: h
|
|
1551
1499
|
}), !1);
|
|
1552
1500
|
} else {
|
|
1553
|
-
if (
|
|
1501
|
+
if (ae(s))
|
|
1554
1502
|
return this.logger.error(
|
|
1555
|
-
`[BodhiExtClient] Stream API error for ${
|
|
1556
|
-
),
|
|
1557
|
-
type:
|
|
1558
|
-
requestId:
|
|
1559
|
-
response:
|
|
1503
|
+
`[BodhiExtClient] Stream API error for ${n}: ${s.response.status}`
|
|
1504
|
+
), o.postMessage({
|
|
1505
|
+
type: a.EXT2EXT_CLIENT_STREAM_API_ERROR,
|
|
1506
|
+
requestId: n,
|
|
1507
|
+
response: s.response
|
|
1560
1508
|
}), !1;
|
|
1561
|
-
if (
|
|
1509
|
+
if (ce(s))
|
|
1562
1510
|
return this.logger.error(
|
|
1563
|
-
`[BodhiExtClient] Stream error for ${
|
|
1564
|
-
|
|
1565
|
-
),
|
|
1566
|
-
type:
|
|
1567
|
-
requestId:
|
|
1511
|
+
`[BodhiExtClient] Stream error for ${n}:`,
|
|
1512
|
+
s.error.message
|
|
1513
|
+
), o.postMessage({
|
|
1514
|
+
type: a.EXT2EXT_CLIENT_STREAM_ERROR,
|
|
1515
|
+
requestId: n,
|
|
1568
1516
|
error: {
|
|
1569
|
-
message: `stream error: ${JSON.stringify(
|
|
1517
|
+
message: `stream error: ${JSON.stringify(s)}`,
|
|
1570
1518
|
type: "extension_error"
|
|
1571
1519
|
}
|
|
1572
1520
|
}), !0;
|
|
@@ -1579,42 +1527,42 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1579
1527
|
* Handle raw text streaming request — translates STREAM_TEXT_* messages to EXT2EXT_CLIENT_STREAM_TEXT_*
|
|
1580
1528
|
*/
|
|
1581
1529
|
async handleStreamTextRequest(e, t) {
|
|
1582
|
-
const { requestId: r, request:
|
|
1530
|
+
const { requestId: r, request: i } = t;
|
|
1583
1531
|
await this.handleGenericStreamRelay(
|
|
1584
1532
|
e,
|
|
1585
1533
|
r,
|
|
1586
|
-
|
|
1587
|
-
|
|
1534
|
+
i,
|
|
1535
|
+
he,
|
|
1588
1536
|
_.STREAM_TEXT_REQUEST,
|
|
1589
|
-
|
|
1590
|
-
(
|
|
1591
|
-
switch (
|
|
1537
|
+
a.EXT2EXT_CLIENT_STREAM_TEXT_ERROR,
|
|
1538
|
+
(s, o, n) => {
|
|
1539
|
+
switch (s.type) {
|
|
1592
1540
|
case _.STREAM_TEXT_START:
|
|
1593
|
-
return
|
|
1594
|
-
type:
|
|
1595
|
-
requestId:
|
|
1596
|
-
status:
|
|
1597
|
-
headers:
|
|
1541
|
+
return o.postMessage({
|
|
1542
|
+
type: a.EXT2EXT_CLIENT_STREAM_TEXT_START,
|
|
1543
|
+
requestId: n,
|
|
1544
|
+
status: s.status,
|
|
1545
|
+
headers: s.headers
|
|
1598
1546
|
}), !1;
|
|
1599
1547
|
case _.STREAM_TEXT_CHUNK:
|
|
1600
|
-
return
|
|
1601
|
-
type:
|
|
1602
|
-
requestId:
|
|
1603
|
-
chunk:
|
|
1548
|
+
return o.postMessage({
|
|
1549
|
+
type: a.EXT2EXT_CLIENT_STREAM_TEXT_CHUNK,
|
|
1550
|
+
requestId: n,
|
|
1551
|
+
chunk: s.chunk
|
|
1604
1552
|
}), !1;
|
|
1605
1553
|
case _.STREAM_TEXT_DONE:
|
|
1606
|
-
return this.logger.info(`[BodhiExtClient] Stream text complete for ${
|
|
1607
|
-
type:
|
|
1608
|
-
requestId:
|
|
1554
|
+
return this.logger.info(`[BodhiExtClient] Stream text complete for ${n}`), o.postMessage({
|
|
1555
|
+
type: a.EXT2EXT_CLIENT_STREAM_TEXT_DONE,
|
|
1556
|
+
requestId: n
|
|
1609
1557
|
}), !0;
|
|
1610
1558
|
case _.STREAM_TEXT_ERROR:
|
|
1611
1559
|
return this.logger.error(
|
|
1612
|
-
`[BodhiExtClient] Stream text error for ${
|
|
1613
|
-
|
|
1614
|
-
),
|
|
1615
|
-
type:
|
|
1616
|
-
requestId:
|
|
1617
|
-
error:
|
|
1560
|
+
`[BodhiExtClient] Stream text error for ${n}:`,
|
|
1561
|
+
s.error.message
|
|
1562
|
+
), o.postMessage({
|
|
1563
|
+
type: a.EXT2EXT_CLIENT_STREAM_TEXT_ERROR,
|
|
1564
|
+
requestId: n,
|
|
1565
|
+
error: s.error
|
|
1618
1566
|
}), !0;
|
|
1619
1567
|
}
|
|
1620
1568
|
return !1;
|
|
@@ -1666,7 +1614,7 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1666
1614
|
async _doRefreshToken(e) {
|
|
1667
1615
|
this.logger.debug("Refreshing access token");
|
|
1668
1616
|
try {
|
|
1669
|
-
const t = await
|
|
1617
|
+
const t = await re(
|
|
1670
1618
|
this.authEndpoints.token,
|
|
1671
1619
|
e,
|
|
1672
1620
|
this.authClientId
|
|
@@ -1678,7 +1626,7 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1678
1626
|
} catch (t) {
|
|
1679
1627
|
this.logger.warn("Token refresh failed:", t);
|
|
1680
1628
|
}
|
|
1681
|
-
throw this.logger.warn("Token refresh failed, keeping tokens for manual retry"),
|
|
1629
|
+
throw this.logger.warn("Token refresh failed, keeping tokens for manual retry"), d(
|
|
1682
1630
|
"auth_error",
|
|
1683
1631
|
"Access token expired and unable to refresh. Try logging out and logging in again."
|
|
1684
1632
|
);
|
|
@@ -1706,32 +1654,32 @@ const pe = ["ggedphdcbekjlomjaidbajglgihbeaon"], me = ["bjdjhiombmfbcoeojijpfckl
|
|
|
1706
1654
|
]);
|
|
1707
1655
|
}
|
|
1708
1656
|
parseJwt(e) {
|
|
1709
|
-
const r = e.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"),
|
|
1710
|
-
atob(r).split("").map((
|
|
1657
|
+
const r = e.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"), i = decodeURIComponent(
|
|
1658
|
+
atob(r).split("").map((s) => "%" + ("00" + s.charCodeAt(0).toString(16)).slice(-2)).join("")
|
|
1711
1659
|
);
|
|
1712
|
-
return JSON.parse(
|
|
1660
|
+
return JSON.parse(i);
|
|
1713
1661
|
}
|
|
1714
1662
|
createErrorClientNotInitialized(e) {
|
|
1715
1663
|
return `Client not initialized. Extension discovery not triggered nor extensionId set, cannot handle request: ${JSON.stringify(e)}`;
|
|
1716
1664
|
}
|
|
1717
1665
|
};
|
|
1718
|
-
|
|
1719
|
-
let
|
|
1720
|
-
const
|
|
1666
|
+
p.STREAM_TIMEOUT = 6e4;
|
|
1667
|
+
let A = p;
|
|
1668
|
+
const xe = "production";
|
|
1721
1669
|
export {
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1670
|
+
A as BodhiExtClient,
|
|
1671
|
+
_e as ChromeSessionStorageAdapter,
|
|
1672
|
+
Te as DEFAULT_API_TIMEOUT_MS,
|
|
1673
|
+
ue as DISCOVERY_ATTEMPTS,
|
|
1674
|
+
le as DISCOVERY_ATTEMPT_TIMEOUT,
|
|
1675
|
+
de as DISCOVERY_ATTEMPT_WAIT_MS,
|
|
1676
|
+
Ee as DISCOVERY_TIMEOUT_MS,
|
|
1677
|
+
m as EXT2EXT_CLIENT_ACTIONS,
|
|
1678
|
+
a as EXT2EXT_CLIENT_MESSAGE_TYPES,
|
|
1679
|
+
U as EXT2EXT_CLIENT_STREAM_PORT,
|
|
1680
|
+
D as EXT2EXT_CLIENT_STREAM_TEXT_PORT,
|
|
1681
|
+
xe as EXT_BUILD_MODE,
|
|
1682
|
+
ye as ExtUIClient,
|
|
1683
|
+
Ae as InMemoryStorage,
|
|
1684
|
+
ge as isExtClientApiError
|
|
1737
1685
|
};
|