general chat
This commit is contained in:
@@ -5,10 +5,6 @@ WORKDIR /app
|
|||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
|
|
||||||
RUN npm install
|
RUN npm install
|
||||||
RUN npm install dotenv
|
|
||||||
RUN npm install pg
|
|
||||||
RUN npm install bcrypt
|
|
||||||
RUN npm install jsonwebtoken
|
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
|||||||
+19
-1
@@ -1,20 +1,38 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
|
const http = require('http');
|
||||||
|
const cors = require('cors');
|
||||||
|
const {Server} = require('socket.io');
|
||||||
const authRouter = require('./routes/auth');
|
const authRouter = require('./routes/auth');
|
||||||
|
const chatRouter = require('./routes/global_chat');
|
||||||
const {waitForDb, createTables} = require('./db');
|
const {waitForDb, createTables} = require('./db');
|
||||||
|
const setupSocketIO = require('./services/socket');
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
const server = http.createServer(app);
|
||||||
|
const io = new Server(server,
|
||||||
|
{
|
||||||
|
cors:
|
||||||
|
{
|
||||||
|
origin: "*",
|
||||||
|
methods: ["GET", "POST"]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use(cors());
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
|
setupSocketIO(io);
|
||||||
|
|
||||||
async function startServer()
|
async function startServer()
|
||||||
{
|
{
|
||||||
await waitForDb();
|
await waitForDb();
|
||||||
await createTables();
|
await createTables();
|
||||||
|
|
||||||
app.use('/api/auth', authRouter);
|
app.use('/api/auth', authRouter);
|
||||||
|
app.use('/api/global_chat', chatRouter);
|
||||||
app.get('/api', (req, res) => res.send('Backend running'));
|
app.get('/api', (req, res) => res.send('Backend running'));
|
||||||
|
|
||||||
app.listen(3001, () =>
|
server.listen(3001, () =>
|
||||||
{
|
{
|
||||||
console.log('Server ready and listening');
|
console.log('Server ready and listening');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
{
|
{
|
||||||
"dependencies":
|
"dependencies":
|
||||||
{
|
{
|
||||||
"express": "^4.18.2"
|
"express": "^4.18.2",
|
||||||
|
"pg": "^8.11.3",
|
||||||
|
"bcrypt": "^5.1.0",
|
||||||
|
"jsonwebtoken": "^9.0.2",
|
||||||
|
"dotenv": "^17.2.3",
|
||||||
|
"socket.io": "^4.6.1",
|
||||||
|
"cors": "^2.8.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
const chatService = require('../services/global_chat');
|
||||||
|
const authenticateToken = require('../middleware/auth');
|
||||||
|
|
||||||
|
router.get('/messages', authenticateToken, async(req, res) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const messages = await chatService.getRecentMessages(50);
|
||||||
|
res.json(messages);
|
||||||
|
}
|
||||||
|
catch(err)
|
||||||
|
{
|
||||||
|
console.error(err);
|
||||||
|
res.status(500).json({error: 'Server error'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
@@ -21,7 +21,10 @@ async function login(username, password)
|
|||||||
|
|
||||||
const token = jwt.sign
|
const token = jwt.sign
|
||||||
(
|
(
|
||||||
{userId: user.id},
|
{
|
||||||
|
userId: user.id,
|
||||||
|
username: username
|
||||||
|
},
|
||||||
process.env.JWT_SECRET,
|
process.env.JWT_SECRET,
|
||||||
{expiresIn: '1h'}
|
{expiresIn: '1h'}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
const {query} = require('../db');
|
||||||
|
|
||||||
|
async function saveMessage(userId, content)
|
||||||
|
{
|
||||||
|
const result = await query
|
||||||
|
(
|
||||||
|
'INSERT INTO messages (sender_id, content) VALUES ($1 ,$2) RETURNING *',
|
||||||
|
[userId, content]
|
||||||
|
);
|
||||||
|
return (result.rows[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getRecentMessages(limit = 50)
|
||||||
|
{
|
||||||
|
const result = await query
|
||||||
|
(
|
||||||
|
`SELECT m.sender_id, m.content, m.created_at, u.username
|
||||||
|
FROM messages m
|
||||||
|
JOIN users u ON m.sender_id = u.id
|
||||||
|
ORDER BY m.created_at DESC
|
||||||
|
LIMIT $1`,
|
||||||
|
[limit]
|
||||||
|
);
|
||||||
|
return (result.rows.reverse());
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports =
|
||||||
|
{
|
||||||
|
saveMessage,
|
||||||
|
getRecentMessages
|
||||||
|
};
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
const jwt = require('jsonwebtoken');
|
||||||
|
const chatService = require('./global_chat');
|
||||||
|
|
||||||
|
function setupSocketIO(io)
|
||||||
|
{
|
||||||
|
io.use((socket, next) =>
|
||||||
|
{
|
||||||
|
const token = socket.handshake.auth.token;
|
||||||
|
if (!token)
|
||||||
|
return (next(new Error('Authentication error')));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
||||||
|
socket.user = decoded;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
catch(err)
|
||||||
|
{
|
||||||
|
next(new Error('Authentication error'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
io.on('connection', (socket) =>
|
||||||
|
{
|
||||||
|
console.log(`User connected: ${socket.user.username}`);
|
||||||
|
|
||||||
|
socket.join('general-chat');
|
||||||
|
socket.on('chat-message', async(data) =>
|
||||||
|
{
|
||||||
|
const message = await chatService.saveMessage(socket.user.userId, data.content);
|
||||||
|
io.to('general-chat').emit('chat-message',
|
||||||
|
{
|
||||||
|
id:message.id,
|
||||||
|
username: socket.user.username,
|
||||||
|
content: message.content,
|
||||||
|
created_at: message.created_at
|
||||||
|
});
|
||||||
|
});
|
||||||
|
socket.on('disconnect', () =>
|
||||||
|
{
|
||||||
|
console.log(`User disconnected: ${socket.user.username}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = setupSocketIO;
|
||||||
Reference in New Issue
Block a user