From 2482d0e013db7d4af3d3f02335a5fb0444c4e003 Mon Sep 17 00:00:00 2001 From: Ahsan Date: Tue, 28 Mar 2023 00:05:53 +0600 Subject: [PATCH] example of secured room and namespace including client --- examples/secured-room-namespace/LICENSE | 21 +++++++ examples/secured-room-namespace/README.md | 15 +++++ examples/secured-room-namespace/index.html | 34 +++++++++++ examples/secured-room-namespace/index.ts | 22 +++++++ examples/secured-room-namespace/package.json | 55 ++++++++++++++++++ examples/secured-room-namespace/socketio.png | Bin 0 -> 40258 bytes examples/secured-room-namespace/src/socket.ts | 50 ++++++++++++++++ examples/secured-room-namespace/tsconfig.json | 19 ++++++ examples/secured-room-namespace/tslint.json | 6 ++ 9 files changed, 222 insertions(+) create mode 100644 examples/secured-room-namespace/LICENSE create mode 100644 examples/secured-room-namespace/README.md create mode 100644 examples/secured-room-namespace/index.html create mode 100644 examples/secured-room-namespace/index.ts create mode 100644 examples/secured-room-namespace/package.json create mode 100644 examples/secured-room-namespace/socketio.png create mode 100644 examples/secured-room-namespace/src/socket.ts create mode 100644 examples/secured-room-namespace/tsconfig.json create mode 100644 examples/secured-room-namespace/tslint.json diff --git a/examples/secured-room-namespace/LICENSE b/examples/secured-room-namespace/LICENSE new file mode 100644 index 0000000000..a1b765967f --- /dev/null +++ b/examples/secured-room-namespace/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Ahsan Aasim + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/examples/secured-room-namespace/README.md b/examples/secured-room-namespace/README.md new file mode 100644 index 0000000000..40d6d6ead1 --- /dev/null +++ b/examples/secured-room-namespace/README.md @@ -0,0 +1,15 @@ +

+Socket IO Logo +

+ +

