Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | 2x 2x 2x 2x 10x 10x 7x 3x 3x 1x 2x 2x 2x 9x 9x 7x 2x 2x 1x 1x 1x 2x 7x 7x 7x 7x 7x 35x 7x 1x 6x 5x 1x 1x 2x | /**
* Notification routes — FCM token management and notification settings.
*
* POST /api/notifications/token -> Save FCM token
* DELETE /api/notifications/token -> Remove FCM token
* PATCH /api/notifications/settings -> Update notification settings
*/
const router = require('express').Router();
const { db, FieldValue } = require('../utils/firebase');
const log = require('../utils/log');
// -- Save FCM token --
router.post('/notifications/token', async (req, res) => {
try {
if (!req.body?.token || typeof req.body.token !== 'string' || req.body.token.length > 500) {
return res.status(400).json({ error: 'token must be a non-empty string' });
}
const uniqueId = req.auth.uniqueId;
await db.doc(`users/${uniqueId}`).update({
fcmTokens: FieldValue.arrayUnion(req.body.token),
});
return res.json({ success: true });
} catch (err) {
log.error('notifications', 'Error saving FCM token', { error: err.message });
return res.status(500).json({ error: 'Internal server error' });
}
});
// -- Remove FCM token --
router.delete('/notifications/token', async (req, res) => {
try {
if (!req.body?.token || typeof req.body.token !== 'string' || req.body.token.length > 500) {
return res.status(400).json({ error: 'token must be a non-empty string' });
}
const uniqueId = req.auth.uniqueId;
await db.doc(`users/${uniqueId}`).update({
fcmTokens: FieldValue.arrayRemove(req.body.token),
});
return res.json({ success: true });
} catch (err) {
log.error('notifications', 'Error removing FCM token', { error: err.message });
return res.status(500).json({ error: 'Internal server error' });
}
});
// -- Update notification settings --
router.patch('/notifications/settings', async (req, res) => {
try {
Iif (!req.body) {
return res.status(400).json({ error: 'Invalid body' });
}
const allowedFields = [
'pmNotificationsEnabled',
'pmSoundEnabled',
'pmShowTimestamps',
'pmShowDateSeparators',
'pmNotificationPreview',
];
const updates = {};
for (const key of allowedFields) {
if (key in req.body) updates[key] = !!req.body[key];
}
if (Object.keys(updates).length === 0) {
return res.status(400).json({ error: 'No valid fields' });
}
await db.doc(`users/${req.auth.uniqueId}`).update(updates);
return res.json({ success: true });
} catch (err) {
log.error('notifications', 'Error updating notification settings', { error: err.message });
return res.status(500).json({ error: 'Internal server error' });
}
});
module.exports = router;
|