alerts,filters,websocket sync

This commit is contained in:
vriti 2025-05-27 21:07:33 +05:30
commit 6441027b89
11 changed files with 292 additions and 3 deletions

9
.env
View File

@ -1,7 +1,14 @@
ENCRYPTION_SECRET=mySuperSecretKey123 ENCRYPTION_SECRET=mySuperSecretKey123
PORT=3000 PORT=3000
<<<<<<< HEAD
MYSQL_HOST = localhost MYSQL_HOST = localhost
MYSQL_USER = guardian MYSQL_USER = guardian
MYSQL_PASSWORD = Admin@123 MYSQL_PASSWORD = Admin@123
MYSQL_DATABASE = guardiandb MYSQL_DATABASE = guardiandb
=======
MYSQL_HOST =
MYSQL_USER =
MYSQL_PASSWORD =
MYSQL_DATABASE =
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065

20
app.js
View File

@ -6,10 +6,14 @@ const userRoutes = require('./routes/userRoutes');
const https = require('https'); const https = require('https');
const fs = require("fs") const fs = require("fs")
<<<<<<< HEAD
const {initWebSocket} = require('./services/webSocket') const {initWebSocket} = require('./services/webSocket')
const { connectDB } = require('./config/database'); const { connectDB } = require('./config/database');
connectDB(); connectDB();
=======
const {initWebSocket} = require('./services/webSocket')
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
const app = express(); const app = express();
const sslOptions = { const sslOptions = {
// key: fs.readFileSync('./certificates/fullchain.pem'), // key: fs.readFileSync('./certificates/fullchain.pem'),
@ -18,12 +22,18 @@ const sslOptions = {
// Create HTTP server (use HTTP for now to avoid SSL issues, in production use HTTPS with valid certificates) // Create HTTP server (use HTTP for now to avoid SSL issues, in production use HTTPS with valid certificates)
const server = require('http').createServer(app); const server = require('http').createServer(app);
<<<<<<< HEAD
// Initialize WebSocket server // Initialize WebSocket server
initWebSocket(server); initWebSocket(server);
console.log('WebSocket server initialized'); console.log('WebSocket server initialized');
connectDB() connectDB()
=======
// Initialize WebSocket server
initWebSocket(server);
console.log('WebSocket server initialized');
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
// Middleware to parse JSON bodies // Middleware to parse JSON bodies
app.use(express.json()); // 👈 Add this line app.use(express.json()); // 👈 Add this line
@ -31,7 +41,11 @@ app.use(express.json()); // 👈 Add this line
app.use(express.static('public')); app.use(express.static('public'));
// CORS Configuration // CORS Configuration
<<<<<<< HEAD
const allowedOrigins = ['https://guardiancalls.tech4bizsolutions.com','http://localhost:5174', 'https://dashboard.tech4biz.info','http://localhost:5173', 'http://192.168.1.35:5173']; // Replace as needed const allowedOrigins = ['https://guardiancalls.tech4bizsolutions.com','http://localhost:5174', 'https://dashboard.tech4biz.info','http://localhost:5173', 'http://192.168.1.35:5173']; // Replace as needed
=======
const allowedOrigins = ['https://guardiancalls.tech4bizsolutions.com','http://localhost:5174', 'https://yourfrontend.com','http://localhost:5173', 'http://192.168.1.35:5173']; // Replace as needed
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
app.use((req, res, next) => { app.use((req, res, next) => {
// Check if the request is for the WebSocket test page // Check if the request is for the WebSocket test page
@ -82,4 +96,8 @@ const PORT = process.env.PORT || 3000;
server.listen(PORT, () => { server.listen(PORT, () => {
console.log(`HTTP server running on port ${PORT}`); console.log(`HTTP server running on port ${PORT}`);
console.log(`WebSocket server available at ws://localhost:${PORT}`); console.log(`WebSocket server available at ws://localhost:${PORT}`);
}); <<<<<<< HEAD
});
=======
});
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065

View File

@ -0,0 +1,48 @@
-----BEGIN CERTIFICATE-----
MIIDsjCCAzigAwIBAgISBVXyKhgq+z0CAq8r8xlfVOimMAoGCCqGSM49BAMDMDIx
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF
NTAeFw0yNTA1MjMwOTU3MjdaFw0yNTA4MjEwOTU3MjZaMC4xLDAqBgNVBAMTI2d1
YXJkaWFuY2FsbHMudGVjaDRiaXpzb2x1dGlvbnMuY29tMFkwEwYHKoZIzj0CAQYI
KoZIzj0DAQcDQgAEFkj1St8i4vM5I3bTlGcAqsc4YssKgdYV/OAy+3y8hMMPHbUi
zF/BMa42ycDEXtw1geS+bzJVFA7HXrco8oOvjqOCAjAwggIsMA4GA1UdDwEB/wQE
AwIHgDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIw
ADAdBgNVHQ4EFgQU9oBKl2iP0cojuMRm98APDaPPynQwHwYDVR0jBBgwFoAUnytf
zzwhT50Et+0rLMTGcIvS1w0wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzAChhZo
dHRwOi8vZTUuaS5sZW5jci5vcmcvMC4GA1UdEQQnMCWCI2d1YXJkaWFuY2FsbHMu
dGVjaDRiaXpzb2x1dGlvbnMuY29tMBMGA1UdIAQMMAowCAYGZ4EMAQIBMC0GA1Ud
HwQmMCQwIqAgoB6GHGh0dHA6Ly9lNS5jLmxlbmNyLm9yZy8zOS5jcmwwggEDBgor
BgEEAdZ5AgQCBIH0BIHxAO8AdQDM+w9qhXEJZf6Vm1PO6bJ8IumFXA2XjbapflTA
/kwNsAAAAZb8yRBYAAAEAwBGMEQCIHz+37rvli/z4bySkF6Agh4Y/jC0+y/nfK4f
U8DPeRimAiB8Em8y3E85EYbVFIN0z/IrlzSoCUprLW9fJIqjOTyoRgB2AA3h8jAr
0w3BQGISCepVLvxHdHyx1+kw7w5CHrR+Tqo0AAABlvzJEF0AAAQDAEcwRQIgHkAk
1qxFx/uC6tR9UsXyoCsNsQJebJQobahCGxLq7AcCIQDZ+61TBS1DWMoreCG+CEa0
HeZDfEdZHGXLPpaiPOSkITAKBggqhkjOPQQDAwNoADBlAjEA49BB3QqaDbT43Pdy
xwSI6Loq5eYJNMekJipVsvu+rSmDZ1KU4AEadpd5wZhQoWKlAjB9nS05qX1Q6Gcg
Fq7D/bA2inv7MF2riCMbfkp1nWRJ0LFcOOHlYbor0wrNAwd9w7c=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEVzCCAj+gAwIBAgIRAIOPbGPOsTmMYgZigxXJ/d4wDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw
WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCRTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNCzqK
a2GOtu/cX1jnxkJFVKtj9mZhSAouWXW0gQI3ULc/FnncmOyhKJdyIBwsz9V8UiBO
VHhbhBRrwJCuhezAUUE8Wod/Bk3U/mDR+mwt4X2VEIiiCFQPmRpM5uoKrNijgfgw
gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSfK1/PPCFPnQS37SssxMZw
i9LXDTAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB
AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g
BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu
Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAH3KdNEVCQdqk0LKyuNImTKdRJY1C
2uw2SJajuhqkyGPY8C+zzsufZ+mgnhnq1A2KVQOSykOEnUbx1cy637rBAihx97r+
bcwbZM6sTDIaEriR/PLk6LKs9Be0uoVxgOKDcpG9svD33J+G9Lcfv1K9luDmSTgG
6XNFIN5vfI5gs/lMPyojEMdIzK9blcl2/1vKxO8WGCcjvsQ1nJ/Pwt8LQZBfOFyV
XP8ubAp/au3dc4EKWG9MO5zcx1qT9+NXRGdVWxGvmBFRAajciMfXME1ZuGmk3/GO
koAM7ZkjZmleyokP1LGzmfJcUd9s7eeu1/9/eg5XlXd/55GtYjAM+C4DG5i7eaNq
cm2F+yxYIPt6cbbtYVNJCGfHWqHEQ4FYStUyFnv8sjyqU8ypgZaNJ9aVcWSICLOI
E1/Qv/7oKsnZCWJ926wU6RqG1OYPGOi1zuABhLw61cuPVDT28nQS/e6z95cJXq0e
K1BcaJ6fJZsmbjRgD5p3mvEf5vdQM7MCEvU0tHbsx2I5mHHJoABHb8KVBgWp/lcX
GWiWaeOyB7RP+OfDtvi2OsapxXiV7vNVs7fMlrRjY1joKaqmmycnBvAq14AEbtyL
sVfOS66B8apkeFX2NY4XPEYV4ZSCe8VHPrdrERk2wILG3T/EGmSIkCYVUMSnjmJd
VQD9F6Na/+zmXCc=
-----END CERTIFICATE-----

5
certificates/privkey.pem Normal file
View File

@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgH6ulvQnwnXO+vjBV
IW7bkzyG1ZjAGYdpW2PSoK2JYtOhRANCAAQWSPVK3yLi8zkjdtOUZwCqxzhiywqB
1hX84DL7fLyEww8dtSLMX8ExrjbJwMRe3DWB5L5vMlUUDsdetyjyg6+O
-----END PRIVATE KEY-----

View File

@ -10,7 +10,11 @@ const connectDB = async () => {
user: process.env.MYSQL_USER, user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD, password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE, database: process.env.MYSQL_DATABASE,
<<<<<<< HEAD
port: process.env.MYSQL_PORT || 3306, port: process.env.MYSQL_PORT || 3306,
=======
port: process.env.PORT || 3306,
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
waitForConnections: true, waitForConnections: true,
connectionLimit: 100, connectionLimit: 100,
queueLimit: 0, queueLimit: 0,
@ -31,4 +35,8 @@ const getPool = () => {
return pool; return pool;
}; };
<<<<<<< HEAD
module.exports = { connectDB, getPool }; module.exports = { connectDB, getPool };
=======
module.exports = { connectDB, getPool };
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065

View File

@ -1,7 +1,11 @@
const { fetchContacts } = require("../services/apiService"); const { fetchContacts } = require("../services/apiService");
<<<<<<< HEAD
const { sendAlertToUser } = require("../services/webSocket"); const { sendAlertToUser } = require("../services/webSocket");
const jwt = require("jsonwebtoken"); const jwt = require("jsonwebtoken");
const {getPool} = require("../config/database") const {getPool} = require("../config/database")
=======
const { sendAlertToUser } = require("../services/webSocket")
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
const fieldTitleMap = { const fieldTitleMap = {
Hq5fePgYMo1lfrJeSXkr: "call_frequency", Hq5fePgYMo1lfrJeSXkr: "call_frequency",
@ -82,6 +86,7 @@ async function getNotifications(req,res){
} }
<<<<<<< HEAD
async function updateAlerts(req, res) { async function updateAlerts(req, res) {
let id = req.body.id let id = req.body.id
@ -132,4 +137,7 @@ async function updateAlerts(req, res) {
res.status(500).json({ error: 'Internal server error' }); res.status(500).json({ error: 'Internal server error' });
} }
} }
module.exports = { getUserData ,getNotifications,updateAlerts}; module.exports = { getUserData ,getNotifications,updateAlerts};
=======
module.exports = { getUserData ,getNotifications};
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065

27
node_modules/.package-lock.json generated vendored
View File

@ -39,6 +39,7 @@
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
}, },
<<<<<<< HEAD
"node_modules/aws-ssl-profiles": { "node_modules/aws-ssl-profiles": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz", "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz",
@ -48,6 +49,8 @@
"node": ">= 6.0.0" "node": ">= 6.0.0"
} }
}, },
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
"node_modules/axios": { "node_modules/axios": {
"version": "1.9.0", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
@ -64,6 +67,7 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true "dev": true
}, },
<<<<<<< HEAD
"node_modules/bignumber.js": { "node_modules/bignumber.js": {
"version": "9.0.0", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
@ -73,6 +77,8 @@
"node": "*" "node": "*"
} }
}, },
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
"node_modules/binary-extensions": { "node_modules/binary-extensions": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
@ -320,6 +326,7 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
<<<<<<< HEAD
"node_modules/denque": { "node_modules/denque": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
@ -329,6 +336,8 @@
"node": ">=0.10" "node": ">=0.10"
} }
}, },
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
"node_modules/depd": { "node_modules/depd": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@ -588,6 +597,7 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
<<<<<<< HEAD
"node_modules/generate-function": { "node_modules/generate-function": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
@ -597,6 +607,8 @@
"is-property": "^1.0.2" "is-property": "^1.0.2"
} }
}, },
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
"node_modules/get-intrinsic": { "node_modules/get-intrinsic": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
@ -798,12 +810,15 @@
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="
}, },
<<<<<<< HEAD
"node_modules/is-property": { "node_modules/is-property": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
"integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==",
"license": "MIT" "license": "MIT"
}, },
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
"node_modules/isarray": { "node_modules/isarray": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@ -894,6 +909,7 @@
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
"license": "MIT" "license": "MIT"
}, },
<<<<<<< HEAD
"node_modules/long": { "node_modules/long": {
"version": "5.3.2", "version": "5.3.2",
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
@ -924,6 +940,8 @@
"url": "https://github.com/sponsors/wellwelwel" "url": "https://github.com/sponsors/wellwelwel"
} }
}, },
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
"node_modules/math-intrinsics": { "node_modules/math-intrinsics": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@ -1062,6 +1080,7 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
<<<<<<< HEAD
"node_modules/mysql": { "node_modules/mysql": {
"version": "2.18.1", "version": "2.18.1",
"resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz",
@ -1139,6 +1158,8 @@
"node": ">=12.0.0" "node": ">=12.0.0"
} }
}, },
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
"node_modules/negotiator": { "node_modules/negotiator": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
@ -1416,11 +1437,14 @@
"node": ">= 18" "node": ">= 18"
} }
}, },
<<<<<<< HEAD
"node_modules/seq-queue": { "node_modules/seq-queue": {
"version": "0.0.5", "version": "0.0.5",
"resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz",
"integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="
}, },
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
"node_modules/serve-static": { "node_modules/serve-static": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz",
@ -1520,6 +1544,7 @@
"node": ">=10" "node": ">=10"
} }
}, },
<<<<<<< HEAD
"node_modules/sqlstring": { "node_modules/sqlstring": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz",
@ -1529,6 +1554,8 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
"node_modules/statuses": { "node_modules/statuses": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",

9
package-lock.json generated
View File

@ -18,8 +18,11 @@
"https": "^1.0.0", "https": "^1.0.0",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"multer": "^2.0.0", "multer": "^2.0.0",
<<<<<<< HEAD
"mysql": "^2.18.1", "mysql": "^2.18.1",
"mysql2": "^3.14.1", "mysql2": "^3.14.1",
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
"ws": "^8.18.2" "ws": "^8.18.2"
}, },
"devDependencies": { "devDependencies": {
@ -930,6 +933,7 @@
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
"license": "MIT" "license": "MIT"
}, },
<<<<<<< HEAD
"node_modules/long": { "node_modules/long": {
"version": "5.3.2", "version": "5.3.2",
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
@ -960,6 +964,8 @@
"url": "https://github.com/sponsors/wellwelwel" "url": "https://github.com/sponsors/wellwelwel"
} }
}, },
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
"node_modules/math-intrinsics": { "node_modules/math-intrinsics": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@ -2377,6 +2383,7 @@
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
}, },
<<<<<<< HEAD
"long": { "long": {
"version": "5.3.2", "version": "5.3.2",
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
@ -2392,6 +2399,8 @@
"resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.2.tgz", "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.2.tgz",
"integrity": "sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg==" "integrity": "sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg=="
}, },
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
"math-intrinsics": { "math-intrinsics": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",

View File

@ -21,8 +21,11 @@
"https": "^1.0.0", "https": "^1.0.0",
"jsonwebtoken": "^9.0.2", "jsonwebtoken": "^9.0.2",
"multer": "^2.0.0", "multer": "^2.0.0",
<<<<<<< HEAD
"mysql": "^2.18.1", "mysql": "^2.18.1",
"mysql2": "^3.14.1", "mysql2": "^3.14.1",
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
"ws": "^8.18.2" "ws": "^8.18.2"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,13 +1,20 @@
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
<<<<<<< HEAD
const { getUserData, getNotifications,updateAlerts} = require('../controllers/userController'); const { getUserData, getNotifications,updateAlerts} = require('../controllers/userController');
=======
const { getUserData, getNotifications} = require('../controllers/userController');
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
const multer = require('multer'); const multer = require('multer');
const upload = multer(); // No disk storage, just for parsing fields const upload = multer(); // No disk storage, just for parsing fields
router.post('/data', upload.none(), getUserData); router.post('/data', upload.none(), getUserData);
router.post('/notifications',upload.none(),getNotifications) router.post('/notifications',upload.none(),getNotifications)
<<<<<<< HEAD
router.post('/acknowledge',upload.none(),updateAlerts) router.post('/acknowledge',upload.none(),updateAlerts)
=======
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
module.exports = router; module.exports = router;

View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
// const WebSocket = require('ws'); // const WebSocket = require('ws');
// const jwt = require('jsonwebtoken'); // const jwt = require('jsonwebtoken');
// const db = require('../config/database'); // const db = require('../config/database');
@ -238,15 +239,36 @@ async function sendUserAlertHistory(ws, userId) {
/** /**
* Initializes the WebSocket server. * Initializes the WebSocket server.
=======
const WebSocket = require('ws');
const jwt = require('jsonwebtoken');
// user_id -> websocket mapping
const userSocketMap = new Map();
// Keep track of connection attempts to prevent rapid reconnection loops
const connectionAttempts = new WeakMap();
/**
* Initializes the WebSocket server.
* @param {https.Server} server - The HTTP/HTTPS server instance from Express.
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
*/ */
function initWebSocket(server) { function initWebSocket(server) {
const wss = new WebSocket.Server({ const wss = new WebSocket.Server({
server, server,
clientTracking: true, clientTracking: true,
<<<<<<< HEAD
=======
// Consider adding ping/pong for connection health
// clientTracking: true,
// maxPayload: 100 * 1024 * 1024, // 100MB
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
}); });
console.log('WebSocket server initialized'); console.log('WebSocket server initialized');
<<<<<<< HEAD
wss.on('connection', (ws, req) => { wss.on('connection', (ws, req) => {
const location = url.parse(req.url, true); const location = url.parse(req.url, true);
const token = location.query?.token; const token = location.query?.token;
@ -301,10 +323,39 @@ function initWebSocket(server) {
}, 30000); }, 30000);
ws.on('pong', () => { ws.isAlive = true; }); ws.on('pong', () => { ws.isAlive = true; });
=======
// Handle new connections
wss.on('connection', (ws, req) => {
const clientIp = req.socket.remoteAddress;
// console.log(`New WebSocket connection from ${clientIp}`);
// Set up ping/pong to detect dead connections
let isAlive = true;
ws.isAlive = true;
const pingInterval = setInterval(() => {
if (!isAlive) {
console.log('Terminating dead connection');
return ws.terminate();
}
isAlive = false;
try {
ws.ping(() => {});
} catch (e) {
console.error('Error sending ping:', e);
}
}, 30000);
ws.on('pong', () => {
isAlive = true;
});
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
ws.on('message', (message) => { ws.on('message', (message) => {
try { try {
const data = JSON.parse(message); const data = JSON.parse(message);
<<<<<<< HEAD
if (data.type === 'MESSAGE') { if (data.type === 'MESSAGE') {
ws.send(JSON.stringify({ ws.send(JSON.stringify({
type: 'MESSAGE_RECEIVED', type: 'MESSAGE_RECEIVED',
@ -331,10 +382,98 @@ function initWebSocket(server) {
console.error('WebSocket error:', error); console.error('WebSocket error:', error);
if (ws.readyState === WebSocket.OPEN) { if (ws.readyState === WebSocket.OPEN) {
ws.close(1011, 'Internal server error'); ws.close(1011, 'Internal server error');
=======
// Handle different message types
if (data.type === 'MESSAGE') {
console.log(`Received message: ${data.content}`);
ws.send(JSON.stringify({
type: 'MESSAGE_RECEIVED',
content: data.content,
timestamp: new Date().toISOString()
}));
return;
}
// Handle authentication with token
const { token } = data;
if (!token) {
ws.send(JSON.stringify({
type: 'ERROR',
error: 'No token provided',
timestamp: new Date().toISOString()
}));
return;
}
const decoded = jwt.decode(token); // Use jwt.verify() in production
const userId = decoded?.claims?.user_id;
if (!userId) {
ws.send(JSON.stringify({
type: 'ERROR',
error: 'Invalid token or missing user_id in claims',
timestamp: new Date().toISOString()
}));
return;
}
console.log(`Authenticated user: ${userId}`);
// Store the WebSocket connection with the user ID
userSocketMap.set(userId, ws);
// Store user ID in the WebSocket object for cleanup
ws.userId = userId;
ws.send(JSON.stringify({
type: 'CONNECTED',
message: `Connected as ${userId}`,
timestamp: new Date().toISOString()
}));
} catch (err) {
console.error('WebSocket message error:', err);
try {
ws.send(JSON.stringify({
type: 'ERROR',
error: 'Invalid message format or processing error',
timestamp: new Date().toISOString()
}));
} catch (sendErr) {
console.error('Failed to send error message:', sendErr);
}
}
});
// Handle connection close
ws.on('close', () => {
// console.log(`WebSocket closed for ${ws.userId || 'unknown user'}`);
if (ws.userId) {
userSocketMap.delete(ws.userId);
}
clearInterval(pingInterval);
});
// Handle errors
ws.on('error', (error) => {
console.error('WebSocket error:', error);
if (ws.readyState === WebSocket.OPEN) {
try {
ws.close(1011, 'Internal server error');
} catch (e) {
// Ignore errors during close
}
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
} }
}); });
}); });
<<<<<<< HEAD
=======
// Handle server errors
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
wss.on('error', (error) => { wss.on('error', (error) => {
console.error('WebSocket server error:', error); console.error('WebSocket server error:', error);
}); });
@ -343,6 +482,7 @@ function initWebSocket(server) {
} }
/** /**
<<<<<<< HEAD
* Send a real-time alert to a specific user via WebSocket. * Send a real-time alert to a specific user via WebSocket.
*/ */
async function sendAlertToUser(userId, alert) { async function sendAlertToUser(userId, alert) {
@ -367,6 +507,15 @@ async function sendAlertToUser(userId, alert) {
console.error("Database operation failed:", err); console.error("Database operation failed:", err);
} }
=======
* Sends an alert to a user via WebSocket.
* @param {string} userId - The target user ID.
* @param {string|object} alert - The alert message or payload.
* @returns {boolean} - Success/failure.
*/
function sendAlertToUser(userId, alert) {
console.log("socket -- invoked---")
>>>>>>> 3d47f2d539024e036b3db88eb1e020180e656065
const ws = userSocketMap.get(userId); const ws = userSocketMap.get(userId);
if (ws && ws.readyState === WebSocket.OPEN) { if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'ALERT', payload: alert })); ws.send(JSON.stringify({ type: 'ALERT', payload: alert }));