I am trying to use Google OAuth2 for Google Drive authentication on both Android and iOS. I had a solution working on Android using ChildBrowser, but it did not work on iOS. PhoneGap Build support suggested I use InAppBrowser because ChildBrowser is depreciated.
I can get iOS and Android both to prompt my user for ID/PW then it shows "Allow Access" button all in InAppBrowser to give Googl Drive access. On Android tapping Allow Access button gives page not available error with correct code and OAuth token in the url. When using childbrowser it was this change event that allowed you to check for code 4 and get the token. InAppBrowser only has LoadStart, LoadStop and Exit events.
How can I check the Google return URL for success/failure and if success grab the token?
Thanks for any and all help!
Here's how I use InAppBrowser to do Facebook auth. Since you're just trying to grab a value out of the url, it should work the same way:
var fb = {
id: '...'
,secret: '...'
,namespace: '...'
,redirect: '...'
,display: 'touch'
,scope: ['publish_actions']
,windowRef: null
,code: null
,onLoadEvent: function(event){
var url = event.url;
console.log(url);
//once we've been redirected to this domain, fb's job is done
if (/my.domain.com/.test(url)){
if (/code=/.test(url)){
//auth done
var code = url.match(/code=([^\&]+)/)
if (code) code = code[1];
window.fb.code = code;
window.fb.windowRef.close();
}else if (/error_description=/.test(url)){
//login unsuccessful
var error = url.match(/error_description=([^\&]+)/);
if (error) error = error[1].replace(/[^A-Z0-9 ]/gi, " ");
console.error("facebook login failed: " + error);
window.fb.code = null;
window.fb.windowRef.close();
}
}
}
};
var authUrl = "https://graph.facebook.com/oauth/authorize?"
+ "client_id=" + fb.id
+ "&redirect_uri=" + encodeURI(fb.redirect)
+ "&display=" + fb.display
+ "&scope=" + fb.scope.join('%2C');
fb.windowRef = window.open(authUrl, '_blank', loginPopupOptions);
//no reason we can't use the same function twice...
fb.windowRef.addEventListener('loadstart', fb.onLoadEvent);
fb.windowRef.addEventListener('loadstop', fb.onLoadEvent);
I tried to pull only the relevant bits out of our structure so hopefully it makes sense this way...
Related
I have a news website based on WordPress, I send notifications using OneSignal plugin, recently I created Android webview app, the notifications received on mobiles when clicked the article open in a browser instead of the App itself.
According to OneSignal documentation, I should create a most used plugin file "mu-plugin" including this PHP functions :
<?php
add_filter('onesignal_send_notification', 'onesignal_send_notification_filter', 10, 4);
function onesignal_send_notification_filter($fields, $new_status, $old_status, $post) {
/* Goal: We don't want to modify the original $fields array, because we want the original web push notification to go out unmodified. However, we want to send an additional notification to Android and iOS devices with an additionalData property.
* */
$fields_dup = $fields;
$fields_dup['isAndroid'] = true;
$fields_dup['isIos'] = true;
$fields_dup['isAnyWeb'] = true;
$fields_dup['isWP'] = false;
$fields_dup['isAdm'] = false;
$fields_dup['isChrome'] = false;
// $fields_dup['android_channel_id'] = "<CHANNEL ID UUID HERE>";
$fields_dup['data'] = array("myappurl" => $fields['url']);
/* Important to set web_url to support opening through both mobile and browser*/
$fields_dup['web_url'] = $fields_dup['url'];
/* Important to unset the URL to prevent opening the browser when the notification is clicked for mobile app users */
unset($fields_dup['url']);
$onesignal_post_url = "https://onesignal.com/api/v1/notifications";
/* Hopefully OneSignal::get_onesignal_settings(); can be called outside of the plugin */
$onesignal_wp_settings = OneSignal::get_onesignal_settings();
$onesignal_auth_key = $onesignal_wp_settings['app_rest_api_key'];
$request = array("headers" => array("content-type" => "application/json;charset=utf-8", "Authorization" => "Basic " . $onesignal_auth_key), "body" => json_encode($fields_dup), "timeout" => 60);
$response = wp_remote_post($onesignal_post_url, $request);
if (is_wp_error($response) || !is_array($response) || !isset($response['body'])) {
$status = $response->get_error_code();
$error_message = $response->get_error_message();
error_log("There was a " . $status . " error returned from OneSignal when sending to mobile users: " . $error_message);
return;
}
return $fields;
}
?>
Now the notification open up the mobile app instead of browser, but showing the home page instead of the article it self.
Note: If I use OneSignal dashboard to send notification, and I unset the "Launch URL", then add in "Additional Data" the following fields :
Key : URL
Value : The post url
Then the notification will open the mobile app with deep linking to the article page.
Anyone can help me modify the function ?
Thanks :)
I'm trying to run my desktop chrome extension on Android, so i tried running it in Yandex browser on my phone. It runs ok except for the google login.(everything works well on desktop Chrome and desktop Yandex).
This code is called by the background scripts:
var url = 'https://accounts.google.com/o/oauth2/auth' +
'?client_id=' + clientId +
'&response_type=id_token' +
'&access_type=offline' +
'&redirect_uri=' + redirectUri +
'&scope=' + scopes;
getIdToken: function (message) {
const _this = this;
var idToken = "";
chrome.identity.launchWebAuthFlow(
{
'url': url,
'interactive': true
},
function (redirectedTo) {
console.log("[2]auth-manager called: "+redirectedTo);
if (chrome.runtime.lastError) {
// Example: Authorization page could not be loaded.
console.log("lastError: "+chrome.runtime.lastError.message);
}
else {
var response = redirectedTo.split('#', 2)[1];
// Example: id_token=<YOUR_BELOVED_ID_TOKEN>&authuser=0&hd=<SOME.DOMAIN.PL>&session_state=<SESSION_SATE>&prompt=<PROMPT>
idToken = (response.split('&')[0]).split('=', 2)[1];
console.log("auth-manager id token", idToken);
if (message != undefined) {
message.data.google_id_token = idToken;
cloudWebSocket.sendMessage(JSON.stringify(message));
_this.isLogged = true;
closePopup();
alert('login successful');
}
}
}
);
}
When I call this function, redirectedTo is undefined, and i get a chrome.runtime.lastError.message:"canceled". That's it.
I use the very same manifest from the desktop apps, with the same clientId,redirectUri and scopes.
I can't figure out, what causes this problem?
If there's another way to perform a google login without this issue it can also help.
see the Web Extensions API ...in particular the platform support table there.
initiating the oAuth2 flow on the server-side should nevertheless be possible.
I am trying to integrate the Square Payment on my Ionic 1 application using the Web API based on their docs here. They are using intent anchor to call the Square app and send appropriate payment details. But when I tried to implement, it gives me this error:
Can't display PDF file (intent URL cannot be opened)
Here's my code snippet:
var hrefString = 'intent://#Intent;';
var extrasObject = { /* extras */
"action": "com.squareup.register.action.CHARGE",
"package":"com.squareup",
"S.browser_fallback_url":"<my-fallback-url>",
"S.com.squareup.register.CLIENT_ID":"<my-client-id>",
"S.com.squareup.register.WEB_CALLBACK_URI": "<registered-callback-uri>",
"S.com.squareup.register.API_VERSION":"v1.3",
"i.com.squareup.register.TOTAL_AMOUNT": 100,
"S.com.squareup.register.CURRENCY_CODE":"USD",
"S.com.squareup.register.TENDER_TYPES":"com.squareup.register.TENDER_CARD,com.squareup.register.TENDER_CARD_ON_FILE,com.squareup.register.TENDER_CASH,com.squareup.register.TENDER_OTHER"
};
// Generate intent anchor
for(var key in extrasObject) {
hrefString += key + '=' + extrasObject[key] + ';';
}
// Convert string to URI
var intentURL = encodeURIComponent(hrefString + 'end');
window.open(intentURL, "_system", "location=no");
Prior to this implementation, I already install the InAppBrowser Cordova plugin here.
Can someone help me on this one? Thanks in advance!
I have created an app through facebook developers and added an iOS platform and Android platform. iOS is now working with 3.2.2. Android however is not. My aim is to post a pre defined message onto a user's wall. My code is as follows. When I press my button fbShare(outlined below), I am getting a screen pop up with facebook at the top and a message stating:
App Not Setup: The developers of this app have not set up this app properly for facebook
I added the android platform in the apps settings page and copied the bundleID from my project. I also generated the key hash for both the location of my debug keystore and my actual production keystore. Neither have worked. My code for sharing is as follows:
var fbShare=Ti.UI.createImageView({
image:'/images/fbShare.png',
width:'36dp',
height:'36dp',
left:'5dp'
});
Navbar.add(fbShare);
fbShare.addEventListener("click", function (e){
facebookLogin();
});
var fb;
var facebookLogin = function(){
fb = require('facebook');
fb.appid = 'xxxxxxxxxx';
Ti.API.info('facebook logedin?' + fb.loggedIn);
//login if not logged in
if (!fb.loggedIn) {
fb.permissions = ['publish_stream'];
fb.forceDialogAuth = false;
fb.authorize();
fb.addEventListener('login', function(e) {
if (e.success) {
Ti.API.info("Facebook logged in - stage 1");
postToFacebook();
} else if (e.error) {
alert(e.error + " - stage 1");
} else if (e.cancelled) {
alert("Facebook login cancelled - stage 2");
}
});
}else{
postToFacebook();
}
};
var data = {
link : "www.mylink.com",
name : "my name",
message : "my message",
caption : "my caption",
picture : "myPic.jpg",
description : "My description."
};
var postToFacebook = function(){
Ti.API.info("attempting to post to facebook...please wait");
fb.requestWithGraphPath('me/feed', data,
"POST", function(e) {
if (e.success) {
alert("Shared to facebook successfully!");
fbShare.setEnabled(true);
fbShare.setImage('/images/fbShare.png');
Ti.API.info("Posted to facebook wall!");
}else{
if(e.error){
Ti.API.info("cant post to facebook " + e.error);
}else{
Ti.API.info("something else happened...");
}
alert('Something went wrong with your post but facebook could not confirm what.');
fbShare.setEnabled(true);
fbShare.setImage('/images/fbShare.png');
}
});
};
I've been stuck on this for days, Any help or guidance appreciated
I had a similar issue yesterday. My code was correct but I still get that message. I fixed it by setting "Do you want to make this app and all its live features available to the general public?" to YES under "status and review" in Facebook developer website.
if you have done it already then please make sure your key Hashes are correct. Remember you need a debug key and release key.
if you have done the above steps and sure your key hashes are correct then there
will be some other issue.
I hope this helps.
I am using $getJSON to hit a node.js endpoint under Phonegap and Android. The code looks like this
$.getJSON(
serverURL + "/login?callback=?",
"playerId=" + playerId + "&pwd=" + pwd,
function(data){
theCallbackFunction.call(null, JSON.parse(data));
},
function(jqXHR, textStatus, errorThrown) {
alert('error ' + textStatus + " " + errorThrown);
}
);
In response to the login request, my server sends back a session cookie. This cookie is only accepted and returned in subsequent AJAX requests if 'Third-Party Cookies' are enabled in the browser. I have found that older Android devices (e.g. 2.2) allow this by default but new ones (3.2) do not.
Is it possible to force Phonegap to enable Third-Party Cookies for my Android application?
I had a similar problem when trying to authenticate with my server. I instead resorted to the use of localStorage. See the code below or here.
var store = window.localStorage,
request = {
url: {SERVER_URL},
headers : {
Cookie: store.getItem('session')
},
complete: function (jqXHR, status){
if (status != 'success') {
console.log('ajax status: failure');
} else if (store.getItem('session') != null) {
console.log('ajax status: session exists');
} else {
console.log('ajax status: saving cookie');
var header = jqXHR.getAllResponseHeaders();
var match = header.match(/(Set-Cookie|set-cookie): (.+?);/);
if (match) {
session = match[2];
store.setItem("session", session);
}
}
}
}
$.ajax(request);
In the above, I'm checking for the localStorage variable 'session' and if it exists, it will send the stored cookie. If it doesn't exist, it will take the 'set-cookie' paramater sent in the headers by the server, match the pertinent part and store it in the 'session' variable of localStorage.
Phonegap does not support cookie abstraction. Never really needed to as there are already apps/plug-ins that do. Plus it is intended to wrap up the functionality of the phone/device, not the browser. You CAN however do this with a jQuery plug-in.
https://github.com/carhartl/jquery-cookie