Devices
Scopo
I device sono endpoint SIP associati a originator o terminator. Il modulo distingue endpoint statici IP/porta da endpoint dynamic/SIP register, gestisce NAT, codec, credenziali SIP e bulk operations operative.
Dove
| Elemento | Valore |
|---|---|
| Route UI | /devices, /devices/[id] |
| Voce di menu | Clients / Devices |
| Componenti principali | apps/frontend/src/app/[locale]/(dashboard)/devices/*, apps/frontend/src/components/devices/*, apps/frontend/src/components/forms/device-form.tsx, apps/frontend/src/schemas/device.ts |
Campi & comportamento
| Campo | Significato | Validazione / comportamento |
|---|---|---|
name | Codice/nome device | Obbligatorio; disabilitato in edit. Max 120 nel drawer lista, max 255 nella modale detail. |
type | Tipo device | Lista/drawer usa static o register, payload converte register in dynamic; modale detail usa direttamente static o dynamic. Il tipo non si cambia in edit. |
is_active | Abilitazione device | Checkbox; filtro server-side e bulk enable/disable. |
| Associazione | Originator o terminator | Modale detail consente associazione esclusiva originator/terminator in creazione. Drawer lista espone originator_id; in edit mostra label terminator se gia' associato ma non consente cambiare associazione. |
nat | NAT enabled | Checkbox nella modale detail; bulk NAT on/off dalla lista. Il drawer legacy invia nat: false. |
codec / codec_priority | Codec preferito | Testo opzionale, placeholder PCMU, PCMA o G.711a. |
max_concurrent_calls / max_channels | Canali concorrenti | Intero positivo/opzionale; in drawer schema e' non negativo e viene mappato a null se vuoto. |
outbound_proxy | Proxy SIP outbound | Testo opzionale nella modale detail; usato anche per inferire transport nella lista. |
inbound_ip_whitelist | IP autorizzati | CSV in modale detail; per static nel drawer viene valorizzato con l'IP. |
notes | Note operative | Testo opzionale, max 500 nel drawer. |
Variante static / IP fisso
| Campo | Significato | Validazione / comportamento |
|---|---|---|
host / ip_address | IP o FQDN dell'endpoint | Obbligatorio. Modale detail accetta IPv4/FQDN con porta opzionale; drawer lista valida IP IPv4/IPv6. |
port | Porta SIP | Default 5060; intero 1-65535. Se host contiene :porta, la modale detail separa host e porta. |
inbound_ip_whitelist | Whitelist inbound | Nel detail e' CSV esplicito; nel drawer static diventa [ip_address]. |
Variante dynamic / SIP register
| Campo | Significato | Validazione / comportamento |
|---|---|---|
sip_username / username | Username SIP | Obbligatorio; nella modale detail minimo 3 caratteri, massimo 64, lettere/numeri/underscore/trattino. |
sip_realm / registrar | Realm/registrar SIP | Obbligatorio; default caricato da signaling.registrar_host quando disponibile. |
password | Password SIP | In creazione drawer e' obbligatoria per register: almeno 12 caratteri, una maiuscola, una cifra e un simbolo. La password viene inviata a endpoint dedicato dopo la create. |
register_expires_seconds / expires | Scadenza registrazione | Default 3600, minimo 60. |
last_register_at, last_ip | Stato runtime register | Mostrati in lista/detail; health online se ultimo register e' entro 5 minuti. |
Azioni
| Azione | Dove | Effetto |
|---|---|---|
| Create da lista | /devices, bottone New Device | Drawer DeviceForm, POST /api/v1/devices; per register segue POST /api/v1/devices/{id}/sip-password e rollback delete se fallisce. |
| Edit detail | /devices/[id], bottone Edit | Modale DeviceModal, PATCH /api/v1/devices/{id} con shape limitata in edit. |
| Edit da drawer | /devices, editData del drawer | PATCH /api/v1/devices/{id}; se register e password valorizzata, chiama anche endpoint password. |
| Delete | /devices/[id] | DELETE /api/v1/devices/{id} con MFA re-challenge action devices.delete e header X-MFA-Challenge-Token. |
| Set/Rotate password detail | Tab SIP Config su device dynamic | POST /api/v1/devices/{id}/sip-password con MFA re-challenge action devices.sip_password.set. |
| Bulk enable/disable | /devices, toolbar selezione | PATCH /api/v1/devices/{id} con is_active. |
| Bulk NAT on/off | /devices, toolbar selezione | PATCH /api/v1/devices/{id} con nat. |
| Bulk rotate cred | /devices, toolbar selezione | POST /api/v1/devices/{id}/sip-password solo per dynamic con username e realm; static e dynamic senza auth sono saltati. |
API consumate
- List devices, Get device, Create device, Update device, Delete device.
- Set SIP password - rotate credenziali singola o bulk.
- List originators e List terminators - select associazione.
- MFA challenge - usato tramite hook re-challenge per delete e password.
Permessi/ruoli
La UI usa azioni MFA esplicite devices.delete e devices.sip_password.set. I ruoli RBAC completi sono da verificare in backend/RBAC.
Stati & edge case
- Banner regola: IP+port devono essere univoci; se piu' trunk condividono lo stesso IP si usa Virtual Device; e' ammessa dual association Originator + Terminator secondo testo UI.
- Lista calcola
real/virtualclient-side raggruppando perhost:last_ip+port: il primo del gruppo e' real, i successivi virtual. - Filtri server-side:
q,originator_id,terminator_id,is_active. Filtri client-side: kind real/virtual, host type, health, transport, auth. - Transport e' inferito da
outbound_proxy:sips:o;transport=tls-> TLS,;transport=tcp-> TCP, altrimenti UDP. - Health e' client-side: static
unknown, dynamic senza registeroffline, dynamic con register recente online. - Stats detail mostra KPI placeholder a zero; audit log non e' esposto dal backend e usa righe locali solo dopo update/password rotate.
- Bulk rotate dalla lista non mostra re-challenge MFA nel codice, mentre rotate da detail lo mostra: da verificare in UI/backend se l'endpoint rifiuta bulk senza header MFA.
Collegamenti
- Moduli correlati: Originators, Terminators, Routing.
- Task storici emersi in NEEDS_INPUT risolti:
TASK-287-devices-form-static-vs-sip,TASK-400-device-set-sip-password-ha1,TASK-401-kamailio-location-table-migration,TASK-402-kamailio-registrar-digest-auth-config.