mirror of
https://github.com/Cameri/nostream.git
synced 2025-03-17 13:21:45 +01:00
fix: lots of bugs
Signed-off-by: Ricardo Arturo Cabral Mejía <me@ricardocabral.io>
This commit is contained in:
parent
f9c53eeeb8
commit
9c010e7865
Caddyfile.localdocker-compose.local.ymldocker-compose.tor.ymldocker-compose.yml
src
@types
adapters
app
factories
maintenance-worker-factory.tspayments-service-factory.tspost-invoice-controller-factory.tszebedee-callback-controller-factory.ts
handlers/request-handlers
repositories
services
utils
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user