Cordova InAppBrowser show location bar Cordova AngularJS Oauth - angularjs

Hi I'm using the Cordova InAppBrowser and AngularJS Oauth plugins.
When I press a normal link button like this:
<a class="external" ng-href="https://www.website.com/" targe="_blank" >open link</a>
In combination with this:
<script>
$( document ).ready(function() {
// open links in native browser (phonegap);
$(document).on('click', '.external', function (event) {
event.preventDefault();
window.open($(this).attr('href'), '_blank');
return false;
});
});
</script>
It opens the link in the in app browser. In the InAppBrowser when loading the url it is showing the url location at the bottom. So this is working OK.
When the AngularJS Oauth plugin opens the InAppBrowser and starts to load the login page of Facebook for example it doesn't show the loading url location at the bottom.
I tried to add "location=yes" in the Oauth plugin like this, but it is still not showing the url loading bar at the bottom:
window.open('https://www.website.com/oauth/authorize?client_id=' + clientId + '&redirect_uri=http://localhost/callback&scope=' + appScope.join(",") + '&response_type=code&approval_prompt=force', '_blank', 'location=yes,clearsessioncache=yes,clearcache=yes');
How can I force to show the loading bar with Oauth in the InAppBrowser ?
The reason I want this is when a login page needs some time to load there is no loading indication and you mind think there is nothing happening.
This is how the Oauth function looks like with location=yes:
strava: function(clientId, clientSecret, appScope) {
var deferred = $q.defer();
if(window.cordova) {
var cordovaMetadata = cordova.require("cordova/plugin_list").metadata;
if(cordovaMetadata.hasOwnProperty("cordova-plugin-inappbrowser") === true || cordovaMetadata.hasOwnProperty("org.apache.cordova.inappbrowser") === true) {
var browserRef = window.open('https://www.strava.com/oauth/authorize?client_id=' + clientId + '&redirect_uri=http://localhost/callback&scope=' + appScope.join(",") + '&response_type=code&approval_prompt=force', '_blank', 'location=yes,clearsessioncache=yes,clearcache=yes');
browserRef.addEventListener('loadstart', function(event) {
if((event.url).indexOf("http://localhost") === 0) {
requestToken = (event.url).split("code=")[1];
$http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
$http({method: "post", url: "https://www.strava.com/oauth/token", data: "client_id=" + clientId + "&client_secret=" + clientSecret + "&code=" + requestToken })
.success(function(data) {
deferred.resolve(data);
})
.error(function(data, status) {
deferred.reject("Problem authenticating");
})
.finally(function() {
setTimeout(function() {
browserRef.close();
}, 10);
});
}
});
browserRef.addEventListener('exit', function(event) {
deferred.reject("The sign in flow was canceled");
});
} else {
deferred.reject("Could not find InAppBrowser plugin");
}
} else {
deferred.reject("Cannot authenticate via a web browser");
}
return deferred.promise;
},

I found the solution.
My app was loading the oauth plugin twice, once via a separate oauth script I added to my project and once via the ngCordova library. The ngCordova script was overruling the oauth script I added so that's why the location=yes was not working.
I removed the separate oauth script and changed location=no to yes in the ngCordova oauth script.

Related

response.redirect() is not working in express (NodeJS)

I want redirect to dashboard.html from login.html if username is correct, if not then alert box will be shown, I used both express response.redirect('path') or response.sendFile('path') but none is working here.
I am using angularJs as front-end and express module of nodeJs in back-end.
Express route code:
module.exports = function(app,db,path){
app.post('/student-login', function (request, response) {
var user = request.body;
if(user.username == "abhinav")
{
response.redirect('/views/dashboard.html');
response.end();
}
else{
response.send("Wrong username");
response.end();
}
});
}
AngularJs code:
angular.module('loginService',[])
.service('loginService',function($http){
return {
sendStudent : function(data){
return $http.post('/student-login',data)
.then(function(response){
return response.data;
});
}
}
});
AngularJs controller Code:
if ($scope.myForm.$valid)
loginService.sendStudent($scope.studentData)
.then(function(data){
if(data=="Wrong username")
alert(data);
});
Developer option > Network :
As you can see in the Network tab, browser does make a request to the /views/dashboard.html route. It means that redirect is working. The reason why you don't get the expected behavior is because you need to navigate to that page (right now you are simply loading content of the page).
I would suggest moving redirection logic from express to frontend and using http status codes to signal login errors.
Express code:
module.exports = function(app,db,path){
app.post('/student-login', function (request, response) {
var user = request.body;
if (user.username == "abhinav") {
response.sendStatus(200);
} else {
response.sendStatus(401);
}
});
}
AngularJS controller code:
if ($scope.myForm.$valid) {
loginService.sendStudent($scope.studentData).then(() => {
// login successful, response status is 200
location.href = '/views/dashboard.html'
}).catch(response => {
if (response.status === 401) {
alert("Wrong username")
} else {
alert("Some other error")
}
})
}
I'm using location.href as an example only because I'm not familiar with angularjs routing. It will reload the whole page, use API provided by angularjs router if you want to avoid that.

