@floegence/floe-webapp-boot 0.62.0 → 0.63.0
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/acquisition-lifecycle.d.ts +3 -0
- package/dist/acquisition-lifecycle.js +16 -14
- package/dist/acquisition.d.ts +1 -0
- package/dist/acquisition.js +141 -139
- package/dist/proxy-bootstrap.d.ts +5 -2
- package/dist/proxy-bootstrap.js +99 -67
- package/package.json +2 -2
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import type { FetchServerSentEventsOptions, ServerSentEvent } from './server-sent-events';
|
|
1
2
|
import type { ConnectionSnapshot } from '@floegence/flowersec-core';
|
|
2
3
|
import { type AcquisitionSource, ConnectedAcquisition } from './acquisition';
|
|
3
4
|
import { ProxyBootstrapOwner } from './proxy-bootstrap';
|
|
4
5
|
export interface AcquisitionConnectionLifecycle {
|
|
6
|
+
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
7
|
+
events(input: RequestInfo | URL, options?: Omit<FetchServerSentEventsOptions, 'fetch'>): AsyncGenerator<ServerSentEvent>;
|
|
5
8
|
synchronize(snapshot: ConnectionSnapshot): void;
|
|
6
9
|
dispose(): void;
|
|
7
10
|
}
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import { createSessionHealthMonitor as
|
|
2
|
-
import { clearAcquisitionSource as
|
|
3
|
-
import { closeProxyBootstrap as
|
|
4
|
-
function
|
|
5
|
-
let
|
|
6
|
-
const
|
|
1
|
+
import { createSessionHealthMonitor as u } from "./session-health.js";
|
|
2
|
+
import { clearAcquisitionSource as a, AcquisitionError as l, synchronizeAcquisitionSourceSnapshot as f } from "./acquisition.js";
|
|
3
|
+
import { createProxyBootstrapOwner as p, closeProxyBootstrap as y, synchronizeProxyBootstrap as d, readProxyBootstrapEvents as h, fetchProxyBootstrap as x } from "./proxy-bootstrap.js";
|
|
4
|
+
function w(i, c = {}) {
|
|
5
|
+
let n = !1, r = null;
|
|
6
|
+
const s = u(), t = c.proxyBootstrap ?? p();
|
|
7
7
|
return Object.freeze({
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
fetch: (e, o) => x(t, e, o),
|
|
9
|
+
events: (e, o) => h(t, e, o),
|
|
10
|
+
synchronize(e) {
|
|
11
|
+
if (n) throw new l("acquisition_lifecycle_disposed");
|
|
12
|
+
const o = f(i, e);
|
|
13
|
+
if (e.state === "connected" && o === null)
|
|
14
|
+
throw new l("connected_acquisition_missing");
|
|
15
|
+
d(t, o), o !== null && o !== r && c.onConnected?.(o), r = o, s.synchronize(e.state === "connected" ? e.currentSession ?? null : null);
|
|
14
16
|
},
|
|
15
17
|
dispose() {
|
|
16
|
-
|
|
18
|
+
n || (n = !0, r = null, s.dispose(), y(t), a(i));
|
|
17
19
|
}
|
|
18
20
|
});
|
|
19
21
|
}
|
|
20
22
|
export {
|
|
21
|
-
|
|
23
|
+
w as createAcquisitionConnectionLifecycle
|
|
22
24
|
};
|
package/dist/acquisition.d.ts
CHANGED
package/dist/acquisition.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { sha256 as x } from "@noble/hashes/sha2.js";
|
|
2
|
-
import { createArtifactLease as
|
|
2
|
+
import { createArtifactLease as S, parseArtifact as E } from "@floegence/flowersec-core";
|
|
3
3
|
import { assertProxyRuntimeScope as C } from "@floegence/flowersec-core/proxy";
|
|
4
|
-
const
|
|
4
|
+
const A = 32, L = 16384, H = "#redeven=";
|
|
5
5
|
class r extends Error {
|
|
6
|
-
constructor(
|
|
7
|
-
super(`Floe acquisition failed (code=${
|
|
6
|
+
constructor(i) {
|
|
7
|
+
super(`Floe acquisition failed (code=${i})`), this.code = i, this.name = "AcquisitionError";
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
class w {
|
|
@@ -15,8 +15,8 @@ class w {
|
|
|
15
15
|
static create() {
|
|
16
16
|
return new w();
|
|
17
17
|
}
|
|
18
|
-
static assertAuthentic(
|
|
19
|
-
|
|
18
|
+
static assertAuthentic(i) {
|
|
19
|
+
i.#e;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
class v {
|
|
@@ -27,46 +27,46 @@ class v {
|
|
|
27
27
|
static create() {
|
|
28
28
|
return new v();
|
|
29
29
|
}
|
|
30
|
-
static assertAuthentic(
|
|
31
|
-
|
|
30
|
+
static assertAuthentic(i) {
|
|
31
|
+
i.#e;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
const g = /* @__PURE__ */ new WeakMap(),
|
|
34
|
+
const g = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap(), P = /* @__PURE__ */ new WeakMap(), D = /* @__PURE__ */ new Set();
|
|
35
35
|
function ee(e) {
|
|
36
36
|
if (g.has(e)) throw new r("duplicate_acquisition_source");
|
|
37
37
|
g.set(e, { pending: [] });
|
|
38
38
|
}
|
|
39
|
-
async function te(e,
|
|
40
|
-
return q(e,
|
|
39
|
+
async function te(e, i, t) {
|
|
40
|
+
return q(e, i, t, E, S);
|
|
41
41
|
}
|
|
42
|
-
async function ie(e,
|
|
42
|
+
async function ie(e, i, t) {
|
|
43
43
|
const n = await import("@floegence/flowersec-core/browser");
|
|
44
44
|
return q(
|
|
45
45
|
e,
|
|
46
|
-
t,
|
|
47
46
|
i,
|
|
47
|
+
t,
|
|
48
48
|
n.parsePrivateLoopbackArtifactV1,
|
|
49
49
|
n.createPrivateLoopbackArtifactLeaseV1
|
|
50
50
|
);
|
|
51
51
|
}
|
|
52
|
-
async function ne(e,
|
|
52
|
+
async function ne(e, i, t) {
|
|
53
53
|
const n = await import("@floegence/flowersec-core/browser");
|
|
54
54
|
return q(
|
|
55
55
|
e,
|
|
56
|
-
t,
|
|
57
56
|
i,
|
|
57
|
+
t,
|
|
58
58
|
n.parseHTTPDirectArtifactV1,
|
|
59
59
|
n.createHTTPDirectArtifactLeaseV1
|
|
60
60
|
);
|
|
61
61
|
}
|
|
62
|
-
async function q(e,
|
|
62
|
+
async function q(e, i, t, n, c) {
|
|
63
63
|
const o = g.get(e);
|
|
64
64
|
if (o === void 0) throw new r("invalid_acquisition_source");
|
|
65
|
-
const a = await R(
|
|
65
|
+
const a = await R(i, t, n);
|
|
66
66
|
return B(
|
|
67
67
|
a,
|
|
68
68
|
c,
|
|
69
|
-
|
|
69
|
+
t.commitSpend,
|
|
70
70
|
(d) => {
|
|
71
71
|
o.pending.push(d);
|
|
72
72
|
},
|
|
@@ -75,41 +75,42 @@ async function q(e, t, i, n, c) {
|
|
|
75
75
|
}
|
|
76
76
|
);
|
|
77
77
|
}
|
|
78
|
-
function re(e,
|
|
79
|
-
const
|
|
80
|
-
if (
|
|
81
|
-
if (
|
|
82
|
-
return (
|
|
83
|
-
if (
|
|
84
|
-
return
|
|
85
|
-
const n =
|
|
86
|
-
if (n.length !== 1 ||
|
|
87
|
-
throw
|
|
78
|
+
function re(e, i) {
|
|
79
|
+
const t = g.get(e);
|
|
80
|
+
if (t === void 0) return null;
|
|
81
|
+
if (i.state !== "connected" || i.currentSession === void 0)
|
|
82
|
+
return (i.state === "idle" || i.state === "waiting" || i.state === "failed" || i.state === "closed") && (t.pending = [], t.connected = void 0, t.connectedSession = void 0), null;
|
|
83
|
+
if (t.connected !== void 0 && t.connectedSession === i.currentSession)
|
|
84
|
+
return t.connected;
|
|
85
|
+
const n = t.pending.filter((a) => a.committed);
|
|
86
|
+
if (n.length !== 1 || t.pending.length !== 1)
|
|
87
|
+
throw t.pending = [], new r("connected_acquisition_mismatch");
|
|
88
88
|
const c = n[0];
|
|
89
89
|
if (c === void 0) throw new r("connected_acquisition_mismatch");
|
|
90
90
|
const o = w.create();
|
|
91
|
-
return
|
|
91
|
+
return j.set(
|
|
92
92
|
o,
|
|
93
93
|
Object.freeze({
|
|
94
|
-
session:
|
|
94
|
+
session: i.currentSession,
|
|
95
95
|
scope: c.scope,
|
|
96
96
|
bindingIdentity: c.bindingIdentity,
|
|
97
|
-
|
|
97
|
+
appOrigin: c.appOrigin,
|
|
98
|
+
attempt: i.attempt
|
|
98
99
|
})
|
|
99
|
-
),
|
|
100
|
+
), t.pending = [], t.connected = o, t.connectedSession = i.currentSession, o;
|
|
100
101
|
}
|
|
101
102
|
function oe(e) {
|
|
102
|
-
const
|
|
103
|
-
|
|
103
|
+
const i = g.get(e);
|
|
104
|
+
i !== void 0 && (i.pending = [], i.connected = void 0, i.connectedSession = void 0);
|
|
104
105
|
}
|
|
105
106
|
function ce(e) {
|
|
106
107
|
w.assertAuthentic(e);
|
|
107
|
-
const
|
|
108
|
-
if (
|
|
109
|
-
return
|
|
108
|
+
const i = j.get(e);
|
|
109
|
+
if (i === void 0) throw new r("invalid_connected_acquisition");
|
|
110
|
+
return i;
|
|
110
111
|
}
|
|
111
112
|
async function ae(e) {
|
|
112
|
-
const
|
|
113
|
+
const i = e.rawHandoff, t = typeof i != "string" || V(`${H}${i}`) > L;
|
|
113
114
|
let n = !1;
|
|
114
115
|
try {
|
|
115
116
|
n = e.clearSensitiveLocation() === !0;
|
|
@@ -118,8 +119,8 @@ async function ae(e) {
|
|
|
118
119
|
}
|
|
119
120
|
if (!n)
|
|
120
121
|
throw e.navigateToLauncher(), new r("isolated_location_clear_failed");
|
|
121
|
-
if (
|
|
122
|
-
const c = m(
|
|
122
|
+
if (t) throw new r("isolated_handoff_too_large");
|
|
123
|
+
const c = m(i, "invalid_isolated_handoff"), o = await G(c);
|
|
123
124
|
if (D.has(o))
|
|
124
125
|
throw new r("isolated_handoff_consumed");
|
|
125
126
|
D.add(o);
|
|
@@ -137,29 +138,29 @@ async function ae(e) {
|
|
|
137
138
|
let s;
|
|
138
139
|
const l = B(
|
|
139
140
|
d,
|
|
140
|
-
|
|
141
|
+
S,
|
|
141
142
|
e.commitSpend,
|
|
142
|
-
(
|
|
143
|
-
s =
|
|
143
|
+
(u) => {
|
|
144
|
+
s = u;
|
|
144
145
|
},
|
|
145
146
|
() => {
|
|
146
147
|
}
|
|
147
148
|
);
|
|
148
149
|
if (s === void 0 || s.lease !== l)
|
|
149
150
|
throw new r("isolated_materialization_failed");
|
|
150
|
-
const
|
|
151
|
-
return P.set(
|
|
151
|
+
const p = v.create();
|
|
152
|
+
return P.set(p, { pending: s, state: "ready" }), p;
|
|
152
153
|
}
|
|
153
|
-
async function F(e,
|
|
154
|
-
const n = J(e,
|
|
154
|
+
async function F(e, i, t) {
|
|
155
|
+
const n = J(e, i), c = await R(
|
|
155
156
|
n.acquisition,
|
|
156
157
|
{
|
|
157
|
-
commitSpend:
|
|
158
|
+
commitSpend: t,
|
|
158
159
|
expectedConsumer: "isolated",
|
|
159
160
|
validateSpendBinding: (o) => {
|
|
160
|
-
M(n, o,
|
|
161
|
+
M(n, o, i);
|
|
161
162
|
try {
|
|
162
|
-
|
|
163
|
+
i.validateTargetBinding(o.targetBinding);
|
|
163
164
|
} catch {
|
|
164
165
|
throw new r("invalid_spend_binding");
|
|
165
166
|
}
|
|
@@ -177,11 +178,11 @@ async function F(e, t, i) {
|
|
|
177
178
|
}
|
|
178
179
|
return c;
|
|
179
180
|
}
|
|
180
|
-
async function se(e,
|
|
181
|
+
async function se(e, i, t) {
|
|
181
182
|
const n = g.get(e);
|
|
182
183
|
if (n === void 0) throw new r("invalid_acquisition_source");
|
|
183
184
|
const c = h(
|
|
184
|
-
|
|
185
|
+
i,
|
|
185
186
|
["v", "runtime_origin", "runtime_handoff_b64u"],
|
|
186
187
|
"invalid_isolated_handoff"
|
|
187
188
|
), o = c.runtime_handoff_b64u;
|
|
@@ -195,51 +196,52 @@ async function se(e, t, i) {
|
|
|
195
196
|
throw new r("invalid_isolated_handoff");
|
|
196
197
|
}
|
|
197
198
|
const s = d, l = {
|
|
198
|
-
...
|
|
199
|
+
...t.context,
|
|
199
200
|
runtimeOrigin: f(c.runtime_origin),
|
|
200
201
|
appOrigin: f(s?.app_origin)
|
|
201
|
-
},
|
|
202
|
+
}, p = await F(
|
|
202
203
|
d,
|
|
203
204
|
l,
|
|
204
|
-
|
|
205
|
-
),
|
|
206
|
-
if (!
|
|
207
|
-
return
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
(
|
|
212
|
-
(
|
|
213
|
-
n.pending = n.pending.filter((y) => y !==
|
|
205
|
+
t.commitSpend
|
|
206
|
+
), u = s?.acquisition;
|
|
207
|
+
if (!u) throw new r("invalid_isolated_handoff");
|
|
208
|
+
return t.validateSpendBinding($(u.spend_scope)), B(
|
|
209
|
+
p,
|
|
210
|
+
S,
|
|
211
|
+
t.commitSpend,
|
|
212
|
+
(_) => n.pending.push(_),
|
|
213
|
+
(_) => {
|
|
214
|
+
n.pending = n.pending.filter((y) => y !== _);
|
|
214
215
|
}
|
|
215
216
|
);
|
|
216
217
|
}
|
|
217
|
-
async function de(e,
|
|
218
|
+
async function de(e, i = {}) {
|
|
218
219
|
v.assertAuthentic(e);
|
|
219
|
-
const
|
|
220
|
-
if (
|
|
220
|
+
const t = P.get(e);
|
|
221
|
+
if (t === void 0 || t.state !== "ready")
|
|
221
222
|
throw new r("isolated_acquisition_consumed");
|
|
222
|
-
|
|
223
|
+
t.state = "connecting";
|
|
223
224
|
try {
|
|
224
|
-
const { connect: n } = await import("@floegence/flowersec-core/browser"), c = await n(
|
|
225
|
-
if (!
|
|
225
|
+
const { connect: n } = await import("@floegence/flowersec-core/browser"), c = await n(t.pending.lease, i);
|
|
226
|
+
if (!t.pending.committed)
|
|
226
227
|
throw await c.close().catch(() => {
|
|
227
228
|
}), new r("isolated_spend_not_committed");
|
|
228
229
|
const o = w.create();
|
|
229
|
-
return
|
|
230
|
+
return j.set(
|
|
230
231
|
o,
|
|
231
232
|
Object.freeze({
|
|
232
233
|
session: c,
|
|
233
|
-
scope:
|
|
234
|
-
bindingIdentity:
|
|
234
|
+
scope: t.pending.scope,
|
|
235
|
+
bindingIdentity: t.pending.bindingIdentity,
|
|
236
|
+
appOrigin: t.pending.appOrigin,
|
|
235
237
|
attempt: 1
|
|
236
238
|
})
|
|
237
|
-
),
|
|
239
|
+
), t.state = "consumed", o;
|
|
238
240
|
} catch (n) {
|
|
239
|
-
throw
|
|
241
|
+
throw t.state = "consumed", n;
|
|
240
242
|
}
|
|
241
243
|
}
|
|
242
|
-
async function R(e,
|
|
244
|
+
async function R(e, i, t) {
|
|
243
245
|
const n = h(
|
|
244
246
|
e,
|
|
245
247
|
["v", "connect_artifact", "critical_scope_projection_json", "spend_scope"],
|
|
@@ -247,7 +249,7 @@ async function R(e, t, i) {
|
|
|
247
249
|
);
|
|
248
250
|
if (n.v !== 1 || typeof n.connect_artifact != "string" || n.connect_artifact.length === 0 || typeof n.critical_scope_projection_json != "string" || n.critical_scope_projection_json.length === 0)
|
|
249
251
|
throw new r("invalid_acquisition_envelope");
|
|
250
|
-
const c = U(n.spend_scope,
|
|
252
|
+
const c = U(n.spend_scope, i.expectedConsumer), o = new TextEncoder().encode(n.connect_artifact), a = new TextEncoder().encode(n.critical_scope_projection_json);
|
|
251
253
|
await I(o, c.artifact_digest_b64u, "artifact_digest_mismatch"), await I(
|
|
252
254
|
a,
|
|
253
255
|
c.projection_digest_b64u,
|
|
@@ -272,27 +274,27 @@ async function R(e, t, i) {
|
|
|
272
274
|
} catch {
|
|
273
275
|
throw new r("invalid_proxy_runtime_scope");
|
|
274
276
|
}
|
|
275
|
-
let
|
|
277
|
+
let p;
|
|
276
278
|
try {
|
|
277
|
-
|
|
279
|
+
p = t(n.connect_artifact);
|
|
278
280
|
} catch {
|
|
279
281
|
throw new r("invalid_connect_artifact");
|
|
280
282
|
}
|
|
281
|
-
const
|
|
282
|
-
if (
|
|
283
|
+
const u = $(c), _ = i.validateSpendBinding(u);
|
|
284
|
+
if (_ !== void 0 && (typeof _ != "string" || _.trim() === "" || _ !== _.trim()))
|
|
283
285
|
throw new r("invalid_spend_binding_identity");
|
|
284
286
|
return Object.freeze({
|
|
285
|
-
artifact:
|
|
287
|
+
artifact: p,
|
|
286
288
|
scope: l,
|
|
287
|
-
binding:
|
|
288
|
-
bindingIdentity:
|
|
289
|
+
binding: u,
|
|
290
|
+
bindingIdentity: _ ?? `${u.artifactDigestB64u}.${u.projectionDigestB64u}`,
|
|
289
291
|
receipt: c.receipt
|
|
290
292
|
});
|
|
291
293
|
}
|
|
292
|
-
function B(e,
|
|
294
|
+
function B(e, i, t, n, c) {
|
|
293
295
|
const o = e.artifact, a = e.scope, d = e.binding, s = e.bindingIdentity;
|
|
294
|
-
let l = e.receipt,
|
|
295
|
-
const
|
|
296
|
+
let l = e.receipt, p;
|
|
297
|
+
const u = i(o, async (_) => {
|
|
296
298
|
const y = l;
|
|
297
299
|
if (l = void 0, y === void 0) throw new r("spend_binding_consumed");
|
|
298
300
|
const k = Object.freeze({
|
|
@@ -301,15 +303,15 @@ function B(e, t, i, n, c) {
|
|
|
301
303
|
receipt: y
|
|
302
304
|
});
|
|
303
305
|
try {
|
|
304
|
-
await
|
|
306
|
+
await t(k, _), p.committed = !0;
|
|
305
307
|
} catch (N) {
|
|
306
|
-
throw c(
|
|
308
|
+
throw c(p), N;
|
|
307
309
|
}
|
|
308
310
|
});
|
|
309
|
-
return
|
|
311
|
+
return p = { lease: u, scope: a, bindingIdentity: s, appOrigin: d.appOrigin, committed: !1 }, n(p), u;
|
|
310
312
|
}
|
|
311
|
-
function U(e,
|
|
312
|
-
const
|
|
313
|
+
function U(e, i) {
|
|
314
|
+
const t = h(
|
|
313
315
|
e,
|
|
314
316
|
[
|
|
315
317
|
"v",
|
|
@@ -325,21 +327,21 @@ function U(e, t) {
|
|
|
325
327
|
],
|
|
326
328
|
"invalid_spend_scope"
|
|
327
329
|
);
|
|
328
|
-
if (
|
|
330
|
+
if (t.v !== 1 || typeof t.receipt != "string" || !Z(t.receipt) || typeof t.artifact_digest_b64u != "string" || !T(t.artifact_digest_b64u) || typeof t.projection_digest_b64u != "string" || !T(t.projection_digest_b64u) || t.consumer !== i || typeof t.expires_at != "string" || !W(t.expires_at) || !b(t.target_binding))
|
|
329
331
|
throw new r("invalid_spend_scope");
|
|
330
|
-
const n = f(
|
|
331
|
-
if (Date.parse(
|
|
332
|
+
const n = f(t.launcher_origin), c = f(t.runtime_origin), o = f(t.app_origin);
|
|
333
|
+
if (Date.parse(t.expires_at) <= Date.now()) throw new r("expired_spend_scope");
|
|
332
334
|
return Object.freeze({
|
|
333
335
|
v: 1,
|
|
334
|
-
receipt:
|
|
335
|
-
artifact_digest_b64u:
|
|
336
|
-
projection_digest_b64u:
|
|
336
|
+
receipt: t.receipt,
|
|
337
|
+
artifact_digest_b64u: t.artifact_digest_b64u,
|
|
338
|
+
projection_digest_b64u: t.projection_digest_b64u,
|
|
337
339
|
launcher_origin: n,
|
|
338
340
|
runtime_origin: c,
|
|
339
341
|
app_origin: o,
|
|
340
|
-
consumer:
|
|
341
|
-
target_binding:
|
|
342
|
-
expires_at:
|
|
342
|
+
consumer: i,
|
|
343
|
+
target_binding: O(t.target_binding),
|
|
344
|
+
expires_at: t.expires_at
|
|
343
345
|
});
|
|
344
346
|
}
|
|
345
347
|
function $(e) {
|
|
@@ -354,8 +356,8 @@ function $(e) {
|
|
|
354
356
|
expiresAt: e.expires_at
|
|
355
357
|
});
|
|
356
358
|
}
|
|
357
|
-
function J(e,
|
|
358
|
-
const
|
|
359
|
+
function J(e, i) {
|
|
360
|
+
const t = h(
|
|
359
361
|
e,
|
|
360
362
|
[
|
|
361
363
|
"v",
|
|
@@ -372,46 +374,46 @@ function J(e, t) {
|
|
|
372
374
|
],
|
|
373
375
|
"invalid_isolated_handoff"
|
|
374
376
|
);
|
|
375
|
-
if (
|
|
377
|
+
if (t.v !== 6 || t.env_public_id !== i.envPublicId || t.floe_app !== i.floeApp || t.code_space_id !== i.codeSpaceId || t.app_path !== i.appPath || t.launcher_kind !== i.launcherKind || t.launcher_id !== i.launcherId || t.launcher_origin !== i.launcherOrigin || t.runtime_origin !== i.runtimeOrigin || t.app_origin !== i.appOrigin)
|
|
376
378
|
throw new r("isolated_context_mismatch");
|
|
377
|
-
return f(
|
|
379
|
+
return f(t.launcher_origin), f(t.runtime_origin), f(t.app_origin), t;
|
|
378
380
|
}
|
|
379
|
-
function M(e,
|
|
380
|
-
if (
|
|
381
|
+
function M(e, i, t) {
|
|
382
|
+
if (i.consumer !== "isolated" || i.launcherOrigin !== e.launcher_origin || i.runtimeOrigin !== e.runtime_origin || i.appOrigin !== e.app_origin || e.runtime_origin !== t.runtimeOrigin || e.app_origin !== t.appOrigin)
|
|
381
383
|
throw new r("isolated_spend_binding_mismatch");
|
|
382
384
|
}
|
|
383
|
-
function h(e,
|
|
385
|
+
function h(e, i, t) {
|
|
384
386
|
if (e === null || typeof e != "object" || Array.isArray(e))
|
|
385
|
-
throw new r(
|
|
386
|
-
const n = e, c = new Set(
|
|
387
|
-
if (o.length !==
|
|
388
|
-
throw new r(
|
|
387
|
+
throw new r(t);
|
|
388
|
+
const n = e, c = new Set(i), o = Object.keys(n);
|
|
389
|
+
if (o.length !== i.length || o.some((a) => !c.has(a)))
|
|
390
|
+
throw new r(t);
|
|
389
391
|
return n;
|
|
390
392
|
}
|
|
391
393
|
function f(e) {
|
|
392
394
|
if (typeof e != "string") throw new r("invalid_spend_scope");
|
|
393
|
-
let
|
|
395
|
+
let i;
|
|
394
396
|
try {
|
|
395
|
-
|
|
397
|
+
i = new URL(e);
|
|
396
398
|
} catch {
|
|
397
399
|
throw new r("invalid_spend_scope");
|
|
398
400
|
}
|
|
399
|
-
if (
|
|
401
|
+
if (i.protocol !== "https:" && i.protocol !== "http:" || i.origin !== e || i.username !== "" || i.password !== "")
|
|
400
402
|
throw new r("invalid_spend_scope");
|
|
401
403
|
return e;
|
|
402
404
|
}
|
|
403
405
|
function Z(e) {
|
|
404
|
-
const
|
|
405
|
-
if (
|
|
406
|
+
const i = /^r1\.([A-Za-z0-9_-]{1,64})\.([A-Za-z0-9_-]+)$/u.exec(e);
|
|
407
|
+
if (i === null || i[2] === void 0) return !1;
|
|
406
408
|
try {
|
|
407
|
-
return m(
|
|
409
|
+
return m(i[2], "invalid_spend_scope").length === A;
|
|
408
410
|
} catch {
|
|
409
411
|
return !1;
|
|
410
412
|
}
|
|
411
413
|
}
|
|
412
414
|
function T(e) {
|
|
413
415
|
try {
|
|
414
|
-
return m(e, "invalid_spend_scope").length ===
|
|
416
|
+
return m(e, "invalid_spend_scope").length === A;
|
|
415
417
|
} catch {
|
|
416
418
|
return !1;
|
|
417
419
|
}
|
|
@@ -419,29 +421,29 @@ function T(e) {
|
|
|
419
421
|
function W(e) {
|
|
420
422
|
return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/u.test(e) ? Number.isFinite(Date.parse(e)) : !1;
|
|
421
423
|
}
|
|
422
|
-
function b(e,
|
|
423
|
-
return
|
|
424
|
-
(
|
|
424
|
+
function b(e, i = 0) {
|
|
425
|
+
return i > 32 ? !1 : e === null || typeof e == "string" || typeof e == "boolean" ? !0 : typeof e == "number" ? Number.isFinite(e) : Array.isArray(e) ? e.every((t) => b(t, i + 1)) : typeof e != "object" ? !1 : Object.values(e).every(
|
|
426
|
+
(t) => b(t, i + 1)
|
|
425
427
|
);
|
|
426
428
|
}
|
|
427
|
-
function
|
|
429
|
+
function O(e) {
|
|
428
430
|
if (Array.isArray(e)) {
|
|
429
|
-
for (const
|
|
431
|
+
for (const i of e) O(i);
|
|
430
432
|
return Object.freeze(e);
|
|
431
433
|
}
|
|
432
434
|
if (e !== null && typeof e == "object") {
|
|
433
|
-
for (const
|
|
435
|
+
for (const i of Object.values(e)) O(i);
|
|
434
436
|
return Object.freeze(e);
|
|
435
437
|
}
|
|
436
438
|
return e;
|
|
437
439
|
}
|
|
438
|
-
async function I(e,
|
|
439
|
-
const n = await x(e), c = m(
|
|
440
|
-
if (n.length !== c.length) throw new r(
|
|
440
|
+
async function I(e, i, t) {
|
|
441
|
+
const n = await x(e), c = m(i, t);
|
|
442
|
+
if (n.length !== c.length) throw new r(t);
|
|
441
443
|
let o = 0;
|
|
442
444
|
for (let a = 0; a < n.length; a += 1)
|
|
443
445
|
o |= n[a] ^ c[a];
|
|
444
|
-
if (o !== 0) throw new r(
|
|
446
|
+
if (o !== 0) throw new r(t);
|
|
445
447
|
}
|
|
446
448
|
async function G(e) {
|
|
447
449
|
return z(await x(e));
|
|
@@ -449,25 +451,25 @@ async function G(e) {
|
|
|
449
451
|
function X() {
|
|
450
452
|
if (globalThis.crypto?.getRandomValues === void 0)
|
|
451
453
|
throw new r("acquisition_entropy_unavailable");
|
|
452
|
-
return z(globalThis.crypto.getRandomValues(new Uint8Array(
|
|
454
|
+
return z(globalThis.crypto.getRandomValues(new Uint8Array(A)));
|
|
453
455
|
}
|
|
454
|
-
function m(e,
|
|
455
|
-
if (!/^[A-Za-z0-9_-]*$/u.test(e) || e.length % 4 === 1) throw new r(
|
|
456
|
-
const
|
|
456
|
+
function m(e, i) {
|
|
457
|
+
if (!/^[A-Za-z0-9_-]*$/u.test(e) || e.length % 4 === 1) throw new r(i);
|
|
458
|
+
const t = e.replace(/-/gu, "+").replace(/_/gu, "/") + "=".repeat((4 - e.length % 4) % 4);
|
|
457
459
|
let n;
|
|
458
460
|
try {
|
|
459
|
-
n = atob(
|
|
461
|
+
n = atob(t);
|
|
460
462
|
} catch {
|
|
461
|
-
throw new r(
|
|
463
|
+
throw new r(i);
|
|
462
464
|
}
|
|
463
465
|
const c = Uint8Array.from(n, (o) => o.charCodeAt(0));
|
|
464
|
-
if (z(c) !== e) throw new r(
|
|
466
|
+
if (z(c) !== e) throw new r(i);
|
|
465
467
|
return c;
|
|
466
468
|
}
|
|
467
469
|
function z(e) {
|
|
468
|
-
let
|
|
469
|
-
for (const
|
|
470
|
-
return btoa(
|
|
470
|
+
let i = "";
|
|
471
|
+
for (const t of e) i += String.fromCharCode(t);
|
|
472
|
+
return btoa(i).replace(/\+/gu, "-").replace(/\//gu, "_").replace(/=+$/u, "");
|
|
471
473
|
}
|
|
472
474
|
function V(e) {
|
|
473
475
|
return new TextEncoder().encode(e).length;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type FetchServerSentEventsOptions, type ServerSentEvent } from './server-sent-events';
|
|
1
2
|
import { type ProxyRuntime } from '@floegence/flowersec-core/proxy';
|
|
2
3
|
import { ConnectedAcquisition } from './acquisition';
|
|
3
4
|
export type ProxyBootstrapBinding = Readonly<{
|
|
@@ -25,7 +26,7 @@ export type ProxyBootstrapOwnerOptions = Readonly<{
|
|
|
25
26
|
}>;
|
|
26
27
|
export type ProxyBootstrapSnapshot = Readonly<{
|
|
27
28
|
generation: number;
|
|
28
|
-
mode: 'service_worker' | 'controller_bridge';
|
|
29
|
+
mode: 'session' | 'service_worker' | 'controller_bridge';
|
|
29
30
|
bindingIdentity: string;
|
|
30
31
|
}>;
|
|
31
32
|
export declare class ProxyBootstrapOwner {
|
|
@@ -34,6 +35,8 @@ export declare class ProxyBootstrapOwner {
|
|
|
34
35
|
static create(): ProxyBootstrapOwner;
|
|
35
36
|
static assertAuthentic(value: ProxyBootstrapOwner): void;
|
|
36
37
|
}
|
|
37
|
-
export declare function createProxyBootstrapOwner(options
|
|
38
|
+
export declare function createProxyBootstrapOwner(options?: ProxyBootstrapOwnerOptions): ProxyBootstrapOwner;
|
|
38
39
|
export declare function synchronizeProxyBootstrap(owner: ProxyBootstrapOwner, acquisition: ConnectedAcquisition | null): ProxyBootstrapSnapshot | null;
|
|
40
|
+
export declare function fetchProxyBootstrap(owner: ProxyBootstrapOwner, input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
|
|
41
|
+
export declare function readProxyBootstrapEvents(owner: ProxyBootstrapOwner, input: RequestInfo | URL, options?: Omit<FetchServerSentEventsOptions, 'fetch'>): AsyncGenerator<ServerSentEvent>;
|
|
39
42
|
export declare function closeProxyBootstrap(owner: ProxyBootstrapOwner): void;
|
package/dist/proxy-bootstrap.js
CHANGED
|
@@ -1,101 +1,133 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { ServerSentEventStreamError as f, fetchServerSentEvents as b } from "./server-sent-events.js";
|
|
2
|
+
import { createProxyRuntime as w } from "@floegence/flowersec-core/proxy";
|
|
3
|
+
import { connectedAcquisitionDetails as y, AcquisitionError as a } from "./acquisition.js";
|
|
4
|
+
class l {
|
|
4
5
|
#e = void 0;
|
|
5
6
|
constructor() {
|
|
6
7
|
Object.freeze(this);
|
|
7
8
|
}
|
|
8
9
|
static create() {
|
|
9
|
-
return new
|
|
10
|
+
return new l();
|
|
10
11
|
}
|
|
11
12
|
static assertAuthentic(t) {
|
|
12
13
|
t.#e;
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
|
-
const
|
|
16
|
-
function
|
|
17
|
-
const t =
|
|
18
|
-
return
|
|
16
|
+
const v = /* @__PURE__ */ new WeakMap();
|
|
17
|
+
function B(r) {
|
|
18
|
+
const t = l.create();
|
|
19
|
+
return v.set(t, { options: r, generation: 0 }), t;
|
|
19
20
|
}
|
|
20
|
-
function
|
|
21
|
-
const
|
|
21
|
+
function _(r, t) {
|
|
22
|
+
const e = h(r);
|
|
22
23
|
if (t === null)
|
|
23
|
-
return
|
|
24
|
-
if (
|
|
24
|
+
return u(e), null;
|
|
25
|
+
if (e.acquisition === t && e.snapshot !== void 0) return e.snapshot;
|
|
25
26
|
const n = y(t);
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
const
|
|
27
|
+
u(e);
|
|
28
|
+
const i = e.generation + 1;
|
|
29
|
+
e.generation = i;
|
|
30
|
+
const o = n.scope, c = w({
|
|
30
31
|
session: n.session,
|
|
31
|
-
|
|
32
|
-
...
|
|
33
|
-
...
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
externalOrigin: n.appOrigin,
|
|
33
|
+
...o.limits ?? {},
|
|
34
|
+
...o.http?.extraRequestHeaders === void 0 ? {} : { extraRequestHeaders: o.http.extraRequestHeaders },
|
|
35
|
+
...o.appBasePath === void 0 ? {} : { pathPolicy: {
|
|
36
|
+
allowedPathPrefixes: Object.freeze([o.appBasePath, ...o.http?.additionalPathPrefixes ?? []]),
|
|
37
|
+
allowedWebSocketPathPrefixes: Object.freeze([o.appBasePath])
|
|
36
38
|
} }
|
|
37
39
|
});
|
|
38
40
|
try {
|
|
39
|
-
let
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
41
|
+
let s;
|
|
42
|
+
if (e.options !== void 0)
|
|
43
|
+
if (o.mode === "service_worker") {
|
|
44
|
+
const d = e.options.serviceWorker;
|
|
45
|
+
if (d === void 0) throw new a("service_worker_bootstrap_unavailable");
|
|
46
|
+
s = d(Object.freeze({
|
|
47
|
+
runtime: c,
|
|
48
|
+
generation: i,
|
|
49
|
+
bindingIdentity: n.bindingIdentity,
|
|
50
|
+
scriptUrl: o.serviceWorker.scriptUrl,
|
|
51
|
+
serviceWorkerScope: o.serviceWorker.scope,
|
|
52
|
+
...o.appBasePath === void 0 ? {} : { appBasePath: o.appBasePath }
|
|
53
|
+
}));
|
|
54
|
+
} else {
|
|
55
|
+
const d = e.options.controllerBridge;
|
|
56
|
+
if (d === void 0) throw new a("controller_bridge_bootstrap_unavailable");
|
|
57
|
+
s = d(Object.freeze({
|
|
58
|
+
runtime: c,
|
|
59
|
+
generation: i,
|
|
60
|
+
bindingIdentity: n.bindingIdentity,
|
|
61
|
+
allowedOrigins: o.controllerBridge.allowedOrigins,
|
|
62
|
+
...o.appBasePath === void 0 ? {} : { appBasePath: o.appBasePath },
|
|
63
|
+
capabilityNonce: g()
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
if (e.options !== void 0 && (s === null || typeof s != "object" || typeof s.dispose != "function"))
|
|
67
|
+
throw new a("invalid_proxy_bootstrap_binding");
|
|
68
|
+
const p = Object.freeze({ generation: i, mode: e.options === void 0 ? "session" : o.mode, bindingIdentity: n.bindingIdentity });
|
|
69
|
+
return e.acquisition = t, e.runtime = c, e.binding = s, e.snapshot = p, p;
|
|
70
|
+
} catch (s) {
|
|
71
|
+
throw c.dispose(), s;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function O(r, t, e) {
|
|
75
|
+
const n = h(r), i = n.runtime;
|
|
76
|
+
if (i === void 0) throw new a("session_http_unavailable");
|
|
77
|
+
const o = await i.fetch(t, e);
|
|
78
|
+
if (n.runtime !== i)
|
|
79
|
+
throw await o.body?.cancel().catch(() => {
|
|
80
|
+
}), new a("session_http_replaced");
|
|
81
|
+
return o;
|
|
82
|
+
}
|
|
83
|
+
async function* A(r, t, e = {}) {
|
|
84
|
+
const n = h(r), i = n.runtime;
|
|
85
|
+
if (i === void 0) throw new f("transport", "session HTTP is unavailable");
|
|
86
|
+
e.signal?.throwIfAborted();
|
|
87
|
+
const o = new Headers(e.headers ?? (t instanceof Request ? t.headers : void 0));
|
|
88
|
+
o.set("Accept", "text/event-stream");
|
|
89
|
+
for await (const c of b(t, {
|
|
90
|
+
...e,
|
|
91
|
+
headers: o,
|
|
92
|
+
fetch: (s, p) => i.fetch(s, p),
|
|
93
|
+
onActivity: () => {
|
|
94
|
+
n.runtime === i && !e.signal?.aborted && e.onActivity?.();
|
|
62
95
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return o.acquisition = t, o.runtime = p, o.binding = i, o.snapshot = u, u;
|
|
67
|
-
} catch (i) {
|
|
68
|
-
throw p.dispose(), i;
|
|
96
|
+
})) {
|
|
97
|
+
if (e.signal?.throwIfAborted(), n.runtime !== i) throw new f("transport", "session HTTP was replaced");
|
|
98
|
+
yield c;
|
|
69
99
|
}
|
|
70
100
|
}
|
|
71
|
-
function
|
|
72
|
-
|
|
101
|
+
function S(r) {
|
|
102
|
+
u(h(r));
|
|
73
103
|
}
|
|
74
|
-
function h(
|
|
75
|
-
|
|
76
|
-
const t =
|
|
77
|
-
if (t === void 0) throw new
|
|
104
|
+
function h(r) {
|
|
105
|
+
l.assertAuthentic(r);
|
|
106
|
+
const t = v.get(r);
|
|
107
|
+
if (t === void 0) throw new a("invalid_proxy_bootstrap_owner");
|
|
78
108
|
return t;
|
|
79
109
|
}
|
|
80
|
-
function
|
|
81
|
-
const t =
|
|
82
|
-
|
|
110
|
+
function u(r) {
|
|
111
|
+
const t = r.binding, e = r.runtime;
|
|
112
|
+
r.acquisition = void 0, r.binding = void 0, r.runtime = void 0, r.snapshot = void 0;
|
|
83
113
|
try {
|
|
84
114
|
t?.dispose();
|
|
85
115
|
} finally {
|
|
86
|
-
|
|
116
|
+
e?.dispose();
|
|
87
117
|
}
|
|
88
118
|
}
|
|
89
119
|
function g() {
|
|
90
|
-
if (globalThis.crypto?.getRandomValues === void 0) throw new
|
|
91
|
-
const
|
|
120
|
+
if (globalThis.crypto?.getRandomValues === void 0) throw new a("acquisition_entropy_unavailable");
|
|
121
|
+
const r = globalThis.crypto.getRandomValues(new Uint8Array(32));
|
|
92
122
|
let t = "";
|
|
93
|
-
for (const
|
|
123
|
+
for (const e of r) t += String.fromCharCode(e);
|
|
94
124
|
return btoa(t).replace(/\+/gu, "-").replace(/\//gu, "_").replace(/=+$/u, "");
|
|
95
125
|
}
|
|
96
126
|
export {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
127
|
+
l as ProxyBootstrapOwner,
|
|
128
|
+
S as closeProxyBootstrap,
|
|
129
|
+
B as createProxyBootstrapOwner,
|
|
130
|
+
O as fetchProxyBootstrap,
|
|
131
|
+
A as readProxyBootstrapEvents,
|
|
132
|
+
_ as synchronizeProxyBootstrap
|
|
101
133
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@floegence/floe-webapp-boot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.63.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"clean": "rm -rf dist *.tsbuildinfo"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@floegence/flowersec-core": "5.
|
|
38
|
+
"@floegence/flowersec-core": "5.3.1",
|
|
39
39
|
"@noble/hashes": "2.4.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|