Create calls API routes

GitLab: #107
Change-Id: Ic1ff2bd7bf2af4d851eb04b6595f52713df9629f
diff --git a/server/src/app.ts b/server/src/app.ts
index 16e9f12..32f930e 100644
--- a/server/src/app.ts
+++ b/server/src/app.ts
@@ -24,6 +24,7 @@
 
 import { accountRouter } from './routers/account-router.js';
 import { authRouter } from './routers/auth-router.js';
+import { callRouter } from './routers/call-router.js';
 import { contactsRouter } from './routers/contacts-router.js';
 import { conversationRouter } from './routers/conversation-router.js';
 import { nameserverRouter } from './routers/nameserver-router.js';
@@ -44,7 +45,7 @@
     app.use('/contacts', contactsRouter);
     // TODO: Moderator routes: https://git.jami.net/savoirfairelinux/jami-web/-/issues/93
     app.use('/conversations', conversationRouter);
-    // TODO: Call routes: https://git.jami.net/savoirfairelinux/jami-web/-/issues/107
+    app.use('/calls', callRouter);
     app.use('/ns', nameserverRouter);
 
     // Setup 404 error handling
diff --git a/server/src/jamid/jami-swig.ts b/server/src/jamid/jami-swig.ts
index b48db13..484aad1 100644
--- a/server/src/jamid/jami-swig.ts
+++ b/server/src/jamid/jami-swig.ts
@@ -93,6 +93,9 @@
   sendMessage(accountId: string, conversationId: string, message: string, replyTo: string): void;
   loadConversationMessages(accountId: string, conversationId: string, fromMessage: string, n: number): number;
 
+  getCallList(accountId: string): StringVect;
+  getCallDetails(accountId: string, callId: string): StringMap;
+
   // IntVect: Constructable<IntVect>;
   // UintVect: Constructable<UintVect>;
   // FloatVect: Constructable<FloatVect>;
diff --git a/server/src/jamid/jamid.ts b/server/src/jamid/jamid.ts
index 858f4d5..957f370 100644
--- a/server/src/jamid/jamid.ts
+++ b/server/src/jamid/jamid.ts
@@ -292,6 +292,15 @@
     this.jamiSwig.sendMessage(accountId, conversationId, message, replyTo || '');
   }
 
+  getCallIds(accountId: string): string[] {
+    return stringVectToArray(this.jamiSwig.getCallList(accountId));
+  }
+
+  // TODO: Replace Record with interface
+  getCallDetails(accountId: string, callId: string): Record<string, string> {
+    return stringMapToRecord(this.jamiSwig.getCallDetails(accountId, callId));
+  }
+
   getAccountIdFromUsername(username: string): string | undefined {
     return this.usernamesToAccountIds.get(username);
   }
diff --git a/server/src/routers/call-router.ts b/server/src/routers/call-router.ts
new file mode 100644
index 0000000..835bf66
--- /dev/null
+++ b/server/src/routers/call-router.ts
@@ -0,0 +1,38 @@
+/*
+ * 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 { Router } from 'express';
+import { Container } from 'typedi';
+
+import { Jamid } from '../jamid/jamid.js';
+import { authenticateToken } from '../middleware/auth.js';
+
+const jamid = Container.get(Jamid);
+
+export const callRouter = Router();
+
+callRouter.use(authenticateToken);
+
+callRouter.get('/', (_req, res) => {
+  const callIds = jamid.getCallIds(res.locals.accountId);
+  res.send(callIds);
+});
+
+callRouter.get('/:callId', (req, res) => {
+  const callDetails = jamid.getCallDetails(res.locals.accountId, req.params.callId);
+  res.send(callDetails);
+});