How to open a redirect link in my app without redirecting to external link?

I have the following code (AJS + Cordova):
$scope.update = function () {
myService.update()
.then(function (response) {
$scope.result = response.data;//prints [Object object]
console.log("Success!..." + response.data + "result.." + $scope.result);
angular.forEach($scope.result, function(value, key){
console.log(key + ': ' + value); //prints success:true
// $location.url(""+urlToGo);
$window.location.href = urlToGo;
})
},
function (error) {
$scope.status = 'Unable toget resposne ' + error;
});
};
Here, $window.location.href = urlToGo; will open a new window in mobile browser, which means user will leave my app. So, is there any technique, I can handle it inside my app using Angular or Cordova, without showing browser to him?
The following Link helped me resolve this issue for my Cordova App.
Phonegap - How to open external link inside the app
Briefly from that post:
var onInApp = window.open('http://paymentpage.com', '_blank', 'location=no,hidden=yes,closebuttoncaption=Done,toolbar=no');
I did have to play with the settings dependant upon the platform to get the correct result.
The latest Cordova Docs explain it much better :
https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/index.html
Hopefully this will point you in the correct direction.

Ionic http get request (with Ionic) returns html data

I am using Ionic and making http request like this:
$http.get('//GLOBAL.IP/?username=' + username + '&content_type=json')
.then(function (result) {
$scope.days = [];
alert(JSON.stringify(result));
for (first in result.data.weeks) break;
var currentWeek = result.data.weeks[first];
var time = currentWeek.overall.as_time;
$scope.week = currentWeek;
for (day in currentWeek.days.sort().reverse()) {
if (day < 2) {
continue;
}
var currentDay = currentWeek.days[day];
$scope.days.push(currentDay);
if (currentDay.present) {
console.log(parseInt(currentDay.work_time_balance) + parseInt(currentWeek.overall.seconds));
}
}
}, function (result) {
alert(JSON.stringify(result));
$ionicPopup.alert({
title: 'Error',
template: 'Connection failed, try again later!'
});
})
.finally(function () {
// Stop the ion-refresher from spinning
$scope.$broadcast('scroll.refreshComplete');
});
While I am opening app in browser with command ionic serve, everything seems working okay, I've already fixed CORS and other stuff.
But when In mobile app, I am getting this (sorry for not providing plaintext)
UPDATE
$http.get('//GLOBAL.IP/?username=' + username + '&content_type=json')
.then(function (result) {
alert('Good');
}, function (result) {
alert('Bad');
})
This code returns me GOOD, but result.data is still with script tags.
When you are testing this app in working mode what is localhost, Its a local server running on same machine, right.
When you install or run app in your mobile device where it is pointing to? Do you know that, If code is okay then replacing localhost with IP of your machine should resolve this issue.
Many script tags with addRow in ionic http request response, was because of // in the beginning of uri, protocol was selecting successfully in browser, but not in compiled app.

Basic authentication in Grails 3.0.4 with Spring Security

