fix: lots of bugs

Signed-off-by: Ricardo Arturo Cabral Mejía <me@ricardocabral.io>
This commit is contained in:
Ricardo Arturo Cabral Mejía 2023-01-27 10:20:55 -05:00
parent f9c53eeeb8
commit 9c010e7865
18 changed files with 62 additions and 43 deletions

@ -5,5 +5,5 @@
nostream.localtest.me {
tls /root/certs/nostream.localtest.me.pem /root/certs/nostream.localtest.me-key.pem
reverse_proxy nostr-ts-relay:8008
reverse_proxy nostream:8008
}

@ -1,7 +1,7 @@
services:
relay:
nostream:
volumes:
- ${PWD}/.nostr.local:/home/node/
- ${PWD}/.nostr.local:/home/node
caddy:
image: caddy:2.6.2-alpine
container_name: caddy

@ -4,7 +4,7 @@ services:
container_name: tor
user: toruser
depends_on:
- relay
- nostream
volumes:
- ${PWD}/tor/torrc:/etc/tor/torrc
- ${PWD}/.nostr/tor/data:/var/lib/tor

@ -38,8 +38,6 @@ services:
# DEBUG: "primary:*"
# DEBUG: "worker:*"
# DEBUG: "knex:query"
env_file:
- test.env
user: node:node
volumes:
- ${PWD}/.nostr:/home/node/.nostr

@ -3,11 +3,12 @@ import { SubscriptionFilter } from './subscription'
export interface IWebSocketServerAdapter extends EventEmitter, IWebServerAdapter {
getConnectedClients(): number
close(callback: () => void): void
close(callback?: () => void): void
}
export interface IWebServerAdapter extends EventEmitter {
listen(port: number): void
close(callback?: () => void): void
}

@ -28,7 +28,7 @@ export type Factory<TOutput = any, TInput = void> = (input: TInput) => TOutput
export type DatabaseClient = Knex
export type DatabaseTransaction<T = any> = Knex.Transaction<T, T[]>
export type DatabaseTransaction<T extends Record<string, unknown> = any> = Knex.Transaction<T, T[]>
export interface ContextMetadata {
remoteAddress: SocketAddress

@ -154,7 +154,7 @@ export interface PaymentsProcessors {
export interface Settings {
info: Info
payments?: Payments
paymentProcessors?: PaymentsProcessors
paymentsProcessors?: PaymentsProcessors
network: Network
workers?: Worker
limits?: Limits

@ -10,7 +10,7 @@ export class WebServerAdapter extends EventEmitter implements IWebServerAdapter
public constructor(
protected readonly webServer: Server,
) {
debug('web server starting')
debug('created')
super()
this.webServer
.on('error', this.onError.bind(this))
@ -40,8 +40,17 @@ export class WebServerAdapter extends EventEmitter implements IWebServerAdapter
socket.end('HTTP/1.1 400 Bad Request\r\nContent-Type: text/html\r\n')
}
public close(callback?: () => void): void {
this.webServer.removeAllListeners()
this.webServer.close()
if (typeof callback !== 'undefined') {
callback()
}
debug('closed')
}
protected onClose() {
debug('stopped listening to incoming connections')
this.webServer.removeAllListeners()
this.close()
}
}

@ -30,6 +30,7 @@ export class WebSocketServerAdapter extends WebServerAdapter implements IWebSock
>,
private readonly settings: () => Settings,
) {
debug('created')
super(webServer)
this.webSocketsAdapters = new WeakMap()
@ -46,11 +47,20 @@ export class WebSocketServerAdapter extends WebServerAdapter implements IWebSock
this.heartbeatInterval = setInterval(this.onHeartbeat.bind(this), WSS_CLIENT_HEALTH_PROBE_INTERVAL)
}
public close(callback: () => void): void {
this.onClose()
public close(callback?: () => void): void {
debug('closing')
clearInterval(this.heartbeatInterval)
this.webSocketServer.clients.forEach((webSocket: WebSocket) => {
debug('terminating client')
webSocket.terminate()
})
this.removeAllListeners()
this.webSocketServer.removeAllListeners()
this.webSocketServer.close(() => {
this.webServer.close(callback)
super.close()
})
debug('closed')
}
private onBroadcast(event: Event) {
@ -90,15 +100,6 @@ export class WebSocketServerAdapter extends WebServerAdapter implements IWebSock
}
protected onClose() {
debug('closing')
clearInterval(this.heartbeatInterval)
this.webSocketServer.clients.forEach((webSocket: WebSocket) => {
debug('terminating client')
webSocket.terminate()
})
this.removeAllListeners()
this.webSocketServer.removeAllListeners()
super.onClose()
debug('closed')
this.close()
}
}

@ -57,8 +57,6 @@ export class AppWorker implements IRunnable {
watcher.close()
}
}
if (typeof callback !== 'undefined') {
this.adapter.close(callback)
}
this.adapter.close(callback)
}
}

