Kevin L'Hereec
f9e56c78b1
refactor: migrate all internal imports to package.json subpath aliases
...
- Add #domain, #protocol, #utils aliases to package.json imports map
- Replace all relative imports (./, ../, ../..) in app/ and
database/mongo_migrations/ with the corresponding #alias imports,
eliminating relative path traversal across the codebase
- Remove dead code: ConfigurationVersionModel.findByConfigurationIdentifier
(unused, superseded by paginateVersions) and unused exception classes
(NotFoundException, UnprocessableEntityException, DatabaseException)
from app/exceptions/index.ts, keeping only BadRequestException
- Fix pre-existing syntax error in configuration_version.ts (mismatched
parenthesis) that broke tsc
- Fix eqeqeq violation in configuration_service.ts and isNaN ->
Number.isNaN in configuration_engine.ts / cwmp-1-0.ts / exchange_controller.ts
- Fix no-shadow violation in cwmp-1-0.ts EventStruct constructor
- Prettier formatting pass on touched files
Validated: tsc --noEmit clean, eslint app/ clean, full test suite green.
2026-07-22 11:45:14 +02:00
Kevin L'Hereec
9cceb139b7
fix: eslint consistent-type-imports and eqeqeq violations
...
- Convert value imports used only as types to 'import type' across
all modified files (cwmp_message_builder, task_queue, device_action_executor,
main_state_machine, immediate_command_state_machine, configuration_evaluation_state,
cwmp_controller, cwmp_middleware, device.ts, soap.ts, soap_envelope.ts, tr069_types.ts)
- Replace != null with !== null && !== undefined in main_state_machine and cwmp_controller
2026-07-20 17:14:12 +02:00
Kevin L'Hereec
f3eb8e1650
feat: restore strong typing on TR-069/CWMP protocol layer
...
- Copy cwmp-1-0..4.ts source classes from cwmp-connector (papaye) into
app/protocol/ as local files (ts-nocheck, external dependency)
- Add soap_envelope.ts: SoapEnvelope, SoapEnvelopeHeader, CwmpID, NAMESPACES
- Add tr069_types.ts: re-exports all CWMP classes + CwmpMessage discriminated
union + typed task payload interfaces (CWMPTaskType, CWMPTaskPayload, etc.)
- Rewrite cwmp_message_builder.ts to use class-based builders instead of raw
XML template strings; add transferCompleteResponse() and soapFault()
- soap.ts: extractCwmpMessage returns CwmpMessage union, adds runtime allowlist
guard against unknown CWMP method names from CPE
- cwmp_middleware.ts: envelope typed SoapEnvelope|null, message CwmpMessage|null
- cwmp_controller.ts: handleInform(informData: Inform), remove any, migrate
TransferComplete and fault to new builder path, drop buildSoapEnvelope import
- task_queue.ts: CWMPTask.type → CWMPTaskType literal union, payload →
CWMPTaskPayload, result → CWMPTaskResultData
- device_action_executor.ts: GPV/GPN/GPA responses typed, no more any
- main_state_machine.ts: DeviceContext.message.data → CWMPTaskResultData,
organizeParameters receives ParameterInfoStruct[] directly
- device.ts: tmpParamValues typed ParameterValueStruct[], organizeParameters
signature updated, updateFromValues typed
- device_id.ts: fromInform typed with DeviceIdStruct
- soap_envelope.ts: remove unconditional <cwmp:noMoreRequests> header
(CPE→ACS only per TR-069 §3.7.1.4)
2026-07-20 15:25:26 +02:00
Kevin L'Hereec
8969355688
feat: improve critical reads, device list and modelPaths bug fix
...
Build & Deploy / build (push) Successful in 34s
Build & Deploy / docker (push) Successful in 1m4s
Build & Deploy / deploy (push) Successful in 32s
- main_state_machine.ts: add to CriticalReadsState GPV:
ProvisioningCode (confirm CPE persisted value), UpTime (detect reboots),
ManagementServer.URL (verify ACS URL), ConnectionRequestUsername/Password
(ensure wake credentials are always available)
- Home.vue: add Last Seen column (device.updatedAt)
- pages_controller.ts: fix modelPaths bug — was never passed to DeviceDetail,
now auto-detected from dataModel and passed as predefined TR-181/TR-098 paths
2026-07-17 16:57:08 +02:00
Kevin L'Hereec
7d603da0ca
fix: Connection Request fallback to IPv4 when CPE has IPv6-only URL
...
Build & Deploy / build (push) Successful in 30s
Build & Deploy / docker (push) Successful in 57s
Build & Deploy / deploy (push) Successful in 24s
- device_record.ts: add lastRemoteIp field to store the CPE public IP
from each Inform (X-Forwarded-For or TCP remote IP)
- cwmp_controller.ts: persist lastRemoteIp on every Inform alongside
lastPeriodicInformAt (single operation)
- device_service.ts: sendWakeOnWlan() now tries the original URL first
(may be IPv6), then falls back to a rebuilt URL using lastRemoteIp
(IPv4 public IP) if the ACS server has no IPv6 connectivity
2026-07-17 16:45:30 +02:00
Kevin L'Hereec
7835f99657
fix: correct CWMP session management side effects
...
Build & Deploy / build (push) Successful in 29s
Build & Deploy / docker (push) Successful in 1m0s
Build & Deploy / deploy (push) Successful in 34s
- state_machine_manager: add deviceToRemotes reverse index (Map<deviceKeyJson, Set<remoteKey>>)
so completeMachine/failMachine clean up remoteToDevice in O(1) — fixes unbounded memory leak
- state_machine_manager: getHashIdForRemoteIp() now only matches RUNNING sessions and
returns undefined when multiple candidates exist (NAT/CGNAT safety)
- state_machine_manager: IPv6 bracket normalization in IP comparison
- cwmp_controller: apply IP fallback to TransferComplete and generic response handler
(same new-TCP-port scenario as empty POST after firmware reboot)
- cwmp_logger_middleware: reuse request.cwmp.sessionId instead of recomputing
from socket to avoid formula drift
2026-07-17 15:39:41 +02:00
Kevin L'Hereec
d44d896556
fix: persist empty POST in TR-069 trace when CPE uses a new TCP port
...
Build & Deploy / build (push) Successful in 38s
Build & Deploy / docker (push) Successful in 1m5s
Build & Deploy / deploy (push) Successful in 23s
When a CPE sends an empty POST (polling) on a new TCP connection, the
remoteKey (IP:port) differs from the one registered during Inform.
Add StateMachineManager.getHashIdForRemoteIp() to find the device by
IP alone as a fallback, so cwmpDeviceId is resolved and the exchange
is properly stored in the trace (cwmpMethod: Empty, dashed arrow).
2026-07-17 14:24:44 +02:00
kevin.lhereec
5ea25d462e
feat: logs debug sur les echanges XML CWMP
...
Build & Deploy / build (push) Failing after 36s
Build & Deploy / docker (push) Skipped
Build & Deploy / deploy (push) Skipped
- cwmp_middleware: log XML brut recu (bodyPreview 500 chars), contentType,
bodyLength, et message extrait (type, cwmpVersion, cwmpId, messageKeys)
+ log body vide (CPE polling)
- cwmp_logger_middleware: log XML pretty-print complet CPE->ACS et ACS->CPE
en debug, independamment du statut trace
- cwmp_controller: log routage message (messageType), InformResponse,
TransferCompleteResponse, reponses state machine avec longueur
2026-07-17 10:36:57 +02:00
kevin.lhereec
b00c0c94a8
feat: suppression des commandes PENDING depuis /commands
...
Build & Deploy / build (push) Successful in 40s
Build & Deploy / docker (push) Successful in 1m4s
Build & Deploy / deploy (push) Successful in 26s
- Ajout de destroy() dans CommandsController (DELETE /commands/:id)
- Routes DELETE /commands/:id dans les groupes /api/v1 et /internal
- Bouton supprimer dans Commands.vue visible uniquement sur les commandes PENDING
- Utilise fetchWithCsrf pour la protection CSRF
2026-07-17 10:31:56 +02:00
Kevin L'Hereec
991173aa05
feat(auth): add session login page, API key guard, and remove orphan SQL migrations
...
- Add session-based authentication for web-UI (Login.vue, AuthController)
- Add AuthSessionMiddleware: redirects unauthenticated users to /login
- Add ApiKeyMiddleware: validates X-Api-Key header on all /api/v1 routes
- Add BasicAuthMiddleware: registered for future M2M use
- Use timingSafeEqual for all credential comparisons (timing attack prevention)
- Regenerate session ID on login (session fixation prevention)
- Validate redirect target after login (open redirect prevention)
- Require WEBUI_USERNAME, WEBUI_PASSWORD, API_KEY as mandatory env vars
- Share auth.username/authenticated via Inertia shared props
- Add user dropdown in navbar (avatar icon + username + logout)
- Add login i18n keys in fr.json and en.json
- Remove orphan SQL migrations (users, auth_access_tokens) and @adonisjs/lucid
2026-07-03 13:59:05 +02:00
Kevin L'Hereec
ec7e66555d
fix
2026-06-08 16:54:37 +02:00
ATX Bot
23b5e33a6b
Implement DeviceModel.distinctCriteriaValues() — fixes 500 on /api/v1/devices/criteria-values. Uses MongoDB distinct() to get unique manufacturers, OUIs, productClasses from devices collection. Build status: Success
2026-06-08 13:01:19 +00:00
Kevin L'Hereec and Continue
aad93911e4
feat: TR-069 CWMP state machine hardening + exchange viewer improvements
...
- TR-069 CWMP state machine hardening (14 phases): shared event utility,
multi-event routing, GPN circuit breaker, IdleState GPN guard, expanded
GPN fault codes, CriticalReadsState, ConfigEval GPN guard, task queue
race condition fix, explicit error handling, terminal states
(OperationalState/PartialOperationalState), consolidated reclassify,
crash pattern detection, removed enqueueImmediate, state flow wiring
- Fix SOAP Fault not processed by state machine (soap-env:Fault detection)
- Fix GPN circuit breaker not persisting after session drops
- Fix CriticalReadsState GPV response parsing (xsi:type normalization)
- Fix CriticalReadsState not processing GPV response values
- Skip SPV when device is already compliant (ProvisioningCode check)
- Add Device.DeviceInfo.ModelName to critical reads GPV
- Fix TypeError on DeviceDetail parameters view (null guards)
- Log empty 204 responses in exchange trace UI
- TR-181 catalog: type corrections and new entries (+6640 lines)
- SequenceViewer: replace session-nav buttons with compact dropdown select
- SequenceViewer: fix CPE/ACS lifeline headers wrapping to 2 lines
- Add 20 unit tests for state machine fixes (SOAP Fault, GPN circuit
breaker, CriticalReads, stale session, ConfigEval/ComplianceUpdate skips)
Generated with [Continue](https://continue.dev )
Co-Authored-By: Continue <noreply@continue.dev >
2026-06-08 12:49:00 +00:00
Kevin L'Hereec
0c83a4ccb2
feat: TR-069 Exchange Viewer - structured MongoDB storage with SSE streaming and sequence diagram UI
...
- MongoDB storage: cwmp_exchanges collection with indexes (deviceId+timestamp, deviceId+sequenceNumber unique, TTL 24h)
- ExchangeStoreService: CWMP method extraction, per-device queue for ordering, retry logic, message cap (5000/device)
- Exchange API: GET/DELETE/SSE stream endpoints with Last-Event-ID reconnection
- CwmpLoggerMiddleware: dual-write (MongoDB + legacy files) with fire-and-forget
- Frontend: SequenceViewer (CPE↔ACS lifelines, arrows, auto-scroll, virtual scroll) + InspectorPanel (formatted XML, copy, syntax highlighting)
- Tr069Trace page: integrated new viewer with col-6/col-6 layout
- DeviceDetail page: collapsible exchange section when device is traced
- 14 property-based tests, 40+ unit tests, 5 integration tests
- Health check includes index verification
- Config: feature flags, SSE timeouts, retry policy
2026-06-03 15:52:44 +02:00
Kevin L'Hereec
670ed860aa
feat: initialize lastPeriodicInformAt on BOOTSTRAP too
2026-06-02 18:16:16 +02:00
Kevin L'Hereec
7882a49d71
refactor: move dynamic imports to file headers
...
- getReferenceEngine import moved to top of cwmp_controller
- Fix makeContext type in configuration_evaluation_state tests
2026-06-02 17:58:07 +02:00
Kevin L'Hereec
31578e368f
feat: estimated next connection + fix build errors
...
- Store lastPeriodicInformAt on device when PERIODIC Inform received
- Display 'Prochaine connexion' in DeviceDetail identity card
- Fix tsconfig exclude (tests, inertia, coverage) for Docker build
- Fix TS errors in tests (CommandResult type, unused imports)
- Fix distinctCriteriaValues typing in controller
2026-06-02 17:56:17 +02:00
Kevin L'Hereec
e1e8ae5097
refactor: move validator imports to file header
2026-06-02 17:12:24 +02:00
Kevin L'Hereec
0cb8e12466
refactor: wire validators into controllers
...
- configurations_v1_controller: use createConfigurationValidator/updateConfigurationValidator
- firmware_catalog_controller: use createFirmwareEntryValidator/updateFirmwareEntryValidator/createMigrationRouteValidator
- Remove dead isModeType/parseMode from mode.ts
- Remove dead NAMESPACES from soap.ts
2026-06-02 17:09:15 +02:00
Kevin L'Hereec
e857b4fbe7
feat: reference providers system with Wassup integration
...
- Pluggable multi-provider architecture (ReferenceEngine)
- Wassup provider implementation (HTTP GET + X_WASSUP_USER_IP)
- Auto-resolve references on Inform (BOOT/BOOTSTRAP events)
- References displayed in device Identity card
- REST API: GET/POST references per device
- Config via config/references.json
- Fix event extraction for single EventStruct and numeric EventCodes
- Mock Wassup provisioned by home-device-simulator on device creation
2026-06-02 15:52:16 +02:00
Kevin L'Hereec
4eb3f0795a
feat: immediate mode (I) commands via Connection Request
...
- Hide Refresh button when ConnectionRequestURL is unavailable
- Fix ImmediateCommandStateMachine session lifecycle (mark complete when no commands)
- Fix preemption: new CONNECTION REQUEST replaces stale immediate session
- Protect ensureSessionForRemote from rebinding to completed machines
- Normalize numeric event codes from simulators (6 -> 6 CONNECTION REQUEST)
- Extract updatePendingCommandsStatus for clarity
2026-06-02 14:00:31 +02:00
Kevin L'Hereec
ea73e91aa4
trace + backup propertie
2026-06-01 16:20:58 +02:00
Kevin L'Hereec
b3b1edec17
ok
2026-06-01 15:49:09 +02:00
Kevin L'Hereec and Copilot
6082a0e610
feat: TR-069 per-device SOAP trace logging + log viewer UI
...
- Remove SOAP from Docker stdout; route to per-device trace files only
- Fix trace service paths using process.cwd() (/app/data/, /app/logs/tr069/)
- Fix Docker volume permissions: dedicated /app/data & /app/logs/tr069 dirs
- Add GET /api/v1/tr069-trace/:id/log endpoint (tail N lines)
- Rewrite Tr069Trace.vue: clickable rows, dark log viewer, 3s auto-refresh
- Add simulator-ui-env.js to public/ (remove from config/)
- TR-181/InternetGatewayDevice dataModel auto-detection
- Parameter writability config with W/R fallback default
- Fix device_action_executor for GetParameterNames detection flow
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
2026-06-01 14:33:44 +02:00
Kevin L'Hereec and Copilot
847da1cdf5
feat: per-device TR-069 SOAP trace logging
...
- Tr069TraceService: in-memory Map O(1) lookup, Promise-queue per device
for sequential file writes, 10MB rotation (5 files kept)
- config/tr069-trace.json: persisted list of traced devices (atomic write)
- CwmpLoggerMiddleware: buffers request+response, writes to device log file
after next() once ctx.cwmpDeviceId is set by controller
- CwmpController: sets ctx.cwmpDeviceId on all code paths (Inform + others)
- StateMachineManager: getHashIdForRemote() for non-Inform messages
- REST API: GET/POST/DELETE /api/v1/tr069-trace
- UI: Tr069Trace Vue page with device search, add/remove tracing
- 8 new unit tests (192 total, all passing)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
2026-06-01 12:07:07 +02:00
Kevin L'Hereec and Copilot
aff8e14a63
feat: compliance report + auto-versioning for configurations
...
- Add ComplianceStatus.PENDING and configVersion to DeviceComplianceInfo
- Add ComplianceReport + ComplianceDeviceResult types to ConfigurationEngine
- Expose evaluateSpecific() as public (used by compliance + dry-run)
- Add complianceReport() method: filter matching devices, evaluate each
- Fix matchesCriteria: skip parameterCriteria entries with null/empty name
- Fix getDeviceParameterValue: fallback to plain object arrays (DeviceRecord)
- Fix findDevice: support lookup by both identifier and deviceId.id
- ConfigurationService.update: version is now auto-managed (no user input)
- behavioral changes (criteria/params/policy/priority/…) → patch bump
- bumpType field allows 'patch' | 'minor' | 'major'
- cosmetic changes (name/tags) → no bump
- Add sanitizeCriteria: filter null/empty parameterCriteria names silently
- Add isBehavioralChange helper
- Add DeviceModel.resetComplianceForConfiguration call on behavioral update
- Add ConfigurationModel.distinctTags() + controller endpoint GET /tags
- Add controller endpoint GET /configurations/:id/compliance
- Add DeviceModel.getDistinctValues for inventory fields
- Fix unit tests: mock DeviceModel, remove obsolete version-validation test
- Add 14 new unit tests (engine: 5, service: 9)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
2026-06-01 11:32:17 +02:00
Kevin L'Hereec and Copilot
b8ff4b68a7
feat: TR-181 parameter writability resolution
...
- Add GpnStatus type ('supported' | 'unsupported' | 'unknown') to Device domain
- Persist gpnStatus in DeviceRecord and all 3 persist paths
(cwmp_controller, main_state_machine, device_action_executor)
- Capture Fault 9000/9001 in getParameterNames → mark device as 'unsupported'
- Fix GPN NextLevel flag: false (non-recursive shallow scan)
- Add static TR-181 catalog (7 727 params, sourced from BBF cwmp-data-models)
- Add parameter_writability service with resolveWritability():
supported → live data; unsupported → catalog → default R/W;
unknown → catalog → null (genuinely unknown)
- Add scripts/generate-tr181-catalog.mjs to regenerate catalog from BBF XML
- Add design doc: docs/design-parameter-writability.md
- Add unit tests: 26 tests covering normalizePath and all gpnStatus branches
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com >
2026-06-01 11:25:15 +02:00
Kevin L'Hereec and Copilot
d1c65dbf1e
chore: initial commit — AdonisJS v7 TR-069 ACS
...
- 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 >
2026-05-29 16:46:37 +02:00