- Docker infrastructure (Dockerfile, docker-compose.yml, genieacs-sim) - AdonisJS v7 app with Inertia.js + Vue 3 - MongoDB integration - CWMP/TR-069 state machine engine - Configuration engine with compliance tracking - Branding: ADAM ACS (favicon, navbar, locales) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
import type { HttpContext } from '@adonisjs/core/http'
|
|
import type { NextFn } from '@adonisjs/core/types/http'
|
|
// @ts-ignore - xml-formatter types conflict with ESM interop
|
|
import formatXml from 'xml-formatter'
|
|
|
|
/**
|
|
* CWMP Logger Middleware
|
|
*
|
|
* Middleware dédié à l'observation des messages TR-069 XML.
|
|
* Trace les échanges CPE↔ACS (requêtes entrantes et réponses sortantes)
|
|
* avec le XML pretty-printed directement sur stdout pour lisibilité humaine.
|
|
*
|
|
* Doit être placé avant le cwmp_middleware dans la chaîne.
|
|
*/
|
|
export default class CwmpLoggerMiddleware {
|
|
private prettyXml(xml: string): string {
|
|
try {
|
|
return (formatXml as any)(xml, { indentation: ' ', collapseContent: true, lineSeparator: '\n' })
|
|
} catch {
|
|
return xml
|
|
}
|
|
}
|
|
|
|
private log(direction: string, sessionId: string, xml: string) {
|
|
const timestamp = new Date().toISOString()
|
|
const separator = '─'.repeat(80)
|
|
process.stdout.write(
|
|
`\n${separator}\n` +
|
|
`[TR-069] ${direction} | ${timestamp} | ${sessionId}\n` +
|
|
`${separator}\n` +
|
|
`${xml}\n` +
|
|
`${separator}\n\n`
|
|
)
|
|
}
|
|
|
|
async handle({ request, response }: HttpContext, next: NextFn) {
|
|
const rawBody = request.raw() || ''
|
|
|
|
const socket = request.request?.socket
|
|
const remoteIp = request.ip()
|
|
const remotePort = socket?.remotePort || 0
|
|
const localAddress = socket?.localAddress || 'unknown'
|
|
const localPort = socket?.localPort || 0
|
|
const sessionId = `${remoteIp}:${remotePort}->${localAddress}:${localPort}`
|
|
|
|
// Log incoming TR-069 message
|
|
if (rawBody && rawBody.trim() !== '') {
|
|
this.log('CPE→ACS', sessionId, this.prettyXml(rawBody))
|
|
}
|
|
|
|
// Intercept response to log outgoing XML
|
|
const originalSend = response.send.bind(response)
|
|
response.send = (body: any) => {
|
|
if (typeof body === 'string' && body.includes('soap-env:Envelope')) {
|
|
this.log('ACS→CPE', sessionId, this.prettyXml(body))
|
|
}
|
|
return originalSend(body)
|
|
}
|
|
|
|
return next()
|
|
}
|
|
}
|