Re: jsoauth-1.3.4 doesnt work in Android (Titanium)

467 views
Skip to first unread message
Message has been deleted

Rob Griffiths

unread,
May 23, 2012, 2:14:38 PM5/23/12
to jso...@googlegroups.com
Hi Rainer

Not sure what's the problem here. Are you using jsOAuth-1.3.4.js or the commonjs module? The compiled js one is usually the better.

Is OAUTH all caps or OAuth? The latter is the constructor name which would imply your theory of path being the issue.

Rob

Kontaktschmied

unread,
May 24, 2012, 1:55:18 AM5/24/12
to jsOAuth


On 23 Mai, 20:14, Rob Griffiths <r...@bytespider.eu> wrote:
> Hi Rainer
>
> Not sure what's the problem here. Are you using jsOAuth-1.3.4.js or the commonjs module? The compiled js one is usually the better.
I'am using jsOAuth-1.3.4.js in developer version.
>
> Is OAUTH all caps or OAuth?
Yes, it was a mistake here in form.
The latter is the constructor name which would imply your theory of
path being the issue.

I have linked with: Ti.include('/lib/jsoauth-1.3.4.js');
and tried:
var oauth = OAuth(this.oauth_options);
and
var oauth = new OAuth(this.oauth_options);

In both version it works on iPhone but on Android comes the message
"OAuth undefined".

If I'am using commonJS, what is the right syntax?

I guess:

