· 4 years ago · Jan 27, 2021, 10:48 AM
1// FILE: controller/session.js
2
3const moment = require('moment');
4const bcrypt = require('bcryptjs');
5
6const pusher = require('../config/pusher');
7
8const Session = require('../models/Session');
9const Table = require('../models/Table');
10const Restaurant = require('../models/Restaurant');
11
12const today = moment().startOf('day');
13
14// @desc Start a session
15// @route POST /api/session/Start
16// @access Public
17// CHANGES: from frontend we need allowMultiple value to be passed here!
18exports.Start_Session = async (req, res, next) => {
19 try {
20 console.log(req.body);
21 const { restaurant, table, allowMultiple } = req.body;
22 const table_1 = await Table.findById(table);
23 const r = await Restaurant.findById(restaurant);
24 if (!r.Open_Now || !r.Authenticated) {
25 return res.status(404).json({
26 success: false,
27 msg: 'Restaurant Closed',
28 });
29 }
30 if (table_1.status === 'disabled') {
31 return res.status(400).json({
32 success: false,
33 msg: 'This QR code is disabled.',
34 });
35 }
36 const sess = await Session.findOne({
37 table: table,
38 active: true,
39 });
40 console.log(`allowMultiple: ${allowMultiple} `);
41 // for Single Session ONLY, ie if allowMultiple=false (for multiple, table.status always 'active')
42 if (!allowMultiple && sess && table_1.status === 'active') {
43 console.log(1);
44 return res.status(401).json({
45 success: false,
46 msg: 'The table is Engaged',
47 flag: -1,
48 join: sess._id, //Prompt User to Join Session by providing the Session Password
49 tableNo: table_1.tableNo,
50 Restaurant_Name: r.Name, // Prompt to set Session Password
51 verify: sess.verify,
52 Short_Address: r.Short_Address,
53 });
54 }
55
56 console.log(2);
57
58 const session = await Session.create(req.body);
59 const t = await Table.findById(table);
60 return res.status(200).json({
61 success: true,
62 data: session,
63 tableNo: t.tableNo,
64 Restaurant_Name: r.Name,
65 Short_Address: r.Short_Address, // Prompt to set Session Password
66 });
67 } catch (error) {
68 console.log(error);
69 return res.status(500).json({
70 success: false,
71 error: error,
72 });
73 }
74};
75
76// @desc Set nickname and password for a newly created session
77// @route POST /api/session/set_password/:session_id
78// @access Public
79// NOTE: as in v2, we want nickname to be unique!
80exports.Set_Session_Password = async (req, res, next) => {
81 try {
82 const { password, verify, allowMultiple } = req.body;
83 const { session_id } = req.params;
84 const salt = await bcrypt.genSalt(10);
85
86 // in case of multiple sessions, we want all nicknames to be unique!
87 if (allowMultiple) {
88 const _session = await Session.findOne({
89 verify,
90 allowMultiple: true,
91 isEnded: false,
92 });
93 // User with same nickname exists for an active session
94 // Current user should change his nickname
95 if (_session) {
96 return res.status(404).json({
97 success: false,
98 msg: `${verify} nickname is already in use! Please enter your ${verify} <lastname>`,
99 });
100 }
101 }
102
103 const encrypted_password = await bcrypt.hash(password, salt);
104
105 const session = await Session.findByIdAndUpdate(
106 session_id,
107 {
108 password: encrypted_password,
109 authentication_requested: true,
110 verify: verify,
111 Date_Ref: Date.now(),
112 },
113 {
114 new: true,
115 runValidators: true,
116 }
117 );
118 console.log(1);
119 if (!session) {
120 return res.status(404).json({
121 success: false,
122 msg: 'There seems to be some error',
123 });
124 }
125 const s = await Session.findById(session_id).populate('table');
126 pusher.trigger('session_request', s.restaurant, s);
127 return res.status(200).json({
128 success: true,
129 data: session,
130 });
131 } catch (error) {
132 return res.status(500).json({
133 success: false,
134 error: error,
135 });
136 }
137};
138
139// NOTE: Only called for single session!
140// @desc For single sessions, user wants to join his missed session via session_id and password
141// @route POST /api/session/Join_session/:session_id
142// @access Public
143exports.Join_Session = async (req, res, next) => {
144 try {
145 const { password } = req.body;
146 const { session_id } = req.params;
147 const session = await Session.findById(session_id);
148 if (!session) {
149 return res.status(404).json({
150 success: false,
151 msg: 'There seems to be some error',
152 });
153 }
154 if (!session.active) {
155 return res.status(404).json({
156 success: false,
157 msg: 'Session Already Closed!',
158 });
159 }
160 const compare = await bcrypt.compare(password, session.password);
161 if (!compare) {
162 return res
163 .status(400)
164 .json({ success: false, msg: 'Incorrect Credentials' });
165 }
166 return res.status(200).json({
167 success: true,
168 data: session,
169 });
170 } catch (error) {
171 return res.status(500).json({
172 success: false,
173 error: error,
174 });
175 }
176};
177
178// NOTE: Only called for multiple session!
179// @desc For multiple sessions, user wants to join his missed session via credentials
180// @route POST /api/session/JoinMultipleSession
181// @access Public
182exports.Join_Multiple_Session = async (req, res, next) => {
183 try {
184 // verify ~ nickname
185 const { verify, password } = req.body;
186 const session = await Session.findOne({
187 verify: verify,
188 allowMultiple: true,
189 isEnded: false,
190 });
191
192 // No session found with given nickname
193 if (!session) {
194 return res.status(404).json({
195 success: false,
196 msg: 'There seems to be some error',
197 });
198 }
199 console.log('A');
200 // Session found via nickname, but vendor closed the session
201 // User needs to create a new session
202 if (!session.active) {
203 return res.status(404).json({
204 success: false,
205 msg: 'Session Already Closed!. You need to create a new session',
206 });
207 }
208 console.log('B');
209
210 // validating user entered pwd with pwd stored in session
211 const isMatch = await bcrypt.compare(password, session.password);
212
213 // incorrect password entered by user
214 if (!isMatch) {
215 return res
216 .status(400)
217 .json({ success: false, msg: 'Incorrect Credentials' });
218 }
219
220 // Success!
221 // Session is active
222 // Credentials matched
223 // Let user enter his session
224 return res.status(200).json({
225 success: true,
226 data: session,
227 });
228 } catch (error) {
229 return res.status(500).json({
230 success: false,
231 error: error,
232 });
233 }
234};
235
236// @desc For single/multiple sessions, vendor approves the session
237// @route PUT /api/session/Authenticate_Session/:session_id/:table_id
238// @access Private
239exports.Authenticate_Session = async (req, res, next) => {
240 try {
241 const table_1 = await Table.findById(req.params.table_id);
242 if (!table_1.allowMultiple && table_1.status === 'active') {
243 console.log(2);
244 return res.status(200).json({
245 success: false,
246 msg: 'Dine-In has already begun on this Table',
247 });
248 }
249 var IndiaDate = new Date().toLocaleString('en-us', {
250 timeZone: 'Asia/Kolkata',
251 });
252 const table = await Table.findByIdAndUpdate(
253 req.params.table_id,
254 {
255 status: 'active',
256 },
257 {
258 new: true,
259 runValidators: true,
260 }
261 );
262
263 if (!table) {
264 console.log(1);
265 return res.status(404).json({
266 success: false,
267 msg: 'There seems to be some error --table',
268 });
269 }
270 console.log(new Date(IndiaDate).toLocaleString());
271 const session = await Session.findByIdAndUpdate(
272 req.params.session_id,
273 {
274 active: true,
275 authenticatedBy: req.user._id,
276 Start: new Date(IndiaDate).toLocaleString(),
277 verified: true,
278 },
279 {
280 new: true,
281 runValidators: true,
282 }
283 );
284 console.log(2);
285 if (!session) {
286 return res.status(404).json({
287 success: false,
288 msg: 'There seems to be some error',
289 });
290 }
291 pusher.trigger('confirm_session', `${session.restaurant}`, session);
292 return res.status(200).json({
293 success: true,
294 data: session,
295 });
296 } catch (error) {
297 console.log(error);
298 return res.status(500).json({
299 success: false,
300 error: error,
301 });
302 }
303};
304
305// NOTE: Needs to be changes!!!
306// @desc Inactive Session list of specific restaurant
307// @route GET /api/session/Sessions_list
308// @access Private
309exports.Session_List = async (req, res, next) => {
310 try {
311 const sessions = await Session.find({
312 restaurant: req.user.restaurant,
313 authentication_requested: true,
314 active: false,
315 verified: false,
316 }).populate('table');
317 console.log(sessions);
318 return res.status(200).json({
319 success: true,
320 data: sessions,
321 });
322 } catch (error) {
323 return res.status(500).json({
324 success: false,
325 error: error,
326 });
327 }
328};
329
330// @desc Deleting a session before approving
331// @route DELETE /api/session/Delete_Session/:session_id
332// @access Public
333exports.Delete_Session = async (req, res, next) => {
334 try {
335 const session = await Session.findByIdAndDelete(req.params.session_id);
336 if (!session) {
337 return res.status(400).json({
338 success: false,
339 msg: 'No such session exists',
340 });
341 }
342 return res.status(200).json({
343 success: true,
344 msg: 'Deleted Session',
345 });
346 } catch (error) {
347 return res.status(500).json({
348 success: false,
349 error: error,
350 });
351 }
352};
353
354// NOTE: Close Session when generating Final Bill
355// @desc daily session
356// @route GET /api/session/Daily_Active_Sessions
357// @access Private
358exports.Get_Daily_Sessions = async (req, res, next) => {
359 try {
360 const s_list = await Session.find({
361 Date_Ref: {
362 $gte: today.toDate(),
363 $lte: moment(today).endOf('day').toDate(),
364 },
365 verified: true,
366 active: true,
367 });
368 if (!s_list) {
369 return res.status(404).json({
370 success: false,
371 msg: 'Sessions Yet not started for the Day',
372 });
373 }
374 return res.status(200).json({
375 success: true,
376 data: s_list,
377 });
378 } catch (error) {
379 return res.status(500).json({
380 success: false,
381 error: error,
382 });
383 }
384};
385
386// @desc Status of a session
387// @route GET /api/session/check_status/:session_id
388// @access Public
389exports.Check_Status = async (req, res, next) => {
390 try {
391 const session = await Session.findById(req.params.session_id);
392 if (!session) {
393 return res.status(404).json({
394 success: false,
395 msg: 'There seems to be some error',
396 });
397 }
398
399 return res.status(200).json({
400 success: true,
401 data: session,
402 });
403 } catch (error) {
404 return res.status(500).json({
405 success: false,
406 error: error,
407 });
408 }
409};
410
411/* -------------------------------------------------------------------------- */
412/* NOTE USED */
413/* -------------------------------------------------------------------------- */
414
415exports.Remove_Spam_Sessions = async (req, res, next) => {
416 try {
417 const session = await Session.deleteMany({
418 authentication_requested: false,
419 restaurant: req.body.restaurant,
420 });
421 return res.status(200).json({
422 success: true,
423 msg: 'Deleted Session',
424 });
425 } catch (error) {
426 return res.status(500).json({
427 success: false,
428 error: error,
429 });
430 }
431};
432
433//To be Executed at the End of the Day to Remove any spam unverified Session Requests
434exports.Remove_unverified = async (req, res, next) => {
435 try {
436 const session = await Session.deleteMany({
437 verified: false,
438 restaurant: req.body.restaurant,
439 });
440 } catch (error) {
441 return res.status(500).json({
442 success: false,
443 error: error,
444 });
445 }
446};
447