From 95fc25d0add0dab8f36bbca83be8e0b461b3e197 Mon Sep 17 00:00:00 2001 From: wancat Date: Mon, 24 Jul 2023 12:18:01 +0800 Subject: [PATCH] feat: connect to different container by sessions Based on the file summaries provided, the best label for this commit would be "feat". This is because the commit introduces several new features to the codebase, such as adding a new ESLint rule, adding a new property to a function, adding authentication middleware, adding a query parameter, and adding a new function to handle user authentication.: update authentication and session handling - Add `"camelcase"` rule to ESLint configuration - Add `containerId` property to the `newSession` object in the `createSession` function - Add authentication middleware to the socket.io connection - Add a query parameter `session_id` to the socket.io connection in `client.js` - Add `defaultUser` function to handle user authentication - Update the `authMiddleware` function to use the `defaultUser` function - Add `defaultUser` function to handle user authentication in `auth.js` - Update `getOrCreateContainer` function to use the `id` parameter instead of `name` parameter --- .eslintrc.js | 1 + .../src/api/controllers/sessionController.js | 1 + server/src/api/socket.js | 28 ++++++++++++++++++- server/src/client.js | 9 +++++- server/src/middleware/auth.js | 12 ++------ server/src/utils/auth.js | 14 ++++++++++ server/src/utils/docker.js | 7 +++-- 7 files changed, 57 insertions(+), 15 deletions(-) create mode 100644 server/src/utils/auth.js diff --git a/.eslintrc.js b/.eslintrc.js index e36019a..ebfa30a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -19,5 +19,6 @@ module.exports = { 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'import/extensions': 'off', + camelcase: ['error', { properties: 'never', ignoreDestructuring: true }], }, } diff --git a/server/src/api/controllers/sessionController.js b/server/src/api/controllers/sessionController.js index 574e50d..19d431d 100644 --- a/server/src/api/controllers/sessionController.js +++ b/server/src/api/controllers/sessionController.js @@ -25,6 +25,7 @@ export async function createSession(req, res) { const newSession = new Session({ user: req.user, quest, + containerId: `quest-${quest.id}-${req.user.username}-${Date.now()}`, }) try { diff --git a/server/src/api/socket.js b/server/src/api/socket.js index e66fc2a..5f08973 100644 --- a/server/src/api/socket.js +++ b/server/src/api/socket.js @@ -1,12 +1,38 @@ import { Server } from 'socket.io' import { getOrCreateContainer, attachContainer } from '../utils/docker.js' +import Session from '../models/session.js' +import { defaultUser } from '../utils/auth.js' export default (server) => { const io = new Server(server) + io.use(async (socket, next) => { + console.log('Authenticating...') + try { + const user = await defaultUser() + // eslint-disable-next-line no-param-reassign + socket.user = user + next() + } catch (err) { + console.error(err) + next(err) + } + }) + io.on('connection', async (socket) => { console.log('Connected to the client.') - const container = await getOrCreateContainer('odyssey-test') + const session = await Session.findOne({ + _id: socket.handshake.query.session_id, + user: socket.user, + }) + + if (!session) { + socket.send('Session not found.') + socket.disconnect() + return + } + + const container = await getOrCreateContainer(session.containerId) const stream = await attachContainer(container) stream.on('data', (chunk) => { diff --git a/server/src/client.js b/server/src/client.js index cdbf7b8..40e16cd 100644 --- a/server/src/client.js +++ b/server/src/client.js @@ -5,7 +5,14 @@ stdin.setRawMode(true) stdin.resume() stdin.setEncoding('utf8') -const socket = io('ws://localhost:3000') +const sessionId = process.argv[2] +console.log(`Session ID: ${sessionId}`) + +const socket = io('ws://localhost:3000', { + query: { + session_id: sessionId, + }, +}) socket.on('open', function open() { console.log('Connected to the server.') diff --git a/server/src/middleware/auth.js b/server/src/middleware/auth.js index 43c8826..62bb190 100644 --- a/server/src/middleware/auth.js +++ b/server/src/middleware/auth.js @@ -1,17 +1,9 @@ /* eslint-disable import/prefer-default-export */ -import User from '../models/user.js' +import { defaultUser } from '../utils/auth.js' export async function authMiddleware(req, res, next) { try { - let user = await User.findOne({ username: 'defaultUser' }) - if (!user) { - user = new User({ - username: 'defaultUser', - email: 'john@example.com', - }) - await user.save() - } - req.user = user + req.user = await defaultUser() next() } catch (err) { res.status(500).json({ message: err.message }) diff --git a/server/src/utils/auth.js b/server/src/utils/auth.js new file mode 100644 index 0000000..e33cf5f --- /dev/null +++ b/server/src/utils/auth.js @@ -0,0 +1,14 @@ +/* eslint-disable import/prefer-default-export */ +import User from '../models/user.js' + +export async function defaultUser() { + let user = await User.findOne({ username: 'defaultUser' }) + if (!user) { + user = new User({ + username: 'defaultUser', + email: 'jackson@example.com', + }) + await user.save() + } + return user +} diff --git a/server/src/utils/docker.js b/server/src/utils/docker.js index d6b56ac..a78b738 100644 --- a/server/src/utils/docker.js +++ b/server/src/utils/docker.js @@ -27,9 +27,10 @@ export async function getContainer(id) { return container } -export async function getOrCreateContainer(name) { +export async function getOrCreateContainer(id) { + console.log(`Getting container: ${id}`) try { - const container = engine.getContainer(name) + const container = engine.getContainer(id) if (!(await container.inspect()).State.Running) { await container.start() } @@ -37,7 +38,7 @@ export async function getOrCreateContainer(name) { } catch (error) { const container = await engine.createContainer({ ...containerOptions, - name, + name: id, }) await container.start() console.log(container.id)