183 lines
5.5 KiB
JavaScript
183 lines
5.5 KiB
JavaScript
/**
|
|
* Simple test server for notification system
|
|
* This bypasses TypeScript compilation issues for testing
|
|
*/
|
|
|
|
const express = require('express');
|
|
const { createServer } = require('http');
|
|
const { Server } = require('socket.io');
|
|
const cors = require('cors');
|
|
const jwt = require('jsonwebtoken');
|
|
|
|
const app = express();
|
|
app.use(cors());
|
|
app.use(express.json());
|
|
|
|
const httpServer = createServer(app);
|
|
const io = new Server(httpServer, {
|
|
cors: {
|
|
origin: '*',
|
|
methods: ['GET', 'POST'],
|
|
credentials: true
|
|
},
|
|
transports: ['websocket', 'polling']
|
|
});
|
|
|
|
const PORT = process.env.PORT || 3001;
|
|
const JWT_SECRET = process.env.JWT_SECRET || 'test-secret-key';
|
|
|
|
// Health check
|
|
app.get('/health', (req, res) => {
|
|
res.json({
|
|
success: true,
|
|
message: 'Test server is running',
|
|
timestamp: new Date().toISOString(),
|
|
socketConnections: io.engine.clientsCount
|
|
});
|
|
});
|
|
|
|
// Generate test token endpoint
|
|
app.post('/auth/token', (req, res) => {
|
|
const { userId = 'test-user-123' } = req.body;
|
|
const token = jwt.sign({ userId }, JWT_SECRET, { expiresIn: '1h' });
|
|
res.json({
|
|
success: true,
|
|
token,
|
|
userId,
|
|
expiresIn: '1h'
|
|
});
|
|
});
|
|
|
|
// Socket.io authentication middleware
|
|
io.use(async (socket, next) => {
|
|
try {
|
|
const token = socket.handshake.auth.token;
|
|
if (!token) {
|
|
return next(new Error('Authentication token required'));
|
|
}
|
|
|
|
const decoded = jwt.verify(token, JWT_SECRET);
|
|
socket.userId = decoded.userId;
|
|
console.log(`✅ User ${decoded.userId} authenticated`);
|
|
next();
|
|
} catch (error) {
|
|
console.error('❌ Authentication failed:', error.message);
|
|
next(new Error('Authentication failed'));
|
|
}
|
|
});
|
|
|
|
// Socket.io connection handling
|
|
io.on('connection', (socket) => {
|
|
const userId = socket.userId;
|
|
console.log(`🔌 User ${userId} connected via socket ${socket.id}`);
|
|
|
|
// Join user-specific room
|
|
socket.join(`user:${userId}`);
|
|
|
|
// Send welcome notification
|
|
socket.emit('notification:new', {
|
|
id: Date.now().toString(),
|
|
type: 'system',
|
|
priority: 'medium',
|
|
title: 'Welcome!',
|
|
message: 'Successfully connected to notification system',
|
|
read: false,
|
|
createdAt: new Date().toISOString()
|
|
});
|
|
|
|
// Handle notification events
|
|
socket.on('notification:markRead', async (notificationId) => {
|
|
console.log(`📖 Marking notification ${notificationId} as read for user ${userId}`);
|
|
socket.emit('notification:read', notificationId);
|
|
socket.to(`user:${userId}`).emit('notification:read', notificationId);
|
|
});
|
|
|
|
socket.on('notification:markAllRead', async () => {
|
|
console.log(`📖 Marking all notifications as read for user ${userId}`);
|
|
socket.emit('notifications:allRead');
|
|
socket.to(`user:${userId}`).emit('notifications:allRead');
|
|
});
|
|
|
|
socket.on('notification:updatePreferences', async (preferences) => {
|
|
console.log(`⚙️ Updating preferences for user ${userId}:`, preferences);
|
|
socket.emit('preferences:updated', preferences);
|
|
});
|
|
|
|
socket.on('notification:subscribe', async (types) => {
|
|
console.log(`📬 User ${userId} subscribing to:`, types);
|
|
socket.emit('subscription:updated', { subscribed: types });
|
|
});
|
|
|
|
socket.on('notification:unsubscribe', async (types) => {
|
|
console.log(`🚫 User ${userId} unsubscribing from:`, types);
|
|
socket.emit('subscription:updated', { unsubscribed: types });
|
|
});
|
|
|
|
// Test notification sender
|
|
socket.on('test:notification', (data) => {
|
|
const notification = {
|
|
id: Date.now().toString(),
|
|
type: data.type || 'task_assigned',
|
|
priority: data.priority || 'medium',
|
|
title: data.title || 'Test Notification',
|
|
message: data.message || 'This is a test notification',
|
|
read: false,
|
|
createdAt: new Date().toISOString(),
|
|
metadata: data.metadata || {}
|
|
};
|
|
|
|
console.log(`📤 Sending test notification to user ${userId}`);
|
|
io.to(`user:${userId}`).emit('notification:new', notification);
|
|
});
|
|
|
|
// Handle disconnection
|
|
socket.on('disconnect', (reason) => {
|
|
console.log(`🔌 User ${userId} disconnected from socket ${socket.id}: ${reason}`);
|
|
});
|
|
});
|
|
|
|
// API endpoint to send notification (for testing)
|
|
app.post('/api/notifications/send', (req, res) => {
|
|
const { userId, notification } = req.body;
|
|
|
|
if (!userId || !notification) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: 'userId and notification are required'
|
|
});
|
|
}
|
|
|
|
const notificationData = {
|
|
id: Date.now().toString(),
|
|
...notification,
|
|
read: false,
|
|
createdAt: new Date().toISOString()
|
|
};
|
|
|
|
// Send via Socket.io
|
|
io.to(`user:${userId}`).emit('notification:new', notificationData);
|
|
|
|
console.log(`📤 API: Sent notification to user ${userId}`);
|
|
|
|
res.json({
|
|
success: true,
|
|
message: 'Notification sent',
|
|
notification: notificationData
|
|
});
|
|
});
|
|
|
|
// Start server
|
|
httpServer.listen(PORT, () => {
|
|
console.log(`
|
|
╔════════════════════════════════════════════╗
|
|
║ 🚀 Notification Test Server Running ║
|
|
║ Port: ${PORT} ║
|
|
║ Health: http://localhost:${PORT}/health ║
|
|
║ Socket.io: ws://localhost:${PORT} ║
|
|
║ Test Client: Open test-client.html ║
|
|
╚════════════════════════════════════════════╝
|
|
|
|
To get a test token:
|
|
curl -X POST http://localhost:${PORT}/auth/token -H "Content-Type: application/json" -d '{"userId":"test-user-123"}'
|
|
`);
|
|
}); |