@interopio/gateway
Version:
[](https://www.npmjs.com/package/@interopio/gateway)
249 lines (190 loc) • 8.32 kB
Markdown
# io.Gateway
[](https://www.npmjs.com/package/@interopio/gateway)
## Overview
The `@interopio/gateway` package is the gateway for io.Connect Desktop/Browser.
## Table of Contents
- [Installation](#installation)
- [Requirements](#requirements)
- [Usage Examples](#usage-examples)
- [Change Token TTL](#change-token-ttl)
- [OAuth 2.0 Authenticator](#oauth-20-authenticator)
- [Custom Authenticator](#custom-authenticator)
- [Client Authentication](#client-authentication)
- [Visibility](#visibility)
- [Changelog](#changelog)
- [License](#license)
## Installation
```shell
npm install @interopio/gateway@beta
```
## Requirements
- WebCrypto - [WebCrypto](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) 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-webcrypto` flag, or set
`globalThis.crypto` your self. For example `const { webcrypto } = require('crypto'); globalThis.crypto = webcrypto;`
- WebSocket - [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/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 `ws` package. For example `npm install ws`.
- fetch - [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/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-fetch` flag, or set `globalThis.fetch` your self.
## API docs
See [`gateway.md`](./gateway.md)
## Usage Examples
### Change Token TTL
```typescript
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();
```
### OAuth 2.0 Authenticator
To secure io.Gateway with OAuth 2.0 authentication services like auth0 or okta you need to configure
```typescript
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 a `user` property.
- 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.
```typescript
// 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
```typescript
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
```typescript
import Gateway from '@interopio/gateway'
const gateway = Gateway({
metrics: {
publishers: ['rest'],
rest: {
endpoint: 'http://localhost:8084/api/metrics',
authentication: false
}
}
});
```
### Visibility
```typescript
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
```typescript
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:
```typescript
import Gateway from '@interopio/gateway';
const gateway = await IOGateway.Gateway({
cluster: {
// io.Bridge url
endpoint: 'http://localhost:8084',
}
});
```
## Changelog
See [changelog](./changelog.md)
## License
[MIT](license.md)