drachtio-srf 4.4.60 → 4.4.63

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.
@@ -3,8 +3,6 @@ name: npm-publish
3
3
  # run when a tag is pushed or kick off manually
4
4
  on:
5
5
  push:
6
- branches:
7
- - main
8
6
  tags:
9
7
  - '*'
10
8
  workflow_dispatch:
@@ -17,7 +15,7 @@ jobs:
17
15
  - uses: actions/checkout@v2
18
16
  - uses: actions/setup-node@v1
19
17
  with:
20
- node-version: '12.x'
18
+ node-version: '14.x'
21
19
  registry-url: 'https://registry.npmjs.org'
22
20
  - run: npm install
23
21
  - run: npm publish --access public
package/lib/dialog.js CHANGED
@@ -4,7 +4,7 @@ const only = require('only') ;
4
4
  const methods = require('sip-methods') ;
5
5
  const debug = require('debug')('drachtio:srf') ;
6
6
  const SipError = require('./sip_error');
7
- const { parseUri } = require('drachtio-sip').parser ;
7
+ const { parseUri } = require('./sip-parser/parser');
8
8
  const sdpTransform = require('sdp-transform');
9
9
 
10
10
 
@@ -12,7 +12,7 @@ const sdpTransform = require('sdp-transform');
12
12
  * Class representing a SIP Dialog.
13
13
  *
14
14
  * Note that instances of this class are not created directly by your code;
