Skip to content

Commit

Permalink
Audio/e2ee (#377)
Browse files Browse the repository at this point in the history
* feat: #310 -  webrtc call added for audio

* feat: #310 -e2e encrypted  oneway audio call

* feat: #310 -e2e encrypted  oneway audio call added

* fix: react hook warning

* fix: few code smell

* fix: minor cleanup
  • Loading branch information
muke1908 authored Sep 19, 2024
1 parent afb97a7 commit 7e1630d
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 46 deletions.
6 changes: 3 additions & 3 deletions client/src/components/Messaging/UserStatusInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ export const UserStatusInfo = ({
const [ callState, setCallState ] = useState(undefined);

useEffect(() => {
chate2ee.onCallAdded((call) => {
chate2ee.on('call-added', (call) => {
setCall(call);
});

chate2ee.onCallRemoved(() => {
chate2ee.on('call-removed', () => {
setCall(null);
});

chate2ee.onPCStateChanged((state) => {
chate2ee.on('pc-state-changed', (state) => {
setCallState(state);
});
}, [chate2ee]);
Expand Down
10 changes: 3 additions & 7 deletions service/src/public/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { SocketListenerTypeInternal } from "../socket/socket";
import { E2ECall } from "../webrtc";
import { SocketListenerType } from "../socket/socket";
import { E2ECall, PeerConnectionEventType } from "../webrtc";

export type SocketListenerType = Omit<SocketListenerTypeInternal, "webrtc-session-description">;
export type LinkObjType = {
hash: string,
link: string,
Expand All @@ -27,13 +26,10 @@ export interface IChatE2EE {
sendMessage(args: { image: string, text: string }): Promise<ISendMessageReturn>;
dispose(): void;
encrypt({ image, text }): { send: () => Promise<ISendMessageReturn> };
on(listener: SocketListenerType, callback: (...args: any) => void): void;
on(listener: SocketListenerType | PeerConnectionEventType, callback: (...args: any) => void): void;
// webrtc call
startCall(): Promise<E2ECall>;
endCall(): void;
onPCStateChanged(cb: (state: RTCPeerConnectionState) => void) : void;
onCallAdded(cb: (call: E2ECall) => void): void,
onCallRemoved(cb: () => void): void
activeCall: E2ECall | null
}

Expand Down
46 changes: 18 additions & 28 deletions service/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { cryptoUtils as _cryptoUtils } from './cryptoRSA';
import deleteLink from './deleteLink';
import getLink from './getLink';
import getUsersInChannel from './getUsersInChannel';
import { configType, IChatE2EE, ISendMessageReturn, LinkObjType, SocketListenerType, TypeUsersInChannel } from './public/types';
import { configType, IChatE2EE, ISendMessageReturn, LinkObjType, TypeUsersInChannel } from './public/types';
import { getPublicKey, sharePublicKey } from './publicKey';
import sendMessage from './sendMessage';
import { SocketInstance, SubscriptionContextType } from './socket/socket';
import { SocketInstance, SubscriptionType } from './socket/socket';
import { Logger } from './utils/logger';
export { setConfig } from './configContext';
import { generateUUID } from './utils/uuid';
import { WebRTCCall, E2ECall } from './webrtc';
import { WebRTCCall, E2ECall, peerConnectionEvents, PeerConnectionEventType } from './webrtc';

export const utils = {
decryptMessage: (ciphertext: string, privateKey: string) => _cryptoUtils.decryptMessage(ciphertext, privateKey),
Expand All @@ -33,31 +33,28 @@ export type chatJoinPayloadType = {
class ChatE2EE implements IChatE2EE {
private channelId?: string;
private userId?: string;
private userName?: string;

private privateKey?: string;
private publicKey?: string;

private receiverPublicKey?: string;

private subscriptions = new Map();
//To Do: Fix types
private subscriptions: Map<string, Set<Function>> = new Map();
private callSubscriptions: Map<string, Set<Function>> = new Map();
private socket: SocketInstance;

private subscriptionLogger = logger.createChild('Subscription');
private callLogger = logger.createChild('Call');

private initialized = false;
private call?: WebRTCCall;
private onCallAddedHandler?: (call: E2ECall) => void;
private onCallRemovedHandler?: () => void;
private onPCStateChangedHandler?: (state: RTCPeerConnectionState) => void;

private iceCandidates = [];

private symEncryption = new AesGcmEncryption();

private onPcConnectionChanged(state: RTCPeerConnectionState): void {
this.onPCStateChangedHandler(state)
this.callSubscriptions.get("pc-state-changed")?.forEach((cb) => cb(state));
if(state === 'failed' || state === 'closed') {
this.callLogger.log(`Ending call, RTCPeerConnectionState: ${state}`);
this.endCall();
Expand Down Expand Up @@ -97,7 +94,7 @@ class ChatE2EE implements IChatE2EE {
if(data.type === 'offer') {
evetLogger.log("New offer");
this.call = this.getWebRtcCall();
this.onCallAddedHandler?.(this.activeCall);
this.callSubscriptions.get("call-added")?.forEach((cb) => cb(this.activeCall));
this.call.signal(data);

// add ICE from buffer
Expand Down Expand Up @@ -145,7 +142,6 @@ class ChatE2EE implements IChatE2EE {
logger.log(`setChannel(), ${JSON.stringify({ channelId, userId,userName })}`);
this.channelId = channelId;
this.userId = userId;
this.userName = userName;

const aesPlain = await this.symEncryption.getRawAesKeyToExport();

Expand Down Expand Up @@ -193,8 +189,14 @@ class ChatE2EE implements IChatE2EE {
})
}

public on(listener: SocketListenerType, callback): void {
public on(listener: string, callback): void {
const loggerWithCount = this.subscriptionLogger.count();
let subscriptions = this.subscriptions;

if(peerConnectionEvents.includes(listener as PeerConnectionEventType)) {
subscriptions = this.callSubscriptions;
}

const sub = this.subscriptions.get(listener);
if (sub) {
if (sub.has(callback)) {
Expand All @@ -205,7 +207,7 @@ class ChatE2EE implements IChatE2EE {
sub.add(callback);
} else {
loggerWithCount.log(`Created: ${listener}`);
this.subscriptions.set(listener, new Set([callback]));
subscriptions.set(listener, new Set([callback]));
}
}

Expand Down Expand Up @@ -240,19 +242,7 @@ class ChatE2EE implements IChatE2EE {
public async endCall(): Promise<void> {
this.call?.endCall();
this.call = null;
this.onCallRemovedHandler?.();
}

public onCallAdded(cb: (call: E2ECall) => void): void {
this.onCallAddedHandler = cb
}

public onCallRemoved(cb: () => void): void {
this.onCallRemovedHandler = cb
}

public onPCStateChanged(cb: (state: RTCPeerConnectionState) => void) : void {
this.onPCStateChangedHandler = cb;
this.callSubscriptions.get("call-removed")?.forEach((cb) => cb());
}

//get receiver public key
Expand All @@ -268,7 +258,7 @@ class ChatE2EE implements IChatE2EE {
}

private createSocketSubcription(): void {
const subscriptionContext: SubscriptionContextType = () => this.subscriptions;
const subscriptionContext = () => this.subscriptions as SubscriptionType;
this.socket = new SocketInstance(subscriptionContext, logger.createChild('Socket'));
}

Expand Down
10 changes: 5 additions & 5 deletions service/src/socket/socket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import socketIOClient, { Socket } from 'socket.io-client';
import { Logger } from '../utils/logger';
import { chatJoinPayloadType } from '../sdk';
import { configContext } from '../configContext';
export type SocketListenerTypeInternal = "limit-reached" | "delivered" | "on-alice-join" | "on-alice-disconnect" | "chat-message" | "webrtc-session-description";
export type SocketListenerType = "limit-reached" | "delivered" | "on-alice-join" | "on-alice-disconnect" | "chat-message" | "webrtc-session-description";

export type SubscriptionType = Map<SocketListenerTypeInternal, Set<(...args: any) => void>>;
export type SubscriptionType = Map<SocketListenerType, Set<Function>>;
export type SubscriptionContextType = () => SubscriptionType;

const SOCKET_LISTENERS: Record<string, SocketListenerTypeInternal> = {
const SOCKET_LISTENERS: Record<string, SocketListenerType> = {
'LIMIT_REACHED': "limit-reached",
'DELIVERED': "delivered",
'ON_ALICE_JOIN': "on-alice-join",
Expand All @@ -26,7 +26,7 @@ export class SocketInstance {
private socket: Socket;

private eventHandlerLogger = this.logger.createChild('eventHandlerLogger');
constructor(private subscriptionContext: SubscriptionContextType, private logger: Logger) {
constructor(private subscriptionContext: () => SubscriptionType, private logger: Logger) {
this.socket = socketIOClient(`${getBaseURL()}/`);
this.socket.on(SOCKET_LISTENERS.LIMIT_REACHED, (...args) => this.handler(SOCKET_LISTENERS.LIMIT_REACHED, args));
this.socket.on(SOCKET_LISTENERS.DELIVERED, (...args) => this.handler(SOCKET_LISTENERS.DELIVERED, args));
Expand All @@ -51,7 +51,7 @@ export class SocketInstance {
this.socket.disconnect();
}

private handler(listener: SocketListenerTypeInternal, args) {
private handler(listener: SocketListenerType, args) {
const loggerWithCount = this.eventHandlerLogger.count();
loggerWithCount.log(`handler called for ${listener}`);
const callbacks = this.subscriptionContext().get(listener);
Expand Down
6 changes: 3 additions & 3 deletions service/src/webrtc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ interface SignalData {
type: RTCSdpType;
sdp: string;
}

export class WebRTCCall {
private callStateChangeCallback?: (state: RTCPeerConnectionState) => void;
export type PeerConnectionEventType = "call-added" | "call-removed" | "pc-state-changed";
export const peerConnectionEvents: PeerConnectionEventType[] = [ "call-added", "call-removed", "pc-state-changed" ];
export class WebRTCCall {
private peer: Peer;

public static isSupported(): boolean {
Expand Down

0 comments on commit 7e1630d

Please sign in to comment.