diff --git a/app.ts b/app.ts
index 450f33c..8ec27f3 100644
--- a/app.ts
+++ b/app.ts
@@ -1,17 +1,16 @@
-'use strict'
+'use strict';
 
-import dotenv from 'dotenv'
-const env = dotenv.config()
+import dotenv from 'dotenv';
+const env = dotenv.config();
 
-import { promises as fs } from 'fs'
-import http from 'http'
-import express, {NextFunction, Response, Request} from 'express'
-import session from 'express-session'
-import cookieParser  from'cookie-parser'
-import {Server, Socket} from 'socket.io'
-import path from 'path'
-import passport from 'passport'
-import { Strategy as LocalStrategy } from 'passport-local'
+import { promises as fs } from 'fs';
+import http from 'http';
+import express, { NextFunction, Response, Request } from 'express';
+import session from 'express-session';
+import { Server, Socket } from 'socket.io';
+import path from 'path';
+import passport from 'passport';
+import { Strategy as LocalStrategy } from 'passport-local';
 //import { createRequire } from 'module';
 //const require = createRequire(import.meta.url);
 
@@ -19,57 +18,57 @@
 //const RedisStore = require('connect-redis')(session)
 /*const passportSocketIo = require('passport.socketio')*/
 
-import indexRouter from './routes/index.js'
+import indexRouter from './routes/index.js';
 
-import cors from 'cors'
+import cors from 'cors';
 
-import JamiRestApi from './routes/jami.js'
-import JamiDaemon from './JamiDaemon.js'
-import Account from "./model/Account";
-import {ExtendedError} from "socket.io/dist/namespace";
+import JamiRestApi from './routes/jami.js';
+import JamiDaemon from './JamiDaemon.js';
+import Account from './model/Account';
+import { ExtendedError } from 'socket.io/dist/namespace';
 // import { sentrySetUp } from './sentry.js'
 
-const configPath = 'jamiServerConfig.json'
+const configPath = 'jamiServerConfig.json';
 
 //const sessionStore = new RedisStore({ client: redis })
-const sessionStore = new session.MemoryStore()
+const sessionStore = new session.MemoryStore();
 
 interface UserConfig {
   accounts: string;
   password?: string;
   username?: string;
-  type?: string
+  type?: string;
 }
 
 interface AppConfig {
-  users: Record<string, UserConfig>
-  authMethods: any[]
+  users: Record<string, UserConfig>;
+  authMethods: any[];
 }
 
 const loadConfig = async (filePath: string): Promise<AppConfig> => {
-    const config = {users: {}, authMethods: []}
-    try {
-        return Object.assign(config, JSON.parse((await fs.readFile(filePath)).toString()))
-    } catch(e) {
-        console.log(e)
-        return config
-    }
-}
+  const config = { users: {}, authMethods: [] };
+  try {
+    return Object.assign(config, JSON.parse((await fs.readFile(filePath)).toString()));
+  } catch (e) {
+    console.log(e);
+    return config;
+  }
+};
 
 const saveConfig = (filePath: string, config: AppConfig) => {
-    return fs.writeFile(filePath, JSON.stringify(config))
-}
+  return fs.writeFile(filePath, JSON.stringify(config));
+};
 
 /*
 Share sessions between Passport.js and Socket.io
 */
 
 function logSuccess() {
-    console.log('passportSocketIo authorized user with Success 😁')
+  console.log('passportSocketIo authorized user with Success 😁');
 }
 
 function logFail() {
-    console.log('passportSocketIo failed to authorized user 👺')
+  console.log('passportSocketIo failed to authorized user 👺');
 }
 
 /*
@@ -81,72 +80,74 @@
 web socket call
 
 */