15
- * rather they are returned from the {@link Srf#createUAC}, {@link Srf#createUAC}, and {@link Srf#createB2BUA}
15
+ * rather they are returned from the {@link Srf#createUAC}, {@link Srf#createUAS}, and {@link Srf#createB2BUA}
16
16
  * @class
17
17
  * @extends EventEmitter
18
18
  */
@@ -34,6 +34,7 @@ class Dialog extends Emitter {
34
34
  this.type = type ;
35
35
  this.req = opts.req ;
36
36
  this.res = opts.res ;
37
+ this.auth = opts.auth;
37
38
  this.agent = this.res.agent ;
38
39
  this.onHold = false ;
39
40
  this.connected = true ;
@@ -171,7 +172,12 @@ class Dialog extends Emitter {
171
172
  * or NOTIFY (in the case of SUBSCRIBE)
172
173
  * @param {Object} [opts] configuration options
173
174
  * @param {Object} [opts.headers] SIP headers to add to the outgoing BYE or NOTIFY
174
- * @param {function} [callback] if provided, callback with signature <code>(err, msg)</code>
175
+ * @param {Object|Function} [opts.auth] sip credentials to use if challenged,
176
+ * or a function invoked with (req, res) and returning (err, username, password) where req is the
177
+ * request that was sent and res is the response that included the digest challenge
178
+ * @param {string} [opts.auth.username] sip username
179
+ * @param {string} [opts.auth.password] sip password
180
+ * @param {function} [callback] if provided, callback with signature <code>(err, msg)</code>
175
181
  * that provides the BYE or NOTIFY message that was sent to terminate the dialog
176
182
  * @return {Promise|Dialog} if no callback is supplied, otherwise a reference to the Dialog
177
183
  */
@@ -183,18 +189,29 @@ class Dialog extends Emitter {
183
189
  }
184
190
  this.queuedRequests = [];
185
191
 
192
+ const removeDialog = (err, res, callback) => {
193
+ this.connected = false ;
194
+ this.srf.removeDialog(this) ;
195
+ callback(err, res) ;
196
+ this.removeAllListeners();
197
+ };
198
+
186
199
  const __x = (callback) => {
187
200
  if (this.dialogType === 'INVITE') {
188
201
  this.agent.request({
189
202
  method: 'BYE',
190
203
  headers: opts.headers || {},
191
204
  stackDialogId: this.id,
205
+ auth: opts.auth || this.auth,
192
206
  _socket: this.socket
193
207
  }, (err, bye) => {
194
- this.connected = false ;
195
- this.srf.removeDialog(this) ;
196
- callback(err, bye) ;
197
- this.removeAllListeners();
208
+ if (err) {
209
+ return removeDialog(err, bye, callback);
210
+ }
211
+
212
+ bye.on('response', () => {
213
+ removeDialog(err, bye, callback);
214
+ });
198
215
  }) ;
199
216
  if (this._emitter) {
200
217
  Object.assign(this._state, {state: 'terminated'});
@@ -212,10 +229,7 @@ class Dialog extends Emitter {
212
229
  stackDialogId: this.id,
213
230
  _socket: this.socket
214
231
  }, (err, notify) => {
215
- this.connected = false ;
216
- this.srf.removeDialog(this) ;
217
- callback(err, notify) ;
218
- this.removeAllListeners();
232
+ removeDialog(err, notify, callback);
219
233
  }) ;
220
234
  }
221
235
  };
@@ -367,6 +381,11 @@ class Dialog extends Emitter {
367
381
  * @param {string} opts.method - SIP method to use for the request
368
382
  * @param {Object} [opts.headers] - SIP headers to apply to the request
369
383
  * @param {string} [opts.body] - body of the SIP request
384
+ * @param {Object|Function} [opts.auth] sip credentials to use if challenged,
385
+ * or a function invoked with (req, res) and returning (err, username, password) where req is the
386
+ * request that was sent and res is the response that included the digest challenge
387
+ * @param {string} [opts.auth.username] sip username
388
+ * @param {string} [opts.auth.password] sip password
370
389
  * @param {function} [callback] - callback invoked with signature <code>(err, req)</code>
371
390
  * when operation has completed
372
391
  * @return {Promise|Dialog} if no callback is supplied a Promise that resolves to the response received,
@@ -383,7 +402,7 @@ class Dialog extends Emitter {
383
402
  method: method,
384
403
  stackDialogId: this.id,
385
404
  headers: opts.headers || {},
386
- auth: opts.auth,
405
+ auth: opts.auth || this.auth,
387
406
  _socket: this.socket,
388
407
  body: opts.body
389
408
  }, (err, req) => {
@@ -2,7 +2,7 @@ const Emitter = require('events');
2
2
  const debug = require('debug')('drachtio:agent');
3
3
  const debugSocket = require('debug')('drachtio:socket');
4
4
  const WireProtocol = require('./wire-protocol') ;
5
- const SipMessage = require('drachtio-sip').SipMessage ;
5
+ const SipMessage = require('./sip-parser/message');
6
6
  const Request = require('./request') ;
7
7
  const Response = require('./response') ;
8
8
  const DigestClient = require('./digest-client') ;
@@ -658,6 +658,10 @@ class DrachtioAgent extends Emitter {
658
658
  this.pendingSipAuthTxnIdUpdate.set(res.req.stackTxnId, {});
659
659
  const client = new DigestClient(res) ;
660
660
  client.authenticate((err, req) => {
661
+ if (!req) {
662
+ sr.req.emit('response', res, ack);
663
+ return;
664
+ }
661
665
  // move all listeners from the old request to the new one we just generated
662
666
  res.req.listeners('response').forEach((l) => { req.on('response', l) ; }) ;
663
667
  res.req.emit('authenticate', req) ;
package/lib/request.js CHANGED
@@ -1,9 +1,9 @@
1
1
  const Emitter = require('events').EventEmitter ;
2
- const sip = require('drachtio-sip') ;
3
2
  const delegate = require('delegates') ;
4
3
  const assert = require('assert') ;
5
4
  const noop = require('node-noop').noop;
6
5
  const debug = require('debug')('drachtio:request');
6
+ const SipMessage = require('./sip-parser/message');
7
7
 
8
8
  class Request extends Emitter {
9
9
 
@@ -11,7 +11,7 @@ class Request extends Emitter {
11
11
  super() ;
12
12
 
13
13
  if (msg) {
14
- assert(msg instanceof sip.SipMessage) ;
14
+ assert(msg instanceof SipMessage) ;
15
15
  this.msg = msg ;
16
16
  this.meta = meta ;
17
17
  }
@@ -148,7 +148,7 @@ class Request extends Emitter {
148
148
  //add a new response to the array
149
149
  const address = meta.address ;
150
150
  const port = +meta.port;
151
- const msg = new sip.SipMessage(rawMsg) ;
151
+ const msg = new SipMessage(rawMsg) ;
152
152
  const obj = {
153
153
  time: meta.time,
154
154
  status: msg.status,
package/lib/response.js CHANGED
@@ -1,17 +1,17 @@
1
1
  const Emitter = require('events').EventEmitter ;
2
- const sip = require('drachtio-sip') ;
3
2
  const delegate = require('delegates') ;
4
3
  const status_codes = require('sip-status') ;
5
4
  const only = require('only') ;
6
5
  const noop = require('node-noop').noop;
7
6
  const assert = require('assert') ;
8
7
  const debug = require('debug')('drachtio:response');
8
+ const SipMessage = require('./sip-parser/message') ;
9
9
  class Response extends Emitter {
10
10
 
11
11
  constructor(agent) {
12
12
  super() ;
13
13
  this._agent = agent ;
14
- this.msg = new sip.SipMessage() ;
14
+ this.msg = new SipMessage() ;
15
15
  this.finished = false ;
16
16
  }
17
17
 
@@ -0,0 +1,103 @@
1
+ const only = require('only') ;
2
+ const parser = require('./parser') ;
3
+
4
+ class SipMessage {
5
+ constructor(msg) {
6
+
7
+ this.headers = {};
8
+
9
+ if (msg) {
10
+ if (typeof msg === 'string') {
11
+ this.raw = msg ;
12
+ const obj = parser.parseSipMessage(msg, true) ;
13
+ if (!obj) throw new Error('failed to parse sip message');
14
+ msg = obj;
15
+ }
16
+ Object.assign(this.headers, msg.headers || {});
17
+ Object.assign(this, only(msg, 'body method version status reason uri payload'));
18
+ }
19
+ }
20
+
21
+ get type() {
22
+ if (this.method) return 'request' ;
23
+ else if (this.status) return 'response' ;
24
+ }
25
+
26
+ get calledNumber() {
27
+ const user = this.uri.match(/sips?:(.*?)@/) ;
28
+ if (user && user.length > 1) {
29
+ return user[1].split(';')[0] ;
30
+ }
31
+ return '' ;
32
+ }
33
+
34
+ get callingNumber() {
35
+ const header = this.has('p-asserted-identity') ? this.get('p-asserted-identity') : this.get('from') ;
36
+ const user = header.match(/sips?:(.*?)@/) ;
37
+ if (user && user.length > 1) {
38
+ return user[1].split(';')[0] ;
39
+ }
40
+ return '' ;
41
+ }
42
+
43
+ get callingName() {
44
+ const header = this.has('p-asserted-identity') ? this.get('p-asserted-identity') : this.get('from') ;
45
+ const user = header.match(/^\"(.+)\"\s*<sips?:.+@/);
46
+ if (user && user.length > 1) {
47
+ return user[1];
48
+ }
49
+ return '';
50
+ }
51
+
52
+ get canFormDialog() {
53
+ return ('INVITE' === this.method || 'SUBSCRIBE' === this.method) && !this.get('to').tag ;
54
+ }
55
+
56
+ set(hdr, value) {
57
+ const hdrs = {} ;
58
+ if (typeof hdr === 'string') hdrs[hdr] = value ;
59
+ else {
60
+ Object.assign(hdrs, hdr);
61
+ }
62
+
63
+ Object.keys(hdrs).forEach((key) => {
64
+ const name = parser.getHeaderName(key) ;
65
+ const newValue = hdrs[key] ;
66
+ let v = '' ;
67
+ if (name in this.headers) {
68
+ v += this.headers[name] ;
69
+ v += ',' ;
70
+ }
71
+ v += newValue ;
72
+ this.headers[name] = v;
73
+ });
74
+
75
+ return this ;
76
+ }
77
+
78
+ get(hdr) {
79
+ if (this.has(hdr)) { return this.headers[parser.getHeaderName(hdr)] ; }
80
+ }
81
+
82
+ has(hdr) {
83
+ const name = parser.getHeaderName(hdr) ;
84
+ return name in this.headers ;
85
+ }
86
+
87
+ getParsedHeader(hdr) {
88
+ const name = parser.getHeaderName(hdr) ;
89
+ const v = this.headers[name] ;
90
+ const fn = parser.getParser(hdr.toLowerCase()) ;
91
+ return fn({s:v, i:0}) ;
92
+ }
93
+
94
+ toString() {
95
+ return parser.stringifySipMessage(this) ;
96
+ }
97
+
98
+ }
99
+
100
+ SipMessage.parseUri = parser.parseUri ;
101
+
102
+
103
+ exports = module.exports = SipMessage ;