Integrate new server authentication to client

Changes:
- Use server authentication REST API
- Log in automatically after registration
- Store token in localStorage
- Give feedback to user if registration or login fails

GitLab: #75
Change-Id: Ib90e5b911621567c6825af5e275920d703cdfe88
diff --git a/client/src/pages/AccountSettings.tsx b/client/src/pages/AccountSettings.tsx
index fe98277..b09fb65 100644
--- a/client/src/pages/AccountSettings.tsx
+++ b/client/src/pages/AccountSettings.tsx
@@ -15,62 +15,68 @@
  * 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 { Container } from '@mui/material';
+import { Account, HttpStatusCode } from 'jami-web-common';
+import { useEffect } from 'react';
+import { useNavigate } from 'react-router-dom';
 
-import authManager from '../AuthManager';
 import AccountPreferences from '../components/AccountPreferences';
 import Header from '../components/Header';
-import { setAccountId, setAccountObject } from '../redux/appSlice';
-import { useAppDispatch } from '../redux/hooks';
+import ProcessingRequest from '../components/ProcessingRequest';
+import { setAccount } from '../redux/appSlice';
+import { useAppDispatch, useAppSelector } from '../redux/hooks';
+import { getAccessToken, setAccessToken } from '../utils/auth';
+import { apiUrl } from '../utils/constants';
 
-type AccountSettingsProps = {
-  accountId?: string;
-  account?: Account;
-};
-
-const AccountSettings = (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');
-  }
-
+export default function AccountSettings() {
   const dispatch = useAppDispatch();
+  const navigate = useNavigate();
 
-  const [account, setAccount] = useState<Account | null>(null);
+  const { account } = useAppSelector((state) => state.userInfo);
+  const accessToken = getAccessToken();
 
   useEffect(() => {
-    dispatch(setAccountId(accountId));
+    if (accessToken) {
+      const getAccount = async () => {
+        const url = new URL('/account', apiUrl);
+        let response: Response;
 
-    const controller = new AbortController();
-    authManager
-      .fetch(`/api/accounts/${accountId}`, { signal: controller.signal })
-      .then((res) => res.json())
-      .then((result) => {
-        const account = Account.from(result);
-        account.setDevices(result.devices);
-        dispatch(setAccountObject(account));
-        setAccount(account);
-      })
-      .catch((e) => console.log(e));
-    // return () => controller.abort() // crash on React18
-  }, [accountId, dispatch]);
+        try {
+          response = await fetch(url, {
+            method: 'GET',
+            mode: 'cors',
+            headers: {
+              Authorization: `Bearer ${accessToken}`,
+            },
+            referrerPolicy: 'no-referrer',
+          });
+        } catch (err) {
+          setAccessToken('');
+          dispatch(setAccount(undefined));
+          navigate('/', { replace: true });
+          return;
+        }
 
+        if (response.status === HttpStatusCode.Ok) {
+          const serializedAccount = await response.json();
+          const account = Account.from(serializedAccount);
+          dispatch(setAccount(account));
+        } else if (response.status === HttpStatusCode.Unauthorized) {
+          setAccessToken('');
+          dispatch(setAccount(undefined));
+          navigate('/', { replace: true });
+        }
+      };
+
+      getAccount();
+    }
+  }, [accessToken, dispatch, navigate]);
+
+  // TODO: Improve component and sub-components UI.
   return (
     <Container maxWidth="sm">
       <Header />
-      {account != null ? (
-        <AccountPreferences account={account} onAccountChanged={(account: Account) => setAccount(account)} />
-      ) : (
-        <CircularProgress />
-      )}
+      {account ? <AccountPreferences account={account} /> : <ProcessingRequest open={true} />}
     </Container>
   );
-};
-
-export default AccountSettings;
+}