Linkedin Javascript SDK catch expired token - javascript

We use Linkedin to have our members "Sign in" to access our back end. We only use the Javascript SDK as our website is very simple. We have many users that come back after 6-months and receive the following error instead of seeing the "Sign in with Linkedin" button:
[unauthorized]. Expired access token. Timestamp: 1501736450333
Since we don't have a backend to renew the tokens in batch prior to their 60 day expiration, a simple solution for our members is to Logout first, see the "Log in" button, and sign-in again -- that we know re validates the token.
Question: I don't know how to "catch" the error or identify when a user has an expired token with Linkenin's Javascript SDK.
<script type="text/javascript" src="//platform.linkedin.com/in.js">
api_key: XXXXXXXXXXXXX
onLoad: li_OnFrameworkLoad
authorize: true
</script>
...
<script type="text/javascript">
function li_OnFrameworkLoad() {
IN.Event.on(IN, "auth", li_OnAuth);
}
</script>
I have tried using the:
if (!IN.User.isAuthorized()) {
li_Logout();
}
method, but that doesn't work as
IN.Event.on(IN, "auth", li_OnAuth);
will trigger the "[unauthorized]..." message without first calling the "li_OnAuth" callback.
Reproducing: The worst part of this bug is that I can't seem to reproduce it on my local machine, if you know how to trigger an "[unauthorized]. Expired access token..." bug please do let me know.
Solution?: One possible recent solution is using:
<script type="text/javascript">
window.onerror = function(e) {
if (e == 'Script error.') {
console.log('There is a chace IN.init failed.');
}
}
</script>
But I am not very familiar with "window.onerror" and I am not sure if the Linkedin Javascript SDK will trigger an error if the token is expired, etc. Basically I just need to catch the error and call my "li_logout();" function to Log Out the user from Linkedin and refresh the page.
Thank you much, any wisdom would be highly appreciated.

Related

Paypal subscription confusion

I've been working on a project for over 2 years and I am finally ready to launch, but first I have to integrate a subscription based payment option so I can actually make some money off of this thing. I've been trying to integrate paypal subscriptions for like 2 months now and it's a major hold up. Also, this is causing me to go bald. Please help!
I think it would be really helpful to have a kind of overview explanation describing the definate process that I need to follow in order to accept subscription based payments. The level of detail would include where each of the steps should occure; frontend or backend (server), and any intermediate steps necessary to understand what data is flowing where. Second to that, the actual code for the smart button with some comments indicating what part of the process the code is addressing. Maybe that's a lot to ask, but it would be greatly appreciated and I believe a great resource for others looking to do the same as I am currently.
At the moment, my primary issue is that when I set the URL pointing to the paypal SDK in my script take to include &intent=authorize, I am told in the error message that I need to set intent=capture, but when I set intent=capture I'm told I need to set intent=authorize. So now I'm confused as to what I am supposed to do; authorize the transaction or capture the transaction. I've been provided links to 2 different guides on the paypal developer website from paypal technical support which seem to contradict each other - the first link said nothing about capture or authorizing payments, the 2nd link does. But I don't understand the context on the second link. The first link is all client side, the second link is on client side and server side. Why would these intent=ca[ture/authorize be needed? I thought that once someone agrees to and completes signing up for a subscription, and I've captured their subscription id, that I don't need to do anything else in order to receive funds on the monthly basis setup in my plan, I would only have to query the paypal APIs to find out if they've paid up upon the customer signing in to my service.
I have setup a sandbox account and I've created a product and a plan. I've got the smart button rendering with my plan ID after the customer logs in.
If I set intent=capture in the paypal SDK script URL, the paypal window opens, you select payment and agree, and then I get this error in my console:
env: "sandbox"
err: "Error: Use intent=authorize to use client-side authorize"
referer: "localhost:88"
timestamp: "1589939180937"
uid: "fad5852fa3_mde6ndq6mdu"
But if I set intent=authorize, I click the smart button, the paypal window shows up and disappears quickly and then I get this error:
buttonSessionID: "e3bf3c6c3d_mdi6mdi6mzq"
env: "sandbox"
err: "Uncaught Error: Expected intent from order api call to be authorize, got capture. Please ensure you are passing intent=capture to the sdk url"
referer: "www.sandbox.paypal.com"
sessionID: "fad5852fa3_mde6ndq6mdu"
timestamp: "1589940160835"
Here is my code:
<!DOCTYPE html>
<head>
<!-- Add meta tags for mobile and IE -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
</head>
<body>
<!-- Set up a container element for the button -->
<div id="paypal-button-container"></div>
<!-- Include the PayPal JavaScript SDK -->
<script
src="https://www.paypal.com/sdk/js?client-id=CLIENT-ID-HERE&currency=USD&vault=true&intent=capture"></script>
<script>
let planid = 'P-48A5110983270751ML2P5NVI';
// Render the PayPal button into #paypal-button-container
paypal.Buttons({
// Set up the transaction
createSubscription: function (data, actions) {
// Create Subscription
return actions.subscription.create({ "plan_id": planid });
},
onApprove: function (data, actions) {
// Authorize the transaction
actions.order.authorize().then(function (authorization) {
// Get the authorization id
var authorizationID = authorization.purchase_units[0]
.payments.authorizations[0].id
// Call your server to validate and capture the transaction
return fetch('/api/company/paypal-transaction-complete', {
method: 'post',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
orderID: data.orderID,
authorizationID: authorizationID,
data: data,
authorization: authorization
})
});
});
}
// Finalize the transaction? Which one do I want, to authorize or to finalize??
// onApprove: function (data, actions) {
// let result = actions.subscription.get();
// return actions.order.capture().then(function(details) {
// // Do I need to send something to my server here?
// // Show a success message to the buyer
// alert('Transaction completed by ' + details.payer.name.given_name + '!');
// });
// }
}).render('#paypal-button-container');
</script>
</body>
Thanks in advance for your help. This has been a most frustrating project.
Why are you using intent=authorize / intent=capture in the URL with subscriptions?
Why are you using actions.order.authorize() with subscriptions?
Who told you to do either of these things with subscriptions?
Please see the Subscriptions Integration guide, which does not include any mention of those things.

