didww-v3 6.0.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +40 -0
- data/examples/voice_in_trunks.rb +65 -0
- data/lib/didww/complex_objects/authentication_methods/credentials_and_ip.rb +2 -2
- data/lib/didww/complex_objects/base.rb +35 -2
- data/lib/didww/complex_objects/configurations/sip_configuration.rb +123 -1
- data/lib/didww/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9cdeedbb317141c84de28bbedb4f652b858793e257d8d84f70155b08fc54623c
|
|
4
|
+
data.tar.gz: c48319beb5292ef53595e7905d4ac62ff0e59685bcb57eb48c2f7e6efbb7bd3e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 42be04280b6673a827de5f4bc680f032f28d72437137d081455f2168aa02e92d3861b7fc842e6c70406e6495d1f377745f90a23ead254fdf0a5a6caf40417d63
|
|
7
|
+
data.tar.gz: e6aeccf261500d0307c5cbc7eae427880a853d008ce28639ff2512daa1ea1cb40c54962b3d0f972f7e3ea0a73274bc40a6a8a57b9df45689b9c0ddfb83987acb
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [6.1.0] - 2026-05-04
|
|
8
|
+
### Added
|
|
9
|
+
- Complete the 2026-04-16 `SipConfiguration` attribute set that was missed during the 2026-04-16 rollout (and is not present in the public Postman collection — server form is the source of truth):
|
|
10
|
+
- `enabled_sip_registration` (bool) — enables SIP registration; the API generates `incoming_auth_*` credentials when set true and requires `port` to be blank.
|
|
11
|
+
- `use_did_in_ruri` (bool) — uses DID number in R-URI; requires SIP registration to be enabled.
|
|
12
|
+
- `network_protocol_priority` (string enum) — `force_ipv4` / `force_ipv6` / `any` / `prefer_ipv4` / `prefer_ipv6`. Constants exposed as `NETWORK_PROTOCOL_PRIORITY_*` and `NETWORK_PROTOCOL_PRIORITIES`.
|
|
13
|
+
- `diversion_inject_mode` (string enum) — `none` / `did_number`. Constants exposed as `DIVERSION_INJECT_MODE_*` and `DIVERSION_INJECT_MODES`.
|
|
14
|
+
- `cnam_lookup` (bool) — enables CNAM resolution for inbound calls.
|
|
15
|
+
- `SipConfiguration#incoming_auth_username` and `#incoming_auth_password` — read-only server-generated SIP authentication credentials returned on `voice_in_trunks` when `enabled_sip_registration` is true.
|
|
16
|
+
- `ComplexObject::Base.property` accepts `read_only: true`. Read-only attributes are still parsed from server responses but are stripped from the JSON:API write payload, so round-tripping a loaded configuration through PATCH no longer triggers `400 Param not allowed`.
|
|
17
|
+
- `ComplexObject::Base.property` accepts `sensitive: true`. The default `#inspect` representation redacts those values with `[FILTERED]` so credentials never leak through default logging / REPL / unhandled exception output. Marked as sensitive: `SipConfiguration#auth_password`, `SipConfiguration#incoming_auth_username/password`, and `AuthenticationMethod::CredentialsAndIp#username/password`.
|
|
18
|
+
- `SipConfiguration` auto-cascades dependent fields whose constraints are server-enforced when set via property setters: `enabled_sip_registration = true` clears `host`/`port` (when previously set), `enabled_sip_registration = false` forces `use_did_in_ruri = false`, and assigning a non-blank `host` flips both flags. Constructor / `[]=` assignments bypass the cascade so server responses deserialize as-is.
|
|
19
|
+
|
|
7
20
|
## [6.0.0] - 2026-04-24
|
|
8
21
|
Support for DIDWW API version **2026-04-16**. The gem now sends `X-DIDWW-API-Version: 2026-04-16` with every request by default. Users staying on API `2022-05-10` should pin to the [`2022-05-10`](https://github.com/didww/didww-v3-ruby/tree/2022-05-10) branch (5.x).
|
|
9
22
|
|
data/README.md
CHANGED
|
@@ -205,6 +205,46 @@ trunk = DIDWW::Client.voice_in_trunks.new(
|
|
|
205
205
|
trunk.save
|
|
206
206
|
```
|
|
207
207
|
|
|
208
|
+
#### SIP Registration (2026-04-16)
|
|
209
|
+
|
|
210
|
+
A Voice In Trunk can also be configured to authenticate inbound calls
|
|
211
|
+
via SIP registration credentials generated by DIDWW. The SDK
|
|
212
|
+
auto-cascades the dependent fields the server requires:
|
|
213
|
+
|
|
214
|
+
* setting `enabled_sip_registration = true` clears any previously-set
|
|
215
|
+
`host` / `port` (the server rejects them with 422 otherwise);
|
|
216
|
+
* setting `host` to a non-blank value flips `enabled_sip_registration`
|
|
217
|
+
back to `false` and forces `use_did_in_ruri = false` so the server
|
|
218
|
+
accepts the disable PATCH.
|
|
219
|
+
|
|
220
|
+
DIDWW generates `incoming_auth_username` and `incoming_auth_password`
|
|
221
|
+
and surfaces them in the response when SIP registration is enabled.
|
|
222
|
+
|
|
223
|
+
```ruby
|
|
224
|
+
trunk = DIDWW::Client.voice_in_trunks.new(
|
|
225
|
+
name: 'Office (registered)',
|
|
226
|
+
configuration: DIDWW::ComplexObject::SipConfiguration.new.tap do |c|
|
|
227
|
+
c.enabled_sip_registration = true
|
|
228
|
+
c.use_did_in_ruri = true
|
|
229
|
+
c.cnam_lookup = true
|
|
230
|
+
end
|
|
231
|
+
)
|
|
232
|
+
trunk.save
|
|
233
|
+
# trunk.configuration.incoming_auth_username -- server-generated
|
|
234
|
+
# trunk.configuration.incoming_auth_password -- server-generated
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
To disable SIP registration on an existing trunk, just set `host` —
|
|
238
|
+
the cascade flips `enabled_sip_registration` to `false` and
|
|
239
|
+
`use_did_in_ruri` to `false` automatically:
|
|
240
|
+
|
|
241
|
+
```ruby
|
|
242
|
+
trunk.configuration = DIDWW::ComplexObject::SipConfiguration.new.tap do |c|
|
|
243
|
+
c.host = 'sip.example.com'
|
|
244
|
+
end
|
|
245
|
+
trunk.save
|
|
246
|
+
```
|
|
247
|
+
|
|
208
248
|
### Voice Out Trunks
|
|
209
249
|
|
|
210
250
|
Voice Out Trunks use a polymorphic `authentication_method` (2026-04-16). Three types are supported:
|
data/examples/voice_in_trunks.rb
CHANGED
|
@@ -41,3 +41,68 @@ if !trunks.empty?
|
|
|
41
41
|
puts " Description: #{specific_trunk.description}"
|
|
42
42
|
puts " Created at: #{specific_trunk.created_at}"
|
|
43
43
|
end
|
|
44
|
+
|
|
45
|
+
# 2026-04-16 — surface the API 2026-04-16 SIP-registration-related attributes when
|
|
46
|
+
# the trunk uses a SIP configuration. `incoming_auth_username` /
|
|
47
|
+
# `incoming_auth_password` are server-generated and only present when
|
|
48
|
+
# `enabled_sip_registration` is true.
|
|
49
|
+
sip_trunk = trunks.find { |t| t.configuration.is_a?(DIDWW::ComplexObject::SipConfiguration) }
|
|
50
|
+
if sip_trunk
|
|
51
|
+
puts "\n=== SIP Configuration (2026-04-16 attributes) ==="
|
|
52
|
+
config = sip_trunk.configuration
|
|
53
|
+
puts "Trunk: #{sip_trunk.name}"
|
|
54
|
+
puts " enabled_sip_registration: #{config.enabled_sip_registration.inspect}"
|
|
55
|
+
puts " use_did_in_ruri: #{config.use_did_in_ruri.inspect}"
|
|
56
|
+
puts " network_protocol_priority: #{config.network_protocol_priority.inspect}"
|
|
57
|
+
puts " diversion_relay_policy: #{config.diversion_relay_policy.inspect}"
|
|
58
|
+
puts " diversion_inject_mode: #{config.diversion_inject_mode.inspect}"
|
|
59
|
+
puts " cnam_lookup: #{config.cnam_lookup.inspect}"
|
|
60
|
+
if config.enabled_sip_registration
|
|
61
|
+
puts " incoming_auth_username: #{config.incoming_auth_username.inspect}"
|
|
62
|
+
puts " incoming_auth_password: #{config.incoming_auth_password.inspect}"
|
|
63
|
+
else
|
|
64
|
+
puts ' (incoming_auth credentials only appear when SIP registration is enabled)'
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Example: create a new SIP trunk with SIP registration enabled. The server
|
|
69
|
+
# generates `incoming_auth_username` / `incoming_auth_password` and returns
|
|
70
|
+
# them in the response. They are READ-ONLY — sending them on POST/PATCH
|
|
71
|
+
# returns 400 Param not allowed; the SDK strips them from write payloads.
|
|
72
|
+
#
|
|
73
|
+
# Server-side rules to keep in mind:
|
|
74
|
+
# * When `enabled_sip_registration: true`, `host` and `port` MUST be left
|
|
75
|
+
# blank (the server will register inbound and pick the host itself).
|
|
76
|
+
# * When DISABLING SIP registration on an existing trunk, you must
|
|
77
|
+
# simultaneously set `host` to a non-blank value and `use_did_in_ruri`
|
|
78
|
+
# to `false` in the same PATCH — otherwise the server returns 422.
|
|
79
|
+
#
|
|
80
|
+
# Uncomment to actually create a trunk in your sandbox account:
|
|
81
|
+
#
|
|
82
|
+
# new_trunk = DIDWW::Resource::VoiceInTrunk.new(
|
|
83
|
+
# name: "SIP-registration trunk #{Time.now.to_i}",
|
|
84
|
+
# priority: 1,
|
|
85
|
+
# weight: 100,
|
|
86
|
+
# cli_format: 'e164',
|
|
87
|
+
# ringing_timeout: 30,
|
|
88
|
+
# configuration: DIDWW::ComplexObject::SipConfiguration.new(
|
|
89
|
+
# # NOTE: do NOT set `host` here — the server requires it to be blank
|
|
90
|
+
# # when enabled_sip_registration is true.
|
|
91
|
+
# enabled_sip_registration: true,
|
|
92
|
+
# use_did_in_ruri: true,
|
|
93
|
+
# cnam_lookup: false,
|
|
94
|
+
# diversion_relay_policy: 'as_is',
|
|
95
|
+
# diversion_inject_mode: 'did_number',
|
|
96
|
+
# network_protocol_priority: 'prefer_ipv4',
|
|
97
|
+
# codec_ids: [9, 7],
|
|
98
|
+
# transport_protocol_id: 1
|
|
99
|
+
# )
|
|
100
|
+
# )
|
|
101
|
+
# created = new_trunk.save
|
|
102
|
+
# if created
|
|
103
|
+
# puts "Created trunk #{new_trunk.id}"
|
|
104
|
+
# puts " incoming_auth_username: #{new_trunk.configuration.incoming_auth_username}"
|
|
105
|
+
# puts " incoming_auth_password: #{new_trunk.configuration.incoming_auth_password}"
|
|
106
|
+
# else
|
|
107
|
+
# puts "Errors: #{new_trunk.errors.full_messages}"
|
|
108
|
+
# end
|
|
@@ -12,8 +12,8 @@ module DIDWW
|
|
|
12
12
|
# only in responses; they cannot be set from the client on create.
|
|
13
13
|
property :allowed_sip_ips, type: :strings
|
|
14
14
|
property :tech_prefix, type: :string
|
|
15
|
-
property :username, type: :string
|
|
16
|
-
property :password, type: :string
|
|
15
|
+
property :username, type: :string, sensitive: true
|
|
16
|
+
property :password, type: :string, sensitive: true
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
end
|
|
@@ -13,6 +13,8 @@ module DIDWW
|
|
|
13
13
|
|
|
14
14
|
def property(name, options = {})
|
|
15
15
|
schema.add(name, options)
|
|
16
|
+
read_only_attributes << name.to_s if options[:read_only]
|
|
17
|
+
sensitive_attributes << name.to_s if options[:sensitive]
|
|
16
18
|
define_method(name.to_sym) { self[name] }
|
|
17
19
|
define_method("#{name}=".to_sym) { |val| self[name] = val }
|
|
18
20
|
end
|
|
@@ -21,6 +23,22 @@ module DIDWW
|
|
|
21
23
|
@schema ||= JsonApiClient::Schema.new
|
|
22
24
|
end
|
|
23
25
|
|
|
26
|
+
# Names of attributes that the server returns but does not accept on
|
|
27
|
+
# write. Excluded from `as_json` so that round-tripping a resource
|
|
28
|
+
# through PATCH does not echo them back and trigger 400 Param not
|
|
29
|
+
# allowed.
|
|
30
|
+
def read_only_attributes
|
|
31
|
+
@read_only_attributes ||= []
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Names of attributes whose values are credentials/secrets. The wire
|
|
35
|
+
# format is unchanged — `as_json` still emits the real values — but
|
|
36
|
+
# `#inspect` redacts them so default logging / error reports / REPL
|
|
37
|
+
# echoes never leak credentials downstream.
|
|
38
|
+
def sensitive_attributes
|
|
39
|
+
@sensitive_attributes ||= []
|
|
40
|
+
end
|
|
41
|
+
|
|
24
42
|
# Type casting for JsonApiClient parser/setters
|
|
25
43
|
def cast(value, default)
|
|
26
44
|
case value
|
|
@@ -77,14 +95,29 @@ module DIDWW
|
|
|
77
95
|
end
|
|
78
96
|
|
|
79
97
|
# When we represent this resource for serialization (create/update), we do so
|
|
80
|
-
# with this implementation
|
|
98
|
+
# with this implementation. Read-only attributes are excluded — the server
|
|
99
|
+
# rejects them with 400 Param not allowed.
|
|
81
100
|
def as_json(*)
|
|
101
|
+
excluded = self.class.read_only_attributes
|
|
82
102
|
{ type: type }.with_indifferent_access.tap do |h|
|
|
83
|
-
h[:attributes] = attributes.as_json
|
|
103
|
+
h[:attributes] = attributes.as_json.reject { |k, _| excluded.include?(k.to_s) }
|
|
84
104
|
end
|
|
85
105
|
end
|
|
86
106
|
|
|
87
107
|
def as_json_api(*); as_json end
|
|
108
|
+
|
|
109
|
+
# Redacts sensitive attribute values so credentials never leak into
|
|
110
|
+
# default logs / REPL output / error reports. The on-the-wire payload
|
|
111
|
+
# is unaffected (see `#as_json`).
|
|
112
|
+
FILTERED = '[FILTERED]'.freeze
|
|
113
|
+
def inspect
|
|
114
|
+
sensitive = self.class.sensitive_attributes
|
|
115
|
+
formatted = attributes.map do |k, v|
|
|
116
|
+
display = sensitive.include?(k.to_s) && !v.nil? ? FILTERED : v
|
|
117
|
+
"#{k}=#{display.inspect}"
|
|
118
|
+
end
|
|
119
|
+
"#<#{self.class.name} #{formatted.join(' ')}>"
|
|
120
|
+
end
|
|
88
121
|
end
|
|
89
122
|
end
|
|
90
123
|
end
|
|
@@ -18,7 +18,7 @@ module DIDWW
|
|
|
18
18
|
# Nullable: No
|
|
19
19
|
# Description: Optional authorization user for the SIP server
|
|
20
20
|
|
|
21
|
-
property :auth_password, type: :string
|
|
21
|
+
property :auth_password, type: :string, sensitive: true
|
|
22
22
|
# Type: String
|
|
23
23
|
# Nullable: No
|
|
24
24
|
# Description: Optional authorization password for the SIP server
|
|
@@ -180,6 +180,54 @@ module DIDWW
|
|
|
180
180
|
# See DIVERSION_RELAY_POLICIES for available values.
|
|
181
181
|
# In API v3.4 this attribute was named `diversion_relay_mode`.
|
|
182
182
|
|
|
183
|
+
property :diversion_inject_mode, type: :string
|
|
184
|
+
# Type: String
|
|
185
|
+
# Nullable: No
|
|
186
|
+
# Description: Diversion header injection mode. See
|
|
187
|
+
# DIVERSION_INJECT_MODES for available values. (API 2026-04-16)
|
|
188
|
+
|
|
189
|
+
property :network_protocol_priority, type: :string
|
|
190
|
+
# Type: String
|
|
191
|
+
# Nullable: No
|
|
192
|
+
# Description: SIP network protocol priority. See
|
|
193
|
+
# NETWORK_PROTOCOL_PRIORITIES for available values. (API 2026-04-16)
|
|
194
|
+
|
|
195
|
+
property :enabled_sip_registration, type: :boolean
|
|
196
|
+
# Type: Boolean
|
|
197
|
+
# Nullable: No
|
|
198
|
+
# Description: Enables SIP registration. When true the API generates
|
|
199
|
+
# `incoming_auth_username` / `incoming_auth_password`; the trunk's
|
|
200
|
+
# `host` and `port` must be left blank. When disabling sip
|
|
201
|
+
# registration on an existing trunk, the same PATCH must also set
|
|
202
|
+
# `host` to a non-blank value and `use_did_in_ruri` to false, or
|
|
203
|
+
# the server returns 422. (API 2026-04-16)
|
|
204
|
+
|
|
205
|
+
property :use_did_in_ruri, type: :boolean
|
|
206
|
+
# Type: Boolean
|
|
207
|
+
# Nullable: No
|
|
208
|
+
# Description: When true, the trunk's R-URI uses the DID number.
|
|
209
|
+
# Requires `enabled_sip_registration` to be true. (API 2026-04-16)
|
|
210
|
+
|
|
211
|
+
property :cnam_lookup, type: :boolean
|
|
212
|
+
# Type: Boolean
|
|
213
|
+
# Nullable: No
|
|
214
|
+
# Description: Enables CNAM resolution for inbound calls on this
|
|
215
|
+
# trunk. (API 2026-04-16)
|
|
216
|
+
|
|
217
|
+
property :incoming_auth_username, type: :string, read_only: true, sensitive: true
|
|
218
|
+
# Type: String
|
|
219
|
+
# Nullable: Yes
|
|
220
|
+
# Description: Server-generated SIP authentication username, returned in
|
|
221
|
+
# responses when `enabled_sip_registration` is true. Read-only; the API
|
|
222
|
+
# rejects any write attempt with 400 Param not allowed. (API 2026-04-16)
|
|
223
|
+
|
|
224
|
+
property :incoming_auth_password, type: :string, read_only: true, sensitive: true
|
|
225
|
+
# Type: String
|
|
226
|
+
# Nullable: Yes
|
|
227
|
+
# Description: Server-generated SIP authentication password, returned in
|
|
228
|
+
# responses when `enabled_sip_registration` is true. Read-only; the API
|
|
229
|
+
# rejects any write attempt with 400 Param not allowed. (API 2026-04-16)
|
|
230
|
+
|
|
183
231
|
DIVERSION_RELAY_POLICY_NONE = 'none'
|
|
184
232
|
DIVERSION_RELAY_POLICY_AS_IS = 'as_is'
|
|
185
233
|
DIVERSION_RELAY_POLICY_SIP = 'sip'
|
|
@@ -192,6 +240,28 @@ module DIDWW
|
|
|
192
240
|
DIVERSION_RELAY_POLICY_TEL
|
|
193
241
|
].freeze
|
|
194
242
|
|
|
243
|
+
DIVERSION_INJECT_MODE_NONE = 'none'
|
|
244
|
+
DIVERSION_INJECT_MODE_DID_NUMBER = 'did_number'
|
|
245
|
+
|
|
246
|
+
DIVERSION_INJECT_MODES = [
|
|
247
|
+
DIVERSION_INJECT_MODE_NONE,
|
|
248
|
+
DIVERSION_INJECT_MODE_DID_NUMBER
|
|
249
|
+
].freeze
|
|
250
|
+
|
|
251
|
+
NETWORK_PROTOCOL_PRIORITY_FORCE_IPV4 = 'force_ipv4'
|
|
252
|
+
NETWORK_PROTOCOL_PRIORITY_FORCE_IPV6 = 'force_ipv6'
|
|
253
|
+
NETWORK_PROTOCOL_PRIORITY_ANY = 'any'
|
|
254
|
+
NETWORK_PROTOCOL_PRIORITY_PREFER_IPV4 = 'prefer_ipv4'
|
|
255
|
+
NETWORK_PROTOCOL_PRIORITY_PREFER_IPV6 = 'prefer_ipv6'
|
|
256
|
+
|
|
257
|
+
NETWORK_PROTOCOL_PRIORITIES = [
|
|
258
|
+
NETWORK_PROTOCOL_PRIORITY_FORCE_IPV4,
|
|
259
|
+
NETWORK_PROTOCOL_PRIORITY_FORCE_IPV6,
|
|
260
|
+
NETWORK_PROTOCOL_PRIORITY_ANY,
|
|
261
|
+
NETWORK_PROTOCOL_PRIORITY_PREFER_IPV4,
|
|
262
|
+
NETWORK_PROTOCOL_PRIORITY_PREFER_IPV6
|
|
263
|
+
].freeze
|
|
264
|
+
|
|
195
265
|
MEDIA_ENCRYPTION_MODES = [
|
|
196
266
|
'disabled',
|
|
197
267
|
'srtp_sdes',
|
|
@@ -257,6 +327,58 @@ module DIDWW
|
|
|
257
327
|
def transport_protocol
|
|
258
328
|
TRANSPORT_PROTOCOLS[transport_protocol_id]
|
|
259
329
|
end
|
|
330
|
+
|
|
331
|
+
# Auto-cascade for server-enforced field dependencies (2026-04-16).
|
|
332
|
+
#
|
|
333
|
+
# The server validates these combinations and rejects mismatches with
|
|
334
|
+
# 422; the SDK fixes them up at assignment time so user code never has
|
|
335
|
+
# to track the full server-side rule set. Future server-required
|
|
336
|
+
# cascades are added here without the caller needing to know.
|
|
337
|
+
#
|
|
338
|
+
# Rules:
|
|
339
|
+
# * `enabled_sip_registration = true` => host = nil, port = nil
|
|
340
|
+
# (server requires both blank when registration is enabled)
|
|
341
|
+
# * `enabled_sip_registration = false` => use_did_in_ruri = false
|
|
342
|
+
# (server requires use_did_in_ruri disabled when sip_registration is)
|
|
343
|
+
# * `host = <non-nil>` => enabled_sip_registration = false,
|
|
344
|
+
# use_did_in_ruri = false (host requires sip_registration disabled,
|
|
345
|
+
# which in turn requires use_did_in_ruri disabled)
|
|
346
|
+
#
|
|
347
|
+
# Constructor-time `[]=` assignments bypass these setters intentionally
|
|
348
|
+
# so that responses returned from the server (e.g. a fixture with
|
|
349
|
+
# `enabled_sip_registration: true` AND `host: nil`) deserialize as-is.
|
|
350
|
+
def enabled_sip_registration=(val)
|
|
351
|
+
case val
|
|
352
|
+
when true
|
|
353
|
+
# Clear host/port only if they were already set — never emit a
|
|
354
|
+
# spurious `host: null` on a fresh config, which would otherwise
|
|
355
|
+
# widen every PATCH/POST body. If the trunk had a host, we have
|
|
356
|
+
# to send `host: null` explicitly so the server clears it.
|
|
357
|
+
self[:host] = nil if attributes.key?('host') && !self[:host].nil?
|
|
358
|
+
self[:port] = nil if attributes.key?('port') && !self[:port].nil?
|
|
359
|
+
when false
|
|
360
|
+
# Server requires use_did_in_ruri = false whenever sip_registration
|
|
361
|
+
# is disabled. Always emit it on the wire so the server's check
|
|
362
|
+
# passes regardless of the prior state of the field.
|
|
363
|
+
self[:use_did_in_ruri] = false
|
|
364
|
+
else
|
|
365
|
+
# `nil` (or any non-bool) — caller is unsetting the field. No
|
|
366
|
+
# cascade: dependent fields stay as the caller left them.
|
|
367
|
+
end
|
|
368
|
+
self[:enabled_sip_registration] = val
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def host=(val)
|
|
372
|
+
unless val.nil?
|
|
373
|
+
# Setting host implies sip_registration is disabled (server-side
|
|
374
|
+
# validation), which in turn implies use_did_in_ruri = false.
|
|
375
|
+
# Always emit both on the wire so the server's checks pass
|
|
376
|
+
# without the caller having to know the rule set.
|
|
377
|
+
self[:enabled_sip_registration] = false
|
|
378
|
+
self[:use_did_in_ruri] = false
|
|
379
|
+
end
|
|
380
|
+
self[:host] = val
|
|
381
|
+
end
|
|
260
382
|
end
|
|
261
383
|
end
|
|
262
384
|
end
|
data/lib/didww/version.rb
CHANGED