-const tempAccounts: Record<string, any> = {}
-const connectedUsers: Record<string, any> = {}
+const tempAccounts: Record<string, any> = {};
+const connectedUsers: Record<string, any> = {};
 
 const createServer = async (appConfig: AppConfig) => {
-    const node_env = process.env.NODE_ENV || 'development'
-    const app = express()
-    console.log(`Loading server for ${node_env} with config:`)
-    console.log(appConfig)
+  const node_env = process.env.NODE_ENV || 'development';
+  const app = express();
+  console.log(`Loading server for ${node_env} with config:`);
+  console.log(appConfig);
 
-    var corsOptions = {
-        origin: 'http://127.0.0.1:3000'
-    }
+  const corsOptions = {
+    origin: 'http://127.0.0.1:3000',
+  };
 
-    if (node_env === 'development') {
-        const webpack = await import('webpack')
-        const webpackDev = await import('webpack-dev-middleware')
-        const webpackHot = await import ('webpack-hot-middleware')
-        const {default: webpackConfig} = await import('jami-web-client/webpack.config.js')
+  if (node_env === 'development') {
+    const webpack = await import('webpack');
+    const webpackDev = await import('webpack-dev-middleware');
+    const webpackHot = await import('webpack-hot-middleware');
+    const { default: webpackConfig } = await import('jami-web-client/webpack.config.js');
 
-        const compiler = webpack.default(webpackConfig)
-        app.use(webpackDev.default(compiler, {
-            publicPath: webpackConfig.output?.publicPath
-        }))
-        app.use(webpackHot.default(compiler))
-    }
+    const compiler = webpack.default(webpackConfig);
+    app.use(
+      webpackDev.default(compiler, {
+        publicPath: webpackConfig.output?.publicPath,
+      })
+    );
+    app.use(webpackHot.default(compiler));
+  }
 
-    /*
+  /*
         Configuation for Passeport Js
     */
-    app.disable('x-powered-by')
+  app.disable('x-powered-by');
 
-    const secret_key = process.env.SECRET_KEY_BASE;
+  const secret_key = process.env.SECRET_KEY_BASE;
 
-    if (!secret_key) {
-        throw new Error("SECRET_KEY_BASE undefined")
+  if (!secret_key) {
+    throw new Error('SECRET_KEY_BASE undefined');
+  }
+
+  const sessionMiddleware = session({
+    store: sessionStore,
+    resave: false,
+    saveUninitialized: true,
+    cookie: {
+      secure: false, //!development,
+      maxAge: 2419200000,
+    },
+    secret: secret_key,
+  });
+
+  app.use(sessionMiddleware);
+  app.use(passport.initialize());
+  app.use(passport.session());
+  // app.use(app.router)
+  app.use(cors(corsOptions));
+
+  const jami = new JamiDaemon((account: Account, conversation: any, message: any) => {
+    console.log('JamiDaemon onMessage');
+
+    if (conversation.listeners) {
+      Object.values(conversation.listeners).forEach((listener: any) => {
+        listener.socket.emit('newMessage', message);
+      });
     }
+  });
+  const apiRouter = new JamiRestApi(jami).getRouter();
 
-    const sessionMiddleware = session({
-        store: sessionStore,
-        resave: false,
-        saveUninitialized: true,
-        cookie: {
-            secure: false,//!development,
-            maxAge: 2419200000
-        },
-        secret: secret_key
-    });
-
-    app.use(sessionMiddleware)
-    app.use(passport.initialize())
-    app.use(passport.session())
-    // app.use(app.router)
-    app.use(cors(corsOptions))
-
-    const jami = new JamiDaemon((account: Account, conversation: any, message: any) => {
-        console.log('JamiDaemon onMessage')
-
-        if (conversation.listeners) {
-            Object.values(conversation.listeners).forEach((listener: any) => {
-                listener.socket.emit('newMessage', message)
-            })
-        }
-    })
-    const apiRouter = new JamiRestApi(jami).getRouter()
-
-    /*
+  /*
     io.use(passportSocketIo.authorize({
         key: 'connect.sid',
         secret: process.env.SECRET_KEY_BASE,
@@ -158,209 +159,201 @@
     }))
     */
 
-    const isSetupComplete = () => {
-        return 'admin' in appConfig.users
+  const isSetupComplete = () => {
+    return 'admin' in appConfig.users;
+  };
+
+  const accountFilter = (filter: string | any[]) => {
+    if (typeof filter === 'string') {
+      if (filter === '*') return undefined;
+      else return (account: Account) => account.getId() === filter;
+    } else if (Array.isArray(filter)) {
+      return (account: Account) => filter.includes(account.getId());
+    } else {
+      throw new Error('Invalid account filter string');
     }
+  };
 
-    const accountFilter = (filter: string | any[]) => {
-        if (typeof filter === 'string') {
-            if (filter === '*')
-                return undefined
-            else
-                return (account: Account) => account.getId() === filter
-        } else if (Array.isArray(filter)) {
-            return (account: Account) => filter.includes(account.getId())
-        } else {
-            throw new Error('Invalid account filter string')
-        }
+  const user = (id: string, config: UserConfig) => {
+    return {
+      id,
+      config,
+      username: config.username || id,
+      accountFilter: accountFilter(config.accounts),
+    };
+  };
+
+  passport.serializeUser((user: any, done) => {
+    connectedUsers[user.id] = user.config;
+    console.log('=============================SerializeUser called ' + user.id);
+    console.log(user);
+    done(null, user.id);
+  });
+
+  const deserializeUser = (id: string, done: (err: any, user?: Express.User | false | null) => void) => {
+    console.log('=============================DeserializeUser called on: ' + id);
+    const userConfig = connectedUsers[id];
+    console.log(userConfig);
+    if (userConfig) {
+      done(null, user(id, userConfig));
+    } else done(404, null);
+  };
+  passport.deserializeUser(deserializeUser);
+
+  const jamsStrategy = new LocalStrategy(async (username, password, done) => {
+    const accountId = await jami.addAccount({
+      managerUri: 'https://jams.savoirfairelinux.com',
+      managerUsername: username,
+      archivePassword: password,
+    });
+    const id = `jams_${username}`;
+    const userConfig = { username, type: 'jams', accounts: accountId };
+    const newUser = user(id, userConfig);
+    console.log('AccountId: ' + accountId);
+    tempAccounts[accountId] = { done, newUser };
+  });
+  jamsStrategy.name = 'jams';
+
+  const localStrategy = new LocalStrategy((username, password, done) => {
+    console.log('localStrategy: ' + username + ' ' + password);
+
+    const id = username;
+    const userConfig = appConfig.users[username];
+    if (!userConfig) {
+      return done(null, false, { message: 'Incorrect username.' });
     }
-
-    const user = (id: string, config: UserConfig) => {
-        return {
-            id,
-            config,
-            username: config.username || id,
-            accountFilter: accountFilter(config.accounts)
-        }
+    if (userConfig.password !== password) {
+      return done(null, false, { message: 'Incorrect password.' });
     }
+    userConfig.type = 'local';
 
-    passport.serializeUser((user: any, done) => {
-        connectedUsers[user.id] = user.config
-        console.log('=============================SerializeUser called ' + user.id)
-        console.log(user)
-        done(null, user.id)
-    })
+    done(null, user(id, userConfig));
+  });
 
-    const deserializeUser = (id: string, done: (err: any, user?: Express.User | false | null) => void) => {
-        console.log('=============================DeserializeUser called on: ' + id)
-        const userConfig = connectedUsers[id]
-        console.log(userConfig)
-        if (userConfig) {
-            done(null, user(id, userConfig))
-        } else
-            done(404, null)
+  passport.use(jamsStrategy);
+  passport.use(localStrategy);
+
+  const secured = (req: Request, res: Response, next: NextFunction) => {
+    if (req.user) {
+      return next();
     }
-    passport.deserializeUser(deserializeUser)
-
-    const jamsStrategy = new LocalStrategy(
-        async (username, password, done) => {
-            const accountId = await jami.addAccount({
-                'managerUri': 'https://jams.savoirfairelinux.com',
-                'managerUsername': username,
-                'archivePassword': password
-            })
-            const id = `jams_${username}`
-            const userConfig = { username, type: 'jams', accounts: accountId }
-            const newUser = user(id, userConfig)
-            console.log('AccountId: ' + accountId)
-            tempAccounts[accountId] = { done, newUser }
-
-        }
-    )
-    jamsStrategy.name = 'jams'
-
-    const localStrategy = new LocalStrategy(
-        (username, password, done) => {
-            console.log('localStrategy: ' + username + ' ' + password)
-
-            const id = username
-            const userConfig = appConfig.users[username]
-            if (!userConfig) {
-                return done(null, false, { message: 'Incorrect username.' })
-            }
-            if (userConfig.password !== password) {
-                return done(null, false, { message: 'Incorrect password.' })
-            }
-            userConfig.type = 'local'
-
-            done(null, user(id, userConfig))
-        }
-    )
-
-    passport.use(jamsStrategy)
-    passport.use(localStrategy)
-
-    const secured = (req: Request, res: Response, next: NextFunction) => {
-        if (req.user) {
-            return next()
-        }
-        res.status(401).end()
+    res.status(401).end();
+  };
+  const securedRedirect = (req: Request, res: Response, next: NextFunction) => {
+    if (req.user && (req.user as any)?.accountId) {
+      return next();
     }
-    const securedRedirect = (req: Request, res: Response, next: NextFunction) => {
-        if (req.user && (req.user as any)?.accountId) {
-            return next()
-        }
-        (req.session as any).returnTo = req.originalUrl
-        res.redirect('/login')
+    (req.session as any).returnTo = req.originalUrl;
+    res.redirect('/login');
+  };
+
+  app.use(express.json());
+  app.post('/setup', (req, res) => {
+    if (isSetupComplete()) {
+      return res.status(404).end();
     }
-
-    app.use(express.json())
-    app.post('/setup', (req, res) => {
-        if (isSetupComplete()) {
-            return res.status(404).end()
-        }
-        if (!req.body.password) {
-            return res.status(400).end()
-        }
-        console.log(req.body)
-        appConfig.users.admin = {
-            'accounts': '*',
-            password: req.body.password
-        }
-        res.status(200).end()
-        saveConfig(configPath, appConfig)
-    })
-    app.post('/auth/jams', passport.authenticate('jams'), (req, res) => {
-        res.json({ loggedin: true })
-    })
-    app.post('/auth/local', passport.authenticate('local'), (req, res) => {
-        res.json({ loggedin: true, user: (req.user as any)?.id })
-    })
-
-    const getState = (req: Request) => {
-        if (req.user) {
-            const user = (req.user || {}) as UserConfig
-            return { loggedin: true, username: user.username, type: user.type }
-        } else if (isSetupComplete()) {
-            return {}
-        } else {
-            return { setupComplete: false }
-        }
+    if (!req.body.password) {
+      return res.status(400).end();
     }
+    console.log(req.body);
+    appConfig.users.admin = {
+      accounts: '*',
+      password: req.body.password,
+    };
+    res.status(200).end();
+    saveConfig(configPath, appConfig);
+  });
+  app.post('/auth/jams', passport.authenticate('jams'), (req, res) => {
+    res.json({ loggedin: true });
+  });
+  app.post('/auth/local', passport.authenticate('local'), (req, res) => {
+    res.json({ loggedin: true, user: (req.user as any)?.id });
+  });
 
-    // sentrySetUp(app);
+  const getState = (req: Request) => {
+    if (req.user) {
+      const user = (req.user || {}) as UserConfig;
+      return { loggedin: true, username: user.username, type: user.type };
+    } else if (isSetupComplete()) {
+      return {};
+    } else {
+      return { setupComplete: false };
+    }
+  };
 
-    app.get('/auth', (req, res) => {
-        const state = getState(req)
-        if (req.user) {
-            res.json(state)
-        } else {
-            res.status(401).json(state)
-        }
-    })
+  // sentrySetUp(app);
 
-    app.use('/api', secured, apiRouter)
+  app.get('/auth', (req, res) => {
+    const state = getState(req);
+    if (req.user) {
+      res.json(state);
+    } else {
+      res.status(401).json(state);
+    }
+  });
 
-    app.use('/', indexRouter)
+  app.use('/api', secured, apiRouter);
 
-    /* GET React App */
+  app.use('/', indexRouter);
 
-    const cwd = process.cwd()
-    app.use(express.static(path.join(cwd,  'client/dist')));
+  /* GET React App */
 
-    app.use((req, res) => {
-        res.render(path.join(cwd, 'client/dist/index.ejs'), {
-            initdata: JSON.stringify(getState(req))
-        })
-    })
+  const cwd = process.cwd();
+  app.use(express.static(path.join(cwd, 'client/dist')));
 
+  app.use((req, res) => {
+    res.render(path.join(cwd, 'client/dist/index.ejs'), {
+      initdata: JSON.stringify(getState(req)),
+    });
+  });
 
-    // @ts-ignore TODO: Fix the typescript error
-    const server = http.Server(app)
+  // @ts-ignore TODO: Fix the typescript error
+  const server = http.Server(app);
 
-    const io = new Server(server, { cors: corsOptions })
-    const wrap = (middleware: any) => (socket: Socket, next: (err?: ExtendedError) => void ) => middleware(socket.request, {}, next)
-    io.use(wrap(sessionMiddleware))
-    io.use(wrap(passport.initialize()))
-    io.use(wrap(passport.session()))
-    io.use((socket, next) => {
-        if ((socket.request as any).user) {
-            next()
-        } else {
-            next(new Error('unauthorized'))
-        }
-    })
-    io.on('connect', (socket) => {
-        console.log(`new connection ${socket.id}`)
-        const session = (socket.request as any).session
-        console.log(`saving sid ${socket.id} in session ${session.id}`)
-        session.socketId = socket.id
-        session.save()
+  const io = new Server(server, { cors: corsOptions });
+  const wrap = (middleware: any) => (socket: Socket, next: (err?: ExtendedError) => void) =>
+    middleware(socket.request, {}, next);
+  io.use(wrap(sessionMiddleware));
+  io.use(wrap(passport.initialize()));
+  io.use(wrap(passport.session()));
+  io.use((socket, next) => {
+    if ((socket.request as any).user) {
+      next();
+    } else {
+      next(new Error('unauthorized'));
+    }
+  });
+  io.on('connect', (socket) => {
+    console.log(`new connection ${socket.id}`);
+    const session = (socket.request as any).session;
+    console.log(`saving sid ${socket.id} in session ${session.id}`);
+    session.socketId = socket.id;
+    session.save();
 
-        socket.on('conversation', (data) => {
-            console.log('io conversation')
-            console.log(data)
-            if (session.conversation) {
-                console.log(`disconnect from old conversation ${session.conversation.conversationId}`)
-                const conversation = jami.getConversation(session.conversation.accountId, session.conversation.conversationId)
-                delete conversation.listeners[socket.id]
-            }
-            session.conversation = { accountId: data.accountId, conversationId: data.conversationId }
-            const conversation = jami.getConversation(data.accountId, data.conversationId)
-            if (!conversation.listeners)
-                conversation.listeners = {}
-            conversation.listeners[socket.id] = {
-                socket, session
-            }
-            session.save()
-        })
-    })
+    socket.on('conversation', (data) => {
+      console.log('io conversation');
+      console.log(data);
+      if (session.conversation) {
+        console.log(`disconnect from old conversation ${session.conversation.conversationId}`);
+        const conversation = jami.getConversation(session.conversation.accountId, session.conversation.conversationId);
+        delete conversation.listeners[socket.id];
+      }
+      session.conversation = { accountId: data.accountId, conversationId: data.conversationId };
+      const conversation = jami.getConversation(data.accountId, data.conversationId);
+      if (!conversation.listeners) conversation.listeners = {};
+      conversation.listeners[socket.id] = {
+        socket,
+        session,
+      };
+      session.save();
+    });
+  });
 
-    return server
-}
+  return server;
+};
 
 loadConfig(configPath)
-    .then(createServer)
-    .then(server => {
-        server.listen(3000)
-    })
+  .then(createServer)
+  .then((server) => {
+    server.listen(3000);
+  });
