diff --git a/README.md b/README.md index e80d707..d38c618 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,166 @@ # Socket.IO Admin UI -WIP +![dashboard screenshot](assets/dashboard.png) + +## Table of contents + +- [How to use](#how-to-use) + - [Server-side](#server-side) + - [Client-side](#client-side) +- [Available options](#available-options) + - [`auth`](#auth) + - [`namespaceName`](#namespacename) + - [`readonly`](#readonly) + - [`serverId`](#serverid) + - [`store`](#store) +- [How it works](#how-it-works) +- [License](#license) + +## How to use + +### Server-side + +First, install the `@socket.io/admin-ui` package: + +``` +npm i @socket.io/admin-ui +``` + +And then invoke the `instrument` method on your Socket.IO server: + +```js +const { createServer } = require("http"); +const { Server } = require("socket.io"); +const { instrument } = require("@socket.io/admin-ui"); + +const httpServer = createServer(); + +const io = new Server(httpServer, { + cors: { + origin: ["https://admin.socket.io"] + } +}); + +instrument(io, { + auth: false +}); + +httpServer.listen(3000); +``` + +The module is compatible with: + +- Socket.IO v4 server +- Socket.IO v3 server (>= 3.1.0), but without the operations on rooms (join, leave, disconnection) + +### Client-side + +You can then head up to https://admin.socket.io, or host the files found in the `ui/dist` folder. + +**Important note**: the website at https://admin.socket.io is totally static (hosted on [Vercel](https://vercel.com)), we do not (and will never) store any information about yourself or your browser (no tracking, no analytics, ...). That being said, hosting the files yourself is totally fine. + +You should see the following modal: + +![login modal screenshot](assets/login-modal.png) + +Please enter the URL of your server, including the namespace (for example, `http://localhost:3000/admin` or `https://example.com/admin`) and the credentials, if applicable (see the `auth` option [below](#auth)). + +### Available options + +#### `auth` + +Default value: `-` + +This option is mandatory. You can either disable authentication (please use with caution): + +```js +instrument(io, { + auth: false +}); +``` + +Or use basic authentication: + +```js +instrument(io, { + auth: { + type: "basic", + username: "admin", + password: "$2b$10$heqvAkYMez.Va6Et2uXInOnkCT6/uQj1brkrbyG3LpopDklcq7ZOS" // "changeit" encrypted with bcrypt + }, +}); +``` + +#### `namespaceName` + +Default value: `/admin` + +The name of the namespace which will be created to handle the administrative tasks. + +```js +instrument(io, { + namespaceName: "custom" +}); +``` + +This namespace is a classic Socket.IO namespace, you can access it with: + +```js +const adminNamespace = io.of("/admin"); +``` + +More information [here](https://socket.io/docs/v4/namespaces/). + +#### `readonly` + +Default value: `false` + +Whether to put the admin UI in read-only mode (no join, leave or disconnect allowed). + +```js +instrument(io, { + readonly: true +}); +``` + +#### `serverId` + +Default value: `require("os").hostname()` + +The ID of the given server. If you have several Socket.IO servers on the same machine, please give them a distinct ID: + +```js +instrument(io, { + serverId: `${require("os").hostname()}#${process.pid}` +}); +``` + +#### `store` + +Default value: `new InMemoryStore()` + +The store is used to store the session IDs so the user do not have to retype the credentials upon reconnection. + +If you use basic authentication in a multi-server setup, you should provide a custom store: + +```js +const { instrument, RedisStore } = require("@socket.io/admin-ui"); + +instrument(io, { + store: new RedisStore(redisClient) +}); +``` + +## How it works + +You can check the details of the implementation in the [lib/index.ts](lib/index.ts) file. + +The `instrument` method simply: + +- creates a [namespace](https://socket.io/docs/v4/namespaces/) and adds an authentication [middleware](https://socket.io/docs/v4/middlewares/) if applicable +- register listeners for the `connection` and `disconnect` event for each existing namespaces to track socket instances +- register a timer which will periodically send stats from the server to the UI +- register handlers for the `join`, `leave` and `_disconnect` commands sent from the UI ## License diff --git a/assets/dashboard.png b/assets/dashboard.png new file mode 100644 index 0000000..d728548 Binary files /dev/null and b/assets/dashboard.png differ diff --git a/assets/login-modal.png b/assets/login-modal.png new file mode 100644 index 0000000..fc25478 Binary files /dev/null and b/assets/login-modal.png differ diff --git a/package.json b/package.json index ebd5b68..7c3e2a4 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "version": "0.0.1", "description": "Admin UI for Socket.IO", "files": [ - "dist/" + "dist/", + "ui/dist/" ], "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -15,7 +16,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/socketio/socket.io-admin.git" + "url": "git+https://github.com/socketio/socket.io-admin-ui.git" }, "keywords": [ "socket.io", @@ -25,12 +26,12 @@ "author": "Damien Arrachequesne ", "license": "MIT", "bugs": { - "url": "https://github.com/socketio/socket.io-admin/issues" + "url": "https://github.com/socketio/socket.io-admin-ui/issues" }, - "homepage": "https://github.com/socketio/socket.io-admin#readme", + "homepage": "https://github.com/socketio/socket.io-admin-ui#readme", "dependencies": { - "@types/bcrypt": "^3.0.0", - "bcrypt": "^5.0.1", + "@types/bcrypt": "~3.0.0", + "bcrypt": "~5.0.1", "debug": "~4.3.1" }, "peerDependencies": {