Fix conversation messages

Change-Id: I999839176bf523f1968dada3e3ebd8703f08656f
diff --git a/server/src/jamid/jami-signal-interfaces.ts b/server/src/jamid/jami-signal-interfaces.ts
index a839309..76025e1 100644
--- a/server/src/jamid/jami-signal-interfaces.ts
+++ b/server/src/jamid/jami-signal-interfaces.ts
@@ -17,6 +17,8 @@
  */
 import { AccountDetails, Message, VolatileDetails } from 'jami-web-common';
 
+import { Blob, StringMap } from './jami-swig.js';
+
 // These interfaces are used to hold all the parameters for signal handlers
 // These parameters' names and types can be found in daemon/bin/nodejs/callback.h
 // or in their relevant SWIG interface files (.i) in daemon/bin/nodejs
@@ -69,6 +71,14 @@
   state: number; // TODO: Replace state number with enum (see account_const.h)
 }
 
+export interface IncomingTrustRequest {
+  accountId: string;
+  conversationId: string;
+  from: string;
+  payload: Blob;
+  received: number;
+}
+
 export interface ContactAdded {
   accountId: string;
   contactId: string;
@@ -81,6 +91,12 @@
   banned: boolean;
 }
 
+export interface ConversationRequestReceived {
+  accountId: string;
+  conversationId: string;
+  metadata: StringMap;
+}
+
 export interface ConversationReady {
   accountId: string;
   conversationId: string;
@@ -98,6 +114,13 @@
   messages: Message[];
 }
 
+export interface ConversationMemberEvent {
+  accountId: string;
+  conversationId: string;
+  memberUri: string;
+  event: number;
+}
+
 export interface MessageReceived {
   accountId: string;
   conversationId: string;
diff --git a/server/src/jamid/jami-signal.ts b/server/src/jamid/jami-signal.ts
index 9455fcf..6a9b15b 100644
--- a/server/src/jamid/jami-signal.ts
+++ b/server/src/jamid/jami-signal.ts
@@ -25,6 +25,7 @@
   AccountsChanged = 'AccountsChanged',
   AccountDetailsChanged = 'AccountDetailsChanged',
   RegistrationStateChanged = 'RegistrationStateChanged',
+  IncomingTrustRequest = 'IncomingTrustRequest',
   ContactAdded = 'ContactAdded',
   ContactRemoved = 'ContactRemoved',
   ExportOnRingEnded = 'ExportOnRingEnded',
diff --git a/server/src/jamid/jami-swig.ts b/server/src/jamid/jami-swig.ts
index bb3d584..df9dd3d 100644
--- a/server/src/jamid/jami-swig.ts
+++ b/server/src/jamid/jami-swig.ts
@@ -28,14 +28,14 @@
   set(key: T, value: U): void;
 }
 
-// export type IntVect = SwigVec<number>;
-// export type UintVect = SwigVec<number>;
-// export type FloatVect = SwigVec<number>;
+// export type IntVect = SwigVect<number>;
+// export type UintVect = SwigVect<number>;
+// export type FloatVect = SwigVect<number>;
 export type StringVect = SwigVect<string>;
 // export type IntegerMap = SwigMap<string, number>;
 export type StringMap = SwigMap<string, string>;
 export type VectMap = SwigVect<StringMap>;
-// export type Blob = SwigVec<number>;
+export type Blob = SwigVect<number>;
 
 function* swigVectToIt<T>(swigVect: SwigVect<T>) {
   const size = swigVect.size();
@@ -106,6 +106,9 @@
   removeContact(accountId: string, contactId: string, ban: boolean): void;
   getContacts(accountId: string): VectMap;
   getContactDetails(accountId: string, contactId: string): StringMap;
+  sendTrustRequest(accountId: string, to: string, payload: Blob): void;
+  acceptTrustRequest(accountId: string, from: string): boolean;
+  discardTrustRequest(accountId: string, from: string): boolean;
 
   getDefaultModerators(accountId: string): StringVect;
   setDefaultModerator(accountId: string, uri: string, state: boolean): void;
@@ -113,6 +116,7 @@
   getConversations(accountId: string): StringVect;
   conversationInfos(accountId: string, conversationId: string): StringMap;
   getConversationMembers(accountId: string, conversationId: string): VectMap;
+  acceptConversationRequest(accountId: string, conversationId: string): void;
 
   sendMessage(accountId: string, conversationId: string, message: string, replyTo: string, flag: number): void;
   loadConversationMessages(accountId: string, conversationId: string, fromMessage: string, n: number): number;
@@ -128,4 +132,5 @@
   StringMap: Constructable<StringMap>;
   // VectMap: Constructable<VectMap>;
   // IntegerMap: Constructable<IntegerMap>;
+  Blob: Constructable<Blob>;
 }