@ -1,18 +1,19 @@
import { getMasterDbClient, getReadReplicaDbClient } from '../database/client'
import { createPaymentsProcessor } from './payments-processor-factory'
import { createSettings } from './settings-factory'
import { EventRepository } from '../repositories/event-repository'
import { getDbClient } from '../database/client'
import { InvoiceRepository } from '../repositories/invoice-repository'
import { MaintenanceWorker } from '../app/maintenance-worker'
import { PaymentsService } from '../services/payments-service'
import { UserRepository } from '../repositories/user-repository'
export const maintenanceWorkerFactory = () => {
const dbClient = getDbClient()
const dbClient = getMasterDbClient()
const rrDbClient = getReadReplicaDbClient()
const paymentsProcessor = createPaymentsProcessor()
const userRepository = new UserRepository(dbClient)
const invoiceRepository = new InvoiceRepository(dbClient)
const eventRepository = new EventRepository(dbClient)
const eventRepository = new EventRepository(dbClient, rrDbClient)
const paymentsService = new PaymentsService(
dbClient,

@ -1,17 +1,18 @@
import { getMasterDbClient, getReadReplicaDbClient } from '../database/client'
import { createPaymentsProcessor } from './payments-processor-factory'
import { createSettings } from './settings-factory'
import { EventRepository } from '../repositories/event-repository'
import { getDbClient } from '../database/client'
import { InvoiceRepository } from '../repositories/invoice-repository'
import { PaymentsService } from '../services/payments-service'
import { UserRepository } from '../repositories/user-repository'
export const createPaymentsService = () => {
const dbClient = getDbClient()
const dbClient = getMasterDbClient()
const rrDbClient = getReadReplicaDbClient()
const invoiceRepository = new InvoiceRepository(dbClient)
const userRepository = new UserRepository(dbClient)
const paymentsProcessor = createPaymentsProcessor()
const eventRepository = new EventRepository(dbClient)
const eventRepository = new EventRepository(dbClient, rrDbClient)
return new PaymentsService(
dbClient,

@ -1,7 +1,7 @@
import { getMasterDbClient, getReadReplicaDbClient } from '../database/client'
import { createPaymentsProcessor } from './payments-processor-factory'
import { createSettings } from './settings-factory'
import { EventRepository } from '../repositories/event-repository'
import { getDbClient } from '../database/client'
import { IController } from '../@types/controllers'
import { InvoiceRepository } from '../repositories/invoice-repository'
import { PaymentsService } from '../services/payments-service'
@ -10,8 +10,9 @@ import { slidingWindowRateLimiterFactory } from './rate-limiter-factory'
import { UserRepository } from '../repositories/user-repository'
export const createPostInvoiceController = (): IController => {
const dbClient = getDbClient()
const eventRepository = new EventRepository(dbClient)
const dbClient = getMasterDbClient()
const rrDbClient = getReadReplicaDbClient()
const eventRepository = new EventRepository(dbClient, rrDbClient)
const invoiceRepository = new InvoiceRepository(dbClient)
const userRepository = new UserRepository(dbClient)
const paymentsProcessor = createPaymentsProcessor()

@ -1,7 +1,7 @@
import { getMasterDbClient, getReadReplicaDbClient } from '../database/client'
import { createPaymentsProcessor } from './payments-processor-factory'
import { createSettings } from './settings-factory'
import { EventRepository } from '../repositories/event-repository'
import { getDbClient } from '../database/client'
import { IController } from '../@types/controllers'
import { InvoiceRepository } from '../repositories/invoice-repository'
import { PaymentsService } from '../services/payments-service'
@ -9,8 +9,9 @@ import { UserRepository } from '../repositories/user-repository'
import { ZebedeeCallbackController } from '../controllers/callbacks/zebedee-callback-controller'
export const createZebedeeCallbackController = (): IController => {
const dbClient = getDbClient()
const eventRepository = new EventRepository(dbClient)
const dbClient = getMasterDbClient()
const rrDbClient = getReadReplicaDbClient()
const eventRepository = new EventRepository(dbClient, rrDbClient)
const invoiceRepotistory = new InvoiceRepository(dbClient)
const userRepository = new UserRepository(dbClient)
const paymentsProcessor = createPaymentsProcessor()

@ -29,6 +29,10 @@ export async function isRateLimited(remoteAddress: string, settings: Settings):
ipWhitelist = [],
} = settings.limits?.connection ?? {}
if (typeof rateLimits === 'undefined') {
return false
}
if (ipWhitelist.includes(remoteAddress)) {
return false
}

@ -139,7 +139,7 @@ export class EventRepository implements IEventRepository {
ifElse(
isEmpty,
() => andWhereRaw('1 = 0', bd),
forEach((criterion: string[]) => void orWhereRaw(
forEach((criterion: string) => void orWhereRaw(
'"event_tags" @> ?',
[
JSON.stringify([[filterName[1], criterion]]) as any,
@ -195,7 +195,7 @@ export class EventRepository implements IEventRepository {
const toJSON = (input: any) => JSON.stringify(input)
const row = applySpec({
const row = applySpec<DBEvent>({
event_id: pipe(prop('id'), toBuffer),
event_pubkey: pipe(prop('pubkey'), toBuffer),
event_created_at: prop('created_at'),

@ -234,8 +234,8 @@ Amount: ${amount.toString()} ${unit}
By paying this invoice, you confirm that you have read and agree to the Terms of Service:
${terms.toString()}
Expires at ${invoice.expiresAt.toISOString()}
${invoice.expiresAt ? `
Expires at ${invoice.expiresAt.toISOString()}` : ''}
${invoice.bolt11}`,
tags: [

@ -15,7 +15,7 @@ export enum SettingsFileTypes {
}
export class SettingsStatic {
static _settings: Settings
static _settings: Settings | undefined
public static getSettingsFileBasePath(): string {
return process.env.NOSTR_CONFIG_DIR ?? join(process.cwd(), '.nostr')
@ -93,6 +93,10 @@ export class SettingsStatic {
SettingsStatic._settings = mergeDeepRight({}, defaults)
}
if (typeof SettingsStatic._settings === 'undefined') {
throw new Error('Unable to set settings')
}
return SettingsStatic._settings
} catch (error) {
debug('error reading config file at %s: %o', settingsFilePath, error)