I'm trying to do Base authentication with Grails 3.0 an AngularJS.
Firstly in build.gradle I added Spring Security plugin (http://grails-plugins.github.io/grails-spring-security-core/guide/index.html):
compile 'org.grails.plugins:spring-security-core:3.0.0.M1'
Then I configured application.yml
grails:
plugin:
springsecurity:
useBasicAuth: true
basic:
realmName: "xxx"
userLookup:
userDomainClassName: xxx
rejectIfNoRule: true
fii:
rejectPublicInvocations: false
controllerAnnotations:
staticRules: [... ommited ...]
In angular service I've created this method:
var authenticateOwner = function (credentials, callback) {
var headers = credentials ? {authorization: "Basic " + btoa(credentials.username + ":" + credentials.password)} : {};
$http.get('/login/owner', {headers: headers}).success(function (data) {
$rootScope.authenticated = !!data.basicUserInfo.name;
callback && callback();
}).error(function () {
$rootScope.authenticated = false;
callback && callback();
});
};
In module confid I added X-Requested-With header to prevent WWW-Authenticate coming back:
angular.module([...]).config(function ($httpProvider) {
$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
});
The problem is that in response I getting WWW-Authenticate: Basic realm="xxx" header which makes browser to show the log in dialog.
So how can I make proper login with AngulrJS & Grails?
PS
I'm using this tutorial: https://spring.io/guides/tutorials/spring-security-and-angular-js/ to develop login in Grails.

Facebook login on mobile via Cordova/Angular/Ionic

I'm working in a hybrid app to report potholes in our city.
The user can register to the app in a classic way (fill forms) or via one of the social networks (facebook, gmail, twitter).
The system works through a server on rails and a mobile app as a client(ionic/angular)
On the server side we have solved this, the user can make sign up / sign in to the page in the way that they want.
But with have several problems with the app, the app does nothing when you make click to the button of "sign in via facebook"
this is the style it is organized.
app/
plugins/
InAppBrowser
www/
css/
js/
controllers/
splash.js
map.js
tabs.js
services/
users.js
notifications.js
app.js
utils.js
lib/
angular/
ng-cordova-oauth/
ngCordova/
ionic/
templates/
map.html
splash.html
tabs.html
index.html
The splash.js controller is in charge of making the login function.
angular.module('app')
.controller('SplashCtrl', function($scope, User, $state, $ionicPopup, $auth, $cordovaOauth) {
$scope.session_id = User.session_id;
$scope.facebookLogin = function() {
alert("flag1");
User.fbSignIn().then(function() {
alert("flag2");
User.fbGetData().then(function() {
alert("flag3");
User.fbAuth().then(function() {
alert("flag4");
// Detect if it is a sign in or sign up
if (User.username) {
console.log('Controller reports successfull social login.');
$state.go('tab.map');
} else {
// Open finish signup modal
console.log('Contorller reports this is a new user');
$state.go('finish_signup');
}
}, function() {
alert("flag5");
$ionicPopup.alert({
title: '<b>App</b>',
template: 'Credenciales no vĂ¡lidas, vuelve a intentar.',
okText: 'Aceptar',
okType: 'button-energized'
})
});
}, function() {
alert("flag6");
// alert('Could not get your Facebook data...');
});
}, function() {
alert("flag7");
// alert('Could not sign you into Facebook...');
});
}
})
I put some alert flags through the functions to see where the app get stuck.
I can only see the 'flag1' alert on the phone.Then nothing happens
the controller communicates with the service users.js
I put the code on pastebin because it's too long
users.js service
The client must request an access token to the server and then compare in SplashCtrl if they got the token access the app redirects the user to tabs.html template that would be the main page.
The console server shows nothing. So the request application never communicates to the server. Eventhough the 'CLIENTS' and 'SERVER' variables are already declared in app.js
.constant('SERVER', {
url: 'https://rails-tutorial-denialtorres.c9.io'
})
.constant('CLIENTS', {
facebook: 'fb Api'
});
I can only logging of the server if I put a username and password in a traditional way
preview
I hope you can help me with this guys
regards and thanks!!
you try this ?
http://ngcordova.com/docs/plugins/oauth/
I tested and work very well, easy to implement, and also you can parse the json with token (and use server side if you need)
Remember this work ONLY with real device, not with Ionic Serve.
In case you looking for custom facebook login (javascript), try this code :
facebookStatus = function() {
var dfd = new jQuery.Deferred();
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
dfd.resolve({status: response.status, token: response.authResponse.accessToken});
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook, //but not connected to the app
dfd.resolve({status: response.status, token: false});
} else {
// the user isn't even logged in to Facebook.
FB.login(function(response) {
if (response.status=="connected"){
var token = response.authResponse.accessToken;
dfd.resolve({status: response.status, token: response.authResponse.accessToken});
}
}, {scope:'YOUR SCOPE HERE'});
}
});
return dfd.promise();
};
*Remember if you use this code, to add on index page the standard Facebook App details (something like)
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : 'YOUR APP ID',
status : true, // check login status
cookie : false, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
};
// Load the SDK asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
When I install the cordova plugin with add org.apache.cordova.inappbrowser
The id for the plugin is cordova-plugin-inappbrowser and the ngcordova.js library is looking for org.apache.cordova.inappbrowser
Changing those lines on ngcordova.js solves the issue.

Resources