Roadmap 'Webhook events': per-license outbound webhooks with HMAC-SHA256 signatures (X-Corrosion-Signature), 5s timeout, fire-and-forget (a webhook failure never breaks the triggering action), last_delivery_at/last_status tracked. - migration 024_webhooks; Webhook entity (events as simple-array); WebhooksModule (@Global, exports WebhooksService) wired into app.module; CRUD controller (license-scoped, webhooks.view/manage). - Hooked events: players.performAction ban -> 'player_banned'; host-agent-consumer going-offline + staleness sweep -> 'server_down'. - 'wipe_completed' event lands next (needs wipe status from the agent reply). Backend tsc green. Migration applies on a fresh DB (Saturday). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
162 lines
5.8 KiB
TypeScript
162 lines
5.8 KiB
TypeScript
import { Module } from '@nestjs/common';
|
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
import { JwtModule } from '@nestjs/jwt';
|
|
import { APP_GUARD } from '@nestjs/core';
|
|
import { ScheduleModule } from '@nestjs/schedule';
|
|
import configuration from './config/configuration';
|
|
|
|
// Guards
|
|
import { JwtAuthGuard } from './common/guards/jwt-auth.guard';
|
|
import { PermissionsGuard } from './common/guards/permissions.guard';
|
|
import { LicenseGuard } from './common/guards/license.guard';
|
|
|
|
// Feature Modules
|
|
import { AuthModule } from './modules/auth/auth.module';
|
|
import { UsersModule } from './modules/users/users.module';
|
|
import { LicensesModule } from './modules/licenses/licenses.module';
|
|
import { ServersModule } from './modules/servers/servers.module';
|
|
import { PlayersModule } from './modules/players/players.module';
|
|
import { WipesModule } from './modules/wipes/wipes.module';
|
|
import { MapsModule } from './modules/maps/maps.module';
|
|
import { PluginsModule } from './modules/plugins/plugins.module';
|
|
import { ChatModule } from './modules/chat/chat.module';
|
|
import { TeamModule } from './modules/team/team.module';
|
|
import { NotificationsModule } from './modules/notifications/notifications.module';
|
|
import { SettingsModule } from './modules/settings/settings.module';
|
|
import { SchedulesModule } from './modules/schedules/schedules.module';
|
|
import { AnalyticsModule } from './modules/analytics/analytics.module';
|
|
import { AlertsModule } from './modules/alerts/alerts.module';
|
|
import { StatusModule } from './modules/status/status.module';
|
|
import { StoreModule } from './modules/store/store.module';
|
|
import { WebstoreModule } from './modules/webstore/webstore.module';
|
|
import { AdminModule } from './modules/admin/admin.module';
|
|
import { SetupModule } from './modules/setup/setup.module';
|
|
import { MigrationModule } from './modules/migration/migration.module';
|
|
import { ChangelogModule } from './modules/changelog/changelog.module';
|
|
import { FilesModule } from './modules/files/files.module';
|
|
import { LootModule } from './modules/loot/loot.module';
|
|
import { TeleportModule } from './modules/teleport/teleport.module';
|
|
import { GatherModule } from './modules/gather/gather.module';
|
|
import { AutoDoorsModule } from './modules/autodoors/autodoors.module';
|
|
import { KitsModule } from './modules/kits/kits.module';
|
|
import { FurnaceSplitterModule } from './modules/furnacesplitter/furnacesplitter.module';
|
|
import { BetterChatModule } from './modules/betterchat/betterchat.module';
|
|
import { TimedExecuteModule } from './modules/timedexecute/timedexecute.module';
|
|
import { RaidableBasesModule } from './modules/raidablebases/raidablebases.module';
|
|
import { EarlyAccessModule } from './modules/early-access/early-access.module';
|
|
import { FleetModule } from './modules/fleet/fleet.module';
|
|
import { InstancesModule } from './modules/instances/instances.module';
|
|
import { ApiKeysModule } from './modules/api-keys/api-keys.module';
|
|
import { WebhooksModule } from './modules/webhooks/webhooks.module';
|
|
|
|
// Shared Services
|
|
import { NatsService } from './services/nats.service';
|
|
import { NatsBridgeService } from './services/nats-bridge.service';
|
|
import { HostAgentConsumerService } from './services/host-agent-consumer.service';
|
|
import { ServerConnection } from './entities/server-connection.entity';
|
|
import { License } from './entities/license.entity';
|
|
import { AgentHost } from './entities/agent-host.entity';
|
|
import { GameInstance } from './entities/game-instance.entity';
|
|
import { SteamService } from './services/steam.service';
|
|
|
|
// Gateway
|
|
import { NatsBridgeGateway } from './gateways/nats-bridge.gateway';
|
|
|
|
@Module({
|
|
imports: [
|
|
// Configuration
|
|
ConfigModule.forRoot({
|
|
isGlobal: true,
|
|
load: [configuration],
|
|
}),
|
|
|
|
// Database
|
|
TypeOrmModule.forRootAsync({
|
|
inject: [ConfigService],
|
|
useFactory: (config: ConfigService) => ({
|
|
type: 'postgres' as const,
|
|
url: config.get<string>('database.url'),
|
|
autoLoadEntities: true,
|
|
synchronize: false, // NEVER auto-sync — use migrations only
|
|
extra: {
|
|
max: config.get<number>('database.maxConnections') || 20,
|
|
},
|
|
}),
|
|
}),
|
|
|
|
// JWT (global)
|
|
JwtModule.registerAsync({
|
|
global: true,
|
|
inject: [ConfigService],
|
|
useFactory: (config: ConfigService) => ({
|
|
secret: config.get<string>('jwt.secret'),
|
|
signOptions: {
|
|
expiresIn: `${config.get<number>('jwt.accessExpirySeconds') || 900}s`,
|
|
},
|
|
}),
|
|
}),
|
|
|
|
// Scheduler
|
|
ScheduleModule.forRoot(),
|
|
|
|
// Repositories for app-level shared services (host-agent consumer)
|
|
TypeOrmModule.forFeature([ServerConnection, License, AgentHost, GameInstance]),
|
|
|
|
// Feature Modules
|
|
AuthModule,
|
|
UsersModule,
|
|
LicensesModule,
|
|
ServersModule,
|
|
PlayersModule,
|
|
WipesModule,
|
|
MapsModule,
|
|
PluginsModule,
|
|
ChatModule,
|
|
TeamModule,
|
|
NotificationsModule,
|
|
SettingsModule,
|
|
SchedulesModule,
|
|
AnalyticsModule,
|
|
AlertsModule,
|
|
StatusModule,
|
|
StoreModule,
|
|
WebstoreModule,
|
|
AdminModule,
|
|
SetupModule,
|
|
MigrationModule,
|
|
ChangelogModule,
|
|
FilesModule,
|
|
LootModule,
|
|
TeleportModule,
|
|
GatherModule,
|
|
AutoDoorsModule,
|
|
KitsModule,
|
|
FurnaceSplitterModule,
|
|
BetterChatModule,
|
|
TimedExecuteModule,
|
|
RaidableBasesModule,
|
|
EarlyAccessModule,
|
|
FleetModule,
|
|
InstancesModule,
|
|
ApiKeysModule,
|
|
WebhooksModule,
|
|
],
|
|
providers: [
|
|
// Global guards (order matters: auth first, then license, then permissions)
|
|
{ provide: APP_GUARD, useClass: JwtAuthGuard },
|
|
{ provide: APP_GUARD, useClass: PermissionsGuard },
|
|
|
|
// Shared services
|
|
NatsService,
|
|
NatsBridgeService,
|
|
HostAgentConsumerService,
|
|
SteamService,
|
|
|
|
// WebSocket gateway
|
|
NatsBridgeGateway,
|
|
],
|
|
exports: [NatsService, NatsBridgeService, SteamService],
|
|
})
|
|
export class AppModule {}
|