@fanoutio/connect-grip
Advanced tools
Comparing version 0.1.0-beta.7 to 0.1.0-beta.8
/// <reference types="node" /> | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
import * as CallableInstance from "callable-instance"; | ||
import { IGripConfig, PrefixedPublisher } from "@fanoutio/grip"; | ||
import { IGripConfig } from "@fanoutio/grip"; | ||
import IConnectGripConfig from "./IConnectGripConfig"; | ||
import { ConnectGripApiResponse } from "./ConnectGripApiResponse"; | ||
import { ConnectGripApiRequest } from "./ConnectGripApiRequest"; | ||
import PrefixedPublisher from "./PrefixedPublisher"; | ||
export default class ConnectGrip extends CallableInstance<[IncomingMessage, ServerResponse, Function], void> { | ||
gripProxies?: IGripConfig[]; | ||
gripProxies?: string | IGripConfig | IGripConfig[]; | ||
prefix: string; | ||
@@ -11,0 +12,0 @@ isGripProxyRequired: boolean; |
@@ -1,6 +0,6 @@ | ||
import { IGripConfig } from "@fanoutio/grip"; | ||
import { IGripConfig, Publisher } from "@fanoutio/grip"; | ||
export default interface IConnectGripConfig { | ||
gripProxies?: IGripConfig[]; | ||
grip?: string | IGripConfig | IGripConfig[] | Publisher; | ||
gripProxyRequired?: boolean; | ||
gripPrefix?: string; | ||
prefix?: string; | ||
} |
import * as CallableInstance from 'callable-instance'; | ||
import { Publisher, decodeWebSocketEvents, WebSocketContext, validateSig, GripInstruct, encodeWebSocketEvents } from '@fanoutio/grip'; | ||
import { Publisher, decodeWebSocketEvents, WebSocketContext, Auth, validateSig, GripInstruct, encodeWebSocketEvents } from '@fanoutio/grip'; | ||
@@ -92,2 +92,61 @@ /*! ***************************************************************************** | ||
var PrefixedPublisher = /** @class */ (function () { | ||
function PrefixedPublisher(publisher, prefix) { | ||
this.publisher = publisher; | ||
this.prefix = prefix; | ||
} | ||
PrefixedPublisher.prototype.getClients = function () { | ||
return this.publisher.clients; | ||
}; | ||
PrefixedPublisher.prototype.publish = function (channel, item) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.publisher.publish(this.prefix + channel, item)]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
PrefixedPublisher.prototype.publishFormats = function (channel, formats, id, prevId) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.publisher.publishFormats(this.prefix + channel, formats, id, prevId)]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
PrefixedPublisher.prototype.publishHttpResponse = function (channel, data, id, prevId) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.publisher.publishHttpResponse(this.prefix + channel, data, id, prevId)]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
PrefixedPublisher.prototype.publishHttpStream = function (channel, data, id, prevId) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.publisher.publishHttpStream(this.prefix + channel, data, id, prevId)]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
return PrefixedPublisher; | ||
}()); | ||
var CONTENT_TYPE_WEBSOCKET_EVENTS = 'application/websocket-events'; | ||
@@ -112,6 +171,14 @@ function flattenHeader(value) { | ||
if (config === void 0) { config = {}; } | ||
var gripProxies = config.gripProxies, _a = config.gripProxyRequired, gripProxyRequired = _a === void 0 ? false : _a, _b = config.gripPrefix, gripPrefix = _b === void 0 ? '' : _b; | ||
this.gripProxies = gripProxies; | ||
var grip = config.grip, _a = config.gripProxyRequired, gripProxyRequired = _a === void 0 ? false : _a, _b = config.prefix, prefix = _b === void 0 ? '' : _b; | ||
if (this._publisher != null) { | ||
throw new Error("applyConfig called on ConnectGrip that already has an instantiated publisher."); | ||
} | ||
if (grip instanceof Publisher) { | ||
this._publisher = new PrefixedPublisher(grip, prefix); | ||
} | ||
else { | ||
this.gripProxies = grip; | ||
} | ||
this.isGripProxyRequired = gripProxyRequired; | ||
this.prefix = gripPrefix; | ||
this.prefix = prefix; | ||
}; | ||
@@ -124,3 +191,3 @@ ConnectGrip.prototype.getPublisher = function () { | ||
} | ||
this._publisher = publisher.buildPrefixedPublisher(this.prefix); | ||
this._publisher = new PrefixedPublisher(publisher, this.prefix); | ||
} | ||
@@ -144,22 +211,36 @@ return this._publisher; | ||
return __awaiter(this, void 0, void 0, function () { | ||
var gripSigHeader_1, isProxied_1, isSigned, contentTypeHeader, at, acceptTypesHeader, acceptTypes, wsContext_1, cid, meta, _i, _a, _b, key, value, lKey, _c, events, gripInstruct_1, resWriteHead_1, resEnd_1, ex_1; | ||
var gripSigHeader_1, isProxied_1, isSigned, publisher, clients, contentTypeHeader, at, acceptTypesHeader, acceptTypes, wsContext_1, cid, meta, _i, _a, _b, key, value, lKey, _c, events, gripInstruct_1, resWriteHead_1, resEnd_1, ex_1; | ||
return __generator(this, function (_d) { | ||
switch (_d.label) { | ||
case 0: | ||
_d.trys.push([0, 4, , 5]); | ||
if (req.grip != null) { | ||
// This would indicate that we are already running for this request. | ||
// We don't install ourselves multiple times. | ||
return [2 /*return*/]; | ||
} | ||
_d.label = 1; | ||
case 1: | ||
_d.trys.push([1, 5, , 6]); | ||
gripSigHeader_1 = flattenHeader(req.headers['grip-sig']); | ||
isProxied_1 = false; | ||
isSigned = false; | ||
if (gripSigHeader_1 !== undefined && Array.isArray(this.gripProxies) && this.gripProxies.length > 0) { | ||
if (this.gripProxies.every(function (proxy) { return proxy.key; })) { | ||
// If all proxies have keys, then only consider the request | ||
// signed if at least one of them has signed it | ||
if (this.gripProxies.some(function (proxy) { return validateSig(gripSigHeader_1, proxy.key); })) { | ||
if (gripSigHeader_1 !== undefined) { | ||
publisher = this.getPublisher(); | ||
clients = publisher.getClients(); | ||
if (clients.length > 0) { | ||
if (clients.every(function (client) { | ||
return client.auth instanceof Auth.Jwt && | ||
client.auth.key != null; | ||
})) { | ||
// If all proxies have keys, then only consider the request | ||
// signed if at least one of them has signed it | ||
if (clients.some(function (client) { return validateSig(gripSigHeader_1, client.auth.key); })) { | ||
isProxied_1 = true; | ||
isSigned = true; | ||
} | ||
} | ||
else { | ||
isProxied_1 = true; | ||
isSigned = true; | ||
} | ||
} | ||
else { | ||
isProxied_1 = true; | ||
} | ||
} | ||
@@ -183,3 +264,3 @@ if (!isProxied_1 && this.isGripProxyRequired) { | ||
wsContext_1 = null; | ||
if (!(req.method === 'POST' && (contentTypeHeader === CONTENT_TYPE_WEBSOCKET_EVENTS || (acceptTypes === null || acceptTypes === void 0 ? void 0 : acceptTypes.includes(CONTENT_TYPE_WEBSOCKET_EVENTS))))) return [3 /*break*/, 3]; | ||
if (!(req.method === 'POST' && (contentTypeHeader === CONTENT_TYPE_WEBSOCKET_EVENTS || (acceptTypes === null || acceptTypes === void 0 ? void 0 : acceptTypes.includes(CONTENT_TYPE_WEBSOCKET_EVENTS))))) return [3 /*break*/, 4]; | ||
cid = flattenHeader(req.headers['connection-id']); | ||
@@ -199,3 +280,3 @@ if (cid == null) { | ||
} | ||
if (!(req.body == null)) return [3 /*break*/, 2]; | ||
if (!(req.body == null)) return [3 /*break*/, 3]; | ||
_c = req; | ||
@@ -212,6 +293,6 @@ return [4 /*yield*/, new Promise(function (resolve) { | ||
})]; | ||
case 1: | ||
case 2: | ||
_c.body = _d.sent(); | ||
_d.label = 2; | ||
case 2: | ||
_d.label = 3; | ||
case 3: | ||
events = null; | ||
@@ -227,4 +308,4 @@ try { | ||
wsContext_1 = new WebSocketContext(cid, meta, events, this.prefix); | ||
_d.label = 3; | ||
case 3: | ||
_d.label = 4; | ||
case 4: | ||
Object.assign(req, { | ||
@@ -301,7 +382,7 @@ grip: { | ||
} | ||
return [3 /*break*/, 5]; | ||
case 4: | ||
return [3 /*break*/, 6]; | ||
case 5: | ||
ex_1 = _d.sent(); | ||
throw ex_1 instanceof Error ? ex_1 : new Error(ex_1); | ||
case 5: return [2 /*return*/]; | ||
case 6: return [2 /*return*/]; | ||
} | ||
@@ -308,0 +389,0 @@ }); |
@@ -96,2 +96,61 @@ 'use strict'; | ||
var PrefixedPublisher = /** @class */ (function () { | ||
function PrefixedPublisher(publisher, prefix) { | ||
this.publisher = publisher; | ||
this.prefix = prefix; | ||
} | ||
PrefixedPublisher.prototype.getClients = function () { | ||
return this.publisher.clients; | ||
}; | ||
PrefixedPublisher.prototype.publish = function (channel, item) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.publisher.publish(this.prefix + channel, item)]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
PrefixedPublisher.prototype.publishFormats = function (channel, formats, id, prevId) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.publisher.publishFormats(this.prefix + channel, formats, id, prevId)]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
PrefixedPublisher.prototype.publishHttpResponse = function (channel, data, id, prevId) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.publisher.publishHttpResponse(this.prefix + channel, data, id, prevId)]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
PrefixedPublisher.prototype.publishHttpStream = function (channel, data, id, prevId) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.publisher.publishHttpStream(this.prefix + channel, data, id, prevId)]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
return PrefixedPublisher; | ||
}()); | ||
var CONTENT_TYPE_WEBSOCKET_EVENTS = 'application/websocket-events'; | ||
@@ -116,6 +175,14 @@ function flattenHeader(value) { | ||
if (config === void 0) { config = {}; } | ||
var gripProxies = config.gripProxies, _a = config.gripProxyRequired, gripProxyRequired = _a === void 0 ? false : _a, _b = config.gripPrefix, gripPrefix = _b === void 0 ? '' : _b; | ||
this.gripProxies = gripProxies; | ||
var grip$1 = config.grip, _a = config.gripProxyRequired, gripProxyRequired = _a === void 0 ? false : _a, _b = config.prefix, prefix = _b === void 0 ? '' : _b; | ||
if (this._publisher != null) { | ||
throw new Error("applyConfig called on ConnectGrip that already has an instantiated publisher."); | ||
} | ||
if (grip$1 instanceof grip.Publisher) { | ||
this._publisher = new PrefixedPublisher(grip$1, prefix); | ||
} | ||
else { | ||
this.gripProxies = grip$1; | ||
} | ||
this.isGripProxyRequired = gripProxyRequired; | ||
this.prefix = gripPrefix; | ||
this.prefix = prefix; | ||
}; | ||
@@ -128,3 +195,3 @@ ConnectGrip.prototype.getPublisher = function () { | ||
} | ||
this._publisher = publisher.buildPrefixedPublisher(this.prefix); | ||
this._publisher = new PrefixedPublisher(publisher, this.prefix); | ||
} | ||
@@ -148,22 +215,36 @@ return this._publisher; | ||
return __awaiter(this, void 0, void 0, function () { | ||
var gripSigHeader_1, isProxied_1, isSigned, contentTypeHeader, at, acceptTypesHeader, acceptTypes, wsContext_1, cid, meta, _i, _a, _b, key, value, lKey, _c, events, gripInstruct_1, resWriteHead_1, resEnd_1, ex_1; | ||
var gripSigHeader_1, isProxied_1, isSigned, publisher, clients, contentTypeHeader, at, acceptTypesHeader, acceptTypes, wsContext_1, cid, meta, _i, _a, _b, key, value, lKey, _c, events, gripInstruct_1, resWriteHead_1, resEnd_1, ex_1; | ||
return __generator(this, function (_d) { | ||
switch (_d.label) { | ||
case 0: | ||
_d.trys.push([0, 4, , 5]); | ||
if (req.grip != null) { | ||
// This would indicate that we are already running for this request. | ||
// We don't install ourselves multiple times. | ||
return [2 /*return*/]; | ||
} | ||
_d.label = 1; | ||
case 1: | ||
_d.trys.push([1, 5, , 6]); | ||
gripSigHeader_1 = flattenHeader(req.headers['grip-sig']); | ||
isProxied_1 = false; | ||
isSigned = false; | ||
if (gripSigHeader_1 !== undefined && Array.isArray(this.gripProxies) && this.gripProxies.length > 0) { | ||
if (this.gripProxies.every(function (proxy) { return proxy.key; })) { | ||
// If all proxies have keys, then only consider the request | ||
// signed if at least one of them has signed it | ||
if (this.gripProxies.some(function (proxy) { return grip.validateSig(gripSigHeader_1, proxy.key); })) { | ||
if (gripSigHeader_1 !== undefined) { | ||
publisher = this.getPublisher(); | ||
clients = publisher.getClients(); | ||
if (clients.length > 0) { | ||
if (clients.every(function (client) { | ||
return client.auth instanceof grip.Auth.Jwt && | ||
client.auth.key != null; | ||
})) { | ||
// If all proxies have keys, then only consider the request | ||
// signed if at least one of them has signed it | ||
if (clients.some(function (client) { return grip.validateSig(gripSigHeader_1, client.auth.key); })) { | ||
isProxied_1 = true; | ||
isSigned = true; | ||
} | ||
} | ||
else { | ||
isProxied_1 = true; | ||
isSigned = true; | ||
} | ||
} | ||
else { | ||
isProxied_1 = true; | ||
} | ||
} | ||
@@ -187,3 +268,3 @@ if (!isProxied_1 && this.isGripProxyRequired) { | ||
wsContext_1 = null; | ||
if (!(req.method === 'POST' && (contentTypeHeader === CONTENT_TYPE_WEBSOCKET_EVENTS || (acceptTypes === null || acceptTypes === void 0 ? void 0 : acceptTypes.includes(CONTENT_TYPE_WEBSOCKET_EVENTS))))) return [3 /*break*/, 3]; | ||
if (!(req.method === 'POST' && (contentTypeHeader === CONTENT_TYPE_WEBSOCKET_EVENTS || (acceptTypes === null || acceptTypes === void 0 ? void 0 : acceptTypes.includes(CONTENT_TYPE_WEBSOCKET_EVENTS))))) return [3 /*break*/, 4]; | ||
cid = flattenHeader(req.headers['connection-id']); | ||
@@ -203,3 +284,3 @@ if (cid == null) { | ||
} | ||
if (!(req.body == null)) return [3 /*break*/, 2]; | ||
if (!(req.body == null)) return [3 /*break*/, 3]; | ||
_c = req; | ||
@@ -216,6 +297,6 @@ return [4 /*yield*/, new Promise(function (resolve) { | ||
})]; | ||
case 1: | ||
case 2: | ||
_c.body = _d.sent(); | ||
_d.label = 2; | ||
case 2: | ||
_d.label = 3; | ||
case 3: | ||
events = null; | ||
@@ -231,4 +312,4 @@ try { | ||
wsContext_1 = new grip.WebSocketContext(cid, meta, events, this.prefix); | ||
_d.label = 3; | ||
case 3: | ||
_d.label = 4; | ||
case 4: | ||
Object.assign(req, { | ||
@@ -305,7 +386,7 @@ grip: { | ||
} | ||
return [3 /*break*/, 5]; | ||
case 4: | ||
return [3 /*break*/, 6]; | ||
case 5: | ||
ex_1 = _d.sent(); | ||
throw ex_1 instanceof Error ? ex_1 : new Error(ex_1); | ||
case 5: return [2 /*return*/]; | ||
case 6: return [2 /*return*/]; | ||
} | ||
@@ -312,0 +393,0 @@ }); |
{ | ||
"name": "@fanoutio/connect-grip", | ||
"version": "0.1.0-beta.7", | ||
"version": "0.1.0-beta.8", | ||
"author": "Fanout, Inc. <info@fanout.io>", | ||
@@ -67,5 +67,5 @@ "description": "Connect GRIP library", | ||
"dependencies": { | ||
"@fanoutio/grip": "^3.0.0-beta.1", | ||
"@fanoutio/grip": "^3.0.0-beta.3", | ||
"callable-instance": "^2.0.0" | ||
} | ||
} |
@@ -115,7 +115,7 @@ ## connect-grip | ||
const connectGrip = new ConnectGrip({ | ||
gripProxies: [{ | ||
grip: { | ||
control_uri: 'https://api.fanout.io/realm/<realm-name>/publish/', // Publishing endpoint | ||
control_iss: '<realm-name>', // (optional) Needed for servers that require authorization | ||
key: '<realm-key>', // (optinoal) Needed for servers that require authorization | ||
}], | ||
}, | ||
isGripProxyRequired: true, | ||
@@ -128,5 +128,5 @@ }); | ||
| --- | --- | | ||
| `gripProxies` | An array of objects that define GRIP proxies, used to publish messages. See above for an example. | | ||
| `grip` | A definition of GRIP proxies used to publish messages, or a preconfigured Publisher object from `@fanoutio/grip`. See below for details. | | ||
| `gripProxyRequired` | A boolean value representing whether all incoming requests should require that they be called behind a GRIP proxy. If this is true and a GRIP proxy is not detected, then a `501 Not Implemented` error will be issued. Defaults to `false`. | | ||
| `gripPrefix` | An optional string that will be prepended to the name of channels being published to. This can be used for namespacing. Defaults to `''`. | | ||
| `prefix` | An optional string that will be prepended to the name of channels being published to. This can be used for namespacing. Defaults to `''`. | | ||
@@ -136,2 +136,18 @@ In most cases your application will construct a singleton instance of this class and use it as | ||
The `grip` parameter may be provided as any of the following: | ||
1. An object with the following fields: | ||
| Key | Value | | ||
| --- | --- | | ||
| `control_uri` | Publishing endpoint for the GRIP proxy. | | ||
| `control_iss` | A claim string that is needed for servers that require authorization. For Fanout Cloud, this is the Realm ID. | | ||
| `key` | A key string that is needed for servers that require authorization. For Fanout Cloud, this is the Realm Key. | | ||
2. An array of such objects. | ||
3. A GRIP URI, which is a string that encodes the above as a single string. | ||
4. A `Publisher` object that you have instantiated and configrued yourself, from `@fanoutio/grip`. | ||
### Handling a route | ||
@@ -138,0 +154,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
100749
27
920
236
Updated@fanoutio/grip@^3.0.0-beta.3