Skip to content
This repository

Added support for Google Talk & OAuth2 #85

Merged
merged 9 commits into from over 1 year ago

4 participants

Ian Langworth ☠ Astro Renato Gama Daniel Anderson Tiecher
Ian Langworth ☠

Attached are modifications and an example script which will allow you to use node-xmpp with Google Talk using OAuth2.

To test:

  1. Go to the Google OAuth 2.0 Playground
  2. Input https://www.googleapis.com/auth/googletalk into the "Input your own scopes" field on the left and click "Authorize APIs"
  3. Click "Allow access" on the authorization page
  4. Click "Exchange authorization code for tokens"
  5. Copy the access_token value from the response
  6. Run the echo_bot_oauth.js example:

    node examples/echo_bot_oauth.js 'your.name@gmail.com' 'ya29.AHESXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'

Astro
Owner

Great job.

How much in a hurry are you? I'm on holiday til end of this month.

Ian Langworth ☠

Thanks! End of the month would be great.

Renato Gama

Ohh! Great! I need this! :)

Daniel Anderson Tiecher

@statico thanks for adding this feature to node-xmpp! Can definitely put it to some good use.

@astro so how are things going with this PR? Will you be able to review and merge it? Looking forward to use this feature. :)

Astro astro referenced this pull request from a commit October 09, 2012
Astro Merge branch 'oauth'
Github pull request #85
712c531
Astro astro merged commit 08da061 into from October 08, 2012
Astro astro closed this October 08, 2012
Astro
Owner

Thanks @statico

Sorry for the delay.

Renato Gama

When is this feature going to be available via NPM? Thank you!

Astro
Owner

In general there's a lot of cleaning up and testing to be done before the next major node-xmpp release.

Eelco eelcocramer referenced this pull request November 20, 2012
Merged

Various bug fixes #86

Ehtesh Choudhury shurane referenced this pull request in simple-xmpp/node-simple-xmpp November 15, 2013
Open

stream error #37

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
39  examples/echo_bot_oauth.js
... ...
@@ -0,0 +1,39 @@
  1
+/**
  2
+ * Echo Bot - the XMPP Hello World
  3
+ **/
  4
+var xmpp = require('../lib/node-xmpp');
  5
+var argv = process.argv;
  6
+
  7
+if (argv.length != 4) {
  8
+    console.error('Usage: node echo_bot_oauth.js <my-jid> <oauth-token>');
  9
+    process.exit(1);
  10
+}
  11
+
  12
+var cl = new xmpp.Client({ jid: argv[2],
  13
+			   host: 'talk.google.com',
  14
+			   oauth2_token: argv[3],
  15
+			   oauth2_auth: 'http://www.google.com/talk/protocol/auth' });
  16
+cl.on('online',
  17
+      function() {
  18
+	  cl.send(new xmpp.Element('presence', { }).
  19
+		  c('show').t('chat').up().
  20
+		  c('status').t('Happily echoing your <message/> stanzas')
  21
+		 );
  22
+      });
  23
+cl.on('stanza',
  24
+      function(stanza) {
  25
+	  if (stanza.is('message') &&
  26
+	      // Important: never reply to errors!
  27
+	      stanza.attrs.type !== 'error') {
  28
+
  29
+	      // Swap addresses...
  30
+	      stanza.attrs.to = stanza.attrs.from;
  31
+	      delete stanza.attrs.from;
  32
+	      // and send back.
  33
+	      cl.send(stanza);
  34
+	  }
  35
+      });
  36
+cl.on('error',
  37
+      function(e) {
  38
+	  console.error(e);
  39
+      });
20  lib/xmpp/client.js
@@ -35,7 +35,7 @@ var IQID_SESSION = 'sess',
35 35
  *   legacySSL: Boolean (optional) - connect to the legacy SSL port, requires at least the host to be specified
36 36
  *   credentials: Dictionary (optional) - TLS or SSL key and certificate credentials
37 37
  *
38  
- * Example:
  38
+ * Examples:
39 39
  *   var cl = new xmpp.Client({
40 40
  *       jid: "me@example.com",
41 41
  *       password: "secret"
@@ -44,7 +44,13 @@ var IQID_SESSION = 'sess',
44 44
  *       jid: '-' + fbUID + '@chat.facebook.com',
45 45
  *       api_key: '54321', // api key of your facebook app
46 46
  *       access_token: 'abcdefg', // user access token
47  
- *       host: 'chat.facebook.com',
  47
+ *       host: 'chat.facebook.com'
  48
+ *   });
  49
