@abraca/dabra 1.0.22 → 1.0.23
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/abracadabra-provider.cjs +91 -18
- package/dist/abracadabra-provider.cjs.map +1 -1
- package/dist/abracadabra-provider.esm.js +91 -18
- package/dist/abracadabra-provider.esm.js.map +1 -1
- package/dist/index.d.ts +34 -3
- package/package.json +1 -1
- package/src/AbracadabraClient.ts +17 -0
- package/src/IdentityDoc.ts +42 -6
- package/src/webrtc/DevicePairingChannel.ts +101 -13
- package/src/webrtc/SignalingSocket.ts +2 -2
|
@@ -3252,6 +3252,18 @@ var AbracadabraClient = class {
|
|
|
3252
3252
|
auth: false
|
|
3253
3253
|
});
|
|
3254
3254
|
}
|
|
3255
|
+
/**
|
|
3256
|
+
* Fetch a short-lived anonymous pairing token for WebRTC signaling.
|
|
3257
|
+
* No authentication required. The token only grants access to `__pairing_*` rooms.
|
|
3258
|
+
*/
|
|
3259
|
+
static async getPairingToken(serverUrl) {
|
|
3260
|
+
let base = serverUrl;
|
|
3261
|
+
while (base.endsWith("/")) base = base.slice(0, -1);
|
|
3262
|
+
const resp = await fetch(`${base}/auth/pairing-token`, { method: "POST" });
|
|
3263
|
+
if (!resp.ok) throw new Error(`Failed to fetch pairing token: ${resp.status}`);
|
|
3264
|
+
const { token } = await resp.json();
|
|
3265
|
+
return token;
|
|
3266
|
+
}
|
|
3255
3267
|
/** Get encryption info for a document. */
|
|
3256
3268
|
async getDocEncryption(docId) {
|
|
3257
3269
|
return this.request("GET", `/docs/${encodeURIComponent(docId)}/encryption`);
|
|
@@ -8910,8 +8922,8 @@ var SignalingSocket = class extends EventEmitter {
|
|
|
8910
8922
|
break;
|
|
8911
8923
|
case "joined":
|
|
8912
8924
|
this.emit("joined", {
|
|
8913
|
-
|
|
8914
|
-
|
|
8925
|
+
peer_id: msg.peer_id,
|
|
8926
|
+
user_id: msg.user_id,
|
|
8915
8927
|
muted: msg.muted,
|
|
8916
8928
|
video: msg.video,
|
|
8917
8929
|
screen: msg.screen,
|
|
@@ -10349,6 +10361,7 @@ var ManualSignaling = class extends EventEmitter {
|
|
|
10349
10361
|
const CODE_CHARSET = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
|
10350
10362
|
const CODE_LENGTH = 6;
|
|
10351
10363
|
const PAIRING_TIMEOUT_MS = 300 * 1e3;
|
|
10364
|
+
const SIGNALING_CONNECT_TIMEOUT_MS = 5e3;
|
|
10352
10365
|
function generatePairingCode() {
|
|
10353
10366
|
const bytes = crypto.getRandomValues(new Uint8Array(CODE_LENGTH));
|
|
10354
10367
|
return Array.from(bytes).map((b) => CODE_CHARSET[b % 32]).join("");
|
|
@@ -10366,6 +10379,7 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
10366
10379
|
this._destroyed = false;
|
|
10367
10380
|
this._pendingRequest = null;
|
|
10368
10381
|
this._connectedPeerId = null;
|
|
10382
|
+
this._usingFallback = false;
|
|
10369
10383
|
this.role = role;
|
|
10370
10384
|
this.pairingCode = pairingCode;
|
|
10371
10385
|
}
|
|
@@ -10520,12 +10534,41 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
10520
10534
|
}
|
|
10521
10535
|
this.removeAllListeners();
|
|
10522
10536
|
}
|
|
10537
|
+
async resolveToken(serverUrl) {
|
|
10538
|
+
if (this.config.token && serverUrl === this.config.serverUrl) return this.config.token;
|
|
10539
|
+
let base = serverUrl ?? this.config.serverUrl;
|
|
10540
|
+
while (base.endsWith("/")) base = base.slice(0, -1);
|
|
10541
|
+
const resp = await fetch(`${base}/auth/pairing-token`, { method: "POST" });
|
|
10542
|
+
if (!resp.ok) throw new Error(`Failed to fetch pairing token: ${resp.status} ${resp.statusText}`);
|
|
10543
|
+
const { token } = await resp.json();
|
|
10544
|
+
return token;
|
|
10545
|
+
}
|
|
10523
10546
|
start() {
|
|
10547
|
+
this.connectToServer(this.config.serverUrl);
|
|
10548
|
+
this.timeoutHandle = setTimeout(() => {
|
|
10549
|
+
if (!this._destroyed) {
|
|
10550
|
+
this.emit("error", /* @__PURE__ */ new Error("Pairing timed out"));
|
|
10551
|
+
this.destroy();
|
|
10552
|
+
}
|
|
10553
|
+
}, PAIRING_TIMEOUT_MS);
|
|
10554
|
+
}
|
|
10555
|
+
connectToServer(serverUrl, signalingUrl) {
|
|
10556
|
+
const roomId = codeToRoomId(this.pairingCode);
|
|
10557
|
+
const tokenPromise = this.resolveToken(serverUrl);
|
|
10558
|
+
const tokenFactory = async () => {
|
|
10559
|
+
const t = await tokenPromise;
|
|
10560
|
+
if (typeof t === "function") return await t();
|
|
10561
|
+
return t;
|
|
10562
|
+
};
|
|
10563
|
+
if (!this.config.iceServers) new AbracadabraClient({ url: serverUrl }).getIceServers().then((servers) => {
|
|
10564
|
+
if (servers.length > 0) this._resolvedIceServers = servers;
|
|
10565
|
+
});
|
|
10524
10566
|
this.webrtc = new AbracadabraWebRTC({
|
|
10525
|
-
docId:
|
|
10526
|
-
url:
|
|
10527
|
-
|
|
10528
|
-
|
|
10567
|
+
docId: roomId,
|
|
10568
|
+
url: serverUrl,
|
|
10569
|
+
signalingUrl: signalingUrl ?? void 0,
|
|
10570
|
+
token: tokenFactory,
|
|
10571
|
+
iceServers: this.config.iceServers ?? this._resolvedIceServers,
|
|
10529
10572
|
e2ee: this.config.e2ee,
|
|
10530
10573
|
enableDocSync: false,
|
|
10531
10574
|
enableAwarenessSync: false,
|
|
@@ -10533,6 +10576,10 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
10533
10576
|
autoConnect: false,
|
|
10534
10577
|
WebSocketPolyfill: this.config.WebSocketPolyfill
|
|
10535
10578
|
});
|
|
10579
|
+
let connected = false;
|
|
10580
|
+
this.webrtc.on("connected", () => {
|
|
10581
|
+
connected = true;
|
|
10582
|
+
});
|
|
10536
10583
|
this.webrtc.on("e2eeEstablished", ({ peerId }) => {
|
|
10537
10584
|
this._connectedPeerId = peerId;
|
|
10538
10585
|
this.emit("connected");
|
|
@@ -10546,14 +10593,25 @@ var DevicePairingChannel = class DevicePairingChannel extends EventEmitter {
|
|
|
10546
10593
|
this.webrtc.on("signalingError", (err) => {
|
|
10547
10594
|
this.emit("error", /* @__PURE__ */ new Error(`Signaling: ${err.message}`));
|
|
10548
10595
|
});
|
|
10549
|
-
this.
|
|
10550
|
-
|
|
10551
|
-
this.
|
|
10552
|
-
this.
|
|
10553
|
-
|
|
10554
|
-
|
|
10596
|
+
if (this.config.fallbackSignalingUrl && !signalingUrl) {
|
|
10597
|
+
const fallbackTimer = setTimeout(() => {
|
|
10598
|
+
if (this._destroyed || connected) return;
|
|
10599
|
+
if (this.webrtc) {
|
|
10600
|
+
this.webrtc.destroy();
|
|
10601
|
+
this.webrtc = null;
|
|
10602
|
+
}
|
|
10603
|
+
this._usingFallback = true;
|
|
10604
|
+
this.emit("fallback", { url: this.config.fallbackSignalingUrl });
|
|
10605
|
+
this.connectToServer(this.config.fallbackSignalingUrl);
|
|
10606
|
+
}, SIGNALING_CONNECT_TIMEOUT_MS);
|
|
10607
|
+
this.webrtc.on("connected", () => clearTimeout(fallbackTimer));
|
|
10608
|
+
}
|
|
10555
10609
|
this.webrtc.connect();
|
|
10556
10610
|
}
|
|
10611
|
+
/** Whether the connection fell back to the fallback signaling server. */
|
|
10612
|
+
get usingFallback() {
|
|
10613
|
+
return this._usingFallback;
|
|
10614
|
+
}
|
|
10557
10615
|
sendMessage(msg) {
|
|
10558
10616
|
if (!this.webrtc || !this._connectedPeerId) return;
|
|
10559
10617
|
this.webrtc.sendCustomMessage(this._connectedPeerId, JSON.stringify(msg));
|
|
@@ -10801,26 +10859,41 @@ var IdentityDocProvider = class extends EventEmitter {
|
|
|
10801
10859
|
});
|
|
10802
10860
|
for (const { url, key } of targets) {
|
|
10803
10861
|
if (this.providers.has(key)) continue;
|
|
10804
|
-
this.
|
|
10862
|
+
this.connectToServer(key, url);
|
|
10805
10863
|
}
|
|
10806
10864
|
if (this.config.webrtc && !this.webrtc) this._connectWebRTC();
|
|
10807
10865
|
}
|
|
10808
|
-
|
|
10866
|
+
connectToServer(key, serverUrl) {
|
|
10867
|
+
if (this._destroyed) return;
|
|
10868
|
+
const existingProvider = this.providers.get(key);
|
|
10869
|
+
if (existingProvider) {
|
|
10870
|
+
existingProvider.destroy();
|
|
10871
|
+
this.providers.delete(key);
|
|
10872
|
+
}
|
|
10873
|
+
const existingWs = this.websockets.get(key);
|
|
10874
|
+
if (existingWs) {
|
|
10875
|
+
existingWs.destroy();
|
|
10876
|
+
this.websockets.delete(key);
|
|
10877
|
+
}
|
|
10809
10878
|
const token = this.config.tokens?.[serverUrl] ?? this.config.token ?? "";
|
|
10810
10879
|
const ws = new AbracadabraWS({
|
|
10811
10880
|
url: serverUrl.replace(/^http/, "ws").replace(/\/$/, "").concat("/ws"),
|
|
10812
10881
|
WebSocketPolyfill: void 0
|
|
10813
10882
|
});
|
|
10814
10883
|
this.websockets.set(key, ws);
|
|
10815
|
-
const
|
|
10884
|
+
const providerConfig = {
|
|
10816
10885
|
name: this.docId,
|
|
10817
10886
|
document: this.document,
|
|
10818
10887
|
websocketProvider: ws,
|
|
10819
|
-
token,
|
|
10820
10888
|
serverAgnostic: true,
|
|
10821
10889
|
disableOfflineStore: key !== "local" && key !== "sync" ? true : this.config.disableOfflineStore ?? false,
|
|
10822
10890
|
...this.config.providerDefaults
|
|
10823
|
-
}
|
|
10891
|
+
};
|
|
10892
|
+
if (this.config.cryptoIdentity && this.config.signChallenge) {
|
|
10893
|
+
providerConfig.cryptoIdentity = this.config.cryptoIdentity;
|
|
10894
|
+
providerConfig.signChallenge = this.config.signChallenge;
|
|
10895
|
+
} else providerConfig.token = token;
|
|
10896
|
+
const provider = new AbracadabraProvider(providerConfig);
|
|
10824
10897
|
provider.on("synced", () => this.emit("synced", { server: key }));
|
|
10825
10898
|
provider.on("status", (data) => this.emit("status", {
|
|
10826
10899
|
server: key,
|
|
@@ -11027,7 +11100,7 @@ var IdentityDocProvider = class extends EventEmitter {
|
|
|
11027
11100
|
...this.config,
|
|
11028
11101
|
syncServerUrl: url
|
|
11029
11102
|
};
|
|
11030
|
-
this.
|
|
11103
|
+
this.connectToServer("sync", url);
|
|
11031
11104
|
}
|
|
11032
11105
|
}
|
|
11033
11106
|
getProvider(key) {
|