Facebook on PhoneGap/Cordova -- File protocol? - javascript

Have searched everywhere for this without luck. I'm getting this error when running PhoneGap app on device (works fine in browser):
Given URL is not allowed by the Application configuration.: One or more of the given URLs is not allowed by the App's settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App's domains.
This is because I haven't added the host to the facebook app configuration. BUT, PhoneGap/Cordova accesses the app through the file:/// protocol, so there's no domain for me to add to Facebook.
Potential options: 1) Figure out how to use a cordova native plugin (this is hard because we're using Parse), 2) Switch Cordova to use localhost instead of file:// (not sure how to do this).

I've been down this road and ultimately went with option #1. Since we're not really dealing with a website there is no domain to add. Cordova needs to use file:// I don't think there is any way around it. The trick with using the plugin is keeping the login status in sync with Parse (use Parse.FacebookUtils.logIn). He's some code that should help you out. This is how I check the login status:
try {
console.log("Trying to get FB login status");
return FB.getLoginStatus(function(response) {
var accessToken, currentView, expDate, facebookAuthData, uid, user;
console.log(response);
if (response.status === "connected") {
uid = response.authResponse.userID;
accessToken = response.authResponse.accessToken;
console.log("Logged in!");
user = Parse.User.current();
if (user != null) {
console.log("we have a user");
} else {
console.log("we don't have a user... need to login with parse");
expDate = new Date(response.authResponse.expirationTime);
facebookAuthData = {
id: response.authResponse.userID + "",
access_token: response.authResponse.accessToken,
expiration_date: expDate.toISOString()
};
Parse.FacebookUtils.logIn(facebookAuthData, {
success: function(_user) {
return console.log("Logged in with Parse!");
},
error: function(error1, error2) {
return console.log("Unable to create/login as Facebook user");
}
});
}
} else {
// not logged in to fb...
}
});
} catch (e) {
return console.log(e);
}
Here's how I handle logins:
return FB.Event.subscribe("auth.authResponseChange", function(response) {
var expDate, facebookAuthData;
if (response.status === "connected") {
console.log(response.status);
try {
expDate = new Date(response.authResponse.expirationTime);
facebookAuthData = {
id: response.authResponse.userID + "",
access_token: response.authResponse.accessToken,
expiration_date: expDate.toISOString()
};
return Parse.FacebookUtils.logIn(facebookAuthData, {
success: function(_user) {
//return window.location.hash = "loginsuccess";
},
error: function(error1, error2) {
console.log("Unable to create/login to as Facebook user");
}
});
} catch (ex) {
return console.log("parse login error " + ex);
}
} else if (response.status === "not_authorized") {
// handle not auth event
} else {
// take them home?
}
});
}

Related

MSAL.js infinite loop, not calling Microsoft Sign-In Page

I am trying really hard to make MSAL work with Vanilla JavaScript, but it just doesn't work.
Whenever I am trying to click the Sign In button on the Login Page, the Login page just refreshes and nothing happens, the Microsoft Sign In Page is not being shown.
Also no errors are logged to console.
After clicking the Sign In button for like 200 or more times and page refreshing that many times, the Microsoft Sign In page shows up and then it works fine.
Script reference
<script type="text/javascript" src="https://alcdn.msauth.net/lib/1.4.4/js/msal.js" integrity="sha384-fTmwCjhRA6zShZq8Ow5ZkbWwmgp8En46qW6yWpNEkp37MkV50I/V2wjzlEkQ8eWD" crossorigin="anonymous"></script>
JS MSAL code
//Config
const msalConfig = {
auth: {
clientId: "{Client ID}",
authority: "{Authority}",
redirectUri: "{Base App URL}/Dashboard", //This URL is registered in Microsoft AAD
navigateToLoginRequestUrl: false
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true,
}
};
//Login Request Object
const loginRequest = {
scopes: ["User.Read"],
prompt: 'login',
};
//Initialize MSAL
var myMSALObj = new Msal.UserAgentApplication(msalConfig);
myMSALObj.handleRedirectCallback(authRedirectCallBack);
//Handle Callback
function authRedirectCallBack(error, response) {
if (error) {
console.log(error);
} else {
if (response.tokenType === "id_token") {
console.log("id_token acquired at: " + new Date().toString());
if (myMSALObj.getAccount()) {
showWelcomeMessage(myMSALObj.getAccount());
}
} else if (response.tokenType === "access_token") {
console.log("access_token acquired at: " + new Date().toString());
accessToken = response.accessToken;
try {
callMSGraph(graphConfig.graphMailEndpoint, accessToken, updateUI);
} catch (err) {
console.log(err)
}
} else {
console.log("token type is:" + response.tokenType);
}
}
}
$(document).on("click", "#btn-testing-msal", function () {
myMSALObj.loginRedirect(loginRequest);
});
Any help will be appreciated, Thanks in advance
Debug your frontend code like this, just trying to make sure where caused your problem, and it may have some help:

silent sign in using oidc client with identity server 4

