kba / routes /notification.js
ShieldX's picture
Upload 24 files
e14bacb verified
const router = require('express').Router();
const Notification = require('../models/Notification');
const User = require('../models/User');
const verify = require('../utils/verifyToken');
const webpush = require('web-push');
const verifyAdmin = async (req, res, next) => {
const user = await User.findById(req.user._id);
if (user.role !== 'admin') return res.status(403).send("ACCESS DENIED");
next();
};
// Configure Web Push
webpush.setVapidDetails(
process.env.VAPID_EMAIL,
process.env.VAPID_PUBLIC_KEY,
process.env.VAPID_PRIVATE_KEY
);
// 1. GET MY NOTIFICATIONS
router.get('/', verify, async (req, res) => {
try {
const notes = await Notification.find({
$or: [
{ target_user_id: null }, // Global
{ target_user_id: req.user._id } // Personal
]
}).sort({ created_at: -1 }).limit(20);
res.json(notes);
} catch (err) {
res.status(500).send("Error fetching notifications");
}
});
// 1. SAVE SUBSCRIPTION
router.post('/subscribe', verify, async (req, res) => {
const subscription = req.body;
// Save this object to the user in DB
await User.findByIdAndUpdate(req.user._id, { pushSubscription: subscription });
res.status(201).json({});
});
// 2. SEND NOTIFICATION (Updated Admin Route)
router.post('/send', verify, verifyAdmin, async (req, res) => {
const { title, message, url, targetUserId } = req.body;
const payload = JSON.stringify({ title, body: message, url });
try {
if (targetUserId) {
// Send to ONE User
const user = await User.findById(targetUserId);
if (user?.pushSubscription) {
await webpush.sendNotification(user.pushSubscription, payload);
}
} else {
// Send to ALL Users (Global)
// Ideally, do this in batches or a queue for thousands of users
const users = await User.find({ pushSubscription: { $exists: true } });
const promises = users.map(user =>
webpush.sendNotification(user.pushSubscription, payload).catch(err => {
if (err.statusCode === 410) {
// Subscription expired (user cleared data), remove from DB
User.findByIdAndUpdate(user._id, { $unset: { pushSubscription: "" } });
}
})
);
await Promise.all(promises);
}
res.json({ success: true });
} catch (err) {
res.status(500).json({ error: "Push Failed" });
}
});
module.exports = router;