Api

OidcSocketAdminMiddleware

Role guard that restricts a Socket.IO namespace to users with the admin role. Must be chained after OidcSocketMiddleware.

OidcSocketAdminMiddleware

OidcSocketAdminMiddleware is a role guard. It rejects Socket.IO connections that do not carry the "admin" role. It relies on socket.roles and socket.userRole being already set by OidcSocketMiddleware, so it must always be placed after it in the middlewares array.

Registration

import { OidcSocketMiddleware, OidcSocketAdminMiddleware } from "ioserver-oidc";

server.addService({
  name: "admin",
  service: AdminService,
  middlewares: [OidcSocketMiddleware, OidcSocketAdminMiddleware],
});

Middlewares are applied in array order. OidcSocketMiddleware runs first and sets socket.roles / socket.userRole. OidcSocketAdminMiddleware then checks those values.

Check logic

const roles: string[] = Array.isArray(socket.roles)
  ? socket.roles
  : typeof socket.userRole === "string"
    ? [socket.userRole]
    : [];

if (!roles.includes("admin")) {
  return next(new Error("ERR_FORBIDDEN"));
}

The middleware accepts the connection if "admin" appears anywhere in socket.roles. If socket.roles is not an array (e.g. OidcSocketMiddleware was not in the chain), it falls back to checking socket.userRole as a single-element array.

Error handling

On rejection, the client receives a connect_error event:

socket.on("connect_error", (err) => {
  console.error(err.message); // "ERR_FORBIDDEN"
});
Error messageCondition
ERR_FORBIDDENAuthenticated user does not hold the "admin" role

Applying to multiple services

// Non-admin users: authentication only
server.addService({
  name: "tenants",
  service: TenantService,
  middlewares: [OidcSocketMiddleware],
});

// Admin users only: authentication + role guard
server.addService({
  name: "users",
  service: UserService,
  middlewares: [OidcSocketMiddleware, OidcSocketAdminMiddleware],
});

Source

src/OidcSocketAdminMiddleware.ts

Copyright © 2026