UNPKG

tyo-mq

Version:

Distributed Message Pub/Sub Service with socket.io

120 lines (103 loc) 4.12 kB
/** * Client helpers for pending authorization requests and signed manager actions. */ 'use strict'; const ioClient = require('socket.io-client'); const adminSignature = require('./admin-signature'); function connect(options) { options = options || {}; var host = options.host || process.env.TYO_MQ_HOST || 'localhost'; var port = options.port || process.env.TYO_MQ_PORT || 17352; var protocol = options.protocol || process.env.TYO_MQ_PROTOCOL || 'http'; var url = options.url || (protocol + '://' + host + ':' + port); var timeout = options.timeout || 5000; var socket = ioClient(url, {transports: ['websocket']}); return new Promise(function (resolve, reject) { var timer = setTimeout(function () { socket.disconnect(); reject(new Error('Timed out connecting to ' + url)); }, timeout); socket.once('connect', function () { clearTimeout(timer); resolve(socket); }); socket.once('connect_error', function (err) { clearTimeout(timer); socket.disconnect(); reject(err); }); }); } function emitAck(socket, event, payload, timeout) { timeout = timeout || 5000; return new Promise(function (resolve, reject) { var timer = setTimeout(function () { reject(new Error('Timed out waiting for ' + event + ' response')); }, timeout); socket.emit(event, payload, function (response) { clearTimeout(timer); if (!response || response.ok === false) { var err = new Error((response && response.message) || (event + ' failed')); err.response = response; reject(err); return; } resolve(response); }); }); } function withSocket(options, fn) { return connect(options).then(function (socket) { return Promise.resolve(fn(socket)).finally(function () { socket.disconnect(); }); }); } function submitAuthorizationRequest(request, options) { return withSocket(options, function (socket) { return emitAck(socket, 'AUTHORIZATION_REQUEST', request, options && options.timeout); }); } function signedManagerPayload(managerToken, action, body) { body = body || {}; return { body: body, proof: adminSignature.createAdminProof(managerToken, action, body) }; } function nextAuthorizationRequest(managerToken, filter, options) { return withSocket(options, function (socket) { return emitAck(socket, 'AUTHORIZATION_NEXT', signedManagerPayload(managerToken, 'AUTHORIZATION_NEXT', filter || {}), options && options.timeout); }); } function decideAuthorizationRequest(managerToken, decision, options) { return withSocket(options, function (socket) { return emitAck(socket, 'AUTHORIZATION_DECIDE', signedManagerPayload(managerToken, 'AUTHORIZATION_DECIDE', decision || {}), options && options.timeout); }); } function authManagementCommand(adminToken, command, options) { return withSocket(options, function (socket) { return emitAck(socket, 'AUTH_MANAGEMENT_COMMAND', signedManagerPayload(adminToken, 'AUTH_MANAGEMENT_COMMAND', command || {}), options && options.timeout); }); } function nextRealmAuthorizationRequest(managerKey, realm, options) { return nextAuthorizationRequest(managerKey, {realm: realm}, options); } function decideRealmAuthorizationRequest(managerKey, decision, options) { return decideAuthorizationRequest(managerKey, decision, options); } module.exports = { authManagementCommand: authManagementCommand, createAdminProof: adminSignature.createAdminProof, decideAuthorizationRequest: decideAuthorizationRequest, decideRealmAuthorizationRequest: decideRealmAuthorizationRequest, nextAuthorizationRequest: nextAuthorizationRequest, nextRealmAuthorizationRequest: nextRealmAuthorizationRequest, submitAuthorizationRequest: submitAuthorizationRequest };