chore: add RELAY_PRIVATE_KEY env var

Signed-off-by: Ricardo Arturo Cabral Mejía <me@ricardocabral.io>
This commit is contained in:
Ricardo Arturo Cabral Mejía
2023-02-01 23:36:08 -05:00
parent 79042e7f29
commit 45b08d8a21
7 changed files with 34 additions and 40 deletions

View File

@@ -7,6 +7,7 @@ The following environment variables can be set:
| Name | Description | Default |
|----------------------------------|--------------------------------|------------------------|
| RELAY_PORT | Relay's server port | 8008 |
| RELAY_PRIVATE_KEY | Relay's private key in hex | (auto-generated) |
| WORKER_COUNT | Number of workers override | No. of available CPUs |
| DB_HOST | PostgresSQL Hostname | |
| DB_PORT | PostgreSQL Port | 5432 |

View File

@@ -24,7 +24,7 @@ services:
RR_DB_NAME: nostr_ts_relay
RR_DB_MIN_POOL_SIZE: 16
RR_DB_MAX_POOL_SIZE: 64
RR_DB_ACQUIRE_CONNECTION_TIMEOUT: 60000
RR_DB_ACQUIRE_CONNECTION_TIMEOUT: 10000
# Redis
REDIS_HOST: nostream-cache
REDIS_PORT: 6379

View File

@@ -1,7 +1,7 @@
import ws, { WebSocket } from 'ws'
import cluster from 'cluster'
import { EventEmitter } from 'stream'
import { IncomingMessage as IncomingHttpMessage } from 'http'
import { WebSocket } from 'ws'
import { ContextMetadata, Factory } from '../@types/base'
import { createNoticeMessage, createOutgoingEventMessage } from '../utils/messages'
@@ -21,20 +21,6 @@ import { messageSchema } from '../schemas/message-schema'
import { Settings } from '../@types/settings'
import { SocketAddress } from 'net'
(() => {
(ws as any).Receiver.prototype._write = function _write (chunk: any, _encoding: any, cb: any) {
if (this._opcode === 0x08 && this._state == 0) return cb()
this._bufferedBytes += chunk.length
this._buffers.push(chunk)
try {
this.startLoop(cb)
} catch (error) {
console.error('what in the world', error)
cb(error)
}
}
})()
const debug = createLogger('web-socket-adapter')
const debugHeartbeat = debug.extend('heartbeat')
@@ -68,8 +54,6 @@ export class WebSocketAdapter extends EventEmitter implements IWebSocketAdapter
family: address.indexOf(':') >= 0 ? 'ipv6' : 'ipv4',
})
console.log(`web-socket-adapter: new client ${this.clientId} (${this.getClientAddress()}) - ${(this.webSocketServer as any).webSocketServer.clients.size} total on worker ${process.pid}`)
this.client
.on('error', (error) => {
if (error.name === 'RangeError' && error.message === 'Max payload size exceeded') {
@@ -282,7 +266,5 @@ export class WebSocketAdapter extends EventEmitter implements IWebSocketAdapter
this.removeAllListeners()
this.client.removeAllListeners()
console.error(`web-socket-adapter: disconnected client ${this.clientId} (${this.getClientAddress()}) - ${(this.webSocketServer as any).webSocketServer.clients.size} total on worker ${process.pid}`)
}
}

View File

@@ -180,9 +180,15 @@ export const identifyEvent = async (event: UnidentifiedEvent): Promise<UnsignedE
}
export const getPrivateKeyFromSecret =
(secret: string) => (publicKey: Pubkey | Buffer): string => {
(secret: string) => (data: string | Buffer): string => {
if (process.env.RELAY_PRIVATE_KEY) {
return process.env.RELAY_PRIVATE_KEY
}
const hmac = createHmac('sha256', secret)
hmac.update(typeof publicKey === 'string' ? Buffer.from(publicKey, 'hex') : publicKey)
hmac.update(typeof data === 'string' ? Buffer.from(data) : data)
return hmac.digest().toString('hex')
}

View File

@@ -5,21 +5,30 @@ import WebSocket from 'ws'
import { IEventRepository, IUserRepository } from '../../../src/@types/repositories'
import { IWebSocketServerAdapter } from '../../../src/@types/adapters'
import { SettingsStatic } from '../../../src/utils/settings'
import { WebSocketAdapter } from '../../../src/adapters/web-socket-adapter'
import { webSocketAdapterFactory } from '../../../src/factories/websocket-adapter-factory'
describe('webSocketAdapterFactory', () => {
let onStub: Sinon.SinonStub
let createSettingsStub: Sinon.SinonStub
beforeEach(() => {
onStub = Sinon.stub()
createSettingsStub = Sinon.stub(SettingsStatic, 'createSettings')
})
afterEach(() => {
createSettingsStub.restore()
onStub.reset()
})
it('returns a WebSocketAdapter', () => {
createSettingsStub.returns({
network: {
remoteIpHeader: 'remoteIpHeader',
},
})
const eventRepository: IEventRepository = {} as any
const userRepository: IUserRepository = {} as any

View File

@@ -4,24 +4,37 @@ import Sinon from 'sinon'
import * as databaseClientModule from '../../../src/database/client'
import { AppWorker } from '../../../src/app/worker'
import { SettingsStatic } from '../../../src/utils/settings'
import { workerFactory } from '../../../src/factories/worker-factory'
describe('workerFactory', () => {
let createSettingsStub: Sinon.SinonStub
let getMasterDbClientStub: Sinon.SinonStub
let getReadReplicaDbClientStub: Sinon.SinonStub
beforeEach(() => {
createSettingsStub = Sinon.stub(SettingsStatic, 'createSettings')
getMasterDbClientStub = Sinon.stub(databaseClientModule, 'getMasterDbClient')
getReadReplicaDbClientStub = Sinon.stub(databaseClientModule, 'getReadReplicaDbClient')
})
afterEach(() => {
getMasterDbClientStub.restore()
getReadReplicaDbClientStub.restore()
getMasterDbClientStub.restore()
createSettingsStub.restore()
})
it('returns an AppWorker', () => {
createSettingsStub.returns({
info: {
relay_url: 'url',
},
network: {
},
})
const worker = workerFactory()
expect(worker).to.be.an.instanceOf(AppWorker)
worker.close()

View File

@@ -177,23 +177,6 @@ describe('SubscribeMessageHandler', () => {
)
})
it('ends event stream if aborted', async () => {
isClientSubscribedToEventStub.returns(always(true))
const abort = () => (handler as IAbortable).abort()
const fetch = () => (handler as any).fetchAndSend(subscriptionId, filters)
const promise = fetch()
const closeSpy = sandbox.spy()
stream.once('close', closeSpy)
abort()
await expect(promise).to.eventually.be.rejectedWith(Error, 'The operation was aborted')
expect(closeSpy).to.have.been.called
})
it('ends event stream if error occurs', async () => {
const error = new Error('mistakes were made')
isClientSubscribedToEventStub.returns(always(true))