UNPKG

realm-object-server

Version:

Realm Object Server

88 lines 3.81 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const uws = require("uws"); const errors = require("../errors"); const util_1 = require("./util"); class ServiceWebSocketServer extends uws.Server { constructor(logger, tokenValidator) { super({ noServer: true }); this.tokenValidator = tokenValidator; this.logger = logger; } setLogger(logger) { this.logger = logger; } upgradeAuthenticated(req, socket, head, mustBeAdmin = false) { return __awaiter(this, void 0, void 0, function* () { const client = yield this.upgradeWebSocket(req, socket, head); const authenticatedClient = new Promise((resolve, reject) => { client.on("message", message => { try { const token = this.isValidFirstMessage(message, mustBeAdmin); if (token) { socket.identity = token.identity; resolve(client); } else { throw new Error("Not a valid first message"); } } catch (err) { if (err instanceof SyntaxError) { err = new errors.realm.InvalidCredentials({ title: "Expected a serialized JSON object as the first message" }); } reject(err); } }); }); const ms = ServiceWebSocketServer.AUTHENTICATION_TIMEOUT; return util_1.timeout(authenticatedClient, ms).catch((err) => { this.logger.debug(`Couldn't upgrade WebSocket: ${err.stack}`); if (client.readyState === uws.OPEN || client.readyState === uws.CONNECTING) { client.close(1008, err.message); } throw err; }); }); } isValidFirstMessage(message, mustBeAdmin) { const msg = JSON.parse(message); if (!msg.action) { throw new errors.realm.MissingParameters("action"); } if (msg.action === "authenticate") { if (!msg.token) { throw new errors.realm.MissingParameters("token"); } return this.tokenValidator.parse(msg.token, { mustBeAdmin }); } else { const example = '{ action: "authenticate", ... }'; throw new errors.realm.InvalidCredentials({ title: `Expected an authentication message: ${example}` }); } } upgradeWebSocket(req, socket, head) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { this.handleUpgrade(req, socket, head, (client) => { resolve(client); }); }); }); } } ServiceWebSocketServer.AUTHENTICATION_TIMEOUT = 1000; exports.ServiceWebSocketServer = ServiceWebSocketServer; //# sourceMappingURL=websocket.js.map