mirror of
https://github.com/Blockstream/satellite-api.git
synced 2024-11-19 04:50:01 +01:00
Add admin route for SSE on get-protected channels
The auth channel does not allow users to get messages (access them over the internet). Hence, a regular SSE client should not be able to monitor the events generated on the auth channel. In contrast, an admin host should be able to monitor the auth events. For that, this patch adds an /admin/subscribe endpoint that is SSL-authenticated in production, so only the admin hosts can connect to it.
This commit is contained in:
parent
50df236d6b
commit
f2058ac3f8
@ -16,4 +16,11 @@ server {
|
||||
proxy_http_version 1.1;
|
||||
proxy_pass http://sse-server:4500/stream?channels=;
|
||||
}
|
||||
location /admin/subscribe/ {
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_http_version 1.1;
|
||||
proxy_pass http://sse-server:4500/admin/stream?channels=;
|
||||
}
|
||||
}
|
@ -1,24 +1,20 @@
|
||||
// Setup redis
|
||||
const redis = require('redis').createClient(process.env.REDIS_URI),
|
||||
channels = process.env.SUB_CHANNELS.split(',')
|
||||
channels = process.env.SUB_CHANNELS.split(',')
|
||||
|
||||
console.log(`Subscribing to Redis on ${channels.join(',')}`)
|
||||
channels.forEach(chan => redis.subscribe(chan))
|
||||
|
||||
// Log messages and number of SSE subscribers
|
||||
redis.on('message', (chan, msg) => console.log(`Broadcasting ${chan}: ${msg}`))
|
||||
setInterval(_ => console.log(`Total subscribers: ${ redis.listenerCount('message') - 1 }`), 60000)
|
||||
setInterval(_ => console.log(`Total subscribers: ${redis.listenerCount('message') - 1}`), 60000)
|
||||
|
||||
// Setup express server
|
||||
const app = require('express')()
|
||||
app.set('trust proxy', process.env.PROXIED || 'loopback')
|
||||
app.use(require('morgan')('dev'))
|
||||
|
||||
// SSE endpoint
|
||||
app.get('/stream', (req, res) => {
|
||||
const subscriptions = req.query.channels && req.query.channels.split(',')
|
||||
console.log(`New subscriber for ${ subscriptions ? subscriptions.join(',') : 'all channels' }`)
|
||||
|
||||
function configureStream(req, res, subscriptions) {
|
||||
res.set({
|
||||
'X-Accel-Buffering': 'no',
|
||||
'Cache-Control': 'no-cache',
|
||||
@ -26,7 +22,7 @@ app.get('/stream', (req, res) => {
|
||||
'Connection': 'keep-alive'
|
||||
}).flushHeaders()
|
||||
|
||||
function onMsg (chan, msg) {
|
||||
function onMsg(chan, msg) {
|
||||
if (!subscriptions || subscriptions.includes(chan)) {
|
||||
res.write(`event:${chan}\ndata:${msg}\n\n`)
|
||||
}
|
||||
@ -36,11 +32,28 @@ app.get('/stream', (req, res) => {
|
||||
const keepAlive = setInterval(_ => res.write(': keepalive\n\n'), 25000)
|
||||
|
||||
req.once('close', _ => (redis.removeListener('message', onMsg),
|
||||
clearInterval(keepAlive),
|
||||
console.log('Subscriber disconnected')))
|
||||
clearInterval(keepAlive),
|
||||
console.log('Subscriber disconnected')))
|
||||
}
|
||||
|
||||
app.get('/stream', (req, res) => {
|
||||
const subscriptions = req.query.channels && req.query.channels.split(',')
|
||||
// Filter out the channels that can only be monitored by the admin
|
||||
if (subscriptions.includes('auth')) {
|
||||
res.status(401).send("Operation not supported on the auth channel");
|
||||
return;
|
||||
}
|
||||
console.log(`New subscriber for ${subscriptions ? subscriptions.join(',') : 'all channels'}`)
|
||||
configureStream(req, res, subscriptions);
|
||||
})
|
||||
|
||||
app.get('/admin/stream', (req, res) => {
|
||||
const subscriptions = req.query.channels && req.query.channels.split(',')
|
||||
console.log(`New admin subscriber for ${subscriptions ? subscriptions.join(',') : 'all channels'}`)
|
||||
configureStream(req, res, subscriptions);
|
||||
})
|
||||
|
||||
app.listen(
|
||||
process.env.PORT || 4500,
|
||||
function() { console.log(`HTTP server running on ${this.address().address}:${this.address().port}`) }
|
||||
function () { console.log(`HTTP server running on ${this.address().address}:${this.address().port}`) }
|
||||
)
|
||||
|
@ -147,6 +147,19 @@ write_files:
|
||||
}
|
||||
|
||||
# Proxy to mainnet SSE container
|
||||
location /admin/subscribe/ {
|
||||
if ($ssl_client_verify != SUCCESS) {
|
||||
return 403;
|
||||
}
|
||||
chunked_transfer_encoding on;
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
proxy_pass http://${mainnet_ip}:4500/admin/stream?channels=;
|
||||
}
|
||||
|
||||
location /subscribe/ {
|
||||
chunked_transfer_encoding on;
|
||||
proxy_buffering off;
|
||||
|
Loading…
Reference in New Issue
Block a user