diff --git a/app/domain/device/device_record.ts b/app/domain/device/device_record.ts index d225ca9..dbbaaf1 100644 --- a/app/domain/device/device_record.ts +++ b/app/domain/device/device_record.ts @@ -2,7 +2,7 @@ import { type DeviceId } from './device_id.js' import { type PropertySnapshot, type ParameterSnapshot } from './device_parameter.js' import { type DeviceComplianceInfo } from '../configuration/compliance.js' import { type DataModel, type GpnStatus, type GpnCircuitBreaker } from './device.js' -import type { DeviceReference } from '../../services/references/types.js' +import type { DeviceReference } from '#services/references/types' export interface DeviceRecord { identifier?: string diff --git a/app/exceptions/handler.ts b/app/exceptions/handler.ts index ba2fc34..27da7db 100644 --- a/app/exceptions/handler.ts +++ b/app/exceptions/handler.ts @@ -1,5 +1,5 @@ import app from '@adonisjs/core/services/app' -import { HttpContext, ExceptionHandler } from '@adonisjs/core/http' +import { type HttpContext, ExceptionHandler } from '@adonisjs/core/http' export default class HttpExceptionHandler extends ExceptionHandler { protected debug = !app.inProduction diff --git a/app/middleware/api_key_middleware.ts b/app/middleware/api_key_middleware.ts index b4d4d80..46c448f 100644 --- a/app/middleware/api_key_middleware.ts +++ b/app/middleware/api_key_middleware.ts @@ -24,8 +24,7 @@ export default class ApiKeyMiddleware { const expected = Buffer.from(expectedKey) // Lengths must match and content must match in constant time - const valid = - provided.length === expected.length && timingSafeEqual(provided, expected) + const valid = provided.length === expected.length && timingSafeEqual(provided, expected) if (!valid) { return response.status(401).send('Unauthorized: invalid or missing X-Api-Key header') diff --git a/app/middleware/cwmp_logger_middleware.ts b/app/middleware/cwmp_logger_middleware.ts index 4395fdb..bc85258 100644 --- a/app/middleware/cwmp_logger_middleware.ts +++ b/app/middleware/cwmp_logger_middleware.ts @@ -35,14 +35,16 @@ export default class CwmpLoggerMiddleware { const rawBody = request.raw() || '' // Reuse sessionId already computed by CwmpMiddleware to avoid drift - const sessionId = request.cwmp?.sessionId ?? (() => { - const socket = request.request?.socket - const remoteIp = request.ip() - const remotePort = socket?.remotePort || 0 - const localAddress = socket?.localAddress || 'unknown' - const localPort = socket?.localPort || 0 - return `${remoteIp}:${remotePort}->${localAddress}:${localPort}` - })() + const sessionId = + request.cwmp?.sessionId ?? + (() => { + const socket = request.request?.socket + const remoteIp = request.ip() + const remotePort = socket?.remotePort || 0 + const localAddress = socket?.localAddress || 'unknown' + const localPort = socket?.localPort || 0 + return `${remoteIp}:${remotePort}->${localAddress}:${localPort}` + })() let capturedResponseXml: string | null = null let isEmptyResponse = false @@ -68,28 +70,34 @@ export default class CwmpLoggerMiddleware { const exchangeStore = ExchangeStoreService.getInstance() // Persist CPE→ACS (including empty POST) - exchangeStore.persistExchange({ - deviceId, - direction: 'CPE→ACS', - sessionId, - rawXml: rawBody || '', - }).catch(() => {}) + exchangeStore + .persistExchange({ + deviceId, + direction: 'CPE→ACS', + sessionId, + rawXml: rawBody || '', + }) + .catch(() => {}) // Persist ACS→CPE response (will queue after the CPE→ACS above) if (capturedResponseXml) { - exchangeStore.persistExchange({ - deviceId, - direction: 'ACS→CPE', - sessionId, - rawXml: capturedResponseXml, - }).catch(() => {}) + exchangeStore + .persistExchange({ + deviceId, + direction: 'ACS→CPE', + sessionId, + rawXml: capturedResponseXml, + }) + .catch(() => {}) } else if (isEmptyResponse) { - exchangeStore.persistExchange({ - deviceId, - direction: 'ACS→CPE', - sessionId, - rawXml: '', - }).catch(() => {}) + exchangeStore + .persistExchange({ + deviceId, + direction: 'ACS→CPE', + sessionId, + rawXml: '', + }) + .catch(() => {}) } // Old system: file-based writes (kept for Phase 1 dual-write rollback safety) @@ -112,13 +120,23 @@ export default class CwmpLoggerMiddleware { // Always log full XML at debug level regardless of trace status if (rawBody && rawBody.trim() !== '') { logger.debug( - { sessionId, deviceId: deviceId ?? 'unknown', direction: 'CPE→ACS', xml: this.prettyXml(rawBody) }, + { + sessionId, + deviceId: deviceId ?? 'unknown', + direction: 'CPE→ACS', + xml: this.prettyXml(rawBody), + }, 'CWMP XML request' ) } if (capturedResponseXml) { logger.debug( - { sessionId, deviceId: deviceId ?? 'unknown', direction: 'ACS→CPE', xml: this.prettyXml(capturedResponseXml) }, + { + sessionId, + deviceId: deviceId ?? 'unknown', + direction: 'ACS→CPE', + xml: this.prettyXml(capturedResponseXml), + }, 'CWMP XML response' ) } else if (isEmptyResponse) {