Refresh Office365 Authorization Token from Javascript

I currently have an issue with one of my apps.
The issue is that a user can keep the page open for a prolonged period of time before entering any data, so occasionally, when they enter data and hit the submit button, they are redirected to o365 for authentication and therefore lose the entered data.
I have all the standard authentication working for the app. However, i believe in order to do this, i would need to get a refreshed token in javascript when the submit button is clicked, and send this token to an api method in order to give access.
Is this possible and does anybody know how to go about it?
It is an MVC ASP.NET application using Owin O365 security with Microsoft Azure AD.
I am not sure what information or code snippets would be relevant here so if there is anything i can provide, please ask.
I have found multiple examples of getting tokens etc with angular, however, this is not an SPA and does not use angular.
Many Thanks in advance.
UPDATE
I have attempted to retrieve a token using ADAL JS using the following code but it doesnt seem to recognise the AuthorizationContext(config) call:
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.0/js/adal.min.js"></script>
$('#btnSubmit').on('click', function (e) {
e.preventDefault();
CheckUserAuthorised();
});
function CheckUserAuthorised() {
window.config = {
instance: 'https://login.microsoftonline.com/',
tenant: '##################',
clientId: '###################',
postLogoutRedirectUri: window.location.origin,
cacheLocation: 'localStorage'
};
var authContext = new AuthorizationContext(config); //THIS LINE FAILS
var user = authContext.getCachedUser();
if (!user) {
alert("User Not Authorised");
authContext.login();
}
else {
alert('User Authorized');
}
}
This gives the following error in console:
'AuthorizationContext' is undefined
UPDATE
I have no got passed the undefined error. This was because i was calling AuthorizationContext rather than AuthenticationContext. Schoolboy error. However now, whenever i check the user property of the context, it is always null. And i do not know a way around this as the context is initialised on page load.
There is a lack of a step in your code, here is a simple code sample, hope it will help you:
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.10/js/adal.min.js"></script>
<body>
login
access token
get user
</body>
<script type="text/javascript">
var configOptions = {
tenant: "<tenant_id>", // Optional by default, it sends common
clientId: "<client_id>",
postLogoutRedirectUri: window.location.origin,
}
window.authContext = new AuthenticationContext(configOptions);
var isCallback = authContext.isCallback(window.location.hash);
authContext.handleWindowCallback();
function getToken(){
authContext.acquireToken("https://graph.microsoft.com",function(error, token){
console.log(error);
console.log(token);
})
}
function login(){
authContext.login();
}
function getUser(){
var user = authContext.getCachedUser();
console.log(user);
}
</script>
The code sample is from the answer of No 'Access-Control-Allow-Origin' header with Microsoft Online Auth. The issues are different but they are in the same scenario.
any further concern, please feel free to let me know.
I found a similar example on the web and your problem seems to be related to the object you are instantiating.
Instead of
new AuthorizationContext(window.config);
try
new AuthenticationContext(window.config);
The code ran just fine showing that the user was not authenticated.

LinkedIn Login with basic example not working

