Created
August 6, 2025 11:49
-
-
Save losh11/fdba5b6610f6d943e4e5ca129b68ff84 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import express from 'express'; | |
| import * as argon2 from 'argon2'; | |
| import { | |
| sendNotificationToUsers, | |
| sendNotificationToOldUsers, | |
| sendNotificationToEmptyUsers, | |
| sendNotificationToUsersTest, | |
| } from '../utils/notifications'; | |
| interface ISendNotificationRequest { | |
| password: string; | |
| title: string; | |
| body: string; | |
| country?: string; | |
| currency?: string; | |
| lng?: string; | |
| osVersion?: string; | |
| isIOS?: boolean; | |
| } | |
| interface ISendNotificationRequestTest extends ISendNotificationRequest { | |
| deviceToken: string; | |
| } | |
| const router = express.Router(); | |
| // Middleware: authenticate admin via password | |
| async function authenticateAdmin( | |
| req: express.Request, | |
| res: express.Response, | |
| next: express.NextFunction | |
| ) { | |
| const { password } = req.body as { password?: string }; | |
| const hashedPassword = process.env.ADMIN_PASSWORD_HASH; | |
| if (!hashedPassword || !password) { | |
| return res.status(401).json({ success: false, error: 'Invalid password' }); | |
| } | |
| try { | |
| const valid = await argon2.verify(hashedPassword, password); | |
| if (!valid) { | |
| return res.status(401).json({ success: false, error: 'Invalid password' }); | |
| } | |
| next(); | |
| } catch (err) { | |
| return res.status(500).json({ success: false, error: String(err) }); | |
| } | |
| } | |
| // Middleware: validate title and body, optionally deviceToken | |
| function validateNotificationPayload(requireDeviceToken = false) { | |
| return ( | |
| req: express.Request, | |
| res: express.Response, | |
| next: express.NextFunction | |
| ) => { | |
| const { title, body } = req.body as { title?: string; body?: string }; | |
| if (!title || !body) { | |
| return res.status(400).json({ success: false, error: 'Title and body are required' }); | |
| } | |
| if (requireDeviceToken) { | |
| const { deviceToken } = req.body as { deviceToken?: string }; | |
| if (!deviceToken) { | |
| return res.status(400).json({ success: false, error: 'deviceToken is required' }); | |
| } | |
| } | |
| next(); | |
| }; | |
| } | |
| // Common builder for params object | |
| function buildParams(body: any) { | |
| const { country, currency, lng, osVersion } = body; | |
| return { | |
| ...(country && { country }), | |
| ...(currency && { currency }), | |
| ...(lng && { lng }), | |
| ...(osVersion && { osVersion }), | |
| }; | |
| } | |
| // Route: send to all users | |
| router.post( | |
| '/send-notif-to-users', | |
| authenticateAdmin, | |
| validateNotificationPayload(), | |
| async (req, res) => { | |
| try { | |
| const { | |
| title, | |
| body, | |
| isIOS, | |
| } = req.body as ISendNotificationRequest; | |
| const params = buildParams(req.body); | |
| const result = await sendNotificationToUsers(title, body, params, isIOS); | |
| res.json(result); | |
| } catch (error) { | |
| res.status(500).json({ success: false, error: String(error) }); | |
| } | |
| } | |
| ); | |
| // Route: send to old users | |
| router.post( | |
| '/send-notif-to-old-users', | |
| authenticateAdmin, | |
| validateNotificationPayload(), | |
| async (req, res) => { | |
| try { | |
| const { title, body, isIOS } = req.body as ISendNotificationRequest; | |
| const result = await sendNotificationToOldUsers(title, body, isIOS); | |
| res.json(result); | |
| } catch (error) { | |
| res.status(500).json({ success: false, error: String(error) }); | |
| } | |
| } | |
| ); | |
| // Route: send to users with empty profiles | |
| router.post( | |
| '/send-notif-to-empty-users', | |
| authenticateAdmin, | |
| validateNotificationPayload(), | |
| async (req, res) => { | |
| try { | |
| const { title, body, isIOS } = req.body as ISendNotificationRequest; | |
| const result = await sendNotificationToEmptyUsers(title, body, isIOS); | |
| res.json(result); | |
| } catch (error) { | |
| res.status(500).json({ success: false, error: String(error) }); | |
| } | |
| } | |
| ); | |
| // Route: generate password hash | |
| router.post('/generate-hash', async (req, res) => { | |
| try { | |
| const { password } = req.body as { password?: string }; | |
| if (!password) { | |
| return res.status(400).json({ success: false, error: 'Password is required' }); | |
| } | |
| const hash = await argon2.hash(password); | |
| res.json({ success: true, hash }); | |
| } catch (error) { | |
| res.status(500).json({ success: false, error: String(error) }); | |
| } | |
| }); | |
| // Route: send to a single test device | |
| router.post( | |
| '/send-notif-to-users-test', | |
| authenticateAdmin, | |
| validateNotificationPayload(true), | |
| async (req, res) => { | |
| try { | |
| const { | |
| title, | |
| body, | |
| isIOS, | |
| deviceToken, | |
| } = req.body as ISendNotificationRequestTest; | |
| const params = buildParams(req.body); | |
| const result = await sendNotificationToUsersTest( | |
| deviceToken, | |
| title, | |
| body, | |
| params, | |
| isIOS | |
| ); | |
| res.json(result); | |
| } catch (error) { | |
| res.status(500).json({ success: false, error: String(error) }); | |
| } | |
| } | |
| ); | |
| export default router; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment