Migrate client features to use new server

Remove all authManager references where possible.
Change fetch calls url to new server.

GitLab: #79
GitLab: #100
GitLab: #110
Change-Id: I1dce64108ceba67531372df764f8f7563cc50a3b
diff --git a/client/src/pages/AccountSelection.tsx b/client/src/pages/AccountSelection.tsx
deleted file mode 100644
index f8daf0a..0000000
--- a/client/src/pages/AccountSelection.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2022 Savoir-faire Linux Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation; either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this program.  If not, see
- * <https://www.gnu.org/licenses/>.
- */
-import { AddRounded } from '@mui/icons-material';
-import { Avatar, Card, CardHeader, Container, List } from '@mui/material';
-import { motion } from 'framer-motion';
-import { Account } from 'jami-web-common';
-import { Fragment, useEffect, useState } from 'react';
-import { useNavigate } from 'react-router';
-
-import authManager from '../AuthManager';
-import ConversationAvatar from '../components/ConversationAvatar';
-import Header from '../components/Header';
-import ListItemLink from '../components/ListItemLink';
-import LoadingPage from '../components/Loading';
-
-const variants = {
-  enter: { opacity: 1, y: 0 },
-  exit: { opacity: 0, y: '-50px' },
-};
-
-const AccountSelection = () => {
-  const navigate = useNavigate();
-  const [loaded, setLoaded] = useState(false);
-  const [, setError] = useState(false);
-  const [accounts, setAccounts] = useState<Account[]>([]);
-
-  authManager.authenticate('admin', 'admin');
-
-  useEffect(() => {
-    const controller = new AbortController();
-    authManager
-      .fetch(`/api/accounts`, { signal: controller.signal })
-      .then((res) => res.json())
-      .then(
-        (result: Account[]) => {
-          console.log(result);
-          if (result.length === 0) {
-            navigate('/newAccount');
-          } else {
-            setLoaded(true);
-            setAccounts(result.map((account) => Account.from(account)));
-          }
-        },
-        (error) => {
-          console.log(`get error ${error}`);
-          setLoaded(true);
-          setError(true);
-        }
-      )
-      .catch((e) => console.log(e));
-    // return () => controller.abort() // crash on React18
-  }, [navigate]);
-
-  if (!loaded) return <LoadingPage />;
-  return (
-    <Fragment>
-      <Header />
-      <Container maxWidth="sm" style={{ paddingBottom: 32 }}>
-        <motion.div drag="x" initial="exit" animate="enter" exit="exit" variants={variants}>
-          <Card style={{ marginTop: 32, marginBottom: 32 }}>
-            <CardHeader title="Choose an account" />
-            <List>
-              {accounts.map((account) => (
-                <ListItemLink
-                  key={account.getId()}
-                  icon={<ConversationAvatar displayName={account.getDisplayNameNoFallback()} />}
-                  to={`/deprecated-account/${account.getId()}/settings`}
-                  primary={account.getDisplayName()}
-                  secondary={account.getDisplayUri()}
-                />
-              ))}
-              <ListItemLink
-                icon={
-                  <Avatar>
-                    <AddRounded />
-                  </Avatar>
-                }
-                to="/newAccount"
-                primary="Create new account"
-              />
-            </List>
-          </Card>
-        </motion.div>
-      </Container>
-    </Fragment>
-  );
-};
-
-export default AccountSelection;
diff --git a/client/src/pages/AddContactPage.tsx b/client/src/pages/AddContactPage.tsx
index b0dfad0..dd93376 100644
--- a/client/src/pages/AddContactPage.tsx
+++ b/client/src/pages/AddContactPage.tsx
@@ -17,43 +17,40 @@
  */
 import GroupAddRounded from '@mui/icons-material/GroupAddRounded';
 import { Box, Card, CardContent, Container, Fab, Typography } from '@mui/material';
-import { useNavigate, useParams } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
 
-import authManager from '../AuthManager';
+import { useAuthContext } from '../contexts/AuthProvider';
 import { setRefreshFromSlice } from '../redux/appSlice';
 import { useAppDispatch } from '../redux/hooks';
+import { apiUrl } from '../utils/constants';
 
 type AddContactPageProps = {
-  accountId: string;
   contactId: string;
 };
 
