@interopio/gateway
v0.25.0
Published
[](https://www.npmjs.com/package/@interopio/gateway)
Readme
io.Gateway
Overview
The @interopio/gateway package is the gateway for io.Connect Desktop/Browser.
Table of Contents
Installation
npm install @interopio/gateway@latestRequirements
WebCrypto - WebCrypto is a standard API for performing cryptographic operations in web applications. It is supported in most modern browsers and Node.js environments. If running Node.js 18, you need to enable the
--experimental-global-webcryptoflag, or setglobalThis.cryptoyour self. For exampleconst { webcrypto } = require('crypto'); globalThis.crypto = webcrypto;WebSocket - WebSocket is a protocol for full-duplex communication channels over a single TCP connection. It is supported in most modern browsers and Node.js environments. If running Node.js 18, you need to install the
wspackage. For examplenpm install ws.fetch - Fetch API is a modern interface for making HTTP requests in web applications. It is supported in most modern browsers and Node.js environments. If running Node.js 16, you need to enable the
--experimental-fetchflag, or setglobalThis.fetchyour self.URL - URL API is a standard API for parsing and manipulating URLs in web applications. It is supported in most modern browsers and Node.js environments. If running Node.js 10 or below, you need to install the
urlpackage. For examplenpm install urland setglobalThis.URLyour self. For exampleconst { URL } = require('url'); globalThis.URL = URL;
API docs
See gateway.md
Usage Examples
Change Token TTL
import Gateway from '@interopio/gateway'
const gateway = Gateway({
token: {
ttl: 1 * 24 * 60 * 60 // expiry of access tokens in seconds. 86400 is 1 day.
}
});
await gateway.start();Basic Authenticator
By default, io.Gateway is secured with the built-in basic authenticator.
It handles authentication requests with method secret (i.e. client is providing login and/or secret).
It can be customized by providing custom usernameResolver and/or secretVerifier function(s).
import Gateway from '@interopio/gateway';
const gateway = Gateway({
authentication: {
basic: {
usernameResolver: (login?: string) => {
// custom username resolution logic
return login === 'guest' ? '[email protected]' : login;
},
secretVerifier: async (username: string, password: string): Promise<boolean> => {
// custom validation logic
return username === 'admin' && password === 'adminpass';
}
}
}
});OAuth 2.0 Authenticator
To secure io.Gateway with OAuth 2.0 authentication services like auth0 or okta you need to configure
import Gateway from '@interopio/gateway'
const gateway = Gateway({
authentication: {
default: 'oauth2',
available: ['basic', 'oauth2'], // remove basic if want oauth2 only
oauth2: {issuerBaseURL: 'https://<your-issuer-domain>', audience: 'https://<myapi>'}
}
});
const client = gateway.client((msg) => console.log(msg));
const token = '<authorizationToken>';
client.send({type: 'hello', identity: {application: 'test'}, authentication: {method: 'access-token', token}});Custom Authenticator
To secure io.Gateway with a custom authenticator, you can add a subsection with authenticator property in the authentication option.
Then list it in the available array. The custom authenticator is a function that takes an authentication object and returns a promise that resolves to an object with either a type of success or continue.
- If the authentication is successful, resolve the result with
type: 'success'and optionally auserproperty. - If the authentication requires further user interaction, return an object with
type: 'continue'. - If the authentication fails, you can throw an error or return a rejected promise.
// no-user.ts
import {AuthenticationRequest, AuthenticationResponse} from '@interopio/gateway/auth/api';
export default async function none({authentication}: AuthenticationRequest): Promise<AuthenticationResponse> {
if (authentication.method === 'none') {
// No authentication required
return {type: 'success'};
}
return {type: 'error', message: 'Authentication method not supported'};
}
// os-user.ts
import {AuthenticationRequest, AuthenticationResponse} from '@interopio/gateway/auth/api';
export default async function node({authentication}: AuthenticationRequest): Promise<AuthenticationResponse> {
if (authentication.method === 'none') {
return {type: 'success', user: process.env['USER'] ?? process.env['USERNAME']};
}
return {type: 'error', message: 'Authentication method not supported'};
}
// myauth.ts
import {AuthenticationRequest, AuthenticationResponse} from '@interopio/gateway/auth/api';
export default async function myauth({authentication}: AuthenticationRequest): Promise<AuthenticationResponse> {
if (authentication.method === 'access-token') {
// Custom authentication logic
// For example, check a token or perform some validation
if (authentication.token === 'my-secret-token') {
return {type: 'success', user: 'myuser'};
}
return {type: 'error', message: 'Invalid token'};
}
return {type: 'error', message: 'Authentication method not supported'};
}
// index.ts
import Gateway from '@interopio/gateway';
const gateway = Gateway({
authentication: {
default: 'myauth',
available: ['basic', 'myauth'],
myauth: {
authenticator: none
}
}
});Client Authentication
import {IOGateway} from '@interopio/gateway'
const gateway = IOGateway.Factory({});
await gateway.start();
const opts: IOGateway.GatewayClientOptions = {
// this callback is invoked when authentication method 'gateway-client' is requested on hanshake (hello)
onAuthenticate: async (request: IOGateway.Auth.AuthenticationRequest): Promise<IOGateway.Auth.AuthenticationSuccess> => {
// throw Error to reject the request
return {type: 'success', user: 'client'};
}
};
const client: IOGateway.GatewayClient = gateway.client((msg) => {
if (msg.type === 'welcome') {
console.log(`authenticated with user: ${msg.resolved_identity.user}`);
}
}, opts);
// handshake with authentication method 'gateway-client'
client.send({type: 'hello', identity: {application: 'demo'}, authentication: {method:'gateway-client'}});
client.close();
await gateway.close();
Metrics Publisher
import Gateway from '@interopio/gateway'
const gateway = Gateway({
metrics: {
publishers: ['rest'],
rest: {
endpoint: 'http://localhost:8084/api/metrics',
authentication: false
}
}
});Visibility
import Gateway from '@interopio/gateway'
const gateway = Gateway({
contexts: {
visibility: [
{context: /'___channel___.+'/, restrictions: 'cluster'}, // all context starting with '___channel___' are with 'cluster' visibility
{context: /T42\..+/, restrictions: 'local', identity: {application: 'io.Connect Desktop'}}, // all context starting with T42. created by 'io.Connect Desktop' are with 'local' visibility
{context: /.+/, restrictions: 'cluster'} // all other contexts are with cluster visibility
]
},
methods: {
visibility: [
{method: /T42\..+/, restrictions: 'local'}, // all methods and streams starting with T42. are with 'local' visibility
{method: /.+/, restrictions: 'cluster'} // all other methods and streams are with 'cluster' visibility
]
},
peers: {
visibility: [
// {domain: 'context', restrictions: 'cluster'}, does nothing
{domain: 'interop', restrictions: 'local'}, // interop domain is with 'local' visibility
{domain: 'interop', restrictions: 'cluster'},
{domain: 'bus', restrictions: 'local'}
]
}
});Context Lifetime
import Gateway from '@interopio/gateway'
const gateway = Gateway({contexts: {lifetime: 'retained'}});Cluster
You can use the cluster option to configure the cluster settings.
For example, to configure the cluster to use an io.Bridge instance running on localhost:8084, you can do the following:
import Gateway from '@interopio/gateway';
const gateway = await IOGateway.Gateway({
cluster: {
// io.Bridge url
endpoint: 'http://localhost:8084',
}
});Changelog
See changelog
