Get support for Ilshidur/node-mercure
If you're new to LTH, please see our FAQ for more information on what it is we do.
Support Options
Unfortunately, there are currently no active helpers for this repository on the platform. Until they become available, we reccomend the following actions:
View Open IssuesTake a look to see if anyone else has experienced the same issue as you and if they managed to solve it.
Open an IssueMake sure to read any relevant guidelines for opening issues on this repo before posting a new issue.
Sponsor directlyCheck out the page and see if there are any options to sponsor this project or it's developers directly.
Ilshidur/node-mercure
mercure
Mercure Hub & Publisher implemented in Node.js.
Note: this npm package has been transfered for a new project by the initial owner, which serves a totally different purpose. This new version is an implementation of the Mercure protocol. The previous mercure
package had 1 release (0.0.1
) and served as a file downloader. You can still access it: https://www.npmjs.com/package/mercure/v/0.0.1. Please make sure to lock this version in your package.json
file, as the new versions will begin at 0.0.2
and will keep following the semver versioning.
TODOs
- CORS
- Hearthbeat mechanism (https://github.com/dunglas/mercure/pull/53)
- Docker image (iso with official image)
- Prometheus metrics exporter:
- Subscribers count
- Events count / size (in Bytes), per publisher
- Publishers IPs
- Instances count
-
hub.on('connect')
listeners - Events database
- Export authorization.js mechanism
- Discovery helpers
- Handle
Forwarded
andX-Forwarded-For
headers (related issue) - Provide a Socket.io adapter (see this thread)
- Allow the dev to pass an URL in the
Publisher
contructor -
Publisher
: allow the user to specify a JWT key and the claims instead of a JWT -
Publisher
: getters likeget host()
,port
,protocol
... - Increase code quality score
- JSDoc
- Logging
- Unit tests
- Find a way to clear Redis if the process gets interrupted
- Benchmarks
State
This is a beta version. This has not fully been tested in production yet.
This implementation does not reflect the latest specification since they got changed. I don't recommend to use this module.
Requirements
- node.js >= 11.7.0
- Redis (optional)
Features
- 100% implementation of the protocol
- Events asymmetric encryption
- Easy integration to any existing app using
http.Server
orexpress
- Redis-based clustering support
- Inventory of all open connections stored in Redis, per node process
- Kill switch
Future improvements
- Implement as a lambda function ?
Installation
npm install mercure --save
Usage
This library provides 3 components: a Hub
, a Server
and a Publisher
:
Simple hub
The Hub
class is the core component that uses a simple http.Server
instance. An existing instance can be provided to the Hub
, thus the Hub will use it instead of creating a new one.
Use case: implanting the hub on an existing http.Server
app, without the need to handle external publishers (only the app does the publishing).
It handles:
- the SSE connections
- the events database
- the authorization mechanism
- events related to the Hub activity
const http = require('http');
const { Hub } = require('mercure');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('200');
});
const hub = new Hub(server, {
jwtKey: '!UnsecureChangeMe!',
path: '/.well-known/mercure',
});
hub.listen(3000);
Hub server
The Server
is built upon the Hub
component. It creates a new Express instance and allows external publishers to POST
an event to the hub.
Use case: implanting he hub on an new application that is meant to accept external publishers, with no other HTTP server ... or one listening on a different port.
It handles everything the Hub
does, plus:
- a freshly created Express instance, built upon the Hub's
http.Server
(middlewares can be applied to enhance security) - external publishers (POST requests)
const { Server } = require('mercure');
const server = new Server({
jwtKey: '!UnsecureChangeMe!',
path: '/.well-known/mercure',
});
server.listen(3000);
Because the Server leverages Express, it is possible to add middlewares in front of the internal Hub middleware:
const compression = require('compression');
class SecuredHubServer extends Server {
configure() {
this.app.use(compression());
}
}
const server = new SecuredHubServer(...);
Publisher
It can be created in different ways:
- using an existing
Hub
instance (when the app is meant to be THE ONLY publisher) - using an existing
Server
instance (when the app is meant to be a publisher) - using configuration:
host
,port
... (when the publisher and the hub are distant)
It handles:
- Message publication to the Hub
- Message encryption (optional)
const { Publisher } = require('mercure');
const publisher = new Publisher({
protocol: 'https', // or 'http', but please don't.
host: 'example.com',
port: 3000,
path: '/.well-known/mercure',
jwt: 'PUBLISHER_JWT',
});
// Payload to send to the subscribers.
const data = {
'@id': 'http://localhost:3000/books/666.jsonld',
hello: 'world',
};
await publisher.publish(
['https://example.com:3000/books/666.jsonld'], // Topics.
JSON.stringify(data),
);
API
API docs can be found in the docs/API.md file.
Encrypting the datas
In certain cases, the Mercure hub can be hosted by a third-party host. You don't really want them to "sniff" all your cleartext messages. To make the Publisher => Hub => Subscriber flow fully encrypted, it is required that the Publisher sends encrypted data.
To achieve this, the Publisher#useEncryption()
method will activate messages encryption. Thus, the Hub will not be able to access your private datas:
const crypto = require('crypto');
const util = require('util');
const publisher = new Publisher({
// ...
});
const data = { message: 'TOP SECRET DATAS' };
const { privateKey } = await util.promisify(crypto.generateKeyPair)('rsa', {
modulusLength: 4096,
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem',
},
});
// Start encrypting the events.
await publisher.useEncryption({
rsaPrivateKey: privateKey,
});
// Will send encrypted datas.
await publisher.publish(
[...], // Topics.
JSON.stringify(data),
);
Decrypting:
const jose = require('node-jose');
const encryptedData = 'ENCRYPTED DATA';
const decrypted = await jose.JWE.createDecrypt(publisher.keystore).decrypt(encryptedData);
console.log(decrypted.plaintext.toString());
Kill switch
In case the hub must urgently close all connections (e.g.: in case of compromission of the JWT key), a kill switch is available:
await hub.killSwitch();
The new JWT Key will be output to stdout.
License
GNU GENERAL PUBLIC LICENSE v3.
Our Mission
We want to make open source more sustainable. The entire platform was born from this and everything we do is in aid of this.
From the Blog
Interesting Articles
-
Generating income from open source
Jun 23 • 8 min read
-
2023 State of OSS
Apr 23 • 45 min read ★
-
A funding experiment...
Aug 19 • 10 min read
-
But You Said I could
Aug 19 • 2 min read
Thank you for checking out LiveTechHelper |
2025 © lth-dev incorporated
p-e622a1a2