-export default function AddContactPage(props: AddContactPageProps) {
+export default function AddContactPage({ contactId }: AddContactPageProps) {
+  const { token } = useAuthContext();
   const navigate = useNavigate();
 
-  const params = useParams();
-  const accountId = props.accountId || params.accountId;
-  const contactId = props.contactId || params.contactId;
   const dispatch = useAppDispatch();
 
   const handleClick = async () => {
-    const response = await authManager
-      .fetch(`/api/accounts/${accountId}/conversations`, {
-        method: 'POST',
-        headers: {
-          Accept: 'application/json',
-          'Content-Type': 'application/json',
-        },
-        body: JSON.stringify({ members: [contactId] }),
-      })
-      .then((res) => {
-        dispatch(setRefreshFromSlice());
-        return res.json();
-      });
+    const response = await fetch(new URL(`/conversations`, apiUrl), {
+      method: 'POST',
+      headers: {
+        Accept: 'application/json',
+        Authorization: `Bearer ${token}`,
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({ members: [contactId] }),
+    }).then((res) => {
+      dispatch(setRefreshFromSlice());
+      return res.json();
+    });
 
     console.log(response);
     if (response.conversationId) {
-      navigate(`/deprecated-account/${accountId}/conversation/${response.conversationId}`);
+      navigate(`/account/conversation/${response.conversationId}`);
     }
   };
 
diff --git a/client/src/pages/ChatInterface.tsx b/client/src/pages/ChatInterface.tsx
index 4ad1830..b09f2fd 100644
--- a/client/src/pages/ChatInterface.tsx
+++ b/client/src/pages/ChatInterface.tsx
@@ -16,7 +16,7 @@
  * <https://www.gnu.org/licenses/>.
  */
 import { Box, Divider, Stack } from '@mui/material';
-import { Account, ConversationMember, Message } from 'jami-web-common';
+import { ConversationMember, Message } from 'jami-web-common';
 import { useCallback, useContext, useEffect, useState } from 'react';
 import { useDropzone } from 'react-dropzone';
 
@@ -29,18 +29,17 @@
 import { FileHandler } from '../utils/files';
 
 type ChatInterfaceProps = {
-  account: Account;
   conversationId: string;
   members: ConversationMember[];
 };
-const ChatInterface = ({ account, conversationId, members }: ChatInterfaceProps) => {
+const ChatInterface = ({ conversationId, members }: ChatInterfaceProps) => {
   const socket = useContext(SocketContext);
   const [messages, setMessages] = useState<Message[]>([]);
   const [isLoading, setIsLoading] = useState(true);
   const [error, setError] = useState(false);
 
-  const messagesQuery = useMessagesQuery(account.getId(), conversationId);
-  const sendMessageMutation = useSendMessageMutation(account.getId(), conversationId);
+  const messagesQuery = useMessagesQuery(conversationId);
+  const sendMessageMutation = useSendMessageMutation(conversationId);
 
   const [fileHandlers, setFileHandlers] = useState<FileHandler[]>([]);
 
@@ -119,14 +118,14 @@
         />
       )}
       <input {...getInputProps()} />
-      <MessageList account={account} members={members} messages={messages} />
+      <MessageList members={members} messages={messages} />
       <Divider
         sx={{
           margin: '30px 16px 0px 16px',
           borderTop: '1px solid #E5E5E5',
         }}
       />
-      <SendMessageForm account={account} members={members} onSend={sendMessage} openFilePicker={openFilePicker} />
+      <SendMessageForm members={members} onSend={sendMessage} openFilePicker={openFilePicker} />
       {fileHandlers.length > 0 && <FilePreviewsList fileHandlers={fileHandlers} removeFile={removeFile} />}
     </Stack>
   );
diff --git a/client/src/pages/DeprecatedAccountSettings.tsx b/client/src/pages/DeprecatedAccountSettings.tsx
deleted file mode 100644
index f69334d..0000000
--- a/client/src/pages/DeprecatedAccountSettings.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2022 Savoir-faire Linux Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation; either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this program.  If not, see
- * <https://www.gnu.org/licenses/>.
- */
-import { CircularProgress, Container } from '@mui/material';
-import { Account } from 'jami-web-common';
-import { useEffect, useState } from 'react';
-import { useParams } from 'react-router';
-
-import authManager from '../AuthManager';
-import AccountPreferences from '../components/AccountPreferences';
-import Header from '../components/Header';
-import { setAccountId } from '../redux/appSlice';
-import { useAppDispatch } from '../redux/hooks';
-
-type AccountSettingsProps = {
-  accountId?: string;
-  account?: Account;
-};
-
-const DeprecatedAccountSettings = (props: AccountSettingsProps) => {
-  console.log('ACCOUNT SETTINGS', props.account);
-  const params = useParams();
-  const accountId = props.accountId || params.accountId;
-
-  if (accountId == null) {
-    throw new Error('Missing accountId');
-  }
-
-  const dispatch = useAppDispatch();
-
-  const [localAccount, setLocalAccount] = useState<Account | null>(null);
-
-  useEffect(() => {
-    dispatch(setAccountId(accountId));
-
-    const controller = new AbortController();
-    authManager
-      .fetch(`/api/accounts/${accountId}`, { signal: controller.signal })
-      .then((res) => res.json())
-      .then((result) => {
-        console.log(result);
-        const account = Account.from(result);
-        account.setDevices(result.devices);
-        setLocalAccount(account);
-      })
-      .catch((e) => console.log(e));
-    // return () => controller.abort() // crash on React18
-  }, [accountId, dispatch]);
-
-  return (
-    <Container maxWidth="sm">
-      <Header />
-      {localAccount != null ? <AccountPreferences account={localAccount} /> : <CircularProgress />}
-    </Container>
-  );
-};
-
-export default DeprecatedAccountSettings;
diff --git a/client/src/pages/JamiMessenger.tsx b/client/src/pages/JamiMessenger.tsx
index 2cb485b..b0b0812 100644
--- a/client/src/pages/JamiMessenger.tsx
+++ b/client/src/pages/JamiMessenger.tsx
@@ -21,6 +21,7 @@
 import CallInterface from './CallInterface';
 import Messenger from './Messenger';
 
+export type MessengerRouteParams = RouteParams<{ conversationId?: string; contactId?: string }, Record<string, never>>;
 export type CallRouteParams = RouteParams<{ conversationId: string }, { video?: 'true' }>;
 
 export default function JamiMessenger() {
diff --git a/client/src/pages/Messenger.tsx b/client/src/pages/Messenger.tsx
index c38294a..fdbb0f4 100644
--- a/client/src/pages/Messenger.tsx
+++ b/client/src/pages/Messenger.tsx
@@ -18,58 +18,60 @@
 import { Stack } from '@mui/material';
 import { Contact, Conversation } from 'jami-web-common';
 import { useEffect, useState } from 'react';
-import { useParams } from 'react-router';
 
-import authManager from '../AuthManager';
 //import Sound from 'react-sound';
 import ConversationList from '../components/ConversationList';
 import ConversationView from '../components/ConversationView';
 import Header from '../components/Header';
 import LoadingPage from '../components/Loading';
 import NewContactForm from '../components/NewContactForm';
+import { useAuthContext } from '../contexts/AuthProvider';
 import { useAppSelector } from '../redux/hooks';
+import { apiUrl } from '../utils/constants';
+import { useUrlParams } from '../utils/hooks';
 import AddContactPage from './AddContactPage';
+import { MessengerRouteParams } from './JamiMessenger';
 
-type MessengerProps = {
-  accountId?: string;
-  conversationId?: string;
-  contactId?: string;
-};
-
-const Messenger = (props: MessengerProps) => {
+const Messenger = () => {
   const { refresh } = useAppSelector((state) => state.userInfo);
+  const { token, account } = useAuthContext();
 
   const [conversations, setConversations] = useState<Conversation[] | undefined>(undefined);
   const [searchQuery, setSearchQuery] = useState('');
   const [searchResult, setSearchResults] = useState<Conversation | undefined>(undefined);
 
-  const params = useParams();
-  const accountId = props.accountId || params.accountId;
-  const conversationId = props.conversationId || params.conversationId;
-  const contactId = props.contactId || params.contactId;
+  const {
+    urlParams: { conversationId, contactId },
+  } = useUrlParams<MessengerRouteParams>();
 
-  if (accountId == null) {
-    throw new Error('Missing accountId');
-  }
+  const accountId = account.getId();
 
   useEffect(() => {
     console.log('REFRESH CONVERSATIONS FROM MESSENGER');
     const controller = new AbortController();
-    authManager
-      .fetch(`/api/accounts/${accountId}/conversations`, { signal: controller.signal })
+    fetch(new URL(`/conversations`, apiUrl), {
+      headers: {
+        Authorization: `Bearer ${token}`,
+      },
+      signal: controller.signal,
+    })
       .then((res) => res.json())
       .then((result: Conversation[]) => {
         console.log(result);
         setConversations(Object.values(result).map((c) => Conversation.from(accountId, c)));
       });
     // return () => controller.abort()
-  }, [accountId, refresh]);
+  }, [token, accountId, refresh]);
 
   useEffect(() => {
     if (!searchQuery) return;
     const controller = new AbortController();
-    authManager
-      .fetch(`/api/accounts/${accountId}/ns/name/${searchQuery}`, { signal: controller.signal })
+    fetch(new URL(`/ns/username/${searchQuery}`, apiUrl), {
+      headers: {
+        Authorization: `Bearer ${token}`,
+      },
+      signal: controller.signal,
+    })
       .then((response) => {
         if (response.status === 200) {
           return response.json();
@@ -80,14 +82,14 @@
       .then((response) => {
         console.log(response);
         const contact = new Contact(response.address);
-        contact.setRegisteredName(response.name);
+        contact.setRegisteredName(response.username);
         setSearchResults(contact ? Conversation.fromSingleContact(accountId, contact) : undefined);
       })
       .catch(() => {
         setSearchResults(undefined);
       });
     // return () => controller.abort() // crash on React18
-  }, [accountId, searchQuery]);
+  }, [accountId, searchQuery, token]);
 
   console.log('Messenger render');
   return (
@@ -95,7 +97,7 @@
       <Stack flexGrow={0} flexShrink={0} overflow="auto">
         <Header />
         <NewContactForm onChange={setSearchQuery} />
-        {contactId && <AddContactPage accountId={accountId} contactId={contactId} />}
+        {contactId && <AddContactPage contactId={contactId} />}
         {conversations ? (
           <ConversationList search={searchResult} conversations={conversations} accountId={accountId} />
         ) : (
@@ -104,9 +106,7 @@
           </div>
         )}
       </Stack>
-      <Stack flexGrow={1}>
-        {conversationId && <ConversationView accountId={accountId} conversationId={conversationId} />}
-      </Stack>
+      <Stack flexGrow={1}>{conversationId && <ConversationView conversationId={conversationId} />}</Stack>
     </Stack>
   );
 };
diff --git a/client/src/pages/ServerConfiguration.tsx b/client/src/pages/ServerConfiguration.tsx
deleted file mode 100644
index 56d06a8..0000000
--- a/client/src/pages/ServerConfiguration.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2022 Savoir-faire Linux Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation; either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this program.  If not, see
- * <https://www.gnu.org/licenses/>.
- */
-import CircularProgress from '@mui/material/CircularProgress';
-import Container from '@mui/material/Container';
-import { Account } from 'jami-web-common';
-import { useEffect, useState } from 'react';
-import { useParams } from 'react-router-dom';
-
-import authManager from '../AuthManager';
-import AccountPreferences from '../components/AccountPreferences';
-import Header from '../components/Header';
-
-type ServerOverviewProps = {
-  accountId?: string;
-};
-
-const ServerOverview = (props: ServerOverviewProps) => {
-  const [account, setAccount] = useState<Account | null>(null);
-  const params = useParams();
-  const accountId = props.accountId || params.accountId;
-
-  useEffect(() => {
-    const controller = new AbortController();
-    authManager
-      .fetch(`/api/serverConfig`, { signal: controller.signal })
-      .then((res) => res.json())
-      .then((result) => {
-        console.log(result);
-        setAccount(Account.from(result));
-      })
-      .catch((e) => console.log(e));
-    // return () => controller.abort() // crash on React18
-  }, [accountId]);
-
-  return (
-    <Container maxWidth="sm" className="app">
-      <Header />
-      {account != null ? <AccountPreferences account={account} /> : <CircularProgress />}
-    </Container>
-  );
-};
-
-export default ServerOverview;
diff --git a/client/src/pages/ServerSetup.tsx b/client/src/pages/ServerSetup.tsx
index e045751..e6ff0aa 100644
--- a/client/src/pages/ServerSetup.tsx
+++ b/client/src/pages/ServerSetup.tsx
@@ -19,8 +19,6 @@
 import { Box, Card, CardContent, Container, Fab, Input, Typography } from '@mui/material';
 import { FormEvent, useState } from 'react';
 
-import authManager from '../AuthManager';
-
 export default function ServerSetup() {
   const [password, setPassword] = useState('');
   const [passwordRepeat, setPasswordRepeat] = useState('');
@@ -32,7 +30,8 @@
     e.preventDefault();
     setLoading(true);
     if (!isValid()) return;
-    authManager.setup(password);
+    // TODO: Migrate to new server
+    // authManager.setup(password);
   };
 
   return (