diff --git a/server/src/jamid/jamid.ts b/server/src/jamid/jamid.ts
index 9122395..843d7cf 100644
--- a/server/src/jamid/jamid.ts
+++ b/server/src/jamid/jamid.ts
@@ -38,8 +38,10 @@
   ContactAdded,
   ContactRemoved,
   ConversationLoaded,
+  ConversationMemberEvent,
   ConversationReady,
   ConversationRemoved,
+  ConversationRequestReceived,
   IncomingAccountMessage,
   KnownDevicesChanged,
   MessageReceived,
@@ -118,6 +120,10 @@
     handlers.ContactRemoved = (accountId: string, contactId: string, banned: boolean) =>
       onContactRemoved.next({ accountId, contactId, banned });
 
+    const onConversationRequestReceived = new Subject<ConversationRequestReceived>();
+    handlers.ConversationRequestReceived = (accountId: string, conversationId: string, metadata: StringMap) =>
+      onConversationRequestReceived.next({ accountId, conversationId, metadata });
+
     const onConversationReady = new Subject<ConversationReady>();
     handlers.ConversationReady = (accountId: string, conversationId: string) =>
       onConversationReady.next({ accountId, conversationId });
@@ -130,6 +136,16 @@
     handlers.ConversationLoaded = (id: number, accountId: string, conversationId: string, messages: Message[]) =>
       onConversationLoaded.next({ id, accountId, conversationId, messages });
 
+    const onConversationMemberEvent = new Subject<ConversationMemberEvent>();
+    handlers.ConversationMemberEvent = (
+      accountId: string,
+      conversationId: string,
+      memberUri: string,
+      event: number
+    ) => {
+      onConversationMemberEvent.next({ accountId, conversationId, memberUri, event });
+    };
+
     const onMessageReceived = new Subject<MessageReceived>();
     handlers.MessageReceived = (accountId: string, conversationId: string, message: Message) =>
       onMessageReceived.next({ accountId, conversationId, message });
@@ -147,9 +163,11 @@
       onAccountMessageStatusChanged: onAccountMessageStatusChanged.asObservable(),
       onContactAdded: onContactAdded.asObservable(),
       onContactRemoved: onContactRemoved.asObservable(),
+      onConversationRequestReceived: onConversationRequestReceived.asObservable(),
       onConversationReady: onConversationReady.asObservable(),
       onConversationRemoved: onConversationRemoved.asObservable(),
       onConversationLoaded: onConversationLoaded.asObservable(),
+      onConversationMemberEvent: onConversationMemberEvent.asObservable(),
       onMessageReceived: onMessageReceived.asObservable(),
     };
 
@@ -266,6 +284,10 @@
     this.jamiSwig.addContact(accountId, contactId);
   }
 
+  sendTrustRequest(accountId: string, contactId: string): void {
+    this.jamiSwig.sendTrustRequest(accountId, contactId, new this.jamiSwig.Blob());
+  }
+
   removeContact(accountId: string, contactId: string): void {
     this.jamiSwig.removeContact(accountId, contactId, false);
   }
@@ -358,8 +380,8 @@
         `Received VolatileDetailsChanged: {"accountId":"${accountId}",` +
           `"details":{"Account.registeredName":"${username}", ...}}`
       );
-      // Keep map of usernames to account IDs
       if (username) {
+        // Keep map of usernames to account IDs
         this.usernamesToAccountIds.set(username, accountId);
       }
     });
@@ -420,6 +442,17 @@
       log.debug('Received ContactRemoved:', JSON.stringify(signal));
     });
 
+    this.events.onConversationRequestReceived.subscribe((signal) => {
+      log.debug('Received ConversationRequestReceived:', JSON.stringify(signal));
+
+      // TODO: Prompt user to accept conversation request on client
+      // Currently, we auto-accept all incoming conversation requests. In future, we
+      // need to ask the user if they accept the conversation request or not. Part of
+      // it can be done by sending a WebSocket event.
+      // See other implementations e.g. block contact / decline request / accept request.
+      this.jamiSwig.acceptConversationRequest(signal.accountId, signal.conversationId);
+    });
+
     this.events.onConversationReady.subscribe((signal) => {
       log.debug('Received ConversationReady:', JSON.stringify(signal));
     });
@@ -435,8 +468,13 @@
       );
     });
 
+    this.events.onConversationMemberEvent.subscribe((signal) => {
+      log.debug('Received onConversationMemberEvent:', JSON.stringify(signal));
+    });
+
     this.events.onMessageReceived.subscribe((signal) => {
       log.debug('Received MessageReceived:', JSON.stringify(signal));
+
       const data: ConversationMessage = {
         conversationId: signal.conversationId,
         message: signal.message,