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/utils/auth.ts b/client/src/utils/auth.ts
index 98ecdba..8404eee 100644
--- a/client/src/utils/auth.ts
+++ b/client/src/utils/auth.ts
@@ -16,9 +16,11 @@
  * <https://www.gnu.org/licenses/>.
  */
 import { passwordStrength } from 'check-password-strength';
-import { HttpStatusCode, LookupResolveValue } from 'jami-web-common';
+import { HttpStatusCode } from 'jami-web-common';
 
 import { PasswordStrength } from '../enums/password-strength';
+import { apiUrl } from './constants';
+import { InvalidPassword, UsernameNotFound } from './errors';
 
 interface PasswordStrengthResult {
   id: number;
@@ -36,21 +38,17 @@
 
 const idToStrengthValueCode: StrengthValueCode[] = ['too_weak', 'weak', 'medium', 'strong'];
 
-// TODO: Find a way to do it differently or remove this check from account creation.
-// It doesn't work if the server has secured this path, so I tweaked the server for test.
-// The tweak is to remove secured of apiRouter middleware in the server (app.ts).
 export async function isNameRegistered(name: string): Promise<boolean> {
-  try {
-    const response: Response = await fetch(`api/ns/name/${name}`);
-    if (response.status === HttpStatusCode.Ok) {
-      const data: LookupResolveValue = await response.json();
-      return data.name === name;
-    } else if (response.status === HttpStatusCode.NotFound) {
+  const url = new URL(`/ns/username/${name}`, apiUrl);
+  const response = await fetch(url);
+
+  switch (response.status) {
+    case HttpStatusCode.Ok:
+      return true;
+    case HttpStatusCode.NotFound:
       return false;
-    }
-    return true;
-  } catch (err) {
-    return true;
+    default:
+      throw new Error(await response.text());
   }
 }
 
@@ -64,3 +62,52 @@
 
   return checkResult;
 }
+
+export async function registerUser(username: string, password: string): Promise<void> {
+  const url = new URL('/auth/new-account', apiUrl);
+  const response: Response = await fetch(url, {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json',
+    },
+    body: JSON.stringify({ username, password }),
+  });
+
+  if (response.status !== HttpStatusCode.Created) {
+    throw new Error(await response.text());
+  }
+}
+
+export async function loginUser(username: string, password: string): Promise<string> {
+  const url = new URL('/auth/login', apiUrl);
+  const response = await fetch(url, {
+    method: 'POST',
+    headers: {
+      'Content-Type': 'application/json',
+    },
+    body: JSON.stringify({ username, password }),
+  });
+
+  switch (response.status) {
+    case HttpStatusCode.Ok:
+      break;
+    case HttpStatusCode.NotFound:
+      throw new UsernameNotFound();
+    case HttpStatusCode.Unauthorized:
+      throw new InvalidPassword();
+    default:
+      throw new Error(await response.text());
+  }
+
+  const data: { accessToken: string } = await response.json();
+  return data.accessToken;
+}
+
+export function getAccessToken(): string {
+  const accessToken: string | null = localStorage.getItem('accessToken');
+  return accessToken ?? '';
+}
+
+export function setAccessToken(accessToken: string): void {
+  localStorage.setItem('accessToken', accessToken);
+}