示例#1
0
function buildReply({stanza}) {
  return xml('iq', {
    to: stanza.attrs.from,
    from: stanza.attrs.to,
    id: stanza.attrs.id,
  })
}
示例#2
0
        const handler = element => {
          if (element.attrs.xmlns !== NS) {
            return
          }

          if (element.name === 'challenge') {
            mech.challenge(decode(element.text()))
            const resp = mech.response(creds)
            this.entity.send(
              xml(
                'response',
                {xmlns: NS, mechanism: mech.name},
                typeof resp === 'string' ? encode(resp) : ''
              )
            )
            return
          }

          if (element.name === 'failure') {
            reject(
              new SASLError(
                element.children[0].name,
                element.getChildText('text') || '',
                element
              )
            )
          } else if (element.name === 'success') {
            resolve()
            this.entity._status('authenticated')
          }

          this.entity.removeListener('nonza', handler)
        }
示例#3
0
async function bind(entity, iqCaller, resource) {
  const result = await iqCaller.request(
    xml('iq', {type: 'set'}, makeBindElement(resource))
  )
  const jid = result.getChild('bind', NS).getChildText('jid')
  entity._jid(jid)
  return jid
}
示例#4
0
  // https://xmpp.org/extensions/xep-0114.html#example-3
  async authenticate(id, password) {
    const hash = crypto.createHash('sha1')
    hash.update(id + password, 'binary')
    const el = await this.sendReceive(xml('handshake', {}, hash.digest('hex')))
    if (el.name !== 'handshake') {
      throw new Error('Unexpected server response')
    }

    this._jid(this.options.domain)
    this._status('online', this.jid)
  }
示例#5
0
test.cb('resolves', t => {
  t.plan(2)
  const conn = new Connection()
  conn.parser = new EventEmitter()
  conn.footerElement = () => {
    return xml('hello')
  }
  conn.socket = new EventEmitter()
  conn.socket.write = (data, cb) => {
    return cb()
  }
  conn.on('output', el => {
    t.is(el, '<hello/>')
  })
  conn.close().then(el => {
    t.is(el.toString(), `<goodbye/>`)
    t.end()
  })
  conn.parser.emit('end', xml('goodbye'))
})
示例#6
0
module.exports = function (p) {
  const entity = client()
  entity.socket = {
    write(data, cb) {
      cb()
    },
  }
  const plugin = entity.plugin(p)

  return {
    entity,
    plugin,
    fake(...args) {
      const el = xml(...args)
      const p = entity.promise('send')
      entity.emit('element', el)
      return p.then(el => {
        delete el.attrs.xmlns
        return el
      })
    },
  }
}
示例#7
0
 conn.footerElement = () => {
   return xml('hello')
 }
