fix authentication + public key linked to socket.io
This commit is contained in:
		
							
								
								
									
										29
									
								
								src/app.js
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/app.js
									
									
									
									
									
								
							| @@ -16,6 +16,13 @@ const routes = require(__dirname + '/routes'); | ||||
| // session (used for login challenge) | ||||
| const session = require('express-session'); | ||||
| const SQLiteStore = require('connect-sqlite3')(session); | ||||
| const sessionMiddleware = session({ | ||||
|     store: new SQLiteStore, | ||||
|     secret: process.env.COOKIE_SECRET || "toto", | ||||
|     resave: false, | ||||
|     saveUninitialized: true, | ||||
|     cookie: { maxAge: 7 * 24 * 60 * 60 * 1000 } // 1 week | ||||
| }); | ||||
|  | ||||
| // configure app | ||||
| app.set("port", port); | ||||
| @@ -23,24 +30,24 @@ app.set('view engine', 'pug'); | ||||
| app.set('views', __dirname + '/views'); | ||||
| app.use(cookieParser()); | ||||
| app.use(express.json()); | ||||
| app.use(session({ | ||||
|     store: new SQLiteStore, | ||||
|     secret: process.env.COOKIE_SECRET || "toto", | ||||
|     resave: false, | ||||
|     saveUninitialized: true, | ||||
|     cookie: { maxAge: 7 * 24 * 60 * 60 * 1000 } // 1 week | ||||
| })); | ||||
| app.use(sessionMiddleware); | ||||
|  | ||||
| app.use("/", routes); | ||||
| // bootstrap | ||||
| app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css')); | ||||
|  | ||||
| // socket.io | ||||
| io.engine.use(sessionMiddleware); | ||||
| io.on('connection', (socket) => { | ||||
|   console.log('A user connected'); | ||||
|   socket.on('disconnect', () => { | ||||
|     console.log('User disconnected'); | ||||
|   }); | ||||
|     const session = socket.request.session; | ||||
|     console.log('A user connected'); | ||||
|     socket.on('disconnect', () => { | ||||
|         console.log('User disconnected'); | ||||
|     }); | ||||
|     socket.on('chat message', (msg) => { | ||||
|         console.log('message: ' + msg + ', sender: ' + session.id); | ||||
|         console.log(session.publicKey); | ||||
|     }); | ||||
| }); | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,6 @@ const authentication = { | ||||
|                         msg | ||||
|                     ); | ||||
|                     if (verified) { | ||||
|                         console.log('Signature verified successfully with public key:', pemPubKey); | ||||
|                         return pemPubKey; | ||||
|                     } | ||||
|                 } catch (err) { | ||||
|   | ||||
| @@ -36,13 +36,19 @@ const accountController = { | ||||
|         const { signature } = req.body; | ||||
|         const publicKeys = await database.getPublicKeys(); | ||||
|         const msg = new TextEncoder().encode(req.session.randomNumber); | ||||
|         const sig = new TextEncoder().encode(signature); | ||||
|         let validKey = authentication.verifySignature(msg, sig, publicKeys); | ||||
|         const sig = Buffer.from(signature, 'base64'); | ||||
|         let validKey = await authentication.verifySignature(msg, sig, publicKeys); | ||||
|         if (validKey !== null) { | ||||
|             req.session.publicKey = validKey; | ||||
|             socket.auth = { validKey }; | ||||
|             socket.connect(); | ||||
|             return res.status(200).json({ message: "Challenge solved successfully" }); | ||||
|             req.session.save((err) => { | ||||
|                 if (err) { | ||||
|                     console.error("Error saving session:", err); | ||||
|                     return res.status(500).json({ error: "Session save error" }); | ||||
|                 } | ||||
|                 socket.auth = { validKey }; | ||||
|                 socket.connect(); | ||||
|                 return res.status(200).json({ message: "Challenge solved successfully" }); | ||||
|             }); | ||||
|         } else { | ||||
|             return res.status(400).json({ error: "Challenge failed" }); | ||||
|         } | ||||
|   | ||||
| @@ -3,6 +3,7 @@ const path = require('path'); | ||||
| const mainController = { | ||||
|     root: (req, res) => { | ||||
|         let pubKey = req.session.publicKey; | ||||
|         console.log(pubKey); | ||||
|         let isLoggedIn = typeof pubKey !== 'undefined'; | ||||
|         res.render('index', {isLoggedIn, pubKey}); | ||||
|     }, | ||||
|   | ||||
| @@ -3,7 +3,8 @@ import { io } from "socket.io-client"; | ||||
| const URL = "http://localhost:3333"; | ||||
| const socket = io(URL, { | ||||
|   autoConnect: false, | ||||
|   transports: ['websocket', 'polling'] | ||||
|   transports: ['websocket', 'polling'], | ||||
|   withCredentials: true | ||||
| }); | ||||
|  | ||||
| // log during dev | ||||
|   | ||||
| @@ -45,6 +45,9 @@ html(lang="en-US") | ||||
|           .btn-group.mr-2(role="group", aria-label="logout") | ||||
|             a#logout.btn.btn-secondary(href="./account/logout") logout | ||||
|  | ||||
|  | ||||
|         p#pubkey #{pubKey} | ||||
|  | ||||
|         ul#messages | ||||
|  | ||||
|         form#form(action="") | ||||
| @@ -52,3 +55,4 @@ html(lang="en-US") | ||||
|           button Send | ||||
|  | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -29,9 +29,45 @@ describe('authentication module', () => { | ||||
|             const result = await authentication.verifySignature(encodedData, signature, publicKeys); | ||||
|             expect(result).toBe(pemKey); | ||||
|  | ||||
|             let fakeKey = `-----BEGIN PUBLIC KEY-----MCowBQYDK2VwAyEAmrBLT6lyiFh/eUticsIFNY6AkjXuQPqj0Qvb99pCJJk=-----END PUBLIC KEY-----` | ||||
|             let fakeKey = `-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAmrBLT6lyiFh/eUticsIFNY6AkjXuQPqj0Qvb99pCJJk=\n-----END PUBLIC KEY-----` | ||||
|             const result2 = await authentication.verifySignature(encodedData, signature, [fakeKey,]); | ||||
|             expect(result2).toBe(null); | ||||
|         }); | ||||
|  | ||||
|         it('encoding and decoding test', async () => { | ||||
|             const testkey = '-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEILXfcMirlUiI/o/r+8rK7ZIP0fyAMynxYzJXCI6BJHPk\n-----END PRIVATE KEY-----'; | ||||
|             const base64 = testkey.replace(`-----BEGIN PRIVATE KEY-----`, '').replace(`-----END PRIVATE KEY-----`, '').trim(); | ||||
|  | ||||
|             const derBuffer = Buffer.from(base64, 'base64'); | ||||
|  | ||||
|             let privkey = await crypto.subtle.importKey( | ||||
|                 "pkcs8", | ||||
|                 derBuffer, | ||||
|                 { | ||||
|                     name: "Ed25519", | ||||
|                 }, | ||||
|                 true, | ||||
|                 ["sign"], | ||||
|             ); | ||||
|             const msg2 = '12f4b99e3784ac2e8b95427533a3dbc4'; | ||||
|             const encoder2 = new TextEncoder(); | ||||
|             const encodedData2 = encoder2.encode(msg2); | ||||
|             const signature2 = await crypto.subtle.sign( | ||||
|                 { | ||||
|                     name: "Ed25519", | ||||
|                 }, | ||||
|                 privkey, | ||||
|                 encodedData2, | ||||
|             ); | ||||
|             const signatureBase64 = Buffer.from(signature2).toString('base64'); | ||||
|  | ||||
|             const sig = Buffer.from(signatureBase64, 'base64'); | ||||
|  | ||||
|             let pemKey2 = '-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEALrj4A3Vftz5TgWXEHi5KG+HD+uQLGB3bGc4TprDi9kE=\n-----END PUBLIC KEY-----' | ||||
|             const publicKeys2 = [pemKey2,]; | ||||
|             const result3 = await authentication.verifySignature(encodedData2, sig, publicKeys2); | ||||
|             expect(result3).toBe(pemKey2); | ||||
|  | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user