Skip to content

Access ​

Authentication assigns identity; rights control room operations.

ts
import { Server } from "@jolly-pixel/network";

const server = new Server({
  defaultRole: "viewer",
  rights: {
    viewer: {
      "drawing.$join": "write",
      "drawing.*": "read"
    }
  }
});

Authentication ​

AuthenticationProvider implements authenticate(request), returning an identity or null, optionally through a promise. Identity lasts for one connection.

Client profile cannot assign identity or role; server profile fields override it.

request.credential is the credential the client offered, decoded by its transport, or undefined. A malformed WebSocket credential is refused with 4401 before any provider runs.

BypassAuthentication ​

The default BypassAuthentication assigns defaultRole.

PasswordAuthentication ​

PasswordAuthentication from /node grants its role for a correct credential. Missing credentials use the default role unless mandatory is true.

The same entry exports the scrypt helpers it uses:

ts
interface PasswordHash {
  digest: Buffer;
  salt: Buffer;
}

function hashPassword(password: string): Promise<PasswordHash>;
function verifyPassword(password: string, hash: PasswordHash): Promise<boolean>;

hashPassword draws a fresh random salt on every call. verifyPassword compares digests in constant time.

Revocation ​

Refusal emits unauthorized and stops retries. server.revoke(subject) forces reauthentication. Use HTTPS/WSS for remote credentials.

Room admission ​

The server option admits(identity, room) limits an identity to some rooms. It runs before the room is resolved and before rights are checked. false, or a thrown error, refuses the join with a denied envelope for $join. Without the option every room admits every identity.

Profile updates ​

A provider's optional watchProfiles(listener) reports (subject, patch) when server profile fields change. The server applies each report with server.updateProfile(subject, patch), so open connections keep their identity and role while rooms show the new profile.

Rights ​

Rules match ${extension.name}.${event}. First match wins; * matches any text. write permits both directions, read receiving, and void neither.

Joining requires write on $join. A nonempty table denies unmatched keys; no table or {} permits all. Set defaultRole when using named roles.

Opaque inbound protocols cannot be registered with configured rights.

RightsTable / RightsGate ​

RightsTable resolves keys with check; scope returns a namespace-bound RightsGate. replace(rights, defaultRole?) swaps the rules of a configured table, and its gates drop what they cached. scope(namespace, { readOnly: true }) caps every message right at read. gate.gated is true when the table is configured or the scope is read-only; a room then checks each message against the gate.

RightsPattern ​

new RightsPattern(source).matches(key) tests one rule pattern against a key, with the same * matching as the table.

Client access ​

room.can(event) supports UI decisions. The server checks each action and emits denied when refused.