diff --git a/server/WebSocket/controllers/GPS_EventsController.js b/server/WebSocket/controllers/GPS_EventsController.js new file mode 100644 index 0000000..3ec7a1b --- /dev/null +++ b/server/WebSocket/controllers/GPS_EventsController.js @@ -0,0 +1,19 @@ +const Notification = require('../../models/GPS.Notif') + + +module.exports.notifyGPS = async (type, gps_id) => { + try { + const io = global._io + const gps = io.of('/gps') + const data = { type } + + if (type === 'updateGPSInbox') { + const gpsInbox = await Notification.find({ userID:gps_id, seen: false }).sort({updated_at: -1}) + data.gpsInbox = gpsInbox + } + + gps.to(gps_id.toString()).emit(`GPS:notify`, data) + } catch (e) { + console.log(e) + } +} \ No newline at end of file diff --git a/server/WebSocket/middlewares/ws_authentication.js b/server/WebSocket/middlewares/ws_authentication.js index dad95ea..9737675 100644 --- a/server/WebSocket/middlewares/ws_authentication.js +++ b/server/WebSocket/middlewares/ws_authentication.js @@ -1,5 +1,6 @@ const jwt = require('jsonwebtoken') const User = require('../../models/User') +const UserGPS = require('../../models/GPS.User') const authentication = require('../../authentication') module.exports.isAdmin = async (socket, next) => { @@ -65,3 +66,23 @@ module.exports.isAgent = async (socket, next) => { next(new Error(e)) } } + +module.exports.isGPS = async (socket, next) => { + try { + const token = socket.handshake?.auth?.token + if (!token) throw new Error('unauthenticated') + + // verifies secret and checks if the token is expired + const decodedToken = await jwt.verify(token.replace(/^Bearer\s/, ''), authentication.secretKey) + if (!decodedToken) throw new Error('unauthorized') + + // find user + const user = await UserGPS.findById(decodedToken._id) + if (!user || !user.active) throw new Error('unauthorized') + + socket.userId = decodedToken._id.toString() + return next() + } catch (e) { + next(new Error(e)) + } +} diff --git a/server/WebSocket/namespaces/GPS_NameSpace.js b/server/WebSocket/namespaces/GPS_NameSpace.js new file mode 100644 index 0000000..8c10de2 --- /dev/null +++ b/server/WebSocket/namespaces/GPS_NameSpace.js @@ -0,0 +1,25 @@ +const { isGPS } = require('../middlewares/ws_authentication') +const gpsEventsController = require('../controllers/GPS_EventsController') + +module.exports.gpsNamespace = () => { + const io = global._io + const gps = io.of('/gps') + + // gpss middlewares + gps.use(isGPS) + + // attach events + gps.on('connection', socket => { + socket.join(socket.gpsId) + gpsEventsController.getAllNotifs(socket) + + /// /////////////////////////////////////////////////////// handle connection error + socket.on('connect_error', err => { + console.log(err.message) + }) + + /// ////////////////////////////////////////////////////// events + socket.on('gps:fetchAnnouncements', data => gpsEventsController.fetchAnnouncements(socket)) + socket.on('gps:updateAnnouncement', data => gpsEventsController.updateAnnouncement(socket, data)) + }) +} diff --git a/server/WebSocket/wss.js b/server/WebSocket/wss.js index 35aed73..00cb545 100644 --- a/server/WebSocket/wss.js +++ b/server/WebSocket/wss.js @@ -4,6 +4,7 @@ function init(server) { const { userNamespace } = require('./namespaces/user_NameSpace') const { agentNamespace } = require('./namespaces/agent_NameSpace') const { adminNamespace } = require('./namespaces/admin_NameSpace') + const { gpsNamespace } = require('./namespaces/GPS_NameSpace') const { Server } = require('socket.io') const socketIO = require('socket.io') @@ -18,6 +19,7 @@ function init(server) { userNamespace() agentNamespace() adminNamespace() + gpsNamespace() } module.exports = init diff --git a/server/controllers/GPS.Auth.js b/server/controllers/GPS.Auth.js index c8bbf0b..b553951 100644 --- a/server/controllers/GPS.Auth.js +++ b/server/controllers/GPS.Auth.js @@ -7,6 +7,8 @@ const { checkValidations } = require('../plugins/controllersHelperFunctions') const UserGPS = require('../models/GPS.User') const { generateRandomDigits } = require('../plugins/controllersHelperFunctions') +const Notification = require('../models/GPS.Notif') + module.exports.login_with_pass = [ [ body('username') @@ -55,6 +57,10 @@ module.exports.login_with_pass = [ }) user.token = token await user.save() + await Notification.create({ + userID:user._id, + content:"test" + }) return res.status(200).json({ token }) } catch (err) { return res.status(422).json({ @@ -90,6 +96,10 @@ module.exports.login_with_otp = [ }) user.otp = generateRandomDigits(6) user.save() + await Notification.create({ + userID:user._id, + content:"test" + }) return res.status(200).json({ token }) } diff --git a/server/controllers/GPS.Notif.js b/server/controllers/GPS.Notif.js new file mode 100644 index 0000000..07216b6 --- /dev/null +++ b/server/controllers/GPS.Notif.js @@ -0,0 +1,30 @@ +const { param, validationResult } = require('express-validator') +const { _sr } = require('../plugins/serverResponses') +const { checkValidations } = require('../plugins/controllersHelperFunctions') +const Notification = require('../models/GPS.Notif') + + +module.exports.setSeen = [ + [ + param('id').notEmpty().isMongoId().withMessage('ایدی را وارد یا تصحیح کنید') + ], + checkValidations(validationResult), + async (req, res) => { + const notif = await Notification.findById(req.params.id) + if (!notif || notif.userID !== req.userID) { + res.status(404).json({ msg: _sr.fa.not_found.item_id }) + } else { + notif.read = true; + notif.save() + } + } +] + +module.exports.setSeenAll = [ + async (req, res) => { + await Notification.updateMany( + { userID: req.userID }, + { seen: true } + ) + } +] \ No newline at end of file diff --git a/server/models/GPS.Notif.js b/server/models/GPS.Notif.js new file mode 100644 index 0000000..02eaa46 --- /dev/null +++ b/server/models/GPS.Notif.js @@ -0,0 +1,17 @@ +const mongoose = require("mongoose"); + +const notificationSchema = new mongoose.Schema( + { + userID: { + type: String, + ref: 'UserGPS' + }, + content: String, + read: { + type: Boolean, + default: false, + }, + } +); + +module.exports = mongoose.model("Notification", notificationSchema); diff --git a/server/routes/gps.js b/server/routes/gps.js index 62dcf76..0cc7cf5 100644 --- a/server/routes/gps.js +++ b/server/routes/gps.js @@ -8,6 +8,12 @@ const award = require('../controllers/GPS.Award') const awardRequest = require('../controllers/GPS.AwardRequest') const overview = require('../controllers/GPS.Overview') const userGPS = require('../controllers/GPS.User') +const notif = require('../controllers/GPS.Notif') + +/// /////////////// Notification +router.get('/notif/:id', notif.setSeen) +router.get('/notif', notif.setSeenAll) + /// /////////////// User router.get('/user/me', userGPS.getCurrent)