var OAuth = require('/lib/jsOAuth');
var oauth = new OAuth(options);
oauth.fetchRequestToken(function(url) {
}



>
> Rob

Kontaktschmied

unread,
May 24, 2012, 2:11:44 AM5/24/12
to jsOAuth

> I guess:
>
> var OAuth = require('/lib/jsOAuth');
> var oauth = new OAuth(options);
> oauth.fetchRequestToken(function(url) {
>
this code produces:
[WARN] Exception in event callback. {
line = 13;
message = "'[object Object]' is not a constructor (evaluating 'new
OAuth(this.oauth_options)')";
name = TypeError;
sourceId = 165530912;
}

Now I tried the classic, compiled version with:

Ti.include('/lib/jsoauth-1.3.4.js');
var oauth = new OAuth(this.oauth_options);

and it comes the same error on ANdroid:
Uncaught ReferenceError: OAuth is not defined
in this constructor line.

What can I do?

Rainer
>
>
>
>
> }
>
> > Rob

Rob Griffiths

unread,
May 24, 2012, 3:48:20 AM5/24/12
to jso...@googlegroups.com
It maybe
require(yourpath).OAuth

Rob Griffiths

unread,
May 24, 2012, 3:48:50 AM5/24/12
to jso...@googlegroups.com
Var OAuth = require(yourpath).OAuth;

On 24 May 2012, at 06:55 AM, Kontaktschmied <kontakt...@googlemail.com> wrote:

>
>

Kontaktschmied

unread,
May 24, 2012, 4:45:09 AM5/24/12
to jso...@googlegroups.com
Hi,

my module is living in
/lib/OAuth.js

and I have coded:

=====
var OAuth = require('/lib/jsOAuth').OAuth;
/* OK, now I have an object */

/* How can I call the contructor with options? */

/* this code */

var oauth = new OAuth(this.oauth_options);

/* or this*/
var oauth = OAuth(this.oauth_options);

makes this error:

WARN] Exception in event callback. No valid request transport found.




Kontaktschmied

unread,
May 24, 2012, 4:57:16 AM5/24/12
to jso...@googlegroups.com
A question to the classic way:

I have embed your compiled code direct in my module:

=====
var exports=exports||this;exports.OAuth=function(a){function b(a){var b=arguments,c=b.callee, ……
    var oauth = OAuth(oauth_options);
   
    oauth.fetchRequestToken(function(url) {
    }, function() {
    });
=====

In this case my program gives me (only on Android, iPhone works) the error message "OAuth is undefined"
It seems that the android javascript interpreter (V8) has problems with you architecture in the style:
====
var exports=exports||this;
exports.OAuth=function(a){
  function b(
====
I thougt 'exports' works only in this commonJS-Modul environment. ??

Rainer








Rob Griffiths

unread,
May 24, 2012, 5:02:18 AM5/24/12
to jso...@googlegroups.com
Notice the line
var exports=exports||this
That tells the code to use common js exports or the current scope which is usually window.

If you use require you'll most likely need to do

var OAuth = require('lib/jsOAuth.1.3.4.js').OAuth;

var oa = OAuth(options);

If that doesn't work maybe titanium on android uses paths differently?
 

-- 
Rob Griffiths
Sent with Sparrow

Kontaktschmied

unread,
May 24, 2012, 5:13:54 AM5/24/12
to jso...@googlegroups.com
Only the line
var OAuth = require('lib/jsoauth-1.3.4').OAuth;

includes the Class (the moduleName is without '.js'). (in Titanium)

But this version produces 'Exception in event callback. No valid request transport found.'

In you hint you use 'require' and you includes the classic version. Is it correct?
How I can the commonJS-version of your modul. In documentation I have no found any examples.
Message has been deleted

Rob Griffiths

unread,
May 24, 2012, 5:37:11 AM5/24/12
to jso...@googlegroups.com
That would imply that the code couldn't find Titanium.

Try this test version - code console.info() logs if titanium exists.



-- 
Rob Griffiths
Sent with Sparrow

jsOAuth-1.3.5.js

Kontaktschmied

unread,
May 24, 2012, 5:53:33 AM5/24/12
to jso...@googlegroups.com
Thanx!

I have changed you code into:
==
 function Request() {
        var XHR;
        Ti.API.debug(Titanium);
        Ti.API.debug(global.Titanium);
==

and on console appears:

==
[DEBUG] [object TopTiModule]
[DEBUG] <null>
==

Rob Griffiths

unread,
May 24, 2012, 5:55:14 AM5/24/12
to jso...@googlegroups.com
Okay I know how to fix. Give me a moment.

-- 
Rob Griffiths
Sent with Sparrow

Rob Griffiths

unread,
May 24, 2012, 6:26:36 AM5/24/12
to jso...@googlegroups.com
Does this version Work for you?



-- 
Rob Griffiths
Sent with Sparrow

jsOAuth-1.3.5.js

Kontaktschmied

unread,
May 24, 2012, 6:30:46 AM5/24/12
to jso...@googlegroups.com
OK,
the new version gives me:
==
[WARN] Exception in event callback. {
    line = 268;
    message = "'undefined' is not an object (evaluating 'options.enablePrivilege')";
    name = TypeError;
    sourceId = 165880288;
}
==

Rob Griffiths

unread,
May 24, 2012, 6:34:15 AM5/24/12
to jso...@googlegroups.com
You're not passing in any options?

-- 
Rob Griffiths
Sent with Sparrow

Message has been deleted

Rob Griffiths

unread,
May 24, 2012, 6:37:56 AM5/24/12
to jso...@googlegroups.com
Could you find the function Request() {

then add Ti.Api.debug(typeof Titanium.Network.createHTTPClient);

let me know what you get

-- 
Rob Griffiths
Sent with Sparrow

On Thursday, 24 May 2012 at 11:34, Kontaktschmied wrote:

console.log(options)  shows me  'options' are null. Sorry it was me mistake.

Now it comes again:
[INFO] {
    accessTokenUrl = "https://test123poi.signonservice.com/accounts/access_token";
    authorizationUrl = "https://test123poi.signonservice.com/signon/login";
    consumerKey = "consumer-123poi";
    consumerSecret = tHVWb6sx1FGe1SXPnok2;
    requestTokenUrl = "https://test123poi.signonservice.com/accounts/oauth/request_token";
}
[WARN] Exception in event callback. No valid request transport found.



Kontaktschmied

unread,
May 24, 2012, 6:40:57 AM5/24/12
to jso...@googlegroups.com
'function'

here the code:
===
function Request() {
        var XHR;
        Ti.API.debug(typeof Titanium.Network.createHTTPClient);   
===

PS: I should change me secret ;-)

Rob Griffiths

unread,
May 24, 2012, 6:42:24 AM5/24/12
to jso...@googlegroups.com
Okay what was debugged into the console?

Don't worry about the secret - It would be unprofessional to use it in anything other than debugging your problems.

-- 
Rob Griffiths
Sent with Sparrow

Kontaktschmied

unread,
May 24, 2012, 6:42:33 AM5/24/12
to jso...@googlegroups.com
Skype? My name is kontaktschmied

Rob Griffiths

unread,
May 24, 2012, 6:58:41 AM5/24/12
to jso...@googlegroups.com
Added.
I'm working so my apologies if im not too responsive.

-- 
Rob Griffiths
Sent with Sparrow

Kontaktschmied

unread,
May 24, 2012, 8:24:00 AM5/24/12
to jso...@googlegroups.com
Thanx,

i think the xhr wrapper is the problem.

Temporarily I have coded:
==
var XHR;
        // Titanium may be present in the current global scope and not in 'global'
        if( typeof Titanium !== 'undefined' && typeof Titanium.Network.createHTTPClient != 'undefined') {
            XHR = Titanium.Network.createHTTPClient();
            return XHR;
        }
}
==

In this case the next error message is:
[WARN] Exception in event callback. {
    line = 637;
    message = "'undefined' is not a function (evaluating 'global.btoa(signature)')";
    name = TypeError;
    sourceId = 166691296;

Kontaktschmied

unread,
May 24, 2012, 9:24:02 AM5/24/12
to jsOAuth
Hi,

In this version http://pastie.org/3960988
I shortcutted wrapper and moved btoa. It seems to run on Android.

Rob Griffiths

unread,
May 24, 2012, 9:29:28 AM5/24/12
to jso...@googlegroups.com
Thanks for your email. I'll see if I can code up a complete fix based of what you've done here.

-- 
Rob Griffiths
Sent with Sparrow

Kontaktschmied

unread,
May 24, 2012, 11:37:43 AM5/24/12
to jsOAuth
Wonderfull!

After starting of oauth.fetchRequestToken() I see in the console a lot
of URls. I know the next step is retrievig the accessToken.
How can I filter the next parameters?

Rob Griffiths

unread,
May 24, 2012, 11:48:48 AM5/24/12
to jso...@googlegroups.com
Hopefully this will give you a clue. https://gist.github.com/1071227#file_pin_auth.html
You should be able to see the order that you need to call things.

You'll have to manually save the token you get from getAccessToken() so that you can re-load them at a later date. http://bytespider.github.com/jsOAuth/api-reference/#getaccesstoken

Rob

-- 
Rob Griffiths
Sent with Sparrow

Kontaktschmied

unread,
May 24, 2012, 3:19:13 PM5/24/12
to jso...@googlegroups.com
I think to work without Pin. In my case comes a window with login/passwort. After submitting I get a new URL like:

http://***/?oa=1&oa_mode=2&oauth_token=17da35bf-070f-44ac-a4f4-0273ccfbf4e9&oauth_verifier=FT13Xl

I can parse oauth_token and oauth_verifier, but I need accessToken and I'am guessing it is the job of

fetchAccessToken().


The parsing of this two parameters – is it part of your library?

Rainer

Rob Griffiths

unread,
May 24, 2012, 3:24:20 PM5/24/12
to jso...@googlegroups.com
You'll need to handle the parsing of verifier but oauth_token should have been parsed and temporarily set as the access token ready for 
getAccessToken()

When you have parsed the verifier, remember to call setVerifier()

Then you can call fetchAccessToken()

-- 
Rob Griffiths
Sent with Sparrow

Message has been deleted

Kontaktschmied

unread,
May 25, 2012, 9:31:13 AM5/25/12
to jsOAuth
Now I parse the verfier from URL and set it to object:
Here is the object dump:
===
accessTokenUrl = "https://test******service.com/accounts/oauth/
access_token";
authorizationUrl = "https://test******service.com/signon/login";
fetchAccessToken = "<KrollCallback: 0x99a0a20>";
fetchRequestToken = "<KrollCallback: 0x99a2ac0>";
get = "<KrollCallback: 0x99a3d20>";
getAccessToken = "<KrollCallback: 0x99a0540>";
getAccessTokenKey = "<KrollCallback: 0x99a1520>";
getAccessTokenSecret = "<KrollCallback: 0x9938440>";
getJSON = "<KrollCallback: 0x999e900>";
getVerifier = "<KrollCallback: 0x9982180>";
init = "<KrollCallback: 0x99a07e0>";
parseTokenRequest = "<KrollCallback: 0x99a18c0>";
post = "<KrollCallback: 0x99a06b0>";
postJSON = "<KrollCallback: 0x99a1410>";
realm = "";
request = "<KrollCallback: 0x9989980>";
requestTokenUrl = "https://test******service.com/accounts/oauth/
request_token";
setAccessToken = "<KrollCallback: 0x997e790>";
setCallbackUrl = "<KrollCallback: 0x995f940>";
setVerifier = "<KrollCallback: 0x9978330>";
verifier = ptnUaT;
===
Next I call
oauth.fetchAccessToken();

This request gives me:
'The request sent by the client was syntactically incorrect
(Inadequate OAuth consumer credentials.)'

It seems in the object are other secrets lost.

Rob Griffiths

unread,
May 25, 2012, 9:35:24 AM5/25/12
to jso...@googlegroups.com
Sounds to me like accessToken wasn't set correct?

what does getAccessToken() when you debug it? is it set to the key and secret you received from the webview?

-- 
Rob Griffiths
Sent with Sparrow

Kontaktschmied

unread,
May 25, 2012, 10:03:28 AM5/25/12
to jsOAuth
I'am parsing URL and set oauth.veryfier with this value.
The method oauth.setVerfier() doenst change the content of oauth (?)

Here do whole dump:
fetchRequestToken():
This is dump of oauth inside the Requester:
[INFO] {
callbackUrl = oob;
consumerKey = "XXXXXX";
consumerSecret = XXXXXXXPnok2;
enablePrivilege = 0;
signatureMethod = "HMAC-SHA1";
verifier = "";

Now comes the webview with login, after inserting of Login/PW comes a
lot of redirects. From the last I parse the verifier and code
oauth.verfier=MYVERIFIER

Id I dump the oauth in my caller then:

[INFO] {
accessTokenUrl = "https:/MYURL/accounts/oauth/access_token";
authorizationUrl = "https:/MYURL/signon/login";
fetchAccessToken = "<KrollCallback: 0x8ecb4d0>";
fetchRequestToken = "<KrollCallback: 0x8ec94d0>";
get = "<KrollCallback: 0x8ecd610>";
getAccessToken = "<KrollCallback: 0x999a990>";
getAccessTokenKey = "<KrollCallback: 0x99a63b0>";
getAccessTokenSecret = "<KrollCallback: 0x99c5d60>";
getJSON = "<KrollCallback: 0x8ecb8e0>";
getVerifier = "<KrollCallback: 0x99afb50>";
init = "<KrollCallback: 0x8ecd5f0>";
parseTokenRequest = "<KrollCallback: 0x8ecb9e0>";
post = "<KrollCallback: 0x8ecb860>";
postJSON = "<KrollCallback: 0x8ecb960>";
realm = "";
request = "<KrollCallback: 0x99bda40>";
requestTokenUrl = "https:/MYURL/accounts/oauth/request_token";
setAccessToken = "<KrollCallback: 0x999a930>";
setCallbackUrl = "<KrollCallback: 0x99bd9c0>";
setVerifier = "<KrollCallback: 0x99afbd0>";
verifier = iYkAt6;
}

Now I call oauth.fetchAccessToken and inside the requester:
[INFO] {
This is dump of oauth inside the Requester:
accessTokenKey = "*****4b8-4fcd-8fac-776525fcf0a5";
accessTokenSecret = "*********yqfv5IOC5MJigFiNJJg/
ZJXuRV4oR71lA44r76TkWw=";
callbackUrl = oob;
consumerKey = "****";
consumerSecret = ****FGe1SXPnok2;
enablePrivilege = 0;
signatureMethod = "HMAC-SHA1";
verifier = ""; <==== is empty
}
[INFO] {
WRONG creditionals
}

What can I do?

Rainer

Rob Griffiths

unread,
May 25, 2012, 10:06:46 AM5/25/12
to jso...@googlegroups.com
you didnt use oauth.setVerifier(my_verifier); ? you need to do this as oauth is an internal hidden object storing config.

-- 
Rob Griffiths
Sent with Sparrow

Kontaktschmied

unread,
May 25, 2012, 3:50:13 PM5/25/12
to jsOAuth
This version works fine:

function OA(options) {
this.options = options
}

OA.prototype.start = function() {
var self = this;
var parent = self.options.ui.currentView;
var oauth = require('lib/jsOAuth-1.3.5').OAuth(self.options.oauth);
var overlay = Ti.UI.createView({
backgroundColor : 'black',
opacity : 0.3
});
parent.add(overlay);
if(Ti.Platform.name === 'iPhone OS') {
if(self.options.ui.actind) {
parent.add(self.options.ui.actind);
self.options.ui.actind.show();
}
}
oauth.fetchRequestToken(function(url) {
var webview = Ti.UI.createWebView({
width : '100%',
height : '105%',
borderRadius : 8,
borderWidth : 3,
align : 'center',
borderColor : 'silver',
transform : Ti.UI.create2DMatrix().scale(0.92),
url : url
});
parent.add(webview);
/**/
var cron = setInterval(function() {
var url = webview.url;
var vars = url.split('?')[1].split('&');
for(var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if(pair[0] == 'oauth_verifier')
self.options.oauth.oauthVerifier = pair[1];
if(pair[0] == 'oauth_token')
self.options.oauth.oauthToken = pair[1];
}
if(self.options.oauth.oauthVerifier) {
clearInterval(cron);
parent.remove(webview);
parent.remove(overlay);
oauth.setVerifier(self.options.oauth.oauthVerifier);
oauth.fetchAccessToken(function(data) {
}, function(error) {
var secrets = {
token : oauth.getAccessToken(),
key : oauth.getAccessTokenKey(),
secret : oauth.getAccessTokenSecret()
};

if(self.options.ui.success) {
var alert = Ti.UI.createAlertDialog({
buttonNames : ['OK'],
message : self.options.ui.success,
title : 'Login'
});
alert.show();
}
if( typeof (self.options.result200) == 'function') {
self.options.result200(secrets);
}
});

}
}, 500);
}, function() {
});
// oauth.fetchAccessToken(getSomeData, failureHandler);

};
module.exports = OA;

Rob Griffiths

unread,
May 25, 2012, 4:14:41 PM5/25/12
to jso...@googlegroups.com
Excellent news!

Kontaktschmied

unread,
May 28, 2012, 3:56:58 PM5/28/12
to jso...@googlegroups.com
Hi Rob,

my code only works on iPhone.
On my HTC comes in the step: Ti.API.debug(secrets); the following console error:

W/DefaultRequestDirector(19172): Authentication error: Unable to respond to any of these challenges: {oauth=WWW-Authenticate: OAuth}
W/IdleConnectionHandler(19172): Removing a connection that never existed!
E/TiHttpClient(19172): (TiHttpClient-2) [13418,13418] HTTP Error (org.apache.http.client.HttpResponseException): Unauthorized
E/TiHttpClient(19172): org.apache.http.client.HttpResponseException: Unauthorized

This is my current code: http://pastie.org/3984614

I cannot understand the difference.
I'a, not all understanding in your code. My question: are my steps OK?

Rainer




Kontaktschmied

unread,
May 28, 2012, 4:25:42 PM5/28/12
to jso...@googlegroups.com
Comment to last post:

The fetchAccessToken() request answered in HTML-Body with
   'Login unsuccesfull, Please try it again'

On iPhone I can via
var secrets = {
            token : oauth.getAccessToken()[0],
            key : oauth.getAccessTokenKey(),
            secret : oauth.getAccessTokenSecret()
};
access to all 3 secrets – But the AccessToken is an aray (???)


Rainer

Rob Griffiths

unread,
May 29, 2012, 4:51:38 AM5/29/12
to jso...@googlegroups.com
oauth.getAccessToken
is just an array of  

oauth.getAccessTokenKey
and 
oauth.getAccessTokenSecret
You dont need to call it. It was the original way to get both the key and secret before I realised it would be easier to have 2 methods.

So your code should be:
var secrets = {
            key : oauth.getAccessTokenKey(),
            secret : oauth.getAccessTokenSecret()
};

-- 
Rob Griffiths
Sent with Sparrow

Rob Griffiths

unread,
May 29, 2012, 5:00:34 AM5/29/12
to jso...@googlegroups.com
Updated with your changes. Could you see if this version breaks ?


-- 
Rob Griffiths
Sent with Sparrow

Kontaktschmied

unread,
May 29, 2012, 7:53:39 AM5/29/12
to jso...@googlegroups.com
Hi Rob,

it produced the same error.
Here is my partiell running version: http://pastie.org/3988264

In my version is additional a http header named licencekey. It is part of options.

I dont understand this sequence:
if(!!xhr.getAllResponseHeaders) {
    responseHeadersString = xhr.getAllResponseHeaders();
    while(( match = regex.exec(responseHeadersString))) {
    responseHeaders[match[1]] = match[2];
                            }
                        } else if(!!xhr.getResponseHeaders) {
                            responseHeadersString = xhr.getResponseHeaders();
                            for(var i = 0, len = responseHeadersString.length; i < len; ++i) {
                                responseHeaders[responseHeadersString[i][0]] = responseHeadersString[i][1];
                            }
                        }
In TitaniumAPI isnt a method getAllResponseHeaders …

Kontaktschmied

unread,
May 29, 2012, 8:21:37 AM5/29/12
to jso...@googlegroups.com
Comment to last post:

1. on iPhone the script gives me accesstokenkey and accesstokensecret. At the time I cannot test if I can realize an image uplpad with this parameters.
2. in Android comes the error Authentication error: Unable to respond to any of these challenges: {oauth=WWW-Authenticate: OAuth} and I dont get any tokens.
3. in your responseObject the properties resonseHeaders and requestHeaders everytime leaves empty. Only text and xml will fileld.

Any ideas?

Rainer


Am Dienstag, 29. Mai 2012 11:00:34 UTC+2 schrieb Rob Griffiths:

Rob Griffiths

unread,
May 29, 2012, 11:24:56 AM5/29/12
to jso...@googlegroups.com
You don't need to modify the code to add headers - In fact your signature will be incorrect if you do.
If you need to add headers use request();

Rob

-- 
Rob Griffiths
Sent with Sparrow

Reply all
Reply to author
Forward
0 new messages