+ *   var gtalk = new xmpp.Client({
  50
+ *       jid: 'me@gmail.com',
  51
+ *       oauth2_token: 'xxxx.xxxxxxxxxxx', // from OAuth2
  52
+ *       oauth2_auth: 'http://www.google.com/talk/protocol/auth',
  53
+ *       host: 'talk.google.com'
48 54
  *   });
49 55
  *
50 56
  * Example SASL EXTERNAL:
@@ -174,13 +180,17 @@ Client.prototype.useFeatures = function() {
174 180
             this.mech.password = this.password;
175 181
             this.mech.api_key = this.api_key;
176 182
             this.mech.access_token = this.access_token;
  183
+            this.mech.oauth2_token = this.oauth2_token;
  184
+            this.mech.oauth2_auth = this.oauth2_auth;
177 185
             this.mech.realm = this.jid.domain;  // anything?
178 186
             this.mech.digest_uri = "xmpp/" + this.jid.domain;
179 187
             var authMsg = encode64(this.mech.auth());
  188
+            var attribs = this.mech.attribs();
  189
+            attribs.xmlns = NS_XMPP_SASL;
  190
+            attribs.mechanism = this.mech.name;
180 191
             this.send(new ltx.Element('auth',
181  
-                                      { xmlns: NS_XMPP_SASL,
182  
-                                        mechanism: this.mech.name
183  
-                                      }).t(authMsg));
  192
+            			      attribs
  193
+                                      ).t(authMsg));
184 194
         } else {
185 195
             this.emit('error', 'No usable SASL mechanism');
186 196
         }
27  lib/xmpp/sasl.js
@@ -8,7 +8,7 @@ var EventEmitter = require('events').EventEmitter;
8 8
  * @param {Array} mechs Server-offered SASL mechanism names
9 9
  */
10 10
 function selectMechanism(offeredMechs, preferredMech, availableMech) {
11  
-    var mechClasses = [XFacebookPlatform, DigestMD5,
  11
+    var mechClasses = [XOAuth2, XFacebookPlatform, DigestMD5,
12 12
 		       Plain, Anonymous];
13 13
     var byName = {};
14 14
     var mech;
@@ -47,7 +47,12 @@ function availableMechanisms(availableMech) {
47 47
 exports.availableMechanisms = availableMechanisms;
48 48
 
49 49
 // Mechanisms
50  
-var Mechanism = EventEmitter;
  50
+function Mechanism() {
  51
+}
  52
+util.inherits(Mechanism, EventEmitter);
  53
+Mechanism.attribs = function() {
  54
+    return {};
  55
+};
51 56
 
52 57
 function Plain() {
53 58
 }
@@ -64,6 +69,24 @@ Plain.prototype.authServer = function(auth, client) {
64 69
     client.authenticate(this.username, params[2]);
65 70
 };
66 71
 
  72
+function XOAuth2() {
  73
+}
  74
+util.inherits(XOAuth2, Mechanism);
  75
+XOAuth2.prototype.name = "X-OAUTH2";
  76
+XOAuth2.prototype.auth = function() {
  77
+    return "\0" + this.authzid + "\0" + this.oauth2_token;
  78
+};
  79
+XOAuth2.prototype.authServer = function(auth, client) {
  80
+    var params = auth.split("\x00");
  81
+    this.username = params[1];
  82
+    client.authenticate(this.username, params[2]);
  83
+};
  84
+XOAuth2.prototype.attribs = function() {
  85
+    return { "auth:service": "oauth2",
  86
+	     "xmlns:auth": this.oauth2_auth
  87
+    };
  88
+};
  89
+
67 90
 function XFacebookPlatform() {
68 91
 }
69 92
 util.inherits(XFacebookPlatform, Mechanism);
2  lib/xmpp/session.js
@@ -21,6 +21,8 @@ function Session(opts) {
21 21
     this.availableSaslMechanisms = [];
22 22
     this.api_key = opts.api_key;
23 23
     this.access_token = opts.access_token;
  24
+    this.oauth2_token = opts.oauth2_token;
  25
+    this.oauth2_auth = opts.oauth2_auth;
24 26
     this.register = opts.register;
25 27
     delete this.did_bind;
26 28
     delete this.did_session;
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.