@bodhiapp/bodhi-js 0.0.2 → 0.0.4
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-js-sdk/core/src/build-info.d.ts +1 -0
- package/dist/bodhi-js-sdk/core/src/facade-client-base.d.ts +1 -1
- package/dist/bodhi-js-sdk/core/src/index.d.ts +1 -0
- package/dist/bodhi-js-sdk/core/src/storage.d.ts +12 -0
- package/dist/bodhi-js-sdk/web/src/build-info.d.ts +1 -0
- package/dist/bodhi-js-sdk/web/src/constants.d.ts +15 -4
- package/dist/bodhi-js-sdk/web/src/direct-client.d.ts +1 -0
- package/dist/bodhi-js-sdk/web/src/ext-client.d.ts +2 -1
- package/dist/bodhi-js-sdk/web/src/facade-client.d.ts +2 -0
- package/dist/bodhi-js-sdk/web/src/index.d.ts +1 -0
- package/dist/bodhi-web.cjs.js +1 -749
- package/dist/bodhi-web.esm.js +277 -393
- package/package.json +2 -2
- package/dist/bodhi-web.cjs.js.map +0 -1
- package/dist/bodhi-web.esm.js.map +0 -1
package/dist/bodhi-web.esm.js
CHANGED
|
@@ -1,57 +1,38 @@
|
|
|
1
|
-
import { DirectClientBase, STORAGE_PREFIXES, generateCodeVerifier, generateCodeChallenge, isApiResultOperationError, isApiResultSuccess, createStorageKeys, EXTENSION_STATE_NOT_INITIALIZED, Logger, createOAuthEndpoints, NOOP_STATE_CALLBACK, EXTENSION_STATE_NOT_FOUND, PENDING_EXTENSION_READY, BACKEND_SERVER_NOT_REACHABLE, extractUserInfo, refreshAccessToken, createOperationError, backendServerNotReady, SERVER_ERROR_CODES, createApiError, BaseFacadeClient } from "@bodhiapp/bodhi-js-core";
|
|
2
|
-
class
|
|
3
|
-
constructor(
|
|
4
|
-
|
|
5
|
-
this.redirectUri =
|
|
1
|
+
import { DirectClientBase as x, createStoragePrefixWithBasePath as w, STORAGE_PREFIXES as u, generateCodeVerifier as g, generateCodeChallenge as I, isApiResultOperationError as T, isApiResultSuccess as f, createStorageKeys as R, EXTENSION_STATE_NOT_INITIALIZED as y, Logger as C, createOAuthEndpoints as A, NOOP_STATE_CALLBACK as k, EXTENSION_STATE_NOT_FOUND as v, PENDING_EXTENSION_READY as b, BACKEND_SERVER_NOT_REACHABLE as d, extractUserInfo as _, refreshAccessToken as P, createOperationError as S, backendServerNotReady as E, SERVER_ERROR_CODES as O, createApiError as K, BaseFacadeClient as U } from "@bodhiapp/bodhi-js-core";
|
|
2
|
+
class L extends x {
|
|
3
|
+
constructor(e, t) {
|
|
4
|
+
const s = e.basePath || "/", r = w(s, u.DIRECT);
|
|
5
|
+
super({ ...e, storagePrefix: r }, "DirectWebClient", t), this.redirectUri = e.redirectUri;
|
|
6
6
|
}
|
|
7
7
|
// ============================================================================
|
|
8
8
|
// Authentication (Browser Redirect OAuth)
|
|
9
9
|
// ============================================================================
|
|
10
10
|
async login() {
|
|
11
|
-
const
|
|
12
|
-
if (
|
|
13
|
-
return
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
localStorage.
|
|
21
|
-
|
|
22
|
-
const authUrl = new URL(this.authEndpoints.authorize);
|
|
23
|
-
authUrl.searchParams.set("client_id", this.authClientId);
|
|
24
|
-
authUrl.searchParams.set("response_type", "code");
|
|
25
|
-
authUrl.searchParams.set("redirect_uri", this.redirectUri);
|
|
26
|
-
authUrl.searchParams.set("scope", fullScope);
|
|
27
|
-
authUrl.searchParams.set("code_challenge", codeChallenge);
|
|
28
|
-
authUrl.searchParams.set("code_challenge_method", "S256");
|
|
29
|
-
authUrl.searchParams.set("state", state);
|
|
30
|
-
window.location.href = authUrl.toString();
|
|
31
|
-
throw new Error("Redirect initiated");
|
|
32
|
-
}
|
|
33
|
-
async handleOAuthCallback(code, state) {
|
|
34
|
-
const storedState = localStorage.getItem(this.storageKeys.STATE);
|
|
35
|
-
if (!storedState || storedState !== state) {
|
|
11
|
+
const e = await this.getAuthState();
|
|
12
|
+
if (e.isLoggedIn)
|
|
13
|
+
return e;
|
|
14
|
+
const t = await this.requestResourceAccess(), s = `openid profile email roles ${this.userScope} ${t}`, r = g(), i = await I(r), o = g();
|
|
15
|
+
localStorage.setItem(this.storageKeys.CODE_VERIFIER, r), localStorage.setItem(this.storageKeys.STATE, o);
|
|
16
|
+
const a = new URL(this.authEndpoints.authorize);
|
|
17
|
+
throw a.searchParams.set("client_id", this.authClientId), a.searchParams.set("response_type", "code"), a.searchParams.set("redirect_uri", this.redirectUri), a.searchParams.set("scope", s), a.searchParams.set("code_challenge", i), a.searchParams.set("code_challenge_method", "S256"), a.searchParams.set("state", o), window.location.href = a.toString(), new Error("Redirect initiated");
|
|
18
|
+
}
|
|
19
|
+
async handleOAuthCallback(e, t) {
|
|
20
|
+
const s = localStorage.getItem(this.storageKeys.STATE);
|
|
21
|
+
if (!s || s !== t)
|
|
36
22
|
throw new Error("Invalid state parameter - possible CSRF attack");
|
|
37
|
-
|
|
38
|
-
await this.
|
|
39
|
-
|
|
40
|
-
localStorage.removeItem(this.storageKeys.STATE);
|
|
41
|
-
const authState = await this.getAuthState();
|
|
42
|
-
if (!authState.isLoggedIn) {
|
|
23
|
+
await this.exchangeCodeForTokens(e), localStorage.removeItem(this.storageKeys.CODE_VERIFIER), localStorage.removeItem(this.storageKeys.STATE);
|
|
24
|
+
const r = await this.getAuthState();
|
|
25
|
+
if (!r.isLoggedIn)
|
|
43
26
|
throw new Error("Login failed");
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this.setAuthState(result);
|
|
47
|
-
return result;
|
|
27
|
+
const i = r;
|
|
28
|
+
return this.setAuthState(i), i;
|
|
48
29
|
}
|
|
49
30
|
async logout() {
|
|
50
|
-
const
|
|
51
|
-
if (
|
|
31
|
+
const e = localStorage.getItem(this.storageKeys.REFRESH_TOKEN);
|
|
32
|
+
if (e)
|
|
52
33
|
try {
|
|
53
|
-
const
|
|
54
|
-
token:
|
|
34
|
+
const s = new URLSearchParams({
|
|
35
|
+
token: e,
|
|
55
36
|
client_id: this.authClientId,
|
|
56
37
|
token_type_hint: "refresh_token"
|
|
57
38
|
});
|
|
@@ -60,126 +41,107 @@ class DirectWebClient extends DirectClientBase {
|
|
|
60
41
|
headers: {
|
|
61
42
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
62
43
|
},
|
|
63
|
-
body:
|
|
44
|
+
body: s
|
|
64
45
|
});
|
|
65
|
-
} catch (
|
|
66
|
-
this.logger.warn("Token revocation failed:",
|
|
46
|
+
} catch (s) {
|
|
47
|
+
this.logger.warn("Token revocation failed:", s);
|
|
67
48
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
localStorage.removeItem(this.storageKeys.EXPIRES_AT);
|
|
72
|
-
localStorage.removeItem(this.storageKeys.RESOURCE_SCOPE);
|
|
73
|
-
const result = {
|
|
74
|
-
isLoggedIn: false
|
|
49
|
+
localStorage.removeItem(this.storageKeys.ACCESS_TOKEN), localStorage.removeItem(this.storageKeys.REFRESH_TOKEN), localStorage.removeItem(this.storageKeys.EXPIRES_AT), localStorage.removeItem(this.storageKeys.RESOURCE_SCOPE);
|
|
50
|
+
const t = {
|
|
51
|
+
isLoggedIn: !1
|
|
75
52
|
};
|
|
76
|
-
this.setAuthState(
|
|
77
|
-
return result;
|
|
53
|
+
return this.setAuthState(t), t;
|
|
78
54
|
}
|
|
79
55
|
// ============================================================================
|
|
80
56
|
// OAuth Helper Methods
|
|
81
57
|
// ============================================================================
|
|
82
58
|
async requestResourceAccess() {
|
|
83
|
-
const
|
|
59
|
+
const e = await this.sendApiRequest(
|
|
84
60
|
"POST",
|
|
85
61
|
"/bodhi/v1/apps/request-access",
|
|
86
62
|
{ app_client_id: this.authClientId },
|
|
87
63
|
{},
|
|
88
|
-
|
|
64
|
+
!1
|
|
89
65
|
);
|
|
90
|
-
if (
|
|
66
|
+
if (T(e))
|
|
91
67
|
throw new Error("Failed to get resource access scope from server");
|
|
92
|
-
|
|
93
|
-
if (!isApiResultSuccess(response)) {
|
|
68
|
+
if (!f(e))
|
|
94
69
|
throw new Error("Failed to get resource access scope from server: API error");
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
localStorage.setItem(this.storageKeys.RESOURCE_SCOPE, scope);
|
|
98
|
-
return scope;
|
|
70
|
+
const t = e.body.scope;
|
|
71
|
+
return localStorage.setItem(this.storageKeys.RESOURCE_SCOPE, t), t;
|
|
99
72
|
}
|
|
100
|
-
async exchangeCodeForTokens(
|
|
101
|
-
const
|
|
102
|
-
if (!
|
|
73
|
+
async exchangeCodeForTokens(e) {
|
|
74
|
+
const t = localStorage.getItem(this.storageKeys.CODE_VERIFIER);
|
|
75
|
+
if (!t)
|
|
103
76
|
throw new Error("Code verifier not found");
|
|
104
|
-
|
|
105
|
-
const response = await fetch(this.authEndpoints.token, {
|
|
77
|
+
const s = await fetch(this.authEndpoints.token, {
|
|
106
78
|
method: "POST",
|
|
107
79
|
headers: {
|
|
108
80
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
109
81
|
},
|
|
110
82
|
body: new URLSearchParams({
|
|
111
83
|
grant_type: "authorization_code",
|
|
112
|
-
code,
|
|
84
|
+
code: e,
|
|
113
85
|
redirect_uri: this.redirectUri,
|
|
114
86
|
client_id: this.authClientId,
|
|
115
|
-
code_verifier:
|
|
87
|
+
code_verifier: t
|
|
116
88
|
})
|
|
117
89
|
});
|
|
118
|
-
if (!
|
|
119
|
-
const
|
|
120
|
-
throw new Error(`Token exchange failed: ${
|
|
121
|
-
}
|
|
122
|
-
const tokens = await response.json();
|
|
123
|
-
localStorage.setItem(this.storageKeys.ACCESS_TOKEN, tokens.access_token);
|
|
124
|
-
if (tokens.refresh_token) {
|
|
125
|
-
localStorage.setItem(this.storageKeys.REFRESH_TOKEN, tokens.refresh_token);
|
|
90
|
+
if (!s.ok) {
|
|
91
|
+
const i = await s.text();
|
|
92
|
+
throw new Error(`Token exchange failed: ${s.status} ${i}`);
|
|
126
93
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
94
|
+
const r = await s.json();
|
|
95
|
+
if (localStorage.setItem(this.storageKeys.ACCESS_TOKEN, r.access_token), r.refresh_token && localStorage.setItem(this.storageKeys.REFRESH_TOKEN, r.refresh_token), r.expires_in) {
|
|
96
|
+
const i = Date.now() + r.expires_in * 1e3;
|
|
97
|
+
localStorage.setItem(this.storageKeys.EXPIRES_AT, i.toString());
|
|
130
98
|
}
|
|
131
99
|
}
|
|
132
100
|
// ============================================================================
|
|
133
101
|
// Storage Implementation (localStorage)
|
|
134
102
|
// ============================================================================
|
|
135
|
-
async _storageGet(
|
|
136
|
-
return localStorage.getItem(
|
|
103
|
+
async _storageGet(e) {
|
|
104
|
+
return localStorage.getItem(e);
|
|
137
105
|
}
|
|
138
|
-
async _storageSet(
|
|
139
|
-
Object.entries(
|
|
140
|
-
localStorage.setItem(
|
|
106
|
+
async _storageSet(e) {
|
|
107
|
+
Object.entries(e).forEach(([t, s]) => {
|
|
108
|
+
localStorage.setItem(t, String(s));
|
|
141
109
|
});
|
|
142
110
|
}
|
|
143
|
-
async _storageRemove(
|
|
144
|
-
|
|
111
|
+
async _storageRemove(e) {
|
|
112
|
+
e.forEach((t) => localStorage.removeItem(t));
|
|
145
113
|
}
|
|
146
114
|
_getRedirectUri() {
|
|
147
115
|
return this.redirectUri;
|
|
148
116
|
}
|
|
149
117
|
}
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
this.logger = new
|
|
159
|
-
this.authClientId = authClientId;
|
|
160
|
-
this.config = config;
|
|
161
|
-
this.authEndpoints = createOAuthEndpoints(this.config.authServerUrl);
|
|
162
|
-
this.onStateChange = onStateChange ?? NOOP_STATE_CALLBACK;
|
|
118
|
+
const N = 500, D = 5e3;
|
|
119
|
+
R(u.WEB);
|
|
120
|
+
function F(l = "/") {
|
|
121
|
+
const e = w(l, u.WEB);
|
|
122
|
+
return R(e);
|
|
123
|
+
}
|
|
124
|
+
class B {
|
|
125
|
+
constructor(e, t, s, r) {
|
|
126
|
+
this.state = y, this.bodhiext = null, this.refreshPromise = null, this.logger = new C("WindowBodhiextClient", t.logLevel), this.authClientId = e, this.config = t, this.authEndpoints = A(this.config.authServerUrl), this.onStateChange = s ?? k, this.storageKeys = F(r || "/");
|
|
163
127
|
}
|
|
164
128
|
/**
|
|
165
129
|
* Set client state and notify callback
|
|
166
130
|
*/
|
|
167
|
-
setState(
|
|
168
|
-
this.state =
|
|
169
|
-
this.logger.info(`{state: ${JSON.stringify(newState)}} - Setting client state`);
|
|
170
|
-
this.onStateChange({ type: "client-state", state: newState });
|
|
131
|
+
setState(e) {
|
|
132
|
+
this.state = e, this.logger.info(`{state: ${JSON.stringify(e)}} - Setting client state`), this.onStateChange({ type: "client-state", state: e });
|
|
171
133
|
}
|
|
172
134
|
/**
|
|
173
135
|
* Set auth state and notify callback
|
|
174
136
|
*/
|
|
175
|
-
setAuthState(
|
|
176
|
-
this.onStateChange({ type: "auth-state", state:
|
|
137
|
+
setAuthState(e) {
|
|
138
|
+
this.onStateChange({ type: "auth-state", state: e });
|
|
177
139
|
}
|
|
178
140
|
/**
|
|
179
141
|
* Set or update the state change callback
|
|
180
142
|
*/
|
|
181
|
-
setStateCallback(
|
|
182
|
-
this.onStateChange =
|
|
143
|
+
setStateCallback(e) {
|
|
144
|
+
this.onStateChange = e;
|
|
183
145
|
}
|
|
184
146
|
// ============================================================================
|
|
185
147
|
// Extension Communication
|
|
@@ -189,68 +151,58 @@ class WindowBodhiextClient {
|
|
|
189
151
|
* @throws Error if client not initialized
|
|
190
152
|
*/
|
|
191
153
|
ensureBodhiext() {
|
|
192
|
-
if (!this.bodhiext && window.bodhiext)
|
|
193
|
-
this.logger.info("Acquiring window.bodhiext reference");
|
|
194
|
-
this.bodhiext = window.bodhiext;
|
|
195
|
-
}
|
|
196
|
-
if (!this.bodhiext) {
|
|
154
|
+
if (!this.bodhiext && window.bodhiext && (this.logger.info("Acquiring window.bodhiext reference"), this.bodhiext = window.bodhiext), !this.bodhiext)
|
|
197
155
|
throw new Error("Client not initialized");
|
|
198
|
-
}
|
|
199
156
|
}
|
|
200
157
|
/**
|
|
201
158
|
* Send extension request via window.bodhiext.sendExtRequest
|
|
202
159
|
*/
|
|
203
|
-
async sendExtRequest(
|
|
204
|
-
this.ensureBodhiext();
|
|
205
|
-
return this.bodhiext.sendExtRequest(action, params);
|
|
160
|
+
async sendExtRequest(e, t) {
|
|
161
|
+
return this.ensureBodhiext(), this.bodhiext.sendExtRequest(e, t);
|
|
206
162
|
}
|
|
207
163
|
/**
|
|
208
164
|
* Send API message via window.bodhiext.sendApiRequest
|
|
209
165
|
* Converts ApiResponse to ApiResponseResult
|
|
210
166
|
*/
|
|
211
|
-
async sendApiRequest(
|
|
167
|
+
async sendApiRequest(e, t, s, r, i) {
|
|
212
168
|
try {
|
|
213
169
|
this.ensureBodhiext();
|
|
214
|
-
} catch (
|
|
170
|
+
} catch (o) {
|
|
215
171
|
return {
|
|
216
172
|
error: {
|
|
217
|
-
message:
|
|
173
|
+
message: o instanceof Error ? o.message : String(o),
|
|
218
174
|
type: "extension_error"
|
|
219
175
|
}
|
|
220
176
|
};
|
|
221
177
|
}
|
|
222
178
|
try {
|
|
223
|
-
let
|
|
224
|
-
if (
|
|
225
|
-
const
|
|
226
|
-
if (!
|
|
179
|
+
let o = r || {};
|
|
180
|
+
if (i) {
|
|
181
|
+
const c = await this._getAccessTokenRaw();
|
|
182
|
+
if (!c)
|
|
227
183
|
return {
|
|
228
184
|
error: {
|
|
229
185
|
message: "Not authenticated. Please log in first.",
|
|
230
186
|
type: "extension_error"
|
|
231
187
|
}
|
|
232
188
|
};
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
Authorization: `Bearer ${accessToken}`
|
|
189
|
+
o = {
|
|
190
|
+
...o,
|
|
191
|
+
Authorization: `Bearer ${c}`
|
|
237
192
|
};
|
|
238
193
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
194
|
+
return await this.bodhiext.sendApiRequest(
|
|
195
|
+
e,
|
|
196
|
+
t,
|
|
197
|
+
s,
|
|
198
|
+
o
|
|
244
199
|
);
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const errorObj = e == null ? void 0 : e.error;
|
|
248
|
-
const message = (errorObj == null ? void 0 : errorObj.message) ?? (e instanceof Error ? e.message : String(e));
|
|
249
|
-
const errorType = (errorObj == null ? void 0 : errorObj.type) || "extension_error";
|
|
200
|
+
} catch (o) {
|
|
201
|
+
const a = o == null ? void 0 : o.error, c = (a == null ? void 0 : a.message) ?? (o instanceof Error ? o.message : String(o)), n = (a == null ? void 0 : a.type) || "extension_error";
|
|
250
202
|
return {
|
|
251
203
|
error: {
|
|
252
|
-
message,
|
|
253
|
-
type:
|
|
204
|
+
message: c,
|
|
205
|
+
type: n
|
|
254
206
|
}
|
|
255
207
|
};
|
|
256
208
|
}
|
|
@@ -274,61 +226,47 @@ class WindowBodhiextClient {
|
|
|
274
226
|
* Note: Web mode uses stateless discovery (always polls for window.bodhiext)
|
|
275
227
|
* No extensionId storage/restoration needed - window.bodhiext handle is ephemeral
|
|
276
228
|
*/
|
|
277
|
-
async init(
|
|
278
|
-
var
|
|
279
|
-
if (!
|
|
280
|
-
this.logger.info("No testConnection or selectedConnection, returning not-initialized state");
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
if (this.bodhiext && !params.testConnection) {
|
|
284
|
-
this.logger.debug("Already have bodhiext handle, skipping polling");
|
|
285
|
-
return this.state;
|
|
286
|
-
}
|
|
229
|
+
async init(e = {}) {
|
|
230
|
+
var r, i, o, a;
|
|
231
|
+
if (!e.testConnection && !e.selectedConnection)
|
|
232
|
+
return this.logger.info("No testConnection or selectedConnection, returning not-initialized state"), y;
|
|
233
|
+
if (this.bodhiext && !e.testConnection)
|
|
234
|
+
return this.logger.debug("Already have bodhiext handle, skipping polling"), this.state;
|
|
287
235
|
if (!this.bodhiext) {
|
|
288
|
-
const
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
const found = await new Promise((resolve) => {
|
|
292
|
-
const check = () => {
|
|
236
|
+
const c = e.timeoutMs ?? ((i = (r = this.config.initParams) == null ? void 0 : r.extension) == null ? void 0 : i.timeoutMs) ?? D, n = e.intervalMs ?? ((a = (o = this.config.initParams) == null ? void 0 : o.extension) == null ? void 0 : a.intervalMs) ?? N, h = Date.now();
|
|
237
|
+
if (!await new Promise((p) => {
|
|
238
|
+
const m = () => {
|
|
293
239
|
if (window.bodhiext) {
|
|
294
|
-
this.bodhiext = window.bodhiext;
|
|
295
|
-
resolve(true);
|
|
240
|
+
this.bodhiext = window.bodhiext, p(!0);
|
|
296
241
|
return;
|
|
297
242
|
}
|
|
298
|
-
if (Date.now() -
|
|
299
|
-
|
|
243
|
+
if (Date.now() - h >= c) {
|
|
244
|
+
p(!1);
|
|
300
245
|
return;
|
|
301
246
|
}
|
|
302
|
-
setTimeout(
|
|
247
|
+
setTimeout(m, n);
|
|
303
248
|
};
|
|
304
|
-
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
this.logger.warn(`Extension discovery timed out`);
|
|
308
|
-
this.setState(EXTENSION_STATE_NOT_FOUND);
|
|
309
|
-
return this.state;
|
|
310
|
-
}
|
|
249
|
+
m();
|
|
250
|
+
}))
|
|
251
|
+
return this.logger.warn("Extension discovery timed out"), this.setState(v), this.state;
|
|
311
252
|
}
|
|
312
|
-
const
|
|
313
|
-
this.logger.info(`Extension discovered: ${
|
|
314
|
-
const
|
|
253
|
+
const t = await this.bodhiext.getExtensionId();
|
|
254
|
+
this.logger.info(`Extension discovered: ${t}`);
|
|
255
|
+
const s = {
|
|
315
256
|
type: "extension",
|
|
316
257
|
extension: "ready",
|
|
317
|
-
extensionId,
|
|
318
|
-
server:
|
|
258
|
+
extensionId: t,
|
|
259
|
+
server: b
|
|
319
260
|
};
|
|
320
|
-
if (
|
|
261
|
+
if (e.testConnection)
|
|
321
262
|
try {
|
|
322
|
-
const
|
|
323
|
-
this.setState({ ...
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
this.logger.error(`Failed to get server state:`, error);
|
|
327
|
-
this.setState({ ...state, server: BACKEND_SERVER_NOT_REACHABLE });
|
|
263
|
+
const c = await this.getServerState();
|
|
264
|
+
this.setState({ ...s, server: c }), this.logger.info(`Server connectivity tested: ${c.status}`);
|
|
265
|
+
} catch (c) {
|
|
266
|
+
this.logger.error("Failed to get server state:", c), this.setState({ ...s, server: d });
|
|
328
267
|
}
|
|
329
|
-
|
|
330
|
-
this.setState(
|
|
331
|
-
}
|
|
268
|
+
else
|
|
269
|
+
this.setState(s);
|
|
332
270
|
return this.state;
|
|
333
271
|
}
|
|
334
272
|
// ============================================================================
|
|
@@ -340,45 +278,35 @@ class WindowBodhiextClient {
|
|
|
340
278
|
*/
|
|
341
279
|
async requestResourceAccess() {
|
|
342
280
|
this.ensureBodhiext();
|
|
343
|
-
const
|
|
281
|
+
const e = await this.bodhiext.sendApiRequest("POST", "/bodhi/v1/apps/request-access", {
|
|
344
282
|
app_client_id: this.authClientId
|
|
345
283
|
});
|
|
346
|
-
if (!
|
|
284
|
+
if (!f(e))
|
|
347
285
|
throw new Error("Failed to get resource access scope: API error");
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
localStorage.setItem(STORAGE_KEYS.RESOURCE_SCOPE, scope);
|
|
351
|
-
return scope;
|
|
286
|
+
const t = e.body.scope;
|
|
287
|
+
return localStorage.setItem(this.storageKeys.RESOURCE_SCOPE, t), t;
|
|
352
288
|
}
|
|
353
289
|
/**
|
|
354
290
|
* Login via browser redirect OAuth2 + PKCE flow
|
|
355
291
|
* @returns AuthLoggedIn (though in practice, this redirects and never returns)
|
|
356
292
|
*/
|
|
357
293
|
async login() {
|
|
358
|
-
const
|
|
359
|
-
if (
|
|
360
|
-
return
|
|
361
|
-
}
|
|
294
|
+
const e = await this.getAuthState();
|
|
295
|
+
if (e.isLoggedIn)
|
|
296
|
+
return e;
|
|
362
297
|
this.ensureBodhiext();
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
const
|
|
366
|
-
const state = generateCodeVerifier();
|
|
367
|
-
localStorage.setItem(STORAGE_KEYS.CODE_VERIFIER, codeVerifier);
|
|
368
|
-
localStorage.setItem(STORAGE_KEYS.STATE, state);
|
|
369
|
-
const scopes = ["openid", "profile", "email", "roles", this.config.userScope, resourceScope];
|
|
370
|
-
const params = new URLSearchParams({
|
|
298
|
+
const t = await this.requestResourceAccess(), s = g(), r = await I(s), i = g();
|
|
299
|
+
localStorage.setItem(this.storageKeys.CODE_VERIFIER, s), localStorage.setItem(this.storageKeys.STATE, i);
|
|
300
|
+
const o = ["openid", "profile", "email", "roles", this.config.userScope, t], a = new URLSearchParams({
|
|
371
301
|
response_type: "code",
|
|
372
302
|
client_id: this.authClientId,
|
|
373
303
|
redirect_uri: this.config.redirectUri,
|
|
374
|
-
scope:
|
|
375
|
-
state,
|
|
376
|
-
code_challenge:
|
|
304
|
+
scope: o.join(" "),
|
|
305
|
+
state: i,
|
|
306
|
+
code_challenge: r,
|
|
377
307
|
code_challenge_method: "S256"
|
|
378
|
-
})
|
|
379
|
-
|
|
380
|
-
window.location.href = authUrl;
|
|
381
|
-
return new Promise(() => {
|
|
308
|
+
}), c = `${this.authEndpoints.authorize}?${a}`;
|
|
309
|
+
return window.location.href = c, new Promise(() => {
|
|
382
310
|
});
|
|
383
311
|
}
|
|
384
312
|
/**
|
|
@@ -386,58 +314,46 @@ class WindowBodhiextClient {
|
|
|
386
314
|
* Should be called from callback page with extracted URL params
|
|
387
315
|
* @returns AuthLoggedIn with login state and user info
|
|
388
316
|
*/
|
|
389
|
-
async handleOAuthCallback(
|
|
390
|
-
const
|
|
391
|
-
if (!
|
|
317
|
+
async handleOAuthCallback(e, t) {
|
|
318
|
+
const s = localStorage.getItem(this.storageKeys.STATE);
|
|
319
|
+
if (!s || s !== t)
|
|
392
320
|
throw new Error("Invalid state parameter - possible CSRF attack");
|
|
393
|
-
|
|
394
|
-
await this.
|
|
395
|
-
|
|
396
|
-
localStorage.removeItem(STORAGE_KEYS.STATE);
|
|
397
|
-
const authState = await this.getAuthState();
|
|
398
|
-
if (!authState.isLoggedIn) {
|
|
321
|
+
await this.exchangeCodeForTokens(e), localStorage.removeItem(this.storageKeys.CODE_VERIFIER), localStorage.removeItem(this.storageKeys.STATE);
|
|
322
|
+
const r = await this.getAuthState();
|
|
323
|
+
if (!r.isLoggedIn)
|
|
399
324
|
throw new Error("Login failed");
|
|
400
|
-
|
|
401
|
-
this.setAuthState(authState);
|
|
402
|
-
return authState;
|
|
325
|
+
return this.setAuthState(r), r;
|
|
403
326
|
}
|
|
404
327
|
/**
|
|
405
328
|
* Exchange authorization code for tokens
|
|
406
329
|
*/
|
|
407
|
-
async exchangeCodeForTokens(
|
|
408
|
-
const
|
|
409
|
-
if (!
|
|
330
|
+
async exchangeCodeForTokens(e) {
|
|
331
|
+
const t = localStorage.getItem(this.storageKeys.CODE_VERIFIER);
|
|
332
|
+
if (!t)
|
|
410
333
|
throw new Error("Code verifier not found");
|
|
411
|
-
|
|
412
|
-
const params = new URLSearchParams({
|
|
334
|
+
const s = new URLSearchParams({
|
|
413
335
|
grant_type: "authorization_code",
|
|
414
336
|
client_id: this.authClientId,
|
|
415
|
-
code,
|
|
337
|
+
code: e,
|
|
416
338
|
redirect_uri: this.config.redirectUri,
|
|
417
|
-
code_verifier:
|
|
418
|
-
})
|
|
419
|
-
const response = await fetch(this.authEndpoints.token, {
|
|
339
|
+
code_verifier: t
|
|
340
|
+
}), r = await fetch(this.authEndpoints.token, {
|
|
420
341
|
method: "POST",
|
|
421
342
|
headers: {
|
|
422
343
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
423
344
|
},
|
|
424
|
-
body:
|
|
345
|
+
body: s
|
|
425
346
|
});
|
|
426
|
-
if (!
|
|
427
|
-
const
|
|
428
|
-
throw new Error(`Token exchange failed: ${
|
|
347
|
+
if (!r.ok) {
|
|
348
|
+
const o = await r.text();
|
|
349
|
+
throw new Error(`Token exchange failed: ${r.status} ${o}`);
|
|
429
350
|
}
|
|
430
|
-
const
|
|
431
|
-
if (!
|
|
351
|
+
const i = await r.json();
|
|
352
|
+
if (!i.access_token)
|
|
432
353
|
throw new Error("No access token received");
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
localStorage.setItem(STORAGE_KEYS.REFRESH_TOKEN, tokenData.refresh_token);
|
|
437
|
-
}
|
|
438
|
-
if (tokenData.expires_in) {
|
|
439
|
-
const expiresAt = Date.now() + tokenData.expires_in * 1e3;
|
|
440
|
-
localStorage.setItem(STORAGE_KEYS.EXPIRES_AT, expiresAt.toString());
|
|
354
|
+
if (localStorage.setItem(this.storageKeys.ACCESS_TOKEN, i.access_token), i.refresh_token && localStorage.setItem(this.storageKeys.REFRESH_TOKEN, i.refresh_token), i.expires_in) {
|
|
355
|
+
const o = Date.now() + i.expires_in * 1e3;
|
|
356
|
+
localStorage.setItem(this.storageKeys.EXPIRES_AT, o.toString());
|
|
441
357
|
}
|
|
442
358
|
}
|
|
443
359
|
/**
|
|
@@ -445,11 +361,11 @@ class WindowBodhiextClient {
|
|
|
445
361
|
* @returns AuthLoggedOut with logged out state
|
|
446
362
|
*/
|
|
447
363
|
async logout() {
|
|
448
|
-
const
|
|
449
|
-
if (
|
|
364
|
+
const e = localStorage.getItem(this.storageKeys.REFRESH_TOKEN);
|
|
365
|
+
if (e)
|
|
450
366
|
try {
|
|
451
|
-
const
|
|
452
|
-
token:
|
|
367
|
+
const s = new URLSearchParams({
|
|
368
|
+
token: e,
|
|
453
369
|
client_id: this.authClientId,
|
|
454
370
|
token_type_hint: "refresh_token"
|
|
455
371
|
});
|
|
@@ -458,38 +374,28 @@ class WindowBodhiextClient {
|
|
|
458
374
|
headers: {
|
|
459
375
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
460
376
|
},
|
|
461
|
-
body:
|
|
377
|
+
body: s
|
|
462
378
|
});
|
|
463
|
-
} catch (
|
|
464
|
-
this.logger.warn("Token revocation failed:",
|
|
379
|
+
} catch (s) {
|
|
380
|
+
this.logger.warn("Token revocation failed:", s);
|
|
465
381
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
localStorage.removeItem(STORAGE_KEYS.EXPIRES_AT);
|
|
470
|
-
localStorage.removeItem(STORAGE_KEYS.CODE_VERIFIER);
|
|
471
|
-
localStorage.removeItem(STORAGE_KEYS.STATE);
|
|
472
|
-
localStorage.removeItem(STORAGE_KEYS.RESOURCE_SCOPE);
|
|
473
|
-
const result = {
|
|
474
|
-
isLoggedIn: false
|
|
382
|
+
localStorage.removeItem(this.storageKeys.ACCESS_TOKEN), localStorage.removeItem(this.storageKeys.REFRESH_TOKEN), localStorage.removeItem(this.storageKeys.EXPIRES_AT), localStorage.removeItem(this.storageKeys.CODE_VERIFIER), localStorage.removeItem(this.storageKeys.STATE), localStorage.removeItem(this.storageKeys.RESOURCE_SCOPE);
|
|
383
|
+
const t = {
|
|
384
|
+
isLoggedIn: !1
|
|
475
385
|
};
|
|
476
|
-
this.setAuthState(
|
|
477
|
-
return result;
|
|
386
|
+
return this.setAuthState(t), t;
|
|
478
387
|
}
|
|
479
388
|
/**
|
|
480
389
|
* Get current authentication state
|
|
481
390
|
*/
|
|
482
391
|
async getAuthState() {
|
|
483
|
-
const
|
|
484
|
-
if (!
|
|
485
|
-
return { isLoggedIn:
|
|
486
|
-
}
|
|
392
|
+
const e = await this._getAccessTokenRaw();
|
|
393
|
+
if (!e)
|
|
394
|
+
return { isLoggedIn: !1 };
|
|
487
395
|
try {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
this.logger.error("Failed to parse token:", error);
|
|
492
|
-
return { isLoggedIn: false };
|
|
396
|
+
return { isLoggedIn: !0, userInfo: _(e), accessToken: e };
|
|
397
|
+
} catch (t) {
|
|
398
|
+
return this.logger.error("Failed to parse token:", t), { isLoggedIn: !1 };
|
|
493
399
|
}
|
|
494
400
|
}
|
|
495
401
|
/**
|
|
@@ -497,33 +403,26 @@ class WindowBodhiextClient {
|
|
|
497
403
|
* Returns null if not logged in or token expired
|
|
498
404
|
*/
|
|
499
405
|
async _getAccessTokenRaw() {
|
|
500
|
-
const
|
|
501
|
-
|
|
502
|
-
if (!accessToken) {
|
|
406
|
+
const e = localStorage.getItem(this.storageKeys.ACCESS_TOKEN), t = localStorage.getItem(this.storageKeys.EXPIRES_AT);
|
|
407
|
+
if (!e)
|
|
503
408
|
return null;
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
if (refreshToken) {
|
|
510
|
-
return this._tryRefreshToken(refreshToken);
|
|
511
|
-
}
|
|
512
|
-
return null;
|
|
409
|
+
if (t) {
|
|
410
|
+
const s = parseInt(t, 10);
|
|
411
|
+
if (Date.now() >= s - 5 * 1e3) {
|
|
412
|
+
const r = localStorage.getItem(this.storageKeys.REFRESH_TOKEN);
|
|
413
|
+
return r ? this._tryRefreshToken(r) : null;
|
|
513
414
|
}
|
|
514
415
|
}
|
|
515
|
-
return
|
|
416
|
+
return e;
|
|
516
417
|
}
|
|
517
418
|
/**
|
|
518
419
|
* Try to refresh access token using refresh token
|
|
519
420
|
* Race condition prevention: Returns existing promise if refresh already in progress
|
|
520
421
|
*/
|
|
521
|
-
async _tryRefreshToken(
|
|
522
|
-
if (this.refreshPromise)
|
|
523
|
-
this.logger.debug("Refresh already in progress, returning existing promise");
|
|
524
|
-
|
|
525
|
-
}
|
|
526
|
-
this.refreshPromise = this._doRefreshToken(refreshToken);
|
|
422
|
+
async _tryRefreshToken(e) {
|
|
423
|
+
if (this.refreshPromise)
|
|
424
|
+
return this.logger.debug("Refresh already in progress, returning existing promise"), this.refreshPromise;
|
|
425
|
+
this.refreshPromise = this._doRefreshToken(e);
|
|
527
426
|
try {
|
|
528
427
|
return await this.refreshPromise;
|
|
529
428
|
} finally {
|
|
@@ -533,30 +432,27 @@ class WindowBodhiextClient {
|
|
|
533
432
|
/**
|
|
534
433
|
* Perform the actual token refresh
|
|
535
434
|
*/
|
|
536
|
-
async _doRefreshToken(
|
|
435
|
+
async _doRefreshToken(e) {
|
|
537
436
|
this.logger.debug("Refreshing access token");
|
|
538
437
|
try {
|
|
539
|
-
const
|
|
438
|
+
const t = await P(
|
|
540
439
|
this.authEndpoints.token,
|
|
541
|
-
|
|
440
|
+
e,
|
|
542
441
|
this.authClientId
|
|
543
442
|
);
|
|
544
|
-
if (
|
|
545
|
-
this._storeRefreshedTokens(
|
|
546
|
-
const
|
|
547
|
-
this.setAuthState({
|
|
548
|
-
isLoggedIn:
|
|
549
|
-
userInfo,
|
|
550
|
-
accessToken:
|
|
551
|
-
});
|
|
552
|
-
this.logger.info("Token refreshed successfully");
|
|
553
|
-
return tokens.access_token;
|
|
443
|
+
if (t) {
|
|
444
|
+
this._storeRefreshedTokens(t);
|
|
445
|
+
const s = _(t.access_token);
|
|
446
|
+
return this.setAuthState({
|
|
447
|
+
isLoggedIn: !0,
|
|
448
|
+
userInfo: s,
|
|
449
|
+
accessToken: t.access_token
|
|
450
|
+
}), this.logger.info("Token refreshed successfully"), t.access_token;
|
|
554
451
|
}
|
|
555
|
-
} catch (
|
|
556
|
-
this.logger.warn("Token refresh failed:",
|
|
452
|
+
} catch (t) {
|
|
453
|
+
this.logger.warn("Token refresh failed:", t);
|
|
557
454
|
}
|
|
558
|
-
this.logger.warn("Token refresh failed, keeping tokens for manual retry")
|
|
559
|
-
throw createOperationError(
|
|
455
|
+
throw this.logger.warn("Token refresh failed, keeping tokens for manual retry"), S(
|
|
560
456
|
"Access token expired and unable to refresh. Try logging out and logging in again.",
|
|
561
457
|
"token_refresh_failed"
|
|
562
458
|
);
|
|
@@ -564,13 +460,9 @@ class WindowBodhiextClient {
|
|
|
564
460
|
/**
|
|
565
461
|
* Store refreshed tokens
|
|
566
462
|
*/
|
|
567
|
-
_storeRefreshedTokens(
|
|
568
|
-
const
|
|
569
|
-
localStorage.setItem(
|
|
570
|
-
localStorage.setItem(STORAGE_KEYS.EXPIRES_AT, String(expiresAt));
|
|
571
|
-
if (tokens.refresh_token) {
|
|
572
|
-
localStorage.setItem(STORAGE_KEYS.REFRESH_TOKEN, tokens.refresh_token);
|
|
573
|
-
}
|
|
463
|
+
_storeRefreshedTokens(e) {
|
|
464
|
+
const t = Date.now() + e.expires_in * 1e3;
|
|
465
|
+
localStorage.setItem(this.storageKeys.ACCESS_TOKEN, e.access_token), localStorage.setItem(this.storageKeys.EXPIRES_AT, String(t)), e.refresh_token && localStorage.setItem(this.storageKeys.REFRESH_TOKEN, e.refresh_token);
|
|
574
466
|
}
|
|
575
467
|
/**
|
|
576
468
|
* Ping API
|
|
@@ -587,7 +479,7 @@ class WindowBodhiextClient {
|
|
|
587
479
|
"/v1/models",
|
|
588
480
|
void 0,
|
|
589
481
|
void 0,
|
|
590
|
-
|
|
482
|
+
!0
|
|
591
483
|
);
|
|
592
484
|
}
|
|
593
485
|
/**
|
|
@@ -595,88 +487,80 @@ class WindowBodhiextClient {
|
|
|
595
487
|
* Calls /bodhi/v1/info and returns structured server state
|
|
596
488
|
*/
|
|
597
489
|
async getServerState() {
|
|
598
|
-
const
|
|
599
|
-
if (
|
|
600
|
-
return
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
const body = result.body;
|
|
606
|
-
switch (body.status) {
|
|
490
|
+
const e = await this.sendApiRequest("GET", "/bodhi/v1/info");
|
|
491
|
+
if (T(e))
|
|
492
|
+
return d;
|
|
493
|
+
if (!f(e))
|
|
494
|
+
return d;
|
|
495
|
+
const t = e.body;
|
|
496
|
+
switch (t.status) {
|
|
607
497
|
case "ready":
|
|
608
|
-
return { status: "ready", version:
|
|
498
|
+
return { status: "ready", version: t.version || "unknown" };
|
|
609
499
|
case "setup":
|
|
610
|
-
return
|
|
500
|
+
return E("setup", t.version || "unknown");
|
|
611
501
|
case "resource-admin":
|
|
612
|
-
return
|
|
502
|
+
return E("resource-admin", t.version || "unknown");
|
|
613
503
|
case "error":
|
|
614
|
-
return
|
|
504
|
+
return E(
|
|
615
505
|
"error",
|
|
616
|
-
|
|
617
|
-
|
|
506
|
+
t.version || "unknown",
|
|
507
|
+
t.error ? { message: t.error.message, type: t.error.type } : O.SERVER_NOT_READY
|
|
618
508
|
);
|
|
619
509
|
default:
|
|
620
|
-
return
|
|
510
|
+
return d;
|
|
621
511
|
}
|
|
622
512
|
}
|
|
623
513
|
/**
|
|
624
514
|
* Generic streaming via window.bodhiext.sendStreamRequest
|
|
625
515
|
* Wraps ReadableStream as AsyncGenerator
|
|
626
516
|
*/
|
|
627
|
-
async *stream(
|
|
517
|
+
async *stream(e, t, s, r, i = !0) {
|
|
628
518
|
this.ensureBodhiext();
|
|
629
|
-
let
|
|
630
|
-
if (
|
|
631
|
-
const
|
|
632
|
-
if (!
|
|
519
|
+
let o = r || {};
|
|
520
|
+
if (i) {
|
|
521
|
+
const n = await this._getAccessTokenRaw();
|
|
522
|
+
if (!n)
|
|
633
523
|
throw new Error("Not authenticated. Please log in first.");
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
Authorization: `Bearer ${accessToken}`
|
|
524
|
+
o = {
|
|
525
|
+
...o,
|
|
526
|
+
Authorization: `Bearer ${n}`
|
|
638
527
|
};
|
|
639
528
|
}
|
|
640
|
-
const
|
|
641
|
-
const reader = stream.getReader();
|
|
529
|
+
const c = this.bodhiext.sendStreamRequest(e, t, s, o).getReader();
|
|
642
530
|
try {
|
|
643
|
-
|
|
644
|
-
const { value, done } = await
|
|
645
|
-
if (
|
|
531
|
+
for (; ; ) {
|
|
532
|
+
const { value: n, done: h } = await c.read();
|
|
533
|
+
if (h || n != null && n.done)
|
|
646
534
|
break;
|
|
647
|
-
|
|
648
|
-
yield value.body;
|
|
535
|
+
yield n.body;
|
|
649
536
|
}
|
|
650
|
-
} catch (
|
|
651
|
-
if (
|
|
652
|
-
if ("response" in
|
|
653
|
-
const
|
|
654
|
-
throw
|
|
537
|
+
} catch (n) {
|
|
538
|
+
if (n instanceof Error) {
|
|
539
|
+
if ("response" in n) {
|
|
540
|
+
const h = n;
|
|
541
|
+
throw K(n.message, h.response.status, h.response.body);
|
|
655
542
|
}
|
|
656
|
-
|
|
657
|
-
throw createOperationError(err.message, "extension_error");
|
|
658
|
-
}
|
|
659
|
-
throw createOperationError(err.message, "extension_error");
|
|
543
|
+
throw "error" in n ? S(n.message, "extension_error") : S(n.message, "extension_error");
|
|
660
544
|
}
|
|
661
|
-
throw
|
|
545
|
+
throw n;
|
|
662
546
|
} finally {
|
|
663
|
-
|
|
547
|
+
c.releaseLock();
|
|
664
548
|
}
|
|
665
549
|
}
|
|
666
550
|
/**
|
|
667
551
|
* Chat streaming
|
|
668
552
|
*/
|
|
669
|
-
async *streamChat(
|
|
553
|
+
async *streamChat(e, t, s = !0) {
|
|
670
554
|
yield* this.stream(
|
|
671
555
|
"POST",
|
|
672
556
|
"/v1/chat/completions",
|
|
673
557
|
{
|
|
674
|
-
model,
|
|
675
|
-
messages: [{ role: "user", content:
|
|
676
|
-
stream:
|
|
558
|
+
model: e,
|
|
559
|
+
messages: [{ role: "user", content: t }],
|
|
560
|
+
stream: !0
|
|
677
561
|
},
|
|
678
562
|
void 0,
|
|
679
|
-
|
|
563
|
+
s
|
|
680
564
|
);
|
|
681
565
|
}
|
|
682
566
|
/**
|
|
@@ -703,47 +587,47 @@ class WindowBodhiextClient {
|
|
|
703
587
|
};
|
|
704
588
|
}
|
|
705
589
|
}
|
|
706
|
-
class
|
|
707
|
-
constructor(
|
|
708
|
-
const
|
|
709
|
-
redirectUri:
|
|
710
|
-
authServerUrl:
|
|
711
|
-
userScope:
|
|
712
|
-
|
|
713
|
-
|
|
590
|
+
class W extends U {
|
|
591
|
+
constructor(e, t, s, r) {
|
|
592
|
+
const i = {
|
|
593
|
+
redirectUri: t.redirectUri,
|
|
594
|
+
authServerUrl: t.authServerUrl || "https://id.getbodhi.app/realms/bodhi",
|
|
595
|
+
userScope: t.userScope || "scope_user_user",
|
|
596
|
+
basePath: t.basePath || "/",
|
|
597
|
+
logLevel: t.logLevel || "warn",
|
|
598
|
+
initParams: t.initParams
|
|
714
599
|
};
|
|
715
|
-
super(
|
|
600
|
+
super(e, i, s, r, t.basePath);
|
|
716
601
|
}
|
|
717
|
-
createLogger(
|
|
718
|
-
return new
|
|
602
|
+
createLogger(e) {
|
|
603
|
+
return new C("WebUIClient", e.logLevel);
|
|
719
604
|
}
|
|
720
|
-
createExtClient(
|
|
721
|
-
return new
|
|
605
|
+
createExtClient(e, t) {
|
|
606
|
+
return new B(this.authClientId, e, t, e.basePath);
|
|
722
607
|
}
|
|
723
|
-
createDirectClient(
|
|
724
|
-
return new
|
|
608
|
+
createDirectClient(e, t, s) {
|
|
609
|
+
return new L(
|
|
725
610
|
{
|
|
726
|
-
authClientId,
|
|
727
|
-
authServerUrl:
|
|
728
|
-
redirectUri:
|
|
729
|
-
userScope:
|
|
730
|
-
logLevel:
|
|
731
|
-
storagePrefix:
|
|
611
|
+
authClientId: e,
|
|
612
|
+
authServerUrl: t.authServerUrl,
|
|
613
|
+
redirectUri: t.redirectUri,
|
|
614
|
+
userScope: t.userScope,
|
|
615
|
+
logLevel: t.logLevel,
|
|
616
|
+
storagePrefix: u.WEB,
|
|
617
|
+
basePath: t.basePath
|
|
732
618
|
},
|
|
733
|
-
|
|
619
|
+
s
|
|
734
620
|
);
|
|
735
621
|
}
|
|
736
622
|
// ============================================================================
|
|
737
623
|
// Web-specific OAuth Callback
|
|
738
624
|
// ============================================================================
|
|
739
|
-
async handleOAuthCallback(
|
|
740
|
-
|
|
741
|
-
return this.directClient.handleOAuthCallback(code, state);
|
|
742
|
-
}
|
|
743
|
-
return this.extClient.handleOAuthCallback(code, state);
|
|
625
|
+
async handleOAuthCallback(e, t) {
|
|
626
|
+
return this.connectionMode === "direct" ? this.directClient.handleOAuthCallback(e, t) : this.extClient.handleOAuthCallback(e, t);
|
|
744
627
|
}
|
|
745
628
|
}
|
|
629
|
+
const $ = "production";
|
|
746
630
|
export {
|
|
747
|
-
|
|
631
|
+
$ as WEB_BUILD_MODE,
|
|
632
|
+
W as WebUIClient
|
|
748
633
|
};
|
|
749
|
-
//# sourceMappingURL=bodhi-web.esm.js.map
|