# HG changeset patch # User Emmanuel Gil Peyrot # Date 1327612311 -3600 # Node ID 6a6bb8ded046ad0483ac6458dc1441a5f61b127a # Parent b7d52bf259e0130e51eaa37f8b2754255321064d Add a JID object, and use it in Lightstring.Connection. diff --git a/jid.js b/jid.js new file mode 100644 --- /dev/null +++ b/jid.js @@ -0,0 +1,105 @@ +'use strict'; + +/** + Copyright (c) 2012, Emmanuel Gil Peyrot + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + + +/** + * @constructor Creates a new JID object. + * @param {String} [aJID] The host, bare or full JID. + * @memberOf Lightstring + */ +Lightstring.JID = function(aJID) { + this.node = null; + this.domain = null; + this.resource = null; + + if (aJID) + this.full = aJID; + + //TODO: use a stringprep library to validate the input. +}; + +Lightstring.JID.prototype = { + toString: function() { + return this.full; + }, + + get bare() { + if (!this.domain) + return null; + + if (this.node) + return this.node + '@' + this.domain; + + return this.domain; + }, + + set bare(aJID) { + if (!aJID) + return; + + var s = aJID.indexOf('/'); + if (s != -1) + aJID = aJID.substring(0, s); + + s = aJID.indexOf('@'); + if (s == -1) { + this.node = null; + this.domain = aJID; + } else { + this.node = aJID.substring(0, s); + this.domain = aJID.substring(s+1); + } + }, + + get full() { + if (!this.domain) + return null; + + var full = this.domain; + + if (this.node) + full = this.node + '@' + full; + + if (this.resource) + full = full + '/' + this.resource; + + return full; + }, + + set full(aJID) { + if (!aJID) + return; + + var s = aJID.indexOf('/'); + if (s == -1) + this.resource = null; + else { + this.resource = aJID.substring(s+1); + aJID = aJID.substring(0, s); + } + + s = aJID.indexOf('@'); + if (s == -1) { + this.node = null; + this.domain = aJID; + } else { + this.node = aJID.substring(0, s); + this.domain = aJID.substring(s+1); + } + } +}; diff --git a/lightstring.js b/lightstring.js --- a/lightstring.js +++ b/lightstring.js @@ -138,7 +138,7 @@ Lightstring.Connection = function(aServi }); this.on('success', function(stanza, that) { that.send( - "" @@ -185,16 +185,16 @@ Lightstring.Connection = function(aServi } } - var digest_uri = 'xmpp/' + that.host; + var digest_uri = 'xmpp/' + that.jid.domain; if (host !== null) digest_uri = digest_uri + '/' + host; - var A1 = MD5.hash(that.node + + var A1 = MD5.hash(that.jid.node + ':' + realm + ':' + that.password) + - ':' + nonce + ':' + cnonce; + ':' + nonce + ':' + cnonce; var A2 = 'AUTHENTICATE:' + digest_uri; var responseText = ''; - responseText += 'username=' + _quote(that.node) + ','; + responseText += 'username=' + _quote(that.jid.node) + ','; responseText += 'realm=' + _quote(realm) + ','; responseText += 'nonce=' + _quote(nonce) + ','; responseText += 'cnonce=' + _quote(cnonce) + ','; @@ -221,17 +221,11 @@ Lightstring.Connection.prototype = { */ connect: function(aJid, aPassword) { this.emit('connecting'); - if (aJid) - this.jid = aJid; - if (this.jid) { - this.host = this.jid.split('@')[1]; - this.node = this.jid.split('@')[0]; - this.resource = this.jid.split('/')[1]; - } + this.jid = new Lightstring.JID(aJid); if (aPassword) this.password = aPassword; - if (!this.jid) + if (!this.jid.bare) throw 'Lightstring: Connection.jid is undefined.'; if (!this.password) throw 'Lightstring: Connection.password is undefined.'; @@ -251,7 +245,7 @@ Lightstring.Connection.prototype = { if (this.protocol !== 'xmpp') console.error('Lightstring: The server located at '+ that.service + ' doesn\'t seems to be XMPP aware.'); - var stream = Lightstring.stanza.stream.open(that.host); + var stream = Lightstring.stanza.stream.open(that.jid.domain); that.socket.send(stream); that.emit('XMLOutput', stream); @@ -270,7 +264,7 @@ Lightstring.Connection.prototype = { that.emit(elm.tagName, elm); if (elm.tagName === 'iq') - that.emit(elm.getAttribute('id'), elm); + that.emit(elm.getAttribute('id'), elm); //FIXME: possible attack vector. }); }, /**