Create new interfaces for objects transmitted using the REST API

Changes:
- Create new IContact, IAccount, and IConversation interfaces in common/
    - These interfaces represent the serialized versions of the models which are transferred
    - The client models are classes which implement these interfaces
- Create new LookupResult interface for nameserver lookup results
- Create new IConversationMember interface for conversation members
    - The client interface ConversationMember extends this interface to have a Contact field rather than IContact
- Create new ConversationInfos interface for conversation infos
- Create new ContactDetails interface for contact details (used by contacts routes)
- Move request and response body interfaces into common/
- Merge AccountConfig into AccountDetails interface
- Create interfaces for server-only objects:
    - ConversationMemberInfos
    - ConversationRequestMetadata
- Ensure interfaces in jami-signal-interfaces.ts do not contain fields with JamiSwig types
- Rename models/ filenames to camelCase as they are not components
- Rewrite client models to have proper TypeScript accessors and remove unused getters
- Rewrite how client models are initialized from the serialized interface using .fromInterface static methods
- Make client models implement the interfaces in common/ for consistency
- Remove unneeded _next parameter for Express.js route handlers
- Use Partial<T> for all Express.js request body types on server
- Type all Axios response body types with interfaces

GitLab: #92
Change-Id: I4b2c75ac632ec5d9bf12a874a5ba04467c76fa6d
diff --git a/client/src/pages/AddContactPage.tsx b/client/src/pages/AddContactPage.tsx
index 5e3c375..fb7e4bb 100644
--- a/client/src/pages/AddContactPage.tsx
+++ b/client/src/pages/AddContactPage.tsx
@@ -17,6 +17,7 @@
  */
 import GroupAddRounded from '@mui/icons-material/GroupAddRounded';
 import { Box, Card, CardContent, Container, Fab, Typography } from '@mui/material';
+import { ContactDetails } from 'jami-web-common';
 import { useTranslation } from 'react-i18next';
 import { useNavigate } from 'react-router-dom';
 
@@ -36,7 +37,7 @@
   const dispatch = useAppDispatch();
 
   const handleClick = async () => {
-    const { data } = await axiosInstance.put(`/contacts/${contactId}`);
+    const { data } = await axiosInstance.put<ContactDetails>(`/contacts/${contactId}`);
     dispatch(setRefreshFromSlice());
 
     if (data.conversationId) {
diff --git a/client/src/pages/CallInterface.tsx b/client/src/pages/CallInterface.tsx
index 10b1d3c..3d5b366 100644
--- a/client/src/pages/CallInterface.tsx
+++ b/client/src/pages/CallInterface.tsx
@@ -214,7 +214,7 @@
   const { callStartTime } = useContext(CallContext);
   const { conversation } = useConversationContext();
   const [elapsedTime, setElapsedTime] = useState(0);
-  const memberName = useMemo(() => conversation.getFirstMember().contact.getRegisteredName(), [conversation]);
+  const memberName = useMemo(() => conversation.getFirstMember().contact.registeredName, [conversation]);
 
   useEffect(() => {
     if (callStartTime) {
diff --git a/client/src/pages/CallPending.tsx b/client/src/pages/CallPending.tsx
index 2cd57c6..54fb916 100644
--- a/client/src/pages/CallPending.tsx
+++ b/client/src/pages/CallPending.tsx
@@ -149,7 +149,7 @@
   const { callStatus } = useContext(CallContext);
   const { t } = useTranslation();
   const { conversation } = useConversationContext();
-  const memberName = useMemo(() => conversation.getFirstMember().contact.getRegisteredName(), [conversation]);
+  const memberName = useMemo(() => conversation.getFirstMember().contact.registeredName, [conversation]);
 
   let title = t('loading');
 
@@ -183,7 +183,7 @@
 
   const { t } = useTranslation();
   const { conversation } = useConversationContext();
-  const memberName = useMemo(() => conversation.getFirstMember().contact.getRegisteredName(), [conversation]);
+  const memberName = useMemo(() => conversation.getFirstMember().contact.registeredName, [conversation]);
 
   let title = t('loading');
 
diff --git a/client/src/pages/ChatInterface.tsx b/client/src/pages/ChatInterface.tsx
index 4ae9ce6..00aeb3e 100644
--- a/client/src/pages/ChatInterface.tsx
+++ b/client/src/pages/ChatInterface.tsx
@@ -105,7 +105,7 @@
     return <div>Error loading {conversationId}</div>;
   }
 
-  const members = conversation.getMembers();
+  const members = conversation.members;
 
   return (
     <Stack flex={1} overflow="hidden" {...getRootProps()} paddingBottom="16px">
diff --git a/client/src/pages/SetupLogin.tsx b/client/src/pages/SetupLogin.tsx
index d34d366..2ae33b9 100644
--- a/client/src/pages/SetupLogin.tsx
+++ b/client/src/pages/SetupLogin.tsx
@@ -18,7 +18,7 @@
 import GroupAddRounded from '@mui/icons-material/GroupAddRounded';
 import { Box, Card, CardContent, Container, Fab, Input, Typography } from '@mui/material';
 import axios from 'axios';
-import { HttpStatusCode } from 'jami-web-common';
+import { AccessToken, HttpStatusCode } from 'jami-web-common';
 import { FormEvent, useEffect, useState } from 'react';
 import { useTranslation } from 'react-i18next';
 import { useNavigate } from 'react-router-dom';
@@ -45,7 +45,7 @@
 
   const loginAdmin = async (password: string) => {
     try {
-      const { data } = await axios.post('/setup/admin/login', { password }, { baseURL: apiUrl });
+      const { data } = await axios.post<AccessToken>('/setup/admin/login', { password }, { baseURL: apiUrl });
       localStorage.setItem('adminAccessToken', data.accessToken);
     } catch (e: any) {
       if (e.response?.status === HttpStatusCode.Forbidden) {