use ESM, add server setup, cleanup
Change-Id: Iafac35c2082523ae98c31017d9bad5c4d6e18ef3
diff --git a/app.js b/app.js
index 0c92661..ef03a00 100644
--- a/app.js
+++ b/app.js
@@ -1,46 +1,63 @@
-require('dotenv').config()
+'use strict'
-const express = require('express')
-const http = require('http')
-const session = require('express-session')
+import dotenv from 'dotenv'
+dotenv.config()
+
+import { promises as fs } from 'fs'
+import http from 'http'
+import express from 'express'
+import session from 'express-session'
//const cookieParser = require('cookie-parser')
//const io = require('socket.io')(server)
-const path = require('path')
-const passport = require('passport')
- , LocalStrategy = require('passport-local').Strategy
+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);
+import { fileURLToPath } from 'url';
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
//const redis = require('redis-url').connect()
//const RedisStore = require('connect-redis')(session)
/*const passportSocketIo = require('passport.socketio')*/
-const indexRouter = require('./routes/index')
+import indexRouter from './routes/index.js'
//const cors = require('cors')
-const JamiRestApi = require('./routes/jami')
-const JamiDaemon = require('./JamiDaemon')
+import JamiRestApi from './routes/jami.js'
+import JamiDaemon from './JamiDaemon.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 JSON.parse(await fs.readFile(filePath))
- } catch {
- return {}
+ return Object.assign(config, JSON.parse(await fs.readFile(filePath)))
+ } 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 😁");
+ console.log("passportSocketIo authorized user with Success 😁")
}
function logFail() {
- console.log("passportSocketIo failed to authorized user 👺");
+ console.log("passportSocketIo failed to authorized user 👺")
}
/*
@@ -52,8 +69,8 @@
web socket call
*/
-const tempAccounts = {};
-const connectedUsers = {};
+const tempAccounts = {}
+const connectedUsers = {}
const createServer = async (appConfig) => {
const app = express()
@@ -62,19 +79,23 @@
const development = app.get('env') === 'development'
if (development) {
- const webpack = require('webpack')
- const webpackConfig = require('./client/webpack.config.js')
- const compiler = webpack(webpackConfig)
- app.use(require('webpack-dev-middleware')(compiler, {
- publicPath: webpackConfig.output.publicPath
- }));
- app.use(require('webpack-hot-middleware')(compiler));
+ const [ webpack, webpackDev, webpackHot, webpackConfig ] = await Promise.all([
+ import('webpack'),
+ import('webpack-dev-middleware'),
+ import('webpack-hot-middleware'),
+ import('./client/webpack.config.js')
+ ])
+ const compiler = webpack.default(webpackConfig.default)
+ app.use(webpackDev.default(compiler, {
+ publicPath: webpackConfig.default.output.publicPath
+ }))
+ app.use(webpackHot.default(compiler))
}
/*
Configuation for Passeport Js
*/
- app.disable('x-powered-by');
+ app.disable('x-powered-by')
app.use(session({
store: sessionStore,
@@ -85,13 +106,13 @@
maxAge: 2419200000
},
secret: process.env.SECRET_KEY_BASE
- }));
- app.use(passport.initialize());
- app.use(passport.session());
- // app.use(app.router);
+ }))
+ app.use(passport.initialize())
+ app.use(passport.session())
+ // app.use(app.router)
//app.use(cors())
- const jami = new JamiDaemon();
+ const jami = new JamiDaemon()
const apiRouter = new JamiRestApi(jami).getRouter()
/*
@@ -103,166 +124,204 @@
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)
- connectedUsers[user.accountId] = user;
- console.log("=============================SerializeUser called " + user.accountId)
- done(null, user.accountId);
- });
+ done(null, user.id)
+ })
const deserializeUser = (id, done) => {
- console.log("=============================DeserializeUser called on: " + id + " " + connectedUsers[id])
- done(null, connectedUsers[id]);
- };
- passport.deserializeUser(deserializeUser);
-
- //var tempAccountId = '';
+ 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(
(username, password, done) => {
-
- const newUser = {};
- newUser.username = username;
- //newUser.socketid =
-
const accountId = 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 }
- const newProps = jami.getAccount(accountId).details;
- console.log(newProps);
- //Object.entries(newProps).forEach(v => console.log(v[0], v[1]))
- //tempAccountId = accountId;
- newUser.accountId = accountId;
- console.log("AccountId: " + accountId);
- connectedUsers[accountId] = newUser;
- tempAccounts[accountId] = { done, newUser };
-
- //return done(null, newUser);
-
- /*User.findOne({ username: username }, function (err, user) {
- if (err) { return done(err); }
- if (!user) {
- return done(null, false, { message: 'Incorrect username.' });
- }
- if (!user.validPassword(password)) {
- return done(null, false, { message: 'Incorrect password.' });
- }
- return done(null, user);
- });*/
}
- );
- jamsStrategy.name = "jams";
+ )
+ jamsStrategy.name = "jams"
const localStrategy = new LocalStrategy(
(username, password, done) => {
- console.log("localStrategy: " + username + " " + password);
+ console.log("localStrategy: " + username + " " + password)
- const newUser = {};
- newUser.accountId = jami.getAccountList()[0].getId();
- console.log("Local AccountId: " + newUser.accountId);
- connectedUsers[newUser.accountId] = newUser;
- done(null, newUser);
+ 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);
+ passport.use(jamsStrategy)
+ passport.use(localStrategy)
const secured = (req, res, next) => {
- console.log(`isSecured ${req.user}`);
- if (req.user && req.user.accountId) {
- return next();
+ if (req.user) {
+ return next()
}
res.status(401).end()
- };
+ }
const securedRedirect = (req, res, next) => {
if (req.user && req.user.accountId) {
- return next();
+ return next()
}
- req.session.returnTo = req.originalUrl;
- res.redirect('/login');
- };
+ req.session.returnTo = req.originalUrl
+ res.redirect('/login')
+ }
- app.post('/auth', passport.authenticate('jams'), (req, res) => {
+ 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/localLogin', passport.authenticate('local'), (req, res) => {
- res.json({ loggedin: true })
- });
+ })
+ app.post('/auth/local', passport.authenticate('local'), (req, res) => {
+ res.json({ loggedin: true, user: req.user.id })
+ })
+ app.get('/auth', (req, res) => {
+ if (req.user) {
+ res.json({ loggedin: true, username: req.user.username, type: req.user.type })
+ } else if (isSetupComplete()) {
+ res.status(401).json({})
+ } else {
+ res.status(401).json({ setupComplete: false })
+ }
+ })
- app.use('/api', secured, apiRouter);
+ app.use('/api', secured, apiRouter)
- app.use('/', indexRouter);
+ app.use('/', indexRouter)
/* GET React App */
app.use(express.static(path.join(__dirname, 'client', 'dist')))
app.use((req, res, next) => {
- res.sendFile(path.join(__dirname, 'client', 'dist', 'index.html'));
- });
+ res.sendFile(path.join(__dirname, 'client', 'dist', 'index.html'))
+ })
- return http.Server(app);
+ return http.Server(app)
}
-loadConfig()
+loadConfig(configPath)
.then(createServer)
.then(server => {
- server.listen(3000);
+ server.listen(3000)
})
/*
io.on('connection', (socket) => {
console.log("Client just connected !")
socket.on('SendMessage', (data) => {
- console.log("Message " + data.text + " sent to " + data.destinationId + " by " + socket.session.user.accountId);
- const msgMap = new jami.dring.StringMap();
- msgMap.set('text/plain', data.text);
- jami.dring.sendAccountTextMessage(socket.session.user.accountId, data.destinationId, msgMap);
- });
-});
+ console.log("Message " + data.text + " sent to " + data.destinationId + " by " + socket.session.user.accountId)
+ const msgMap = new jami.dring.StringMap()
+ msgMap.set('text/plain', data.text)
+ jami.dring.sendAccountTextMessage(socket.session.user.accountId, data.destinationId, msgMap)
+ })
+})
io.use((socket, next) => {
cookieParser(socket.handshake, {}, (err) => {
if (err) {
- console.log("error in parsing cookie");
- return next(err);
+ console.log("error in parsing cookie")
+ return next(err)
}
if (!socket.handshake.signedCookies) {
- console.log("no secureCookies|signedCookies found");
- return next(new Error("no secureCookies found"));
+ console.log("no secureCookies|signedCookies found")
+ return next(new Error("no secureCookies found"))
}
sessionStore.get(socket.handshake.signedCookies["connect.sid"], (err, session) => {
- socket.session = session;
- if (!err && !session) err = new Error('session not found');
+ socket.session = session
+ if (!err && !session) err = new Error('session not found')
if (err) {
- console.log('failed connection to socket.io:', err);
+ console.log('failed connection to socket.io:', err)
} else {
- console.log(session);
- console.log('successful connection to socket.io ' + session.passport.user);
- const userKey = session.passport.user;
+ console.log(session)
+ console.log('successful connection to socket.io ' + session.passport.user)
+ const userKey = session.passport.user
deserializeUser(userKey, (err, user) => {
console.log("deserializeUser: " + user)
if (err)
- return next(err, true);
+ return next(err, true)
if (!user)
- return next("User not found", false);
+ return next("User not found", false)
console.log("User associated socket id: " + socket.id)
- user.socketId = socket.id;
- socket.session.user = user;
- console.log("User added to session --------> " + user.accountId);
- //auth.success(data, accept);
- next(err, true);
- });
+ user.socketId = socket.id
+ socket.session.user = user
+ console.log("User added to session --------> " + user.accountId)
+ //auth.success(data, accept)
+ next(err, true)
+ })
}
- });
- });
-});
+ })
+ })
+})
*/