I'm trying to implement silent login in oidc-client to use with Angular 2
How can use oidc client to silently check if user is already logged in (idsvr4) and display the login details.
the following code works, but i need to refresh the page
idsvr 4 client
// JavaScript Client
new Client
{
ClientId = "js",
ClientName = "JavaScript Client",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
RedirectUris = { "http://localhost:5002/callback.html" },
PostLogoutRedirectUris = { "http://localhost:5002/index.html" },
AllowedCorsOrigins = { "http://localhost:5002" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api1",
},
RequireConsent=false,
AllowOfflineAccess = true
}
client side code
var config = {
authority: "http://localhost:5000",
client_id: "js",
redirect_uri: "http://localhost:5002/callback.html",
silent_redirect_uri: "http://localhost:5002/callback.html",
response_type: "id_token token",
scope: "openid profile api1 offline_access",
post_logout_redirect_uri: "http://localhost:5002/index.html",
// Number of seconds before the token expires to trigger
// the `tokenExpiring` event
accessTokenExpiringNotificationTime: 4,
// Do we want to renew the access token automatically when it's
// about to expire?
automaticSilentRenew: false,
// Do we want to filter OIDC protocal-specific claims from the response?
filterProtocolClaims: false,
// use localStorage
userStore: new Oidc.WebStorageStateStore({ store: window.localStorage })
};
var mgr = new Oidc.UserManager(config);
// You can hook a logger to the library.
// Conveniently, the methods exposed by the logger match
// the `console` object
Oidc.Log.logger = console;
// When a user logs in successfully or a token is renewed, the `userLoaded`
// event is fired. the `addUserLoaded` method allows to register a callback to
// that event
mgr.events.addUserLoaded(function (loadedUser) {
console.log("$$$$$$$$$$$$$$$$$$$$$$$ added");
});
// Same mechanism for when the automatic renewal of a token fails
mgr.events.addSilentRenewError(function (error) {
console.error('$$$$$$$$$$$$$$$$$$$$$$$ error while renewing the access token', error);
});
// When the automatic session management feature detects a change in
// the user session state, the `userSignedOut` event is fired.
mgr.events.addUserSignedOut(function () {
alert('The user has signed out');
});
mgr.getUser().then(function (user) {
if (user) {
log("User logged in", user.profile);
}
else {
log("User not logged in");
// log("*****************************************************");
mgr.signinSilent()
.then(function (newUser) {
console.log("doneeeeeeeeeeeeeeeeeeeee");
console.log(newUser);
console.log(newUser.profile);
}).catch(function (e) {
console.log("======== " + e);
});;
mgr.signinSilentCallback().then(function (newUser) {
console.log("doneeeeeeeeeeeeeeeeeeeee");
console.log(newUser);
console.log(newUser.profile);
}).catch(function (e) {
console.log("&&&&&&&&&&&& "+e);
});
}
});
no user is getting returned in either methods of silentSignIn
I want to get if user is logged in and retrieve the information as soon as the client is open.
Or if there's a better way to do this in angular 2 then it's better.
I had the same problem. I managed to solve it by using the following signin() method and by managing the process sign in response:
function signin() {
manager.createSigninRequest().then(function (req) {
window.location = req.url;
}).catch(function (err) {
log(err);
});
}
manager.processSigninResponse().then(function (response) {
log("signin response success", response);
}).catch(function (err) {
});
manager.events.addUserLoaded(function (user) {
manager.getUser().then(function () {
log("User logged in", user.profile);
});
});
function api() {
mgr.getUser().then(function (user) {
var url = "http://localhost:5001/identity";
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = function () {
log(xhr.status, JSON.parse(xhr.responseText));
}
xhr.setRequestHeader("Authorization", "Bearer " + idToken);
xhr.send();
});
}

How to preserve user logged in using Parse JS and Facebook SDK

I'm using Parse Server + Parse JS Sdk to handle user login through Facebook. Everything works fine until I refresh web browser. What data should I store after login process is done? I belive that FB AccessToken is important to keep Facebook Session, but what about Parse Session.
Current code:
login: function (callback) {
console.log('loggin in...')
Parse.FacebookUtils.logIn('user_likes,email', {
success: function (parseUser) {
if (!parseUser.existed()) {
console.log('signed up and logged in!')
} else {
console.log('logged in!')
}
console.log('parse user is: ', parseUser.id)
if (callback) { callback() }
},
error: function (parseUser, error) {
console.log('login cancelled: ', error.message)
}
})
}
You don't need to manually store anything. You can use the parse function:
Parse.User.current()
To see if there is already a user logged-in.
We made this function:
function userAuthenticated(){
if(Parse.User.current() === null){
return false;
}
if(Parse.User.current().authenticated()){
return true;
}
else{
return false
}
}

Issue with Wizcorp phonegap facebook plugin

We are trying to integrate the Wizcorp PhoneGap facebook plugin (https://github.com/Wizcorp/phonegap-facebook-plugin) to support the login process in a new Ionic app.
The login with Facebook seems to work just fine for a new user. The problem is when the users sign off and try to log back in he get the error:
Facebook error: Session was closed and not closed normally
what are we doing wrong here ?
Here's the code that we are using right now:
function fbLogin() {
facebookConnectPlugin.login(['email'], function (response) {
alert("Login Successfull");
alert(JSON.stringify(response));
}, function (error) {
alert("Login ERROR");
alert(JSON.stringify(error));
})
}
function getDetails() {
facebookConnectPlugin.getLoginStatus(function (response) {
if (response.status === 'connected') {
alert("You're connected!");
var userID = response.authResponse.userID;
facebookConnectPlugin.api('/' + response.authResponse.userID + '?fields=id,name,picture.width(400).height(400)', [], function (result) {
alert(JSON.stringify(result));
})
} else if (response.status === 'not_authorized') {
alert("Not Autherized!");
} else {
alert("You're not loggin into Facebook!");
}
});
}
function fbLogout() {
facebookConnectPlugin.logout(function (response) {
alert("Logout success");
alert(JSON.stringify(response));
}, function (error) {
alert("Logout ERROR");
alert(JSON.stringify(error));
})
}
We have checked this link:
https://github.com/Wizcorp/phonegap-facebook-plugin/blob/master/TROUBLESHOOTING.md#no-reply-from-login
however when we try to implement the code below - we get an error
Tyeperror cordova.getActivity is not a function
PackageInfo info = cordova.getActivity().getPackageManager().getPackageInfo("com.goapes.golearn", PackageManager.GET_SIGNATURES);
The above link tells us that we need another Hash Key in our Facebook App Dashboard, so is there another way of obtaining this Hash?
I think you better to try this plugin. Because I developed a app using this plugin and it's in production now. :)
here check this

How to handle Callback/Redirects from dpd-passport via Google strategy?

I am building a project using Deployd for assistance with my API, and dpd-passport for authentication.
I seem to have everything authenticating, with session keys behind handed out and users authentication through Google, but I am having trouble with my redirectURLs, as well as translating the callback page I am returned with.
I have dug into the dpd-passport/index.js file, and I believe this is the relevant information:
var sendResponse = function(ctx, err, config) {
var sessionData = ctx.session.data;
var returnUrl = (ctx.req.cookies && ctx.req.cookies.get('_passportReturnUrl')) || null;
if(returnUrl) {
var redirectURL = url.parse(returnUrl, true);
// only append if not disabled
if(!config.disableReturnParams) {
// delete search so that query is used
delete redirectURL.search;
// make sure query is inited
redirectURL.query = redirectURL.query || {};
if(err) {
redirectURL.query.success = false;
redirectURL.query.error = err;
} else {
// append user + session id to the redirect url
redirectURL.query.success = true;
if(!config.disableSessionId) {
redirectURL.query.sid = sessionData.id;
redirectURL.query.uid = sessionData.uid;
}
}
}
var redirectURLString = '';
try {
redirectURLString = url.format(redirectURL);
} catch(ex) {
console.warn('An error happened while formatting the redirectURL', ex);
}
// redirect the user
ctx.res.setHeader("Location", redirectURLString);
ctx.res.statusCode = 302;
ctx.done(null, 'This page has moved to ' + redirectURLString);
} else {
if(err) {
ctx.res.statusCode = 401;
console.error(err);
return ctx.done('bad credentials');
} else {
ctx.done(err, { path: sessionData.path, id: sessionData.id, uid: sessionData.uid });
}
}
};
After successfully authenticating, I am given a returnUrl of:
http://localhost:3000/auth/google/callback?code=4/l4o-H2F4QKJ5tdKbVbGfWygTGRvhHgr9zrHWImFFKdM#
with an body of:
{"path":"/users","id":"d03c0faccfe41134c193266afef979c5af33adf935aeff45844b0f9473dee4ab1fbd1114240e13ea9a542785da3845cfec984e3a5b8cb188d6c595b6fc39a726","uid":"747f97a9bcfa9811"}
which seems to me like my results are hitting the final else statement in the topmost code block.
If this is true, then my returnUrl is NULL.
Tracing back the returnUrl code in the dpd-passport file, it looks like it should be grabbing this from cookies in the follow snippet:
if(ctx.query.redirectURL && this.config.allowedRedirectURLs) {
try {
this.regEx = this.regEx || new RegExp(this.config.allowedRedirectURLs, 'i');
if(ctx.query.redirectURL.match(this.regEx)) {
// save this info into the users session, so that we can access it later (even if the user was redirected to facebook)
if (ctx.res.cookies) ctx.res.cookies.set('_passportReturnUrl', ctx.query.redirectURL);
} else {
debug(ctx.query.redirectURL, 'did not match', this.config.allowedRedirectURLs);
}
} catch(ex) {
debug('Error parsing RedirectURL Regex!', ex);
}
}
To add to this, I have my allowedRedirectUrls in the config as:
^http://localhost:3000/.*$
I am at a loss and am hoping there is something obvious that I am missing.
I have seen the passport routes and authentication strategies similar to the following, but have been unsuccessful in implementing this into dpd-passport:
app.get('/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/');
});
To add to this all, I am using ui-router/AngularJS.
You have to supply the redirectURL to dpd-passport through the link that starts the oauth procedure:
http://localhost:2403/auth/google?redirectURL=http://localhost

Categories

Resources