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/components/AccountPreferences.tsx b/client/src/components/AccountPreferences.tsx
index 6788535..da926d0 100644
--- a/client/src/components/AccountPreferences.tsx
+++ b/client/src/components/AccountPreferences.tsx
@@ -39,7 +39,6 @@
 import { useState } from 'react';
 
 import { useAuthContext } from '../contexts/AuthProvider';
-import { Account } from '../models/Account';
 import ConversationAvatar from './ConversationAvatar';
 import ConversationsOverviewCard from './ConversationsOverviewCard';
 import JamiIdCard from './JamiIdCard';
@@ -60,17 +59,17 @@
   const { account, axiosInstance } = useAuthContext();
 
   const devices: string[][] = [];
-  const accountDevices = account.getDevices();
+  const accountDevices = account.devices;
   for (const i in accountDevices) devices.push([i, accountDevices[i]]);
 
   console.log(devices);
 
-  const isJamiAccount = account.getType() === Account.TYPE_JAMI;
+  const isJamiAccount = account.getType() === 'RING';
   const alias = isJamiAccount ? 'Jami account' : 'SIP account';
-  const moderators = account.getDefaultModerators();
+  const moderators = account.defaultModerators;
   const [defaultModeratorUri, setDefaultModeratorUri] = useState('');
 
-  const [details, setDetails] = useState(account.getDetails());
+  const [details, setDetails] = useState(account.details);
 
   const addModerator = async () => {
     if (defaultModeratorUri) {
@@ -87,7 +86,8 @@
     newDetails[key] = value ? 'true' : 'false';
     console.log(newDetails);
     await axiosInstance.patch('/account', newDetails);
-    setDetails({ ...account.updateDetails(newDetails) });
+    account.updateDetails(newDetails);
+    setDetails(account.details);
   };
 
   return (
@@ -219,19 +219,19 @@
                   </IconButton>
                 </ListItemSecondaryAction>
               </ListItem>
-              {!moderators || moderators.length === 0 ? (
+              {moderators.length === 0 ? (
                 <ListItem key="placeholder">
                   <ListItemText primary="No default moderator" />
                 </ListItem>
               ) : (
                 moderators.map((moderator) => (
-                  <ListItem key={moderator.getUri()}>
+                  <ListItem key={moderator.uri}>
                     <ListItemAvatar>
                       <ConversationAvatar displayName={moderator.getDisplayName()} />
                     </ListItemAvatar>
                     <ListItemText primary={moderator.getDisplayName()} />
                     <ListItemSecondaryAction>
-                      <IconButton onClick={() => removeModerator(moderator.getUri())} size="large">
+                      <IconButton onClick={() => removeModerator(moderator.uri)} size="large">
                         <DeleteRounded />
                       </IconButton>
                     </ListItemSecondaryAction>