diff --git a/routes/index.js b/routes/index.js
index e4cf1e8..ed6b5f1 100644
--- a/routes/index.js
+++ b/routes/index.js
@@ -1,10 +1,10 @@
-import { Router } from 'express'
-const router = Router()
-import { join } from 'path'
+import { Router } from 'express';
+const router = Router();
+import { join } from 'path';
 
 /* GET React App */
 router.get(['/app', '/app/*'], (req, res, next) => {
-    res.sendFile(join(__dirname, '../public', 'index.html'))
-})
+  res.sendFile(join(__dirname, '../public', 'index.html'));
+});
 
-export default router
+export default router;
diff --git a/routes/jami.js b/routes/jami.js
index 49250c4..0e41a89 100644
--- a/routes/jami.js
+++ b/routes/jami.js
@@ -1,312 +1,260 @@
-import { Router } from 'express'
+import { Router } from 'express';
 
 class JamiRestApi {
-    constructor(jami) {
-        this.jami = jami
-    }
+  constructor(jami) {
+    this.jami = jami;
+  }
 
-    getRouter() {
-        const router = Router({ mergeParams: true })
-        //router.use(express.json())
+  getRouter() {
+    const router = Router({ mergeParams: true });
+    //router.use(express.json())
 
-        // Accounts
-        router.get('/accounts', async (req, res) => {
-            console.log('Get account list')
-            let accounts = this.jami.getAccountList()
-            if (req.user.accountFilter)
-                accounts = accounts.filter(account => req.user.accountFilter(account.getId()))
-            res.json(await Promise.all(accounts.map(async account => await account.getSummary())))
-        })
+    // Accounts
+    router.get('/accounts', async (req, res) => {
+      console.log('Get account list');
+      let accounts = this.jami.getAccountList();
+      if (req.user.accountFilter) accounts = accounts.filter((account) => req.user.accountFilter(account.getId()));
+      res.json(await Promise.all(accounts.map(async (account) => await account.getSummary())));
+    });
 
-        const checkCanCreateAccounts = (req, res, next) => {
-            console.log(`checkCanCreateAccounts ${req.params.accountId} for ${req.user.id}`)
-            if (req.user && !req.user.accountFilter) {
-                return next()
-            }
-            res.status(403).end()
+    const checkCanCreateAccounts = (req, res, next) => {
+      console.log(`checkCanCreateAccounts ${req.params.accountId} for ${req.user.id}`);
+      if (req.user && !req.user.accountFilter) {
+        return next();
+      }
+      res.status(403).end();
+    };
+
+    router.post('/accounts', checkCanCreateAccounts, async (req, res) => {
+      console.log('Create new account');
+      console.log(req.body);
+      try {
+        const accountId = await this.jami.addAccount(req.body);
+        if (req.body.registerName) {
+          this.jami
+            .registerName(accountId, '', req.body.registerName)
+            .then((result) => console.log('Name registrtion result: ' + result));
         }
+        res.json({ accountId });
+      } catch (e) {
+        res.status(400).json({ error: e });
+      }
+    });
 
-        router.post('/accounts', checkCanCreateAccounts, async (req, res) => {
-            console.log('Create new account')
-            console.log(req.body)
-            try {
-                const accountId = await this.jami.addAccount(req.body)
-                if (req.body.registerName) {
-                    this.jami.registerName(accountId, '', req.body.registerName)
-                        .then(result => console.log('Name registrtion result: ' + result))
-                }
-                res.json({ accountId })
-            } catch (e) {
-                res.status(400).json({ error: e })
-            }
-        })
+    const checkAccount = (req, res, next) => {
+      console.log(`checkAccount ${req.params.accountId} for ${req.user.id}`);
+      if (req.user && (!req.user.accountFilter || req.user.accountFilter(req.params.accountId))) {
+        return next();
+      }
+      res.status(403).end();
+    };
 
-        const checkAccount = (req, res, next) => {
-            console.log(`checkAccount ${req.params.accountId} for ${req.user.id}`)
-            if (req.user && (!req.user.accountFilter || req.user.accountFilter(req.params.accountId))) {
-                return next()
-            }
-            res.status(403).end()
-        }
+    const accountRouter = Router({ mergeParams: true });
+    router.use('/accounts/:accountId', checkAccount, accountRouter);
 
-        const accountRouter = Router({mergeParams: true})
-        router.use('/accounts/:accountId', checkAccount, accountRouter)
+    accountRouter.get('/', async (req, res) => {
+      console.log(`Get account ${req.params.accountId}`);
+      const account = this.jami.getAccount(req.params.accountId);
+      if (account) {
+        account.defaultModerators = this.jami.getDefaultModerators(account.getId());
+        const obj = await account.getObject();
+        obj.devices = this.jami.getDevices(req.params.accountId);
+        res.json(obj);
+      } else res.status(404).end();
+    });
 
-        accountRouter.get('/', async (req, res) => {
-            console.log(`Get account ${req.params.accountId}`)
-            const account = this.jami.getAccount(req.params.accountId)
-            if (account) {
-                account.defaultModerators = this.jami.getDefaultModerators(account.getId())
-                const obj = await account.getObject()
-                obj.devices = this.jami.getDevices(req.params.accountId)
-                res.json(obj)
-            } else
-                res.status(404).end()
-        })
+    accountRouter.post('/', async (req, res) => {
+      console.log(`Set account details ${req.params.accountId}`);
+      const account = this.jami.getAccount(req.params.accountId);
+      if (account) {
+        const newDetails = account.updateDetails(req.body);
+        this.jami.setAccountDetails(account.getId(), newDetails);
+        res.status(200).end();
+      } else res.status(404).end();
+    });
 
-        accountRouter.post('/', async (req, res) => {
-            console.log(`Set account details ${req.params.accountId}`)
-            const account = this.jami.getAccount(req.params.accountId)
-            if (account) {
-                const newDetails = account.updateDetails(req.body)
-                this.jami.setAccountDetails(account.getId(), newDetails)
-                res.status(200).end()
-            } else res.status(404).end()
-        })
+    // Contacts
+    accountRouter.get('/contacts', (req, res) => {
+      console.log(`Get account ${req.params.accountId}`);
+      const account = this.jami.getAccount(req.params.accountId);
+      if (account) {
+        let rep = account.getContacts();
+        res.json(rep);
+      } else res.status(404).end();
+    });
 
-        // Contacts
-        accountRouter.get('/contacts', (req, res) => {
-            console.log(`Get account ${req.params.accountId}`)
-            const account = this.jami.getAccount(req.params.accountId)
-            if (account) {
-                let rep = account.getContacts()
-                res.json(rep)
-            } else res.status(404).end()
-        })
+    accountRouter.get('/contacts/:contactId', (req, res) => {
+      console.log(`Get account details fot ${req.params.accountId}`);
+      const account = this.jami.getAccount(req.params.accountId);
+      const uri = req.params.uri;
+      if (account) {
+        let rep = account.getContactDetails(uri);
+        res.json(rep);
+      } else res.status(404).end();
+    });
 
-        accountRouter.get('/contacts/:contactId', (req, res) => {
-            console.log(`Get account details fot ${req.params.accountId}`)
-            const account = this.jami.getAccount(req.params.accountId)
-            const uri = req.params.uri
-            if (account) {
-                let rep = account.getContactDetails(uri)
-                res.json(rep)
-            } else res.status(404).end()
-        })
+    accountRouter.get('/contacts/details/:contactId', (req, res) => {
+      console.log(`Get contact ${req.params.contactId} details for ${req.params.accountId}`);
+      const account = this.jami.getAccount(req.params.accountId);
+      if (account) {
+        let rep = this.jami.getContactDetails(req.params.accountId, req.params.contactId);
 
-        accountRouter.get('/contacts/details/:contactId', (req, res) => {
-            console.log(
-                `Get contact ${req.params.contactId} details for ${req.params.accountId}`
-            )
-            const account = this.jami.getAccount(req.params.accountId)
-            if (account) {
-                let rep = this.jami.getContactDetails(
-                    req.params.accountId,
-                    req.params.contactId
-                )
+        console.log(rep);
+        res.json(rep);
+      } else res.status(404).end();
+    });
 
-                console.log(rep)
-                res.json(rep)
-            } else res.status(404).end()
-        })
+    accountRouter.delete('/contacts/remove/:contactId', async (req, res) => {
+      console.log('REMOVED CONTACT: ', req.params.contactId);
+      const account = this.jami.getAccount(req.params.accountId);
+      if (account) {
+        let rep = this.jami.removeContact(req.params.accountId, req.params.contactId);
+        res.json(rep);
+      } else res.status(404).end();
+      res.status(200).end();
+    });
 
-        accountRouter.delete('/contacts/remove/:contactId', async (req, res) => {
-            console.log('REMOVED CONTACT: ', req.params.contactId)
-            const account = this.jami.getAccount(req.params.accountId)
-            if (account) {
-                let rep = this.jami.removeContact(
-                    req.params.accountId,
-                    req.params.contactId
-                )
-                res.json(rep)
-            } else res.status(404).end()
-            res.status(200).end()
-        })
+    accountRouter.delete('/contacts/block/:contactId/', async (req, res) => {
+      console.log('REMOVED AND BLOCKED CONTACT: ', req.params.contactId);
+      const account = this.jami.getAccount(req.params.accountId);
+      if (account) {
+        let rep = this.jami.blockContact(req.params.accountId, req.params.contactId);
+        res.json(rep);
+      } else res.status(404).end();
+      res.status(200).end();
+    });
 
-        accountRouter.delete('/contacts/block/:contactId/', async (req, res) => {
-            console.log('REMOVED AND BLOCKED CONTACT: ', req.params.contactId)
-            const account = this.jami.getAccount(req.params.accountId)
-            if (account) {
-                let rep = this.jami.blockContact(
-                    req.params.accountId,
-                    req.params.contactId
-                )
-                res.json(rep)
-            } else res.status(404).end()
-            res.status(200).end()
-        })
+    // Default modertors
+    accountRouter.put('/defaultModerators/:contactId', async (req, res) => {
+      console.log(`Adding default moderator ${req.params.contactId} to account ${req.params.accountId}`);
+      this.jami.addDefaultModerator(req.params.accountId, req.params.contactId);
+      res.status(200).end();
+    });
 
+    accountRouter.delete('/defaultModerators/:contactId', async (req, res) => {
+      console.log(`Removing default moderator to account ${req.params.accountId}`);
+      this.jami.removeDefaultModerator(req.params.accountId, req.params.contactId);
+      res.status(200).end();
+    });
 
-        // Default modertors
-        accountRouter.put('/defaultModerators/:contactId', async (req, res) => {
-            console.log(
-                `Adding default moderator ${req.params.contactId} to account ${req.params.accountId}`
-            )
-            this.jami.addDefaultModerator(
-                req.params.accountId,
-                req.params.contactId
-            )
-            res.status(200).end()
-        })
-
-        accountRouter.delete(
-            '/defaultModerators/:contactId',
-            async (req, res) => {
-                console.log(
-                    `Removing default moderator to account ${req.params.accountId}`
-                )
-                this.jami.removeDefaultModerator(
-                    req.params.accountId,
-                    req.params.contactId
-                )
-                res.status(200).end()
-            }
+    // Conversations
+    accountRouter.get('/conversations', async (req, res, next) => {
+      console.log(`Get conversations for account ${req.params.accountId}`);
+      const account = this.jami.getAccount(req.params.accountId);
+      if (!account) return res.sendStatus(404);
+      const conversations = account.getConversations();
+      res.json(
+        await Promise.all(
+          Object.keys(conversations).map(
+            async (conversationId) =>
+              await conversations[conversationId].getObject({
+                memberFilter: (member) => member.contact.getUri() !== account.getUri(),
+              })
+          )
         )
+      );
+      //res.json(account.getConversations())
+    });
 
-        // Conversations
-        accountRouter.get('/conversations', async (req, res, next) => {
-            console.log(`Get conversations for account ${req.params.accountId}`)
-            const account = this.jami.getAccount(req.params.accountId)
-            if (!account) return res.sendStatus(404)
-            const conversations = account.getConversations()
-            res.json(
-                await Promise.all(
-                    Object.keys(conversations).map(
-                        async (conversationId) =>
-                            await conversations[conversationId].getObject({
-                                memberFilter: (member) =>
-                                    member.contact.getUri() !== account.getUri(),
-                            })
-                    )
-                )
-            )
-        //res.json(account.getConversations())
+    accountRouter.post('/conversations', (req, res) => {
+      console.log(`Create conversations for account, contact ${req.params.accountId}`);
+      // console.log(req.body)
+      const account = this.jami.getAccount(req.params.accountId);
+      if (!account) return res.sendStatus(404);
+      if (req.body.members.length === 1) {
+        const details = this.jami.addContact(req.params.accountId, req.body.members[0]);
+        res.json(details);
+      } else res.status(400).end();
+    });
+
+    accountRouter.post('/conversations/:conversationId', async (req, res) => {
+      console.log(`Sending message to ${req.params.conversationId} for account ${req.params.accountId}`);
+      this.jami.sendMessage(req.params.accountId, req.params.conversationId, req.body.message);
+      res.status(200).end();
+    });
+
+    accountRouter.get('/conversations/:conversationId', async (req, res) => {
+      console.log(`Get conversation ${req.params.conversationId} for account ${req.params.accountId}`);
+      const account = this.jami.getAccount(req.params.accountId);
+      if (!account) return res.sendStatus(404);
+      const conversation = account.getConversation(req.params.conversationId);
+      if (!conversation) res.status(404).end();
+      else {
+        res.json(
+          await conversation.getObject({
+            memberFilter: (member) => member.contact.getUri() !== account.getUri(),
+          })
+        );
+      }
+    });
+
+    accountRouter.get('/conversations/:conversationId/messages', async (req, res) => {
+      console.log(`Get messages for conversation ${req.params.conversationId} for account ${req.params.accountId}`);
+      try {
+        const messages = await this.jami.loadMessages(req.params.accountId, req.params.conversationId);
+        res.json(messages).end();
+      } catch (e) {
+        res.status(400).json({ error: e.message });
+      }
+    });
+
+    // Calls
+
+    accountRouter.get('/calls', async (req, res) => {
+      console.log(`Get calls for account ${req.params.accountId}`);
+      try {
+        const calls = await this.jami.getCalls(req.params.accountId);
+        res.json(calls).end();
+      } catch (e) {
+        res.status(400).json({ error: e.message });
+      }
+    });
+
+    accountRouter.get('/calls/:callId', async (req, res) => {
+      console.log(`Get call ${req.params.callId} for account ${req.params.accountId}`);
+      try {
+        const messages = await this.jami.getCall(req.params.accountId, req.params.callId);
+        res.json(messages).end();
+      } catch (e) {
+        res.status(400).json({ error: e.message });
+      }
+    });
+
+    // Nameserver
+    const nsRouter = Router({ mergeParams: true });
+    accountRouter.use('/ns', nsRouter); // use account nameserver
+    router.use('/ns', nsRouter); // use default nameserver
+
+    nsRouter.get(['/name/:nameQuery'], (req, res, next) => {
+      console.log(`Name lookup ${req.params.nameQuery}`);
+      this.jami
+        .lookupName(req.params.accountId || '', req.params.nameQuery)
+        .then((result) => {
+          if (result.state == 0) res.json(result);
+          else if (result.state == 1) res.status(400).json({});
+          else res.status(404).json({});
         })
+        .catch((e) => {
+          res.status(404).json({});
+        });
+    });
 
-        accountRouter.post('/conversations', (req, res) => {
-            console.log(
-                `Create conversations for account, contact ${req.params.accountId}`
-            )
-            // console.log(req.body)
-            const account = this.jami.getAccount(req.params.accountId)
-            if (!account) return res.sendStatus(404)
-            if (req.body.members.length === 1) {
-                const details = this.jami.addContact(
-                    req.params.accountId,
-                    req.body.members[0]
-                )
-                res.json(details)
-            } else res.status(400).end()
+    nsRouter.get(['/addr/:addrQuery'], (req, res, next) => {
+      console.log(`Address lookup ${req.params.addrQuery}`);
+      this.jami
+        .lookupAddress(req.params.accountId || '', req.params.addrQuery)
+        .then((result) => {
+          if (result.state == 0) res.json(result);
+          else if (result.state == 1) res.status(400).json({});
+          else res.status(404).json({});
         })
+        .catch((e) => {
+          res.status(404).json({});
+        });
+    });
 
-        accountRouter.post('/conversations/:conversationId', async (req, res) => {
-            console.log(
-                `Sending message to ${req.params.conversationId} for account ${req.params.accountId}`
-            )
-            this.jami.sendMessage(
-                req.params.accountId,
-                req.params.conversationId,
-                req.body.message
-            )
-            res.status(200).end()
-        })
-
-        accountRouter.get('/conversations/:conversationId', async (req, res) => {
-            console.log(
-                `Get conversation ${req.params.conversationId} for account ${req.params.accountId}`
-            )
-            const account = this.jami.getAccount(req.params.accountId)
-            if (!account) return res.sendStatus(404)
-            const conversation = account.getConversation(req.params.conversationId)
-            if (!conversation) res.status(404).end()
-            else {
-                res.json(
-                    await conversation.getObject({
-                        memberFilter: (member) =>
-                            member.contact.getUri() !== account.getUri(),
-                    })
-                )
-            }
-        })
-
-        accountRouter.get(
-            '/conversations/:conversationId/messages',
-            async (req, res) => {
-                console.log(
-                    `Get messages for conversation ${req.params.conversationId} for account ${req.params.accountId}`
-                )
-                try {
-                    const messages = await this.jami.loadMessages(
-                        req.params.accountId,
-                        req.params.conversationId
-                    )
-                    res.json(messages).end()
-                } catch (e) {
-                    res.status(400).json({ error: e.message })
-                }
-            }
-        )
-
-        // Calls
-
-        accountRouter.get('/calls', async (req, res) => {
-            console.log(`Get calls for account ${req.params.accountId}`)
-            try {
-                const calls = await this.jami.getCalls(req.params.accountId)
-                res.json(calls).end()
-            } catch (e) {
-                res.status(400).json({ error: e.message })
-            }
-        })
-
-        accountRouter.get('/calls/:callId', async (req, res) => {
-            console.log(`Get call ${req.params.callId} for account ${req.params.accountId}`)
-            try {
-                const messages = await this.jami.getCall(
-                    req.params.accountId,
-                    req.params.callId
-                )
-                res.json(messages).end()
-            } catch (e) {
-                res.status(400).json({ error: e.message })
-            }
-        })
-
-        // Nameserver
-        const nsRouter = Router({ mergeParams: true })
-        accountRouter.use('/ns', nsRouter) // use account nameserver
-        router.use('/ns', nsRouter) // use default nameserver
-
-        nsRouter.get(['/name/:nameQuery'], (req, res, next) => {
-            console.log(`Name lookup ${req.params.nameQuery}`)
-            this.jami
-                .lookupName(req.params.accountId || '', req.params.nameQuery)
-                .then((result) => {
-                    if (result.state == 0) res.json(result)
-                    else if (result.state == 1) res.status(400).json({})
-                    else res.status(404).json({})
-                })
-                .catch((e) => {
-                    res.status(404).json({})
-                })
-        })
-
-        nsRouter.get(['/addr/:addrQuery'], (req, res, next) => {
-            console.log(`Address lookup ${req.params.addrQuery}`)
-            this.jami
-                .lookupAddress(req.params.accountId || '', req.params.addrQuery)
-                .then((result) => {
-                    if (result.state == 0) res.json(result)
-                    else if (result.state == 1) res.status(400).json({})
-                    else res.status(404).json({})
-                })
-                .catch((e) => {
-                    res.status(404).json({})
-                })
-        })
-
-        return router
-    }
+    return router;
+  }
 }
 
-export default JamiRestApi
+export default JamiRestApi;
