@signalapp/ringrtc 2.26.4 → 2.28.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/index.d.ts +2 -1
- package/dist/index.js +7 -3
- package/dist/ringrtc/CallLinks.d.ts +23 -0
- package/dist/ringrtc/CallLinks.js +55 -0
- package/dist/ringrtc/Native.d.ts +2 -0
- package/dist/ringrtc/Native.js +34 -0
- package/dist/ringrtc/Service.d.ts +133 -14
- package/dist/ringrtc/Service.js +282 -86
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RingRTCType } from './ringrtc/Service';
|
|
2
|
-
export { AnswerMessage, AudioDevice,
|
|
2
|
+
export { AnswerMessage, AudioDevice, DataMode, BusyMessage, Call, CallEndedReason, CallId, CallLogLevel, CallMessageUrgency, CallSettings, CallState, CallingMessage, ConnectionState, DeviceId, GroupCall, GroupCallEndReason, GroupCallObserver, GroupMemberInfo, HangupMessage, HangupType, HttpMethod, HttpResult, IceCandidateMessage, JoinState, LocalDeviceState, OfferMessage, OfferType, OpaqueMessage, PeekDeviceInfo, PeekInfo, PeekStatusCodes, RemoteDeviceState, RingCancelReason, RingRTCType, RingUpdate, UserId, VideoCapturer, VideoRenderer, VideoRequest, callIdFromEra, callIdFromRingId, } from './ringrtc/Service';
|
|
3
3
|
export { CanvasVideoRenderer, GumVideoCapturer, VideoFrameSource, MAX_VIDEO_CAPTURE_AREA, MAX_VIDEO_CAPTURE_BUFFER_SIZE, MAX_VIDEO_CAPTURE_HEIGHT, MAX_VIDEO_CAPTURE_WIDTH, } from './ringrtc/VideoSupport';
|
|
4
|
+
export { CallLinkRootKey, CallLinkRestrictions, CallLinkState, } from './ringrtc/CallLinks';
|
|
4
5
|
export declare const RingRTC: RingRTCType;
|
package/dist/index.js
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
5
5
|
//
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.RingRTC = exports.MAX_VIDEO_CAPTURE_WIDTH = exports.MAX_VIDEO_CAPTURE_HEIGHT = exports.MAX_VIDEO_CAPTURE_BUFFER_SIZE = exports.MAX_VIDEO_CAPTURE_AREA = exports.GumVideoCapturer = exports.CanvasVideoRenderer = exports.callIdFromRingId = exports.callIdFromEra = exports.VideoRequest = exports.RingUpdate = exports.RingRTCType = exports.RingCancelReason = exports.RemoteDeviceState = exports.
|
|
7
|
+
exports.RingRTC = exports.CallLinkState = exports.CallLinkRestrictions = exports.CallLinkRootKey = exports.MAX_VIDEO_CAPTURE_WIDTH = exports.MAX_VIDEO_CAPTURE_HEIGHT = exports.MAX_VIDEO_CAPTURE_BUFFER_SIZE = exports.MAX_VIDEO_CAPTURE_AREA = exports.GumVideoCapturer = exports.CanvasVideoRenderer = exports.callIdFromRingId = exports.callIdFromEra = exports.VideoRequest = exports.RingUpdate = exports.RingRTCType = exports.RingCancelReason = exports.RemoteDeviceState = exports.PeekStatusCodes = exports.OpaqueMessage = exports.OfferType = exports.OfferMessage = exports.LocalDeviceState = exports.JoinState = exports.IceCandidateMessage = exports.HttpMethod = exports.HangupType = exports.HangupMessage = exports.GroupMemberInfo = exports.GroupCallEndReason = exports.GroupCall = exports.ConnectionState = exports.CallingMessage = exports.CallState = exports.CallMessageUrgency = exports.CallLogLevel = exports.CallEndedReason = exports.Call = exports.BusyMessage = exports.DataMode = exports.AnswerMessage = void 0;
|
|
8
8
|
const Service_1 = require("./ringrtc/Service");
|
|
9
9
|
var Service_2 = require("./ringrtc/Service");
|
|
10
10
|
Object.defineProperty(exports, "AnswerMessage", { enumerable: true, get: function () { return Service_2.AnswerMessage; } });
|
|
11
|
-
Object.defineProperty(exports, "
|
|
11
|
+
Object.defineProperty(exports, "DataMode", { enumerable: true, get: function () { return Service_2.DataMode; } });
|
|
12
12
|
Object.defineProperty(exports, "BusyMessage", { enumerable: true, get: function () { return Service_2.BusyMessage; } });
|
|
13
13
|
Object.defineProperty(exports, "Call", { enumerable: true, get: function () { return Service_2.Call; } });
|
|
14
14
|
Object.defineProperty(exports, "CallEndedReason", { enumerable: true, get: function () { return Service_2.CallEndedReason; } });
|
|
@@ -29,7 +29,7 @@ Object.defineProperty(exports, "LocalDeviceState", { enumerable: true, get: func
|
|
|
29
29
|
Object.defineProperty(exports, "OfferMessage", { enumerable: true, get: function () { return Service_2.OfferMessage; } });
|
|
30
30
|
Object.defineProperty(exports, "OfferType", { enumerable: true, get: function () { return Service_2.OfferType; } });
|
|
31
31
|
Object.defineProperty(exports, "OpaqueMessage", { enumerable: true, get: function () { return Service_2.OpaqueMessage; } });
|
|
32
|
-
Object.defineProperty(exports, "
|
|
32
|
+
Object.defineProperty(exports, "PeekStatusCodes", { enumerable: true, get: function () { return Service_2.PeekStatusCodes; } });
|
|
33
33
|
Object.defineProperty(exports, "RemoteDeviceState", { enumerable: true, get: function () { return Service_2.RemoteDeviceState; } });
|
|
34
34
|
Object.defineProperty(exports, "RingCancelReason", { enumerable: true, get: function () { return Service_2.RingCancelReason; } });
|
|
35
35
|
Object.defineProperty(exports, "RingRTCType", { enumerable: true, get: function () { return Service_2.RingRTCType; } });
|
|
@@ -44,5 +44,9 @@ Object.defineProperty(exports, "MAX_VIDEO_CAPTURE_AREA", { enumerable: true, get
|
|
|
44
44
|
Object.defineProperty(exports, "MAX_VIDEO_CAPTURE_BUFFER_SIZE", { enumerable: true, get: function () { return VideoSupport_1.MAX_VIDEO_CAPTURE_BUFFER_SIZE; } });
|
|
45
45
|
Object.defineProperty(exports, "MAX_VIDEO_CAPTURE_HEIGHT", { enumerable: true, get: function () { return VideoSupport_1.MAX_VIDEO_CAPTURE_HEIGHT; } });
|
|
46
46
|
Object.defineProperty(exports, "MAX_VIDEO_CAPTURE_WIDTH", { enumerable: true, get: function () { return VideoSupport_1.MAX_VIDEO_CAPTURE_WIDTH; } });
|
|
47
|
+
var CallLinks_1 = require("./ringrtc/CallLinks");
|
|
48
|
+
Object.defineProperty(exports, "CallLinkRootKey", { enumerable: true, get: function () { return CallLinks_1.CallLinkRootKey; } });
|
|
49
|
+
Object.defineProperty(exports, "CallLinkRestrictions", { enumerable: true, get: function () { return CallLinks_1.CallLinkRestrictions; } });
|
|
50
|
+
Object.defineProperty(exports, "CallLinkState", { enumerable: true, get: function () { return CallLinks_1.CallLinkState; } });
|
|
47
51
|
exports.RingRTC = new Service_1.RingRTCType();
|
|
48
52
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
export declare class CallLinkRootKey {
|
|
3
|
+
readonly bytes: Buffer;
|
|
4
|
+
private constructor();
|
|
5
|
+
static parse(str: string): CallLinkRootKey;
|
|
6
|
+
static fromBytes(bytes: Buffer): CallLinkRootKey;
|
|
7
|
+
static generate(): CallLinkRootKey;
|
|
8
|
+
static generateAdminPassKey(): Buffer;
|
|
9
|
+
deriveRoomId(): Buffer;
|
|
10
|
+
toString(): string;
|
|
11
|
+
}
|
|
12
|
+
export declare class CallLinkState {
|
|
13
|
+
name: string;
|
|
14
|
+
restrictions: CallLinkRestrictions;
|
|
15
|
+
revoked: boolean;
|
|
16
|
+
expiration: Date;
|
|
17
|
+
constructor(name: string, restrictions: CallLinkRestrictions, revoked: boolean, expiration: Date);
|
|
18
|
+
}
|
|
19
|
+
export declare enum CallLinkRestrictions {
|
|
20
|
+
None = 0,
|
|
21
|
+
AdminApproval = 1,
|
|
22
|
+
Unknown = 2
|
|
23
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2023 Signal Messenger, LLC
|
|
4
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
5
|
+
//
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.CallLinkRestrictions = exports.CallLinkState = exports.CallLinkRootKey = void 0;
|
|
11
|
+
const Native_1 = __importDefault(require("./Native"));
|
|
12
|
+
class CallLinkRootKey {
|
|
13
|
+
constructor(bytes) {
|
|
14
|
+
this.bytes = bytes;
|
|
15
|
+
}
|
|
16
|
+
static parse(str) {
|
|
17
|
+
return new CallLinkRootKey(Native_1.default.CallLinkRootKey_parse(str));
|
|
18
|
+
}
|
|
19
|
+
static fromBytes(bytes) {
|
|
20
|
+
Native_1.default.CallLinkRootKey_validate(bytes);
|
|
21
|
+
return new CallLinkRootKey(bytes);
|
|
22
|
+
}
|
|
23
|
+
static generate() {
|
|
24
|
+
return new CallLinkRootKey(Native_1.default.CallLinkRootKey_generate());
|
|
25
|
+
}
|
|
26
|
+
static generateAdminPassKey() {
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
28
|
+
return Native_1.default.CallLinkRootKey_generateAdminPasskey();
|
|
29
|
+
}
|
|
30
|
+
deriveRoomId() {
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
32
|
+
return Native_1.default.CallLinkRootKey_deriveRoomId(this.bytes);
|
|
33
|
+
}
|
|
34
|
+
toString() {
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
36
|
+
return Native_1.default.CallLinkRootKey_toFormattedString(this.bytes);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.CallLinkRootKey = CallLinkRootKey;
|
|
40
|
+
class CallLinkState {
|
|
41
|
+
constructor(name, restrictions, revoked, expiration) {
|
|
42
|
+
this.name = name;
|
|
43
|
+
this.restrictions = restrictions;
|
|
44
|
+
this.revoked = revoked;
|
|
45
|
+
this.expiration = expiration;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.CallLinkState = CallLinkState;
|
|
49
|
+
var CallLinkRestrictions;
|
|
50
|
+
(function (CallLinkRestrictions) {
|
|
51
|
+
CallLinkRestrictions[CallLinkRestrictions["None"] = 0] = "None";
|
|
52
|
+
CallLinkRestrictions[CallLinkRestrictions["AdminApproval"] = 1] = "AdminApproval";
|
|
53
|
+
CallLinkRestrictions[CallLinkRestrictions["Unknown"] = 2] = "Unknown";
|
|
54
|
+
})(CallLinkRestrictions = exports.CallLinkRestrictions || (exports.CallLinkRestrictions = {}));
|
|
55
|
+
//# sourceMappingURL=CallLinks.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
//
|
|
3
|
+
// Copyright 2023 Signal Messenger, LLC
|
|
4
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
5
|
+
//
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
23
|
+
if (mod && mod.__esModule) return mod;
|
|
24
|
+
var result = {};
|
|
25
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
26
|
+
__setModuleDefault(result, mod);
|
|
27
|
+
return result;
|
|
28
|
+
};
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
const os = __importStar(require("os"));
|
|
31
|
+
const process = __importStar(require("process"));
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require
|
|
33
|
+
exports.default = require(`../../build/${os.platform()}/libringrtc-${process.arch}.node`);
|
|
34
|
+
//# sourceMappingURL=Native.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { GumVideoCaptureOptions, VideoPixelFormatEnum } from './VideoSupport';
|
|
3
|
+
import { CallLinkState, CallLinkRestrictions, CallLinkRootKey } from './CallLinks';
|
|
3
4
|
export declare const callIdFromEra: (era: string) => CallId;
|
|
4
5
|
export declare function callIdFromRingId(ringId: bigint): CallId;
|
|
5
6
|
declare class Config {
|
|
@@ -8,18 +9,20 @@ declare class Config {
|
|
|
8
9
|
}
|
|
9
10
|
type GroupId = Buffer;
|
|
10
11
|
type GroupCallUserId = Buffer;
|
|
11
|
-
export
|
|
12
|
+
export interface PeekDeviceInfo {
|
|
12
13
|
demuxId: number;
|
|
13
14
|
userId?: GroupCallUserId;
|
|
14
|
-
constructor(demuxId: number, userId: GroupCallUserId | undefined);
|
|
15
15
|
}
|
|
16
|
-
export
|
|
16
|
+
export interface PeekInfo {
|
|
17
17
|
devices: Array<PeekDeviceInfo>;
|
|
18
18
|
creator?: GroupCallUserId;
|
|
19
19
|
eraId?: string;
|
|
20
20
|
maxDevices?: number;
|
|
21
21
|
deviceCount: number;
|
|
22
|
-
|
|
22
|
+
}
|
|
23
|
+
export declare enum PeekStatusCodes {
|
|
24
|
+
EXPIRED_CALL_LINK = 703,
|
|
25
|
+
INVALID_CALL_LINK = 704
|
|
23
26
|
}
|
|
24
27
|
declare enum NetworkAdapterType {
|
|
25
28
|
Unknown = 0,
|
|
@@ -45,11 +48,19 @@ export declare class ReceivedAudioLevel {
|
|
|
45
48
|
level: RawAudioLevel;
|
|
46
49
|
constructor(demuxId: number, level: RawAudioLevel);
|
|
47
50
|
}
|
|
51
|
+
export type HttpResult<T> = {
|
|
52
|
+
success: true;
|
|
53
|
+
value: T;
|
|
54
|
+
} | {
|
|
55
|
+
success: false;
|
|
56
|
+
errorStatusCode: number;
|
|
57
|
+
};
|
|
48
58
|
export declare class RingRTCType {
|
|
49
59
|
private readonly callManager;
|
|
50
60
|
private _call;
|
|
51
61
|
private _groupCallByClientId;
|
|
52
62
|
private _peekRequests;
|
|
63
|
+
private _callLinkRequests;
|
|
53
64
|
private _callInfoByCallId;
|
|
54
65
|
private getCallInfoKey;
|
|
55
66
|
handleOutgoingSignaling: ((remoteUserId: UserId, message: CallingMessage) => Promise<boolean>) | null;
|
|
@@ -84,10 +95,107 @@ export declare class RingRTCType {
|
|
|
84
95
|
onSendHangup(remoteUserId: UserId, remoteDeviceId: DeviceId, callId: CallId, broadcast: boolean, hangupType: HangupType, deviceId: DeviceId | null): void;
|
|
85
96
|
onSendBusy(remoteUserId: UserId, remoteDeviceId: DeviceId, callId: CallId, broadcast: boolean): void;
|
|
86
97
|
private sendSignaling;
|
|
98
|
+
/**
|
|
99
|
+
* Asynchronous request to get information about a call link.
|
|
100
|
+
*
|
|
101
|
+
* @param sfuUrl - the URL to use when accessing the SFU
|
|
102
|
+
* @param authCredentialPresentation - a serialized CallLinkAuthCredentialPresentation
|
|
103
|
+
* @param linkRootKey - the root key for the call link
|
|
104
|
+
*
|
|
105
|
+
* Expected failure codes include:
|
|
106
|
+
* - 404: the room does not exist (or expired so long ago that it has been removed from the server)
|
|
107
|
+
*/
|
|
108
|
+
readCallLink(sfuUrl: string, authCredentialPresentation: Buffer, linkRootKey: CallLinkRootKey): Promise<HttpResult<CallLinkState>>;
|
|
109
|
+
/**
|
|
110
|
+
* Asynchronous request to create a new call link.
|
|
111
|
+
*
|
|
112
|
+
* This request is idempotent; if it fails due to a network issue, it is safe to retry.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* const linkKey = CallLinkRootKey.generate();
|
|
116
|
+
* const adminPasskey = CallLinkRootKey.generateAdminPasskey();
|
|
117
|
+
* const roomId = linkKey.deriveRoomId();
|
|
118
|
+
* const credential = requestCreateCredentialFromChatServer(roomId); // using libsignal
|
|
119
|
+
* const secretParams = CallLinkSecretParams.deriveFromRootKey(linkKey.bytes);
|
|
120
|
+
* const credentialPresentation = credential.present(roomId, secretParams).serialize();
|
|
121
|
+
* const serializedPublicParams = secretParams.getPublicParams().serialize();
|
|
122
|
+
* const result = await RingRTC.createCallLink(sfuUrl, credentialPresentation, linkKey, adminPasskey, serializedPublicParams);
|
|
123
|
+
* if (result.success) {
|
|
124
|
+
* const state = result.value;
|
|
125
|
+
* // In actuality you may not want to do this until the user clicks Done.
|
|
126
|
+
* saveToDatabase(linkKey.bytes, adminPasskey, state);
|
|
127
|
+
* syncToOtherDevices(linkKey.bytes, adminPasskey);
|
|
128
|
+
* } else {
|
|
129
|
+
* switch (result.errorStatusCode) {
|
|
130
|
+
* case 409:
|
|
131
|
+
* // The room already exists (and isn't yours), i.e. you've hit a 1-in-a-billion conflict.
|
|
132
|
+
* // Fall through to kicking the user out to try again later.
|
|
133
|
+
* default:
|
|
134
|
+
* // Unexpected error, kick the user out for now.
|
|
135
|
+
* }
|
|
136
|
+
* }
|
|
137
|
+
*
|
|
138
|
+
* @param sfuUrl - the URL to use when accessing the SFU
|
|
139
|
+
* @param createCredentialPresentation - a serialized CreateCallLinkCredentialPresentation
|
|
140
|
+
* @param linkRootKey - the root key for the call link
|
|
141
|
+
* @param adminPasskey - the arbitrary passkey to use for the new room
|
|
142
|
+
* @param callLinkPublicParams - the serialized CallLinkPublicParams for the new room
|
|
143
|
+
*/
|
|
144
|
+
createCallLink(sfuUrl: string, createCredentialPresentation: Buffer, linkRootKey: CallLinkRootKey, adminPasskey: Buffer, callLinkPublicParams: Buffer): Promise<HttpResult<CallLinkState>>;
|
|
145
|
+
/**
|
|
146
|
+
* Asynchronous request to update a call link's name.
|
|
147
|
+
*
|
|
148
|
+
* Possible failure codes include:
|
|
149
|
+
* - 401: the room does not exist (and this is the wrong API to create a new room)
|
|
150
|
+
* - 403: the admin passkey is incorrect
|
|
151
|
+
*
|
|
152
|
+
* This request is idempotent; if it fails due to a network issue, it is safe to retry.
|
|
153
|
+
*
|
|
154
|
+
* @param sfuUrl - the URL to use when accessing the SFU
|
|
155
|
+
* @param authCredentialPresentation - a serialized CallLinkAuthCredentialPresentation
|
|
156
|
+
* @param linkRootKey - the root key for the call link
|
|
157
|
+
* @param adminPasskey - the passkey specified when the link was created
|
|
158
|
+
* @param newName - the new name to use
|
|
159
|
+
*/
|
|
160
|
+
updateCallLinkName(sfuUrl: string, authCredentialPresentation: Buffer, linkRootKey: CallLinkRootKey, adminPasskey: Buffer, newName: string): Promise<HttpResult<CallLinkState>>;
|
|
161
|
+
/**
|
|
162
|
+
* Asynchronous request to update a call link's restrictions.
|
|
163
|
+
*
|
|
164
|
+
* Possible failure codes include:
|
|
165
|
+
* - 401: the room does not exist (and this is the wrong API to create a new room)
|
|
166
|
+
* - 403: the admin passkey is incorrect
|
|
167
|
+
*
|
|
168
|
+
* This request is idempotent; if it fails due to a network issue, it is safe to retry.
|
|
169
|
+
*
|
|
170
|
+
* @param sfuUrl - the URL to use when accessing the SFU
|
|
171
|
+
* @param authCredentialPresentation - a serialized CallLinkAuthCredentialPresentation
|
|
172
|
+
* @param linkRootKey - the root key for the call link
|
|
173
|
+
* @param adminPasskey - the passkey specified when the link was created
|
|
174
|
+
* @param restrictions - the new restrictions to use
|
|
175
|
+
*/
|
|
176
|
+
updateCallLinkRestrictions(sfuUrl: string, authCredentialPresentation: Buffer, linkRootKey: CallLinkRootKey, adminPasskey: Buffer, restrictions: Exclude<CallLinkRestrictions, CallLinkRestrictions.Unknown>): Promise<HttpResult<CallLinkState>>;
|
|
177
|
+
/**
|
|
178
|
+
* Asynchronous request to revoke or un-revoke a call link.
|
|
179
|
+
*
|
|
180
|
+
* Possible failure codes include:
|
|
181
|
+
* - 401: the room does not exist (and this is the wrong API to create a new room)
|
|
182
|
+
* - 403: the admin passkey is incorrect
|
|
183
|
+
*
|
|
184
|
+
* This request is idempotent; if it fails due to a network issue, it is safe to retry.
|
|
185
|
+
*
|
|
186
|
+
* @param sfuUrl - the URL to use when accessing the SFU
|
|
187
|
+
* @param authCredentialPresentation - a serialized CallLinkAuthCredentialPresentation
|
|
188
|
+
* @param linkRootKey - the root key for the call link
|
|
189
|
+
* @param adminPasskey - the passkey specified when the link was created
|
|
190
|
+
* @param revoked - whether the link should now be revoked
|
|
191
|
+
*/
|
|
192
|
+
updateCallLinkRevocation(sfuUrl: string, authCredentialPresentation: Buffer, linkRootKey: CallLinkRootKey, adminPasskey: Buffer, revoked: boolean): Promise<HttpResult<CallLinkState>>;
|
|
87
193
|
receivedHttpResponse(requestId: number, status: number, body: Buffer): void;
|
|
88
194
|
httpRequestFailed(requestId: number, debugInfo: string | undefined): void;
|
|
89
195
|
getGroupCall(groupId: Buffer, sfuUrl: string, hkdfExtraInfo: Buffer, audioLevelsIntervalMillis: number | undefined, observer: GroupCallObserver): GroupCall | undefined;
|
|
196
|
+
getCallLinkCall(sfuUrl: string, authCredentialPresentation: Buffer, rootKey: CallLinkRootKey, adminPasskey: Buffer | undefined, hkdfExtraInfo: Buffer, audioLevelsIntervalMillis: number | undefined, observer: GroupCallObserver): GroupCall | undefined;
|
|
90
197
|
peekGroupCall(sfuUrl: string, membershipProof: Buffer, groupMembers: Array<GroupMemberInfo>): Promise<PeekInfo>;
|
|
198
|
+
peekCallLinkCall(sfuUrl: string, authCredentialPresentation: Buffer, rootKey: CallLinkRootKey): Promise<HttpResult<PeekInfo>>;
|
|
91
199
|
requestMembershipProof(clientId: GroupCallClientId): void;
|
|
92
200
|
requestGroupMembers(clientId: GroupCallClientId): void;
|
|
93
201
|
handleConnectionStateChanged(clientId: GroupCallClientId, connectionState: ConnectionState): void;
|
|
@@ -96,7 +204,13 @@ export declare class RingRTCType {
|
|
|
96
204
|
handleAudioLevels(clientId: GroupCallClientId, capturedLevel: RawAudioLevel, receivedLevels: Array<ReceivedAudioLevel>): void;
|
|
97
205
|
handleRemoteDevicesChanged(clientId: GroupCallClientId, remoteDeviceStates: Array<RemoteDeviceState>): void;
|
|
98
206
|
handlePeekChanged(clientId: GroupCallClientId, info: PeekInfo): void;
|
|
99
|
-
handlePeekResponse(requestId: number, info: PeekInfo): void;
|
|
207
|
+
handlePeekResponse(requestId: number, statusCode: number, info: PeekInfo | undefined): void;
|
|
208
|
+
handleCallLinkResponse(requestId: number, statusCode: number, state: {
|
|
209
|
+
name: string;
|
|
210
|
+
rawRestrictions: number;
|
|
211
|
+
revoked: boolean;
|
|
212
|
+
expiration: Date;
|
|
213
|
+
} | undefined): void;
|
|
100
214
|
handleEnded(clientId: GroupCallClientId, reason: GroupCallEndReason): void;
|
|
101
215
|
groupCallRingUpdate(groupId: GroupId, ringIdString: string, sender: GroupCallUserId, state: RingUpdate): void;
|
|
102
216
|
onLogMessage(level: number, fileName: string, line: number, message: string): void;
|
|
@@ -128,7 +242,7 @@ export declare class RingRTCType {
|
|
|
128
242
|
export interface CallSettings {
|
|
129
243
|
iceServer: IceServer;
|
|
130
244
|
hideIp: boolean;
|
|
131
|
-
|
|
245
|
+
dataMode: DataMode;
|
|
132
246
|
audioLevelsIntervalMillis?: number;
|
|
133
247
|
}
|
|
134
248
|
interface IceServer {
|
|
@@ -199,7 +313,7 @@ export declare class Call {
|
|
|
199
313
|
receiveVideoFrame(buffer: Buffer, maxWidth: number, maxHeight: number): [number, number] | undefined;
|
|
200
314
|
private enableOrDisableCapturer;
|
|
201
315
|
private setOutgoingVideoEnabled;
|
|
202
|
-
|
|
316
|
+
updateDataMode(dataMode: DataMode): void;
|
|
203
317
|
private enableOrDisableRenderer;
|
|
204
318
|
}
|
|
205
319
|
export type GroupCallClientId = number;
|
|
@@ -306,7 +420,7 @@ export declare class GroupCall {
|
|
|
306
420
|
private _localDeviceState;
|
|
307
421
|
private _remoteDeviceStates;
|
|
308
422
|
private _peekInfo;
|
|
309
|
-
constructor(callManager: CallManager,
|
|
423
|
+
constructor(callManager: CallManager, observer: GroupCallObserver, clientId: GroupCallClientId);
|
|
310
424
|
connect(): void;
|
|
311
425
|
join(): void;
|
|
312
426
|
leave(): void;
|
|
@@ -320,7 +434,7 @@ export declare class GroupCall {
|
|
|
320
434
|
setOutgoingVideoIsScreenShare(isScreenShare: boolean): void;
|
|
321
435
|
ringAll(): void;
|
|
322
436
|
resendMediaKeys(): void;
|
|
323
|
-
|
|
437
|
+
setDataMode(dataMode: DataMode): void;
|
|
324
438
|
requestVideo(resolutions: Array<VideoRequest>, activeSpeakerHeight: number): void;
|
|
325
439
|
setGroupMembers(members: Array<GroupMemberInfo>): void;
|
|
326
440
|
setMembershipProof(proof: Buffer): void;
|
|
@@ -405,7 +519,7 @@ export declare enum HangupType {
|
|
|
405
519
|
Busy = 3,
|
|
406
520
|
NeedPermission = 4
|
|
407
521
|
}
|
|
408
|
-
export declare enum
|
|
522
|
+
export declare enum DataMode {
|
|
409
523
|
Low = 0,
|
|
410
524
|
Normal = 1
|
|
411
525
|
}
|
|
@@ -417,7 +531,7 @@ export interface CallManager {
|
|
|
417
531
|
setConfig(config: Config): void;
|
|
418
532
|
setSelfUuid(uuid: Buffer): void;
|
|
419
533
|
createOutgoingCall(remoteUserId: UserId, isVideoCall: boolean, localDeviceId: DeviceId): CallId;
|
|
420
|
-
proceed(callId: CallId, iceServerUsername: string, iceServerPassword: string, iceServerUrls: Array<string>, hideIp: boolean,
|
|
534
|
+
proceed(callId: CallId, iceServerUsername: string, iceServerPassword: string, iceServerUrls: Array<string>, hideIp: boolean, dataMode: DataMode, audioLevelsIntervalMillis: number): void;
|
|
421
535
|
accept(callId: CallId): void;
|
|
422
536
|
ignore(callId: CallId): void;
|
|
423
537
|
hangup(): void;
|
|
@@ -427,7 +541,7 @@ export interface CallManager {
|
|
|
427
541
|
setOutgoingAudioEnabled(enabled: boolean): void;
|
|
428
542
|
setOutgoingVideoEnabled(enabled: boolean): void;
|
|
429
543
|
setOutgoingVideoIsScreenShare(enabled: boolean): void;
|
|
430
|
-
|
|
544
|
+
updateDataMode(dataMode: DataMode): void;
|
|
431
545
|
sendVideoFrame(width: number, height: number, format: VideoPixelFormatEnum, buffer: Buffer): void;
|
|
432
546
|
receiveVideoFrame(buffer: Buffer, maxWidth: number, maxHeight: number): [number, number] | undefined;
|
|
433
547
|
receivedOffer(remoteUserId: UserId, remoteDeviceId: DeviceId, localDeviceId: DeviceId, messageAgeSec: number, callId: CallId, offerType: OfferType, opaque: Buffer, senderIdentityKey: Buffer, receiverIdentityKey: Buffer): void;
|
|
@@ -439,6 +553,7 @@ export interface CallManager {
|
|
|
439
553
|
receivedHttpResponse(requestId: number, status: number, body: Buffer): void;
|
|
440
554
|
httpRequestFailed(requestId: number, debugInfo: string | undefined): void;
|
|
441
555
|
createGroupCallClient(groupId: Buffer, sfuUrl: string, hkdfExtraInfo: Buffer, audioLevelsIntervalMillis: number): GroupCallClientId;
|
|
556
|
+
createCallLinkCallClient(sfuUrl: string, authCredentialPresentation: Buffer, linkRootKey: Buffer, adminPasskey: Buffer | undefined, hkdfExtraInfo: Buffer, audioLevelsIntervalMillis: number): GroupCallClientId;
|
|
442
557
|
deleteGroupCallClient(clientId: GroupCallClientId): void;
|
|
443
558
|
connect(clientId: GroupCallClientId): void;
|
|
444
559
|
join(clientId: GroupCallClientId): void;
|
|
@@ -450,12 +565,16 @@ export interface CallManager {
|
|
|
450
565
|
setOutgoingGroupCallVideoIsScreenShare(clientId: GroupCallClientId, isScreenShare: boolean): void;
|
|
451
566
|
groupRing(clientId: GroupCallClientId, recipient: Buffer | undefined): void;
|
|
452
567
|
resendMediaKeys(clientId: GroupCallClientId): void;
|
|
453
|
-
|
|
568
|
+
setDataMode(clientId: GroupCallClientId, dataMode: DataMode): void;
|
|
454
569
|
requestVideo(clientId: GroupCallClientId, resolutions: Array<VideoRequest>, activeSpeakerHeight: number): void;
|
|
455
570
|
setGroupMembers(clientId: GroupCallClientId, members: Array<GroupMemberInfo>): void;
|
|
456
571
|
setMembershipProof(clientId: GroupCallClientId, proof: Buffer): void;
|
|
457
572
|
receiveGroupCallVideoFrame(clientId: GroupCallClientId, remoteDemuxId: number, buffer: Buffer, maxWidth: number, maxHeight: number): [number, number] | undefined;
|
|
573
|
+
readCallLink(requestId: number, sfuUrl: string, authCredentialPresentation: Buffer, linkRootKey: Buffer): void;
|
|
574
|
+
createCallLink(requestId: number, sfuUrl: string, createCredentialPresentation: Buffer, linkRootKey: Buffer, adminPasskey: Buffer, callLinkPublicParams: Buffer): void;
|
|
575
|
+
updateCallLink(requestId: number, sfuUrl: string, authCredentialPresentation: Buffer, linkRootKey: Buffer, adminPasskey: Buffer, newName: string | undefined, newRestrictions: number | undefined, newRevoked: boolean | undefined): void;
|
|
458
576
|
peekGroupCall(requestId: number, sfu_url: string, membership_proof: Buffer, group_members: Array<GroupMemberInfo>): void;
|
|
577
|
+
peekCallLinkCall(requestId: number, sfuUrl: string, authCredentialPresentation: Buffer, linkRootKey: Buffer): void;
|
|
459
578
|
getAudioInputs(): Array<AudioDevice>;
|
|
460
579
|
setAudioInput(index: number): void;
|
|
461
580
|
getAudioOutputs(): Array<AudioDevice>;
|
|
@@ -484,7 +603,7 @@ export interface CallManagerCallbacks {
|
|
|
484
603
|
handleJoinStateChanged(clientId: GroupCallClientId, joinState: JoinState, demuxId: number | undefined): void;
|
|
485
604
|
handleRemoteDevicesChanged(clientId: GroupCallClientId, remoteDeviceStates: Array<RemoteDeviceState>): void;
|
|
486
605
|
handlePeekChanged(clientId: GroupCallClientId, info: PeekInfo): void;
|
|
487
|
-
handlePeekResponse(requestId: number, info: PeekInfo): void;
|
|
606
|
+
handlePeekResponse(requestId: number, statusCode: number, info: PeekInfo | undefined): void;
|
|
488
607
|
handleEnded(clientId: GroupCallClientId, reason: GroupCallEndReason): void;
|
|
489
608
|
onLogMessage(level: number, fileName: string, line: number, message: string): void;
|
|
490
609
|
}
|
package/dist/ringrtc/Service.js
CHANGED
|
@@ -35,14 +35,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
35
35
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
36
36
|
});
|
|
37
37
|
};
|
|
38
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
+
};
|
|
38
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.CallLogLevel = exports.CallEndedReason = exports.CallState = exports.RingCancelReason = exports.
|
|
42
|
+
exports.CallLogLevel = exports.CallEndedReason = exports.CallState = exports.RingCancelReason = exports.DataMode = exports.HangupType = exports.OpaqueMessage = exports.HangupMessage = exports.BusyMessage = exports.IceCandidateMessage = exports.AnswerMessage = exports.OfferType = exports.OfferMessage = exports.CallingMessage = exports.GroupCall = exports.VideoRequest = exports.GroupMemberInfo = exports.RemoteDeviceState = exports.LocalDeviceState = exports.HttpMethod = exports.RingUpdate = exports.CallMessageUrgency = exports.GroupCallEndReason = exports.JoinState = exports.ConnectionState = exports.Call = exports.RingRTCType = exports.ReceivedAudioLevel = exports.NetworkRoute = exports.PeekStatusCodes = exports.callIdFromRingId = exports.callIdFromEra = void 0;
|
|
40
43
|
/* eslint-disable max-classes-per-file */
|
|
41
|
-
const os = __importStar(require("os"));
|
|
42
44
|
const process = __importStar(require("process"));
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
exports.callIdFromEra =
|
|
45
|
+
const CallLinks_1 = require("./CallLinks");
|
|
46
|
+
const Native_1 = __importDefault(require("./Native"));
|
|
47
|
+
exports.callIdFromEra = Native_1.default.callIdFromEra;
|
|
46
48
|
function callIdFromRingId(ringId) {
|
|
47
49
|
return {
|
|
48
50
|
low: Number(BigInt.asIntN(32, ringId)),
|
|
@@ -65,22 +67,25 @@ class NativeCallManager {
|
|
|
65
67
|
this.createCallEndpoint(config);
|
|
66
68
|
}
|
|
67
69
|
createCallEndpoint(config) {
|
|
68
|
-
const fieldTrials = Object.assign({
|
|
70
|
+
const fieldTrials = Object.assign({
|
|
71
|
+
'RingRTC-AnyAddressPortsKillSwitch': 'Enabled',
|
|
72
|
+
'WebRTC-Audio-OpusSetSignalVoiceWithDtx': 'Enabled',
|
|
73
|
+
}, config.field_trials);
|
|
69
74
|
/* eslint-disable prefer-template */
|
|
70
75
|
const fieldTrialsString = Object.entries(fieldTrials)
|
|
71
76
|
.map(([k, v]) => `${k}/${v}`)
|
|
72
77
|
.join('/') + '/';
|
|
73
78
|
/* eslint-enable prefer-template */
|
|
74
|
-
Object.defineProperty(this,
|
|
79
|
+
Object.defineProperty(this, Native_1.default.callEndpointPropertyKey, {
|
|
75
80
|
configurable: true,
|
|
76
81
|
get() {
|
|
77
|
-
const callEndpoint =
|
|
82
|
+
const callEndpoint = Native_1.default.createCallEndpoint(this, config.use_new_audio_device_module, fieldTrialsString);
|
|
78
83
|
if (process.platform === 'darwin') {
|
|
79
84
|
// Preload devices to work around
|
|
80
85
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=1287628
|
|
81
86
|
void window.navigator.mediaDevices.enumerateDevices();
|
|
82
87
|
}
|
|
83
|
-
Object.defineProperty(this,
|
|
88
|
+
Object.defineProperty(this, Native_1.default.callEndpointPropertyKey, {
|
|
84
89
|
configurable: true,
|
|
85
90
|
value: callEndpoint,
|
|
86
91
|
});
|
|
@@ -92,90 +97,86 @@ class NativeCallManager {
|
|
|
92
97
|
}
|
|
93
98
|
// Mirror methods onto NativeCallManager.
|
|
94
99
|
// This is done through direct assignment rather than wrapper methods to avoid indirection.
|
|
95
|
-
NativeCallManager.prototype.setSelfUuid =
|
|
100
|
+
NativeCallManager.prototype.setSelfUuid = Native_1.default.cm_setSelfUuid;
|
|
96
101
|
NativeCallManager.prototype.createOutgoingCall =
|
|
97
|
-
|
|
98
|
-
NativeCallManager.prototype.proceed =
|
|
99
|
-
NativeCallManager.prototype.accept =
|
|
100
|
-
NativeCallManager.prototype.ignore =
|
|
101
|
-
NativeCallManager.prototype.hangup =
|
|
102
|
+
Native_1.default.cm_createOutgoingCall;
|
|
103
|
+
NativeCallManager.prototype.proceed = Native_1.default.cm_proceed;
|
|
104
|
+
NativeCallManager.prototype.accept = Native_1.default.cm_accept;
|
|
105
|
+
NativeCallManager.prototype.ignore = Native_1.default.cm_ignore;
|
|
106
|
+
NativeCallManager.prototype.hangup = Native_1.default.cm_hangup;
|
|
102
107
|
NativeCallManager.prototype.cancelGroupRing =
|
|
103
|
-
|
|
108
|
+
Native_1.default.cm_cancelGroupRing;
|
|
104
109
|
NativeCallManager.prototype.signalingMessageSent =
|
|
105
|
-
|
|
110
|
+
Native_1.default.cm_signalingMessageSent;
|
|
106
111
|
NativeCallManager.prototype.signalingMessageSendFailed =
|
|
107
|
-
|
|
108
|
-
NativeCallManager.prototype.
|
|
109
|
-
|
|
110
|
-
NativeCallManager.prototype.
|
|
111
|
-
NativeCallManager.prototype.receivedAnswer = Native.cm_receivedAnswer;
|
|
112
|
+
Native_1.default.cm_signalingMessageSendFailed;
|
|
113
|
+
NativeCallManager.prototype.updateDataMode = Native_1.default.cm_updateDataMode;
|
|
114
|
+
NativeCallManager.prototype.receivedOffer = Native_1.default.cm_receivedOffer;
|
|
115
|
+
NativeCallManager.prototype.receivedAnswer = Native_1.default.cm_receivedAnswer;
|
|
112
116
|
NativeCallManager.prototype.receivedIceCandidates =
|
|
113
|
-
|
|
114
|
-
NativeCallManager.prototype.receivedHangup =
|
|
115
|
-
NativeCallManager.prototype.receivedBusy =
|
|
117
|
+
Native_1.default.cm_receivedIceCandidates;
|
|
118
|
+
NativeCallManager.prototype.receivedHangup = Native_1.default.cm_receivedHangup;
|
|
119
|
+
NativeCallManager.prototype.receivedBusy = Native_1.default.cm_receivedBusy;
|
|
116
120
|
NativeCallManager.prototype.receivedCallMessage =
|
|
117
|
-
|
|
121
|
+
Native_1.default.cm_receivedCallMessage;
|
|
118
122
|
NativeCallManager.prototype.receivedHttpResponse =
|
|
119
|
-
|
|
123
|
+
Native_1.default.cm_receivedHttpResponse;
|
|
120
124
|
NativeCallManager.prototype.httpRequestFailed =
|
|
121
|
-
|
|
125
|
+
Native_1.default.cm_httpRequestFailed;
|
|
122
126
|
NativeCallManager.prototype.setOutgoingAudioEnabled =
|
|
123
|
-
|
|
127
|
+
Native_1.default.cm_setOutgoingAudioEnabled;
|
|
124
128
|
NativeCallManager.prototype.setOutgoingVideoEnabled =
|
|
125
|
-
|
|
129
|
+
Native_1.default.cm_setOutgoingVideoEnabled;
|
|
126
130
|
NativeCallManager.prototype.setOutgoingVideoIsScreenShare =
|
|
127
|
-
|
|
128
|
-
NativeCallManager.prototype.sendVideoFrame =
|
|
131
|
+
Native_1.default.cm_setOutgoingVideoIsScreenShare;
|
|
132
|
+
NativeCallManager.prototype.sendVideoFrame = Native_1.default.cm_sendVideoFrame;
|
|
129
133
|
NativeCallManager.prototype.receiveVideoFrame =
|
|
130
|
-
|
|
134
|
+
Native_1.default.cm_receiveVideoFrame;
|
|
131
135
|
NativeCallManager.prototype.receiveGroupCallVideoFrame =
|
|
132
|
-
|
|
136
|
+
Native_1.default.cm_receiveGroupCallVideoFrame;
|
|
133
137
|
NativeCallManager.prototype.createGroupCallClient =
|
|
134
|
-
|
|
138
|
+
Native_1.default.cm_createGroupCallClient;
|
|
139
|
+
NativeCallManager.prototype.createCallLinkCallClient =
|
|
140
|
+
Native_1.default.cm_createCallLinkCallClient;
|
|
135
141
|
NativeCallManager.prototype.deleteGroupCallClient =
|
|
136
|
-
|
|
137
|
-
NativeCallManager.prototype.connect =
|
|
138
|
-
NativeCallManager.prototype.join =
|
|
139
|
-
NativeCallManager.prototype.leave =
|
|
140
|
-
NativeCallManager.prototype.disconnect =
|
|
141
|
-
NativeCallManager.prototype.groupRing =
|
|
142
|
+
Native_1.default.cm_deleteGroupCallClient;
|
|
143
|
+
NativeCallManager.prototype.connect = Native_1.default.cm_connect;
|
|
144
|
+
NativeCallManager.prototype.join = Native_1.default.cm_join;
|
|
145
|
+
NativeCallManager.prototype.leave = Native_1.default.cm_leave;
|
|
146
|
+
NativeCallManager.prototype.disconnect = Native_1.default.cm_disconnect;
|
|
147
|
+
NativeCallManager.prototype.groupRing = Native_1.default.cm_groupRing;
|
|
142
148
|
NativeCallManager.prototype.setOutgoingAudioMuted =
|
|
143
|
-
|
|
149
|
+
Native_1.default.cm_setOutgoingAudioMuted;
|
|
144
150
|
NativeCallManager.prototype.setOutgoingVideoMuted =
|
|
145
|
-
|
|
151
|
+
Native_1.default.cm_setOutgoingVideoMuted;
|
|
146
152
|
NativeCallManager.prototype.setOutgoingGroupCallVideoIsScreenShare =
|
|
147
|
-
|
|
148
|
-
NativeCallManager.prototype.setPresenting =
|
|
153
|
+
Native_1.default.cm_setOutgoingGroupCallVideoIsScreenShare;
|
|
154
|
+
NativeCallManager.prototype.setPresenting = Native_1.default.cm_setPresenting;
|
|
149
155
|
NativeCallManager.prototype.resendMediaKeys =
|
|
150
|
-
|
|
151
|
-
NativeCallManager.prototype.
|
|
152
|
-
|
|
153
|
-
NativeCallManager.prototype.requestVideo = Native.cm_requestVideo;
|
|
156
|
+
Native_1.default.cm_resendMediaKeys;
|
|
157
|
+
NativeCallManager.prototype.setDataMode = Native_1.default.cm_setDataMode;
|
|
158
|
+
NativeCallManager.prototype.requestVideo = Native_1.default.cm_requestVideo;
|
|
154
159
|
NativeCallManager.prototype.setGroupMembers =
|
|
155
|
-
|
|
160
|
+
Native_1.default.cm_setGroupMembers;
|
|
156
161
|
NativeCallManager.prototype.setMembershipProof =
|
|
157
|
-
|
|
158
|
-
NativeCallManager.prototype.
|
|
159
|
-
NativeCallManager.prototype.
|
|
160
|
-
NativeCallManager.prototype.
|
|
162
|
+
Native_1.default.cm_setMembershipProof;
|
|
163
|
+
NativeCallManager.prototype.readCallLink = Native_1.default.cm_readCallLink;
|
|
164
|
+
NativeCallManager.prototype.createCallLink = Native_1.default.cm_createCallLink;
|
|
165
|
+
NativeCallManager.prototype.updateCallLink = Native_1.default.cm_updateCallLink;
|
|
166
|
+
NativeCallManager.prototype.peekGroupCall = Native_1.default.cm_peekGroupCall;
|
|
167
|
+
NativeCallManager.prototype.peekCallLinkCall =
|
|
168
|
+
Native_1.default.cm_peekCallLinkCall;
|
|
169
|
+
NativeCallManager.prototype.getAudioInputs = Native_1.default.cm_getAudioInputs;
|
|
170
|
+
NativeCallManager.prototype.setAudioInput = Native_1.default.cm_setAudioInput;
|
|
161
171
|
NativeCallManager.prototype.getAudioOutputs =
|
|
162
|
-
|
|
163
|
-
NativeCallManager.prototype.setAudioOutput =
|
|
164
|
-
NativeCallManager.prototype.processEvents =
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
exports.PeekDeviceInfo = PeekDeviceInfo;
|
|
172
|
-
class PeekInfo {
|
|
173
|
-
constructor() {
|
|
174
|
-
this.devices = [];
|
|
175
|
-
this.deviceCount = 0;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
exports.PeekInfo = PeekInfo;
|
|
172
|
+
Native_1.default.cm_getAudioOutputs;
|
|
173
|
+
NativeCallManager.prototype.setAudioOutput = Native_1.default.cm_setAudioOutput;
|
|
174
|
+
NativeCallManager.prototype.processEvents = Native_1.default.cm_processEvents;
|
|
175
|
+
var PeekStatusCodes;
|
|
176
|
+
(function (PeekStatusCodes) {
|
|
177
|
+
PeekStatusCodes[PeekStatusCodes["EXPIRED_CALL_LINK"] = 703] = "EXPIRED_CALL_LINK";
|
|
178
|
+
PeekStatusCodes[PeekStatusCodes["INVALID_CALL_LINK"] = 704] = "INVALID_CALL_LINK";
|
|
179
|
+
})(PeekStatusCodes = exports.PeekStatusCodes || (exports.PeekStatusCodes = {}));
|
|
179
180
|
// In sync with WebRTC's PeerConnection.AdapterType.
|
|
180
181
|
// Despite how it looks, this is not an option set.
|
|
181
182
|
// A network adapter type can only be one of the listed values.
|
|
@@ -270,6 +271,7 @@ class RingRTCType {
|
|
|
270
271
|
this._call = null;
|
|
271
272
|
this._groupCallByClientId = new Map();
|
|
272
273
|
this._peekRequests = new Requests();
|
|
274
|
+
this._callLinkRequests = new Requests();
|
|
273
275
|
this._callInfoByCallId = new Map();
|
|
274
276
|
}
|
|
275
277
|
setConfig(config) {
|
|
@@ -375,7 +377,7 @@ class RingRTCType {
|
|
|
375
377
|
}
|
|
376
378
|
proceed(callId, settings) {
|
|
377
379
|
sillyDeadlockProtection(() => {
|
|
378
|
-
this.callManager.proceed(callId, settings.iceServer.username || '', settings.iceServer.password || '', settings.iceServer.urls, settings.hideIp, settings.
|
|
380
|
+
this.callManager.proceed(callId, settings.iceServer.username || '', settings.iceServer.password || '', settings.iceServer.urls, settings.hideIp, settings.dataMode, settings.audioLevelsIntervalMillis || 0);
|
|
379
381
|
});
|
|
380
382
|
}
|
|
381
383
|
// Called by Rust
|
|
@@ -542,6 +544,138 @@ class RingRTCType {
|
|
|
542
544
|
}
|
|
543
545
|
}))().catch(e => this.logError(e.toString()));
|
|
544
546
|
}
|
|
547
|
+
// Call Links
|
|
548
|
+
/**
|
|
549
|
+
* Asynchronous request to get information about a call link.
|
|
550
|
+
*
|
|
551
|
+
* @param sfuUrl - the URL to use when accessing the SFU
|
|
552
|
+
* @param authCredentialPresentation - a serialized CallLinkAuthCredentialPresentation
|
|
553
|
+
* @param linkRootKey - the root key for the call link
|
|
554
|
+
*
|
|
555
|
+
* Expected failure codes include:
|
|
556
|
+
* - 404: the room does not exist (or expired so long ago that it has been removed from the server)
|
|
557
|
+
*/
|
|
558
|
+
readCallLink(sfuUrl, authCredentialPresentation, linkRootKey) {
|
|
559
|
+
const [requestId, promise] = this._callLinkRequests.add();
|
|
560
|
+
// Response comes back via handleCallLinkResponse
|
|
561
|
+
sillyDeadlockProtection(() => {
|
|
562
|
+
this.callManager.readCallLink(requestId, sfuUrl, authCredentialPresentation, linkRootKey.bytes);
|
|
563
|
+
});
|
|
564
|
+
return promise;
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Asynchronous request to create a new call link.
|
|
568
|
+
*
|
|
569
|
+
* This request is idempotent; if it fails due to a network issue, it is safe to retry.
|
|
570
|
+
*
|
|
571
|
+
* @example
|
|
572
|
+
* const linkKey = CallLinkRootKey.generate();
|
|
573
|
+
* const adminPasskey = CallLinkRootKey.generateAdminPasskey();
|
|
574
|
+
* const roomId = linkKey.deriveRoomId();
|
|
575
|
+
* const credential = requestCreateCredentialFromChatServer(roomId); // using libsignal
|
|
576
|
+
* const secretParams = CallLinkSecretParams.deriveFromRootKey(linkKey.bytes);
|
|
577
|
+
* const credentialPresentation = credential.present(roomId, secretParams).serialize();
|
|
578
|
+
* const serializedPublicParams = secretParams.getPublicParams().serialize();
|
|
579
|
+
* const result = await RingRTC.createCallLink(sfuUrl, credentialPresentation, linkKey, adminPasskey, serializedPublicParams);
|
|
580
|
+
* if (result.success) {
|
|
581
|
+
* const state = result.value;
|
|
582
|
+
* // In actuality you may not want to do this until the user clicks Done.
|
|
583
|
+
* saveToDatabase(linkKey.bytes, adminPasskey, state);
|
|
584
|
+
* syncToOtherDevices(linkKey.bytes, adminPasskey);
|
|
585
|
+
* } else {
|
|
586
|
+
* switch (result.errorStatusCode) {
|
|
587
|
+
* case 409:
|
|
588
|
+
* // The room already exists (and isn't yours), i.e. you've hit a 1-in-a-billion conflict.
|
|
589
|
+
* // Fall through to kicking the user out to try again later.
|
|
590
|
+
* default:
|
|
591
|
+
* // Unexpected error, kick the user out for now.
|
|
592
|
+
* }
|
|
593
|
+
* }
|
|
594
|
+
*
|
|
595
|
+
* @param sfuUrl - the URL to use when accessing the SFU
|
|
596
|
+
* @param createCredentialPresentation - a serialized CreateCallLinkCredentialPresentation
|
|
597
|
+
* @param linkRootKey - the root key for the call link
|
|
598
|
+
* @param adminPasskey - the arbitrary passkey to use for the new room
|
|
599
|
+
* @param callLinkPublicParams - the serialized CallLinkPublicParams for the new room
|
|
600
|
+
*/
|
|
601
|
+
createCallLink(sfuUrl, createCredentialPresentation, linkRootKey, adminPasskey, callLinkPublicParams) {
|
|
602
|
+
const [requestId, promise] = this._callLinkRequests.add();
|
|
603
|
+
// Response comes back via handleCallLinkResponse
|
|
604
|
+
sillyDeadlockProtection(() => {
|
|
605
|
+
this.callManager.createCallLink(requestId, sfuUrl, createCredentialPresentation, linkRootKey.bytes, adminPasskey, callLinkPublicParams);
|
|
606
|
+
});
|
|
607
|
+
return promise;
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Asynchronous request to update a call link's name.
|
|
611
|
+
*
|
|
612
|
+
* Possible failure codes include:
|
|
613
|
+
* - 401: the room does not exist (and this is the wrong API to create a new room)
|
|
614
|
+
* - 403: the admin passkey is incorrect
|
|
615
|
+
*
|
|
616
|
+
* This request is idempotent; if it fails due to a network issue, it is safe to retry.
|
|
617
|
+
*
|
|
618
|
+
* @param sfuUrl - the URL to use when accessing the SFU
|
|
619
|
+
* @param authCredentialPresentation - a serialized CallLinkAuthCredentialPresentation
|
|
620
|
+
* @param linkRootKey - the root key for the call link
|
|
621
|
+
* @param adminPasskey - the passkey specified when the link was created
|
|
622
|
+
* @param newName - the new name to use
|
|
623
|
+
*/
|
|
624
|
+
updateCallLinkName(sfuUrl, authCredentialPresentation, linkRootKey, adminPasskey, newName) {
|
|
625
|
+
const [requestId, promise] = this._callLinkRequests.add();
|
|
626
|
+
// Response comes back via handleCallLinkResponse
|
|
627
|
+
sillyDeadlockProtection(() => {
|
|
628
|
+
this.callManager.updateCallLink(requestId, sfuUrl, authCredentialPresentation, linkRootKey.bytes, adminPasskey, newName, undefined, undefined);
|
|
629
|
+
});
|
|
630
|
+
return promise;
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Asynchronous request to update a call link's restrictions.
|
|
634
|
+
*
|
|
635
|
+
* Possible failure codes include:
|
|
636
|
+
* - 401: the room does not exist (and this is the wrong API to create a new room)
|
|
637
|
+
* - 403: the admin passkey is incorrect
|
|
638
|
+
*
|
|
639
|
+
* This request is idempotent; if it fails due to a network issue, it is safe to retry.
|
|
640
|
+
*
|
|
641
|
+
* @param sfuUrl - the URL to use when accessing the SFU
|
|
642
|
+
* @param authCredentialPresentation - a serialized CallLinkAuthCredentialPresentation
|
|
643
|
+
* @param linkRootKey - the root key for the call link
|
|
644
|
+
* @param adminPasskey - the passkey specified when the link was created
|
|
645
|
+
* @param restrictions - the new restrictions to use
|
|
646
|
+
*/
|
|
647
|
+
updateCallLinkRestrictions(sfuUrl, authCredentialPresentation, linkRootKey, adminPasskey, restrictions) {
|
|
648
|
+
const [requestId, promise] = this._callLinkRequests.add();
|
|
649
|
+
// Response comes back via handleCallLinkResponse
|
|
650
|
+
sillyDeadlockProtection(() => {
|
|
651
|
+
this.callManager.updateCallLink(requestId, sfuUrl, authCredentialPresentation, linkRootKey.bytes, adminPasskey, undefined, restrictions, undefined);
|
|
652
|
+
});
|
|
653
|
+
return promise;
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* Asynchronous request to revoke or un-revoke a call link.
|
|
657
|
+
*
|
|
658
|
+
* Possible failure codes include:
|
|
659
|
+
* - 401: the room does not exist (and this is the wrong API to create a new room)
|
|
660
|
+
* - 403: the admin passkey is incorrect
|
|
661
|
+
*
|
|
662
|
+
* This request is idempotent; if it fails due to a network issue, it is safe to retry.
|
|
663
|
+
*
|
|
664
|
+
* @param sfuUrl - the URL to use when accessing the SFU
|
|
665
|
+
* @param authCredentialPresentation - a serialized CallLinkAuthCredentialPresentation
|
|
666
|
+
* @param linkRootKey - the root key for the call link
|
|
667
|
+
* @param adminPasskey - the passkey specified when the link was created
|
|
668
|
+
* @param revoked - whether the link should now be revoked
|
|
669
|
+
*/
|
|
670
|
+
updateCallLinkRevocation(sfuUrl, authCredentialPresentation, linkRootKey, adminPasskey, revoked) {
|
|
671
|
+
const [requestId, promise] = this._callLinkRequests.add();
|
|
672
|
+
// Response comes back via handleCallLinkResponse
|
|
673
|
+
sillyDeadlockProtection(() => {
|
|
674
|
+
this.callManager.updateCallLink(requestId, sfuUrl, authCredentialPresentation, linkRootKey.bytes, adminPasskey, undefined, undefined, revoked);
|
|
675
|
+
});
|
|
676
|
+
return promise;
|
|
677
|
+
}
|
|
678
|
+
// HTTP callbacks
|
|
545
679
|
receivedHttpResponse(requestId, status, body) {
|
|
546
680
|
sillyDeadlockProtection(() => {
|
|
547
681
|
try {
|
|
@@ -567,7 +701,15 @@ class RingRTCType {
|
|
|
567
701
|
// Group Calls
|
|
568
702
|
// Called by UX
|
|
569
703
|
getGroupCall(groupId, sfuUrl, hkdfExtraInfo, audioLevelsIntervalMillis, observer) {
|
|
570
|
-
const
|
|
704
|
+
const clientId = this.callManager.createGroupCallClient(groupId, sfuUrl, hkdfExtraInfo, audioLevelsIntervalMillis || 0);
|
|
705
|
+
const groupCall = new GroupCall(this.callManager, observer, clientId);
|
|
706
|
+
this._groupCallByClientId.set(groupCall.clientId, groupCall);
|
|
707
|
+
return groupCall;
|
|
708
|
+
}
|
|
709
|
+
// Called by UX
|
|
710
|
+
getCallLinkCall(sfuUrl, authCredentialPresentation, rootKey, adminPasskey, hkdfExtraInfo, audioLevelsIntervalMillis, observer) {
|
|
711
|
+
const clientId = this.callManager.createCallLinkCallClient(sfuUrl, authCredentialPresentation, rootKey.bytes, adminPasskey, hkdfExtraInfo, audioLevelsIntervalMillis || 0);
|
|
712
|
+
const groupCall = new GroupCall(this.callManager, observer, clientId);
|
|
571
713
|
this._groupCallByClientId.set(groupCall.clientId, groupCall);
|
|
572
714
|
return groupCall;
|
|
573
715
|
}
|
|
@@ -579,6 +721,22 @@ class RingRTCType {
|
|
|
579
721
|
sillyDeadlockProtection(() => {
|
|
580
722
|
this.callManager.peekGroupCall(requestId, sfuUrl, membershipProof, groupMembers);
|
|
581
723
|
});
|
|
724
|
+
return promise.then(result => {
|
|
725
|
+
if (result.success) {
|
|
726
|
+
return result.value;
|
|
727
|
+
}
|
|
728
|
+
else {
|
|
729
|
+
return { devices: [], deviceCount: 0 };
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
// Called by UX
|
|
734
|
+
peekCallLinkCall(sfuUrl, authCredentialPresentation, rootKey) {
|
|
735
|
+
const [requestId, promise] = this._peekRequests.add();
|
|
736
|
+
// Response comes back via handlePeekResponse
|
|
737
|
+
sillyDeadlockProtection(() => {
|
|
738
|
+
this.callManager.peekCallLinkCall(requestId, sfuUrl, authCredentialPresentation, rootKey.bytes);
|
|
739
|
+
});
|
|
582
740
|
return promise;
|
|
583
741
|
}
|
|
584
742
|
// Called by Rust
|
|
@@ -668,14 +826,52 @@ class RingRTCType {
|
|
|
668
826
|
});
|
|
669
827
|
}
|
|
670
828
|
// Called by Rust
|
|
671
|
-
handlePeekResponse(requestId, info) {
|
|
829
|
+
handlePeekResponse(requestId, statusCode, info) {
|
|
672
830
|
sillyDeadlockProtection(() => {
|
|
673
|
-
|
|
831
|
+
let result;
|
|
832
|
+
if (info) {
|
|
833
|
+
result = { success: true, value: info };
|
|
834
|
+
}
|
|
835
|
+
else {
|
|
836
|
+
result = { success: false, errorStatusCode: statusCode };
|
|
837
|
+
}
|
|
838
|
+
if (!this._peekRequests.resolve(requestId, result)) {
|
|
674
839
|
this.logWarn(`Invalid request ID for handlePeekResponse: ${requestId}`);
|
|
675
840
|
}
|
|
676
841
|
});
|
|
677
842
|
}
|
|
678
843
|
// Called by Rust
|
|
844
|
+
handleCallLinkResponse(requestId, statusCode, state) {
|
|
845
|
+
sillyDeadlockProtection(() => {
|
|
846
|
+
// Recreate the state so that we have the correct prototype, in case we add more methods to CallLinkState.
|
|
847
|
+
let result;
|
|
848
|
+
if (state) {
|
|
849
|
+
let restrictions;
|
|
850
|
+
switch (state.rawRestrictions) {
|
|
851
|
+
case 0:
|
|
852
|
+
restrictions = CallLinks_1.CallLinkRestrictions.None;
|
|
853
|
+
break;
|
|
854
|
+
case 1:
|
|
855
|
+
restrictions = CallLinks_1.CallLinkRestrictions.AdminApproval;
|
|
856
|
+
break;
|
|
857
|
+
default:
|
|
858
|
+
restrictions = CallLinks_1.CallLinkRestrictions.Unknown;
|
|
859
|
+
break;
|
|
860
|
+
}
|
|
861
|
+
result = {
|
|
862
|
+
success: true,
|
|
863
|
+
value: new CallLinks_1.CallLinkState(state.name, restrictions, state.revoked, state.expiration),
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
else {
|
|
867
|
+
result = { success: false, errorStatusCode: statusCode };
|
|
868
|
+
}
|
|
869
|
+
if (!this._callLinkRequests.resolve(requestId, result)) {
|
|
870
|
+
this.logWarn(`Invalid request ID for handleCallLinkResponse: ${requestId}`);
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
// Called by Rust
|
|
679
875
|
handleEnded(clientId, reason) {
|
|
680
876
|
sillyDeadlockProtection(() => {
|
|
681
877
|
const groupCall = this._groupCallByClientId.get(clientId);
|
|
@@ -1087,10 +1283,10 @@ class Call {
|
|
|
1087
1283
|
}
|
|
1088
1284
|
});
|
|
1089
1285
|
}
|
|
1090
|
-
|
|
1286
|
+
updateDataMode(dataMode) {
|
|
1091
1287
|
sillyDeadlockProtection(() => {
|
|
1092
1288
|
try {
|
|
1093
|
-
this._callManager.
|
|
1289
|
+
this._callManager.updateDataMode(dataMode);
|
|
1094
1290
|
}
|
|
1095
1291
|
catch (_a) {
|
|
1096
1292
|
// We may not have an active connection any more.
|
|
@@ -1238,11 +1434,11 @@ class GroupCall {
|
|
|
1238
1434
|
return this._clientId;
|
|
1239
1435
|
}
|
|
1240
1436
|
// Called by UI via RingRTC object
|
|
1241
|
-
constructor(callManager,
|
|
1437
|
+
constructor(callManager, observer, clientId) {
|
|
1242
1438
|
this._callManager = callManager;
|
|
1243
1439
|
this._observer = observer;
|
|
1440
|
+
this._clientId = clientId;
|
|
1244
1441
|
this._localDeviceState = new LocalDeviceState();
|
|
1245
|
-
this._clientId = this._callManager.createGroupCallClient(groupId, sfuUrl, hkdfExtraInfo, audioLevelsIntervalMillis || 0);
|
|
1246
1442
|
}
|
|
1247
1443
|
// Called by UI
|
|
1248
1444
|
connect() {
|
|
@@ -1305,8 +1501,8 @@ class GroupCall {
|
|
|
1305
1501
|
this._callManager.resendMediaKeys(this._clientId);
|
|
1306
1502
|
}
|
|
1307
1503
|
// Called by UI
|
|
1308
|
-
|
|
1309
|
-
this._callManager.
|
|
1504
|
+
setDataMode(dataMode) {
|
|
1505
|
+
this._callManager.setDataMode(this._clientId, dataMode);
|
|
1310
1506
|
}
|
|
1311
1507
|
// Called by UI
|
|
1312
1508
|
requestVideo(resolutions, activeSpeakerHeight) {
|
|
@@ -1484,11 +1680,11 @@ var HangupType;
|
|
|
1484
1680
|
HangupType[HangupType["Busy"] = 3] = "Busy";
|
|
1485
1681
|
HangupType[HangupType["NeedPermission"] = 4] = "NeedPermission";
|
|
1486
1682
|
})(HangupType = exports.HangupType || (exports.HangupType = {}));
|
|
1487
|
-
var
|
|
1488
|
-
(function (
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
})(
|
|
1683
|
+
var DataMode;
|
|
1684
|
+
(function (DataMode) {
|
|
1685
|
+
DataMode[DataMode["Low"] = 0] = "Low";
|
|
1686
|
+
DataMode[DataMode["Normal"] = 1] = "Normal";
|
|
1687
|
+
})(DataMode = exports.DataMode || (exports.DataMode = {}));
|
|
1492
1688
|
/// Describes why a ring was cancelled.
|
|
1493
1689
|
var RingCancelReason;
|
|
1494
1690
|
(function (RingCancelReason) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signalapp/ringrtc",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.28.0",
|
|
4
4
|
"description": "Signal Messenger voice and video calling library.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"config": {
|
|
25
25
|
"prebuildUrl": "https://build-artifacts.signal.org/libraries/ringrtc-desktop-build-v${npm_package_version}.tar.gz",
|
|
26
|
-
"prebuildChecksum": "
|
|
26
|
+
"prebuildChecksum": "5d4bd3c13ee3373d0e67dacce7e64a422fdc4e0eb8f9c551495fa5b90ec1f322"
|
|
27
27
|
},
|
|
28
28
|
"author": "",
|
|
29
29
|
"license": "AGPL-3.0-only",
|