+ +[![Codacy Badge](https://app.codacy.com/project/badge/Grade/c23b48873d0e4a5eb60c198c62776921)](https://app.codacy.com/gh/ahsanaasim/boiled-socket.io/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) + +

+ +## Socket.IO Secured Room & Namespace Example + +This is a Socket.IO boilerplate code in TypeScript that includes an example of authentication for securing the socket server, as well as examples of room and namespace usage. + +You can check out [this blog on Medium](https://medium.com/@ahsan.aasim/building-a-secured-socket-server-with-express-and-socket-io-in-typescript-eaa8eac54889) to gain a better understanding of the concept and codes used in building a secured socket server with Express and Socket.IO in TypeScript." \ No newline at end of file diff --git a/examples/secured-room-namespace/index.html b/examples/secured-room-namespace/index.html new file mode 100644 index 0000000000..004975c276 --- /dev/null +++ b/examples/secured-room-namespace/index.html @@ -0,0 +1,34 @@ + + + + + + \ No newline at end of file diff --git a/examples/secured-room-namespace/index.ts b/examples/secured-room-namespace/index.ts new file mode 100644 index 0000000000..909310ef0e --- /dev/null +++ b/examples/secured-room-namespace/index.ts @@ -0,0 +1,22 @@ +import express, { Express, Request, Response } from 'express'; +import { createServer } from 'http'; +import { Socket } from './src/socket'; + +const app: Express = express(); + +app.get('/', (req: Request, res: Response) => { + res.sendFile('index.html', { root: __dirname }); +}); + +const httpServer = createServer(app); + +const socket = new Socket(httpServer); +const space = socket.createNamespace('sessions'); + +socket.onConnect(space, (s) => { + const room = 'room_' + s.handshake.auth.room; + socket.joinRoom(room, s); + socket.emitToRoomInSpace('connect_msg', space, room, { test: 'test', room: s.handshake.auth.room }); +}); + +httpServer.listen(3000); diff --git a/examples/secured-room-namespace/package.json b/examples/secured-room-namespace/package.json new file mode 100644 index 0000000000..5c24f98c9b --- /dev/null +++ b/examples/secured-room-namespace/package.json @@ -0,0 +1,55 @@ +{ + "name": "boiled-socket.io", + "version": "1.0.1", + "description": "", + "main": "index.ts", + "scripts": { + "start:dev": "npx nodemon", + "build": "tsc", + "prepare": "npm run build", + "preversion": "npm run lint", + "version": "npm run format && git add -A src", + "postversion": "git push && git push --tags", + "format": "prettier --config .prettierrc 'src/**/*.ts' --write", + "lint": "tslint -p tsconfig.json", + "test": "mocha --timeout 10000 -r ts-node/register src/**/*.test.ts", + "test-single": "mocha --timeout 10000 -r ts-node/register", + "coverage": "nyc -r lcov -e .ts -x \"*.test.ts\" npm run test" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ahsanaasim/boiled-socket.io.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/ahsanaasim/boiled-socket.io/issues" + }, + "homepage": "https://github.com/ahsanaasim/boiled-socket.io#readme", + "dependencies": { + "@types/uuid": "^9.0.1", + "express": "^4.18.2", + "socket.io": "^4.6.1", + "socket.io-client": "^4.6.1", + "uuid": "^9.0.0" + }, + "optionalDependencies": { + "bufferutil": "^4.0.7", + "utf-8-validate": "^5.0.10" + }, + "devDependencies": { + "@types/chai": "^4.3.4", + "@types/express": "^4.17.17", + "@types/mocha": "^10.0.1", + "@types/node": "^18.15.6", + "chai": "^4.3.7", + "mocha": "^10.2.0", + "nodemon": "^2.0.22", + "nyc": "^15.1.0", + "prettier": "^2.8.7", + "ts-node": "^10.9.1", + "tslint": "^6.1.3", + "tslint-config-prettier": "^1.18.0", + "typescript": "^5.0.2" + } +} diff --git a/examples/secured-room-namespace/socketio.png b/examples/secured-room-namespace/socketio.png new file mode 100644 index 0000000000000000000000000000000000000000..4d1760f9b0ad1b09cb4b77009be86a501376987b GIT binary patch literal 40258 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 { + this.io.use(async (socket, next) => { + try { + if (socket.handshake.auth.token === 'aa') { + next(); + } else { + const err = new Error('unauthorized'); + next(err); + } + } catch (e) { + next(new Error('unauthorized')); + } + }); + }; + + public createNamespace = (spaceName: string): Namespace => { + return this.io.of('/' + spaceName); + }; + + public onConnect = (space: Namespace, cb: (socket: IOSocket) => void) => { + space.on('connection', (socket: IOSocket) => { + cb(socket); + }); + }; + + public joinRoom = (room: string, socket: IOSocket) => { + socket.join(room); + }; + + public emitToRoomInSpace = (name: string, space: Namespace, room: string, data: any) => { + space.to(room).emit(name, data); + }; + + public emitToSpace = (name: string, space: Namespace, data: any) => { + space.emit(name, data); + }; +} diff --git a/examples/secured-room-namespace/tsconfig.json b/examples/secured-room-namespace/tsconfig.json new file mode 100644 index 0000000000..34f4d1702b --- /dev/null +++ b/examples/secured-room-namespace/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "esModuleInterop": true, + "target": "es5", + "module": "commonjs", + "declaration": true, + "outDir": "./lib", + "strict": true, + "rootDir": "./src", + "baseUrl": "./" + }, + "include": [ + "src" + ], + "exclude": [ + "node_modules", + "**/__tests__/*" + ] +} \ No newline at end of file diff --git a/examples/secured-room-namespace/tslint.json b/examples/secured-room-namespace/tslint.json new file mode 100644 index 0000000000..71287e59b5 --- /dev/null +++ b/examples/secured-room-namespace/tslint.json @@ -0,0 +1,6 @@ +{ + "extends": [ + "tslint:recommended", + "tslint-config-prettier" + ] +} \ No newline at end of file