blob: 5f616cd82e66e7633d461efc5c2c5406e740844b [file] [log] [blame]
Larbi Gharibe9af9732021-03-31 15:08:01 +01001require('dotenv/config');
2
3const express = require('express')
4const app = express();
5const server = require('http').Server(app);
6const session = require('express-session')
7const io = require('socket.io')(server);
8const path = require('path');
9
10//const redis = require('redis')
11const redis = require('redis-url').connect();
12const RedisStore = require('connect-redis')(session)
13/*var passportSocketIo = require('passport.socketio');*/
14//const cookieParser = require('cookie-parser');
15const cookieParser = require('cookie-parser')(process.env.SECRET_KEY_BASE); // <- your secret here
16
17var indexRouter = require('./routes/index');
18//const cors = require('cors')
19
20var parser = require('fast-xml-parser');
21
22const RingDaemon = require('./RingDaemon.js');
23const passport = require('passport')
24 , LocalStrategy = require('passport-local').Strategy;
25
26const sessionStore = new RedisStore({ client: redis });
27
28
29/*
30 Configuation for Passeport Js
31*/
32
33// app.use(express.static('public'));
34// app.use(cookieParser());
35// app.use(bodyParser());
36app.use(session({
37 store: sessionStore,
38 resave: false,
39 saveUninitialized: false,
40 cookie: {
41 secure: process.env.ENVIRONMENT !== 'development' && process.env.ENVIRONMENT !== 'test',
42 maxAge: 2419200000
43 },
44 secret: process.env.SECRET_KEY_BASE
45}));
46
47app.use(passport.initialize());
48app.use(passport.session());
49// app.use(app.router);
50//app.use(cors())
51
52/*
53 Share sessions between Passport.js and Socket.io
54*/
55
56function logSuccess() {
57 console.log("passportSocketIo authorized user with Success 😁");
58}
59
60function logFail() {
61 console.log("passportSocketIo failed to authorized user 👺");
62}
63
64/*
65io.use(passportSocketIo.authorize({
66 key: 'connect.sid',
67 secret: process.env.SECRET_KEY_BASE,
68 store: sessionStore,
69 passport: passport,
70 cookieParser: cookieParser,
71 //success: logSuccess(),
72 // fail: logFail(),
73}));
74*/
75
76/*
77
78 tempAccounts holds users accounts while tempting to authenticate them on Jams.
79 connectedUsers holds users accounts after they got authenticated by Jams.
80
81 Users should be removed from connectedUsers when receiving a disconnect
82 web socket call
83
84*/
85const tempAccounts = {};
86const connectedUsers = {};
87
88const callbackMap = {
89 "IncomingAccountMessage": (accountId, from, message) => {
90 console.log("Received message: " + accountId + " " + from + " " + message["text/plain"]);
91
92 if (parser.validate(message["text/plain"]) === true) {
93 console.log(message["text/plain"]);
94 } else {
95
96 user = connectedUsers[accountId];
97 console.log(user.socketId)
98 io.to(user.socketId).emit('receivedMessage', message["text/plain"]);
99 //io.emit('receivedMessage', message["text/plain"]);
100 }
101 },
102 "RegistrationStateChanged": (accountId, state, /*int*/ code, detail) => {
103 console.log("RegistrationStateChanged: " + accountId + " " + state + " " + code + " " + detail);
104 if (state === "REGISTERED") {
105 if (tempAccounts[accountId]) {
106
107 const ctx = tempAccounts[accountId];
108 ctx.newUser.accountId = accountId;
109 ctx.newUser.jamiId = jami.dring.getAccountDetails(accountId).get("Account.username");
110 //connectedUsers[accountId] = ctx.newUser;
111 ctx.done(null, ctx.newUser);
112 delete tempAccounts[accountId];
113 }
114 } else if (state === "ERROR_AUTH") {
115 done(null, false);
116 //remove account
117 }
118 }
119}
120const jami = new RingDaemon(callbackMap);
121
122passport.serializeUser(function (user, done) {
123 console.log(user)
124 connectedUsers[user.accountId] = user;
125 console.log("=============================SerializeUser called " + user.accountId)
126 done(null, user.accountId);
127});
128
129
130const deserializeUser = (id, done) => {
131 console.log("=============================DeserializeUser called on: " + id + " " + connectedUsers[id])
132 done(null, connectedUsers[id]);
133};
134passport.deserializeUser(deserializeUser);
135
136//var tempAccountId = '';
137
138passport.use(new LocalStrategy(
139 (username, password, done) => {
140 const newUser = {};
141 newUser.username = username;
142 //newUser.socketid =
143
144 const template = jami.dring.getAccountTemplate("RING");
145
146 /*
147 For test purpose we are not checking if a user can SSO using Jams,
148 instead we juste create a new user an get he's or her's newly created accountId
149 */
150 template.set("Account.managerUri", "https://jams.savoirfairelinux.com");
151 template.set("Account.managerUsername", username);
152 template.set("Account.archivePassword", password);
153
154 const accountId = jami.dring.addAccount(template);
155
156 const newProps = jami.getAccountDetails(accountId);
157 console.log(newProps);
158 //Object.entries(newProps).forEach(v => console.log(v[0], v[1]))
159 //tempAccountId = accountId;
160 newUser.accountId = accountId;
161 console.log("AccountId: " + accountId);
162 connectedUsers[accountId] = newUser;
163 tempAccounts[accountId] = { done, newUser };
164
165 //return done(null, newUser);
166
167 /*User.findOne({ username: username }, function (err, user) {
168 if (err) { return done(err); }
169 if (!user) {
170 return done(null, false, { message: 'Incorrect username.' });
171 }
172 if (!user.validPassword(password)) {
173 return done(null, false, { message: 'Incorrect password.' });
174 }
175 return done(null, user);
176 });*/
177 }
178));
179
180app.post('/api/login', passport.authenticate('local'), function (req, res) {
181 res.json({ loggedin: true });
182});
183app.use('/', indexRouter);
184
185/* GET React App */
186
187app.use(express.static(path.join(__dirname, 'public')))
188
189app.use(function (req, res, next) {
190 res.sendFile(path.join(__dirname, 'public', 'index.html'));
191});
192
193server.listen(3000);
194
195io.on('connection', (socket) => {
196 console.log("Client just connected !")
197 socket.on('SendMessage', (data) => {
198 console.log("Message " + data.text + " sent to " + data.destinationId + " by " + socket.session.user.accountId);
199 const msgMap = new jami.dring.StringMap();
200 msgMap.set('text/plain', data.text);
201 jami.dring.sendAccountTextMessage(socket.session.user.accountId, data.destinationId, msgMap);
202 });
203});
204
205
206io.use((socket, next) => {
207 cookieParser(socket.handshake, {}, (err) => {
208 if (err) {
209 console.log("error in parsing cookie");
210 return next(err);
211 }
212 if (!socket.handshake.signedCookies) {
213 console.log("no secureCookies|signedCookies found");
214 return next(new Error("no secureCookies found"));
215 }
216 sessionStore.get(socket.handshake.signedCookies["connect.sid"], (err, session) => {
217 socket.session = session;
218 if (!err && !session) err = new Error('session not found');
219 if (err) {
220 console.log('failed connection to socket.io:', err);
221 } else {
222 console.log(session);
223 console.log('successful connection to socket.io ' + session.passport.user);
224 const userKey = session.passport.user;
225 deserializeUser(userKey, (err, user) => {
226 console.log("deserializeUser: " + user)
227 if (err)
228 return next(err, true);
229 if (!user)
230 return next("User not found", false);
231
232 console.log("User associated socket id: " + socket.id)
233 user.socketId = socket.id;
234 socket.session.user = user;
235 console.log("User added to session --------> " + user.accountId);
236 /*data[auth.userProperty] = user;
237 data[auth.userProperty].logged_in = true;*/
238 //auth.success(data, accept);
239 next(err, true);
240 });
241 }
242 });
243 });
244});