102 lines
2.5 KiB
JavaScript
102 lines
2.5 KiB
JavaScript
// routes/push.js
|
|
const express = require('express');
|
|
const { body, validationResult } = require('express-validator');
|
|
const verifyToken = require('../middleware/verifyToken');
|
|
const db = require('../db');
|
|
const { sendPushToUser } = require('../utils/pushService');
|
|
|
|
const router = express.Router();
|
|
router.use(verifyToken);
|
|
|
|
function handleValidation(req, res, next) {
|
|
const errors = validationResult(req);
|
|
if (!errors.isEmpty()) {
|
|
return res.status(400).json({ success: false, errors: errors.array() });
|
|
}
|
|
next();
|
|
}
|
|
|
|
// GET /api/push/vapid-public-key
|
|
router.get('/vapid-public-key', (req, res) => {
|
|
if (!process.env.VAPID_PUBLIC_KEY) {
|
|
return res
|
|
.status(503)
|
|
.json({ success: false, message: 'Push indisponível' });
|
|
}
|
|
res.json({ success: true, data: { key: process.env.VAPID_PUBLIC_KEY } });
|
|
});
|
|
|
|
// POST /api/push/subscribe
|
|
router.post(
|
|
'/subscribe',
|
|
[
|
|
body('endpoint').isString(),
|
|
body('keys.p256dh').isString(),
|
|
body('keys.auth').isString(),
|
|
],
|
|
handleValidation,
|
|
async (req, res) => {
|
|
const userId = req.user.id;
|
|
const { endpoint, keys } = req.body;
|
|
const ua = req.headers['user-agent'] || null;
|
|
|
|
// evita duplicados
|
|
const existing = await db('push_subscriptions')
|
|
.where({ endpoint, user_id: userId })
|
|
.first();
|
|
|
|
if (existing) {
|
|
return res.json({ success: true, data: existing });
|
|
}
|
|
|
|
const [inserted] = await db('push_subscriptions')
|
|
.insert({
|
|
user_id: userId,
|
|
endpoint,
|
|
p256dh: keys.p256dh,
|
|
auth: keys.auth,
|
|
user_agent: ua,
|
|
created_at: new Date().toISOString(),
|
|
})
|
|
.returning('*');
|
|
|
|
res.status(201).json({ success: true, data: inserted });
|
|
}
|
|
);
|
|
|
|
// POST /api/push/unsubscribe
|
|
router.post(
|
|
'/unsubscribe',
|
|
[body('endpoint').optional().isString()],
|
|
handleValidation,
|
|
async (req, res) => {
|
|
const userId = req.user.id;
|
|
const { endpoint } = req.body || {};
|
|
|
|
// se não houver sub no navegador, responde ok
|
|
if (!endpoint) {
|
|
return res.json({ success: true, message: 'No subscription' });
|
|
}
|
|
|
|
await db('push_subscriptions')
|
|
.where({ endpoint, user_id: userId })
|
|
.del();
|
|
|
|
res.json({ success: true, message: 'Unsubscribed' });
|
|
}
|
|
);
|
|
|
|
// POST /api/push/test
|
|
router.post('/test', async (req, res) => {
|
|
const userId = req.user.id;
|
|
await sendPushToUser(userId, {
|
|
title: '📬 Teste EV Station',
|
|
body: 'Push notifications estão a funcionar!',
|
|
url: '/',
|
|
});
|
|
|
|
res.json({ success: true, message: 'Push enviado' });
|
|
});
|
|
|
|
module.exports = router;
|