diff --git a/app.ts b/app.ts
new file mode 100644
index 0000000..eea1786
--- /dev/null
+++ b/app.ts
@@ -0,0 +1,345 @@
+'use strict'
+
+import dotenv from 'dotenv'
+const env = dotenv.config()
+
+import { promises as fs } from 'fs'
+import http from 'http'
+import express from 'express'
+import session from 'express-session'
+import cookieParser  from'cookie-parser'
+import { Server } 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);
+
+//const redis = require('redis-url').connect()
+//const RedisStore = require('connect-redis')(session)
+/*const passportSocketIo = require('passport.socketio')*/
+
+import indexRouter from './routes/index.js'
+
+import cors from 'cors'
+
+import JamiRestApi from './routes/jami.js'
+import JamiDaemon from './JamiDaemon.js'
+// import { sentrySetUp } from './sentry.js'
+
+const configPath = 'jamiServerConfig.json'
+
+//const sessionStore = new RedisStore({ client: redis })
+const sessionStore = new session.MemoryStore()
+
+const loadConfig = async (filePath) => {
+    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, 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 😁')
+}
+
+function logFail() {
+    console.log('passportSocketIo failed to authorized user 👺')
+}
+
+/*
+
+tempAccounts holds users accounts while tempting to authenticate them on Jams.
+connectedUsers  holds users accounts after they got authenticated by Jams.
+
+Users should be removed from connectedUsers when receiving a disconnect
+web socket call
+
+*/
+const tempAccounts = {}
+const connectedUsers = {}
+
+const createServer = async (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'
+    }
+
+    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') as any
+
+        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')
+
+    const sessionMiddleware = session({
+        store: sessionStore,
+        resave: false,
+        saveUninitialized: true,
+        cookie: {
+            secure: false,//!development,
+            maxAge: 2419200000
+        },
+        secret: process.env.SECRET_KEY_BASE
+    })
+
+    app.use(sessionMiddleware)
+    app.use(passport.initialize())
+    app.use(passport.session())
+    // app.use(app.router)
+    app.use(cors(corsOptions))
+
+    const jami = new JamiDaemon((account, conversation, message) => {
+        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,
+        store: sessionStore,
+        passport: passport,
+        cookieParser: cookieParser,
+        //success: logSuccess(),
+        // fail: logFail(),
+    }))
+    */
+
+    const isSetupComplete = () => {
+        return 'admin' in appConfig.users
+    }
+
+    const accountFilter = filter => {
+        if (typeof filter === 'string') {
+            if (filter === '*')
+                return undefined
+            else
+                return account => account.getId() === filter
+        } else if (Array.isArray(filter)) {
+            return account => filter.includes(account.getId())
+        } else {
+            throw new Error('Invalid account filter string')
+        }
+    }
+
+    const user = (id, config) => {
+        return {
+            id,
+            config,
+            username: config.username || id,
+            accountFilter: accountFilter(config.accounts)
+        }
+    }
+
+    passport.serializeUser((user, done) => {
+        connectedUsers[user.id] = user.config
+        console.log('=============================SerializeUser called ' + user.id)
+        console.log(user)
+        done(null, user.id)
+    })
+
+    const deserializeUser = (id, done) => {
+        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.' })
+            }
+            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, res, next) => {
+        if (req.user) {
+            return next()
+        }
+        res.status(401).end()
+    }
+    const securedRedirect = (req, res, next) => {
+        if (req.user && req.user.accountId) {
+            return next()
+        }
+        req.session.returnTo = req.originalUrl
+        res.redirect('/login')
+    }
+
+    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.id })
+    })
+
+    const getState = req => {
+        if (req.user) {
+            return { loggedin: true, username: req.user.username, type: req.user.type }
+        } else if (isSetupComplete()) {
+            return {}
+        } else {
+            return { setupComplete: false }
+        }
+    }
+
+    // sentrySetUp(app);
+
+    app.get('/auth', (req, res) => {
+        const state = getState(req)
+        if (req.user) {
+            res.json(state)
+        } else {
+            res.status(401).json(state)
+        }
+    })
+
+    app.use('/api', secured, apiRouter)
+
+    app.use('/', indexRouter)
+
+    /* GET React App */
+
+    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)
+
+    const io = new Server(server, { cors: corsOptions })
+    const wrap = middleware => (socket, next) => 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()
+        })
+    })
+
+    return server
+}
+
+loadConfig(configPath)
+    .then(createServer)
+    .then(server => {
+        server.listen(3000)
+    })