示例#8
0
function makeBindElement(resource) {
  return xml('bind', {xmlns: NS}, resource && xml('resource', {}, resource))
}
示例#9
0
module.exports = function context(entity = client()) {
  debug(entity)

  entity.socket = mockSocket()
  entity.jid = new JID('foo@bar/test')

  const ctx = {
    entity,
    sanitize(s) {
      const stanza = s.clone()
      const {id} = stanza.attrs
      delete stanza.attrs.id
      delete stanza.attrs.xmlns
      return {stanza, id}
    },
    catch() {
      return promise(entity, 'send').then(s => this.sanitize(s))
    },
    catchOutgoing(match = () => true) {
      return new Promise(resolve => {
        function onSend(stanza) {
          if (match(stanza)) {
            entity.removeListener('send', onSend)
            resolve(stanza)
          }
        }

        entity.on('send', onSend)
      })
    },
    catchOutgoingIq(match = () => true) {
      return this.catchOutgoing(stanza => stanza.is('iq') && match(stanza))
    },
    async catchOutgoingGet(match = () => true) {
      const stanza = await this.catchOutgoingIq(
        stanza => stanza.attrs.type === 'get' && match(stanza)
      )
      const [child] = stanza.children
      if (child) {
        child.parent = null
      }

      return child
    },
    async catchOutgoingSet(match = () => true) {
      const stanza = await this.catchOutgoingIq(
        stanza => stanza.attrs.type === 'set' && match(stanza)
      )
      const [child] = stanza.children
      if (child) {
        child.parent = null
      }

      return child
    },
    scheduleIncomingResult(child) {
      return promise(entity, 'send').then(stanza => {
        const {id} = stanza.attrs
        return this.fakeIncomingResult(child, id)
      })
    },
    scheduleIncomingError(child) {
      return promise(entity, 'send').then(stanza => {
        const {id} = stanza.attrs
        return this.fakeIncomingError(child, id)
      })
    },
    fakeIncomingGet(child, attrs = {}) {
      attrs.type = 'get'
      return this.fakeIncomingIq(xml('iq', attrs, child)).then(stanza => {
        const [child] = stanza.children
        if (child) {
          child.parent = null
        }

        return child
      })
    },
    fakeIncomingSet(child, attrs = {}) {
      attrs.type = 'set'
      return this.fakeIncomingIq(xml('iq', attrs, child)).then(stanza => {
        const [child] = stanza.children
        if (child) {
          child.parent = null
        }

        return child
      })
    },
    fakeIncomingResult(child, id) {
      return this.fakeIncomingIq(xml('iq', {type: 'result', id}, child)).then(
        stanza => {
          const [child] = stanza.children
          if (child) {
            child.parent = null
          }

          return child
        }
      )
    },
    fakeIncomingError(child, id) {
      return this.fakeIncomingIq(xml('iq', {type: 'error', id}, child))
        .then()
        .then(stanza => {
          const [child] = stanza.children
          if (child) {
            child.parent = null
          }

          return child
        })
    },
    fakeIncomingIq(el) {
      const stanza = el.clone()
      if (stanza.is('iq') && !stanza.attrs.id) {
        stanza.attrs.id = 'fake'
      }

      return this.fakeIncoming(stanza)
    },
    async fakeIncoming(el) {
      const p = promise(entity, 'send')
      const stanza = el.clone()
      delete stanza.attrs.xmlns
      await Promise.resolve()
      this.mockInput(el)
      await p
      return this.sanitize(el).stanza
    },
    fakeOutgoing(el) {
      entity.hookOutgoing(el)
    },
    mockInput(el) {
      entity.emit('input', el.toString())
      entity._onElement(el)
    },
  }

  return ctx
}
示例#10
0
function buildError(type, condition) {
  return xml('error', {type}, xml(condition, NS_STANZA))
}
示例#11
0
test('isNonza()', t => {
  const conn = new Connection()
  conn.NS = 'bar'

  t.is(conn.isNonza(xml('foo')), true)
  t.is(conn.isNonza(xml('foo', {xmlns: 'bar'})), true)

  t.is(conn.isNonza(xml('presence', {xmlns: 'foo'})), true)
  t.is(conn.isNonza(xml('iq', {xmlns: 'foo'})), true)
  t.is(conn.isNonza(xml('message', {xmlns: 'foo'})), true)

  t.is(conn.isNonza(xml('presence')), false)
  t.is(conn.isNonza(xml('iq')), false)
  t.is(conn.isNonza(xml('message')), false)

  t.is(conn.isNonza(xml('presence', {xmlns: 'bar'})), false)
  t.is(conn.isNonza(xml('iq', {xmlns: 'bar'})), false)
  t.is(conn.isNonza(xml('message', {xmlns: 'bar'})), false)

  // Conn.online = false
  //
  // t.is(conn.isNonza(xml`<presence/>`), true)
  // t.is(conn.isNonza(xml`<iq/>`), true)
  // t.is(conn.isNonza(xml`<message/>`), true)
  // t.is(conn.isNonza(xml`<presence xmlns='bar'/>`), true)
  // t.is(conn.isNonza(xml`<iq xmlns='bar'/>`), true)
  // t.is(conn.isNonza(xml`<message xmlns='bar'/>`), true)
})