I would like to add the possibility of LinkedIn login to my project. I followed the tutorial given on the LinkedIn developer page and ended up with the following code, really basic stuff from that tutorial:
<!-- linkedin login -->
<script type="text/javascript" src="//platform.linkedin.com/in.js">
api_key: [MY_API_KEY] {~n}
authorize: false {~n}
onLoad: onLinkedInLoad {~n}
</script>
<!-- linkedin login play -->
<script type="text/javascript">
// Setup an event listener to make an API call once auth is complete
function onLinkedInLoad() {
IN.Event.on(IN, "auth", getProfileData);
}
// Handle the successful return from the API call
function onSuccess(data) {
console.log(data);
}
// Handle an error response from the API call
function onError(error) {
console.log(error);
}
// Use the API call wrapper to request the member's basic profile data
function getProfileData() {
IN.API.Raw("/people/~").result(onSuccess).error(onError);
}
</script>
Don't mind the {~n} as I'm using dust.js to render the page and I need them to pass the arguments to the LinkedIn script.
So, the login button appears, this means that LinkedIn was able to connect to my API key correctly, but the Chrome console gives me the following error: Uncaught Error: Could not execute 'onLinkedInLoad'. Please provide a valid function for callback.. Since this is the example given on the tutorial page, I don't know what can be wrong with it. Even if I declare the block of LinkedIn login functions before the call to the LinkedIn in.js, I get the same error.
I think it is a very easy mistake to spot, but I cannot really tell what am I doing wrong.
This is happening cause you are calling onLinkedInLoad() in head section,and if you are working on multiple pages..it will be called on the every page even if it doesn't have data from API call(or simply you are not making any call on the page where this error is appearing).
Try this`
// Removing event listener by calling IN.Event.on() outside of onLinkedInLoad()
IN.Event.on(IN, "auth", getProfileData);
// Handle the successful return from the API call
function onSuccess(data) {
console.log(data);
}
// Handle an error response from the API call
function onError(error) {
console.log(error);
}
// Use the API call wrapper to request the member's basic profile data
function getProfileData() {
IN.API.Raw("/people/~").result(onSuccess).error(onError);
}
`
And Yes remove " onLoad: onLinkedInLoad {~n}" from first script call

Apply by LinkedIn Button, 400 error bad request

I'm trying to add an 'Apply by LinkedIn' button to an expressionengine site. I've created my app on LinkedIn and am using the JS SDK and have followed the guide in order to do so. My code is below:
<script type="text/javascript" src="//platform.linkedin.com/in.js">
api_key: MY CLIENT ID
authorize: true
onLoad: onLinkedInLoad
</script>
<script type="text/javascript">
// Setup an event listener to make an API call once auth is complete
function onLinkedInLoad() {
IN.Event.on(IN, "auth", getProfileData);
}
// Handle the successful return from the API call
function onSuccess(data) {
console.log(data);
}
// Handle an error response from the API call
function onError(error) {
console.log(error);
}
// Use the API call wrapper to request the member's profile data
function getProfileData() {
IN.API.Raw("/people/~:(id, first-name, skills, educations, languages, twitter-accounts)")
.result(onSuccess).error(onError);
}
</script>
I've added the button markup as suggested:
<script type="in/Login"></script>
SO the button is displayed and upon click I'm presented with my account to authorise the app, however, upon authenticating, the button disappears and I get the following error:
Failed to load resource: the server responded with a status of 400 (Bad Request)
ObjecterrorCode: 0message: "Unknown field {_first-name} in resource {Person}"requestId: "LT59BVDVU2"status: 400timestamp: 1436259208629__proto__: Object
Thanks!
Use camelcasing instead of dashes:
IN.API.Raw("/people/~:(id, firstName, skills, educations, languages, twitter-accounts)")

Facebook jQuery Logout using Logout URL and Access Token

When a user logs out of my site, unless they also log out of their Facebook account, they remain logged in to my site.
I'd like to comply with point 6 of this policy, so how can I log my users out of my site and out of their Facebook accounts for security https://developers.facebook.com/policy/
I have the following code bound to my login button and it's not working - the user is still logged in to FB after clicking. My console shows that the var accessToken is not defined but I'm not sure why. I'm sure I'm doing something fundamentally wrong, would really appreciate some help!
<script src="http://connect.facebook.net/en_US/all.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$(".logout").click(function () {
FB.init({appId : <?php echo $this->config->item('facebook_appid');?>,
status : true,
cookie : true,
oauth : true,
frictionlessRequests: true});
FB.login(function(response) {
if (response.authResponse) {
console.log(response.authResponse.accessToken);
var accessToken = response.authResponse.accessToken;
}
});
window.location.replace("https://www.facebook.com/logout.php?confirm=1&next=http://www.mysite.com&access_token="+accessToken+"");
});
});
</script>
<div id="fb-root"></div>
To log out of Facebook, you need to use the FB.logout() method.
If you have already called the FB.init() and the FB.login() methods, you don't need to call these again in your click function.

Categories

Resources