MobileServices.web.js unauthorized api call - javascript

When I leave my WinJS app dormant for a while and then come back to it, and i click on a button, for some reason my calls to my backend aren't working.
I get an "Unauthorized" error from the server.
How do I modify the invokeApi so that it reauthenticates the user or something?
Does anybody have any experience using mobileservices.web.js and how to keep the end user perpetually logged in without having to reauthenticate themselves?
Thankyou.
client.invokeApi("getTopForumsTotal", {
method: "post"
}).then(function (results) {
// do something
}, function (error) {
WinJS.log(error);
});
I use winjs mobileService to authenticate the user.
client.login("microsoftaccount").done(function (results) {
// Create a credential for the returned user.
credential = new Windows.Security.Credentials.PasswordCredential("myapp", results.userId, results.mobileServiceAuthenticationToken);
vault.add(credential);
completeDispatcher();
}, function (error) {
WinJS.log(JSON.stringify(error));
errorDispatcher(error);
});
and this is what I use to refresh the end users token.
client._request("GET", "/.auth/refresh", null, null, {
accept: "application/json",
"ZUMO-API-VERSION": "2.0.0"
}, [], (error, response) => {
if (!error) {
var userObject = JSON.parse(response.responseText)
if (userObject.authenticationToken) {
client.currentUser.mobileServiceAuthenticationToken = userObject.authenticationToken;
testCall().done(function (success) {
if (success) {
credential = new Windows.Security.Credentials.PasswordCredential("myapp", userObject.user.userId, userObject.authenticationToken);
vault.add(credential);
authenticated = true;
completeDispatcher();
}
else errorDispatcher('testCall API does not exist');
});
}
else errorDispatcher('no authentication token returned');
}
else errorDispatcher(error);
});

Instead of wrapping a promise around every API call I just incorporated an idle routine on the client that refreshes the user token when they return to the app as well as refreshes the token every 59 seconds that they are idle.
So for all intense and purposes they will always have an valid token or perpetual state.
$(document).idle({
onIdle: function () {
// refresh user token
if (User.Person !== null)
User.Person.reauthenticate().done();
},
onActive: function () {
// when the user returns refresh their token 1 more time
if (User.Person !== null)
User.Person.reauthenticate().done();
},
idle: 59000, // 59 seconds
recurIdleCall: true // will keep refreshing every 59 seconds
});
https://github.com/kidh0/jquery.idle

Related

Why does this javascript code not redirect the user after the metamask transaction?

I want to make a javascript code that does a metamask transaction and redirects the user to another page after the transation is completed. How easy this may sound, I can not figure it out.
My current code lets the user complete the transaction, but it does not redirect the user to another page. Instead, it gives this error: "MetaMask - RPC Error: invalid argument 0: json: cannot unmarshal non-string into Go value of type common.Hash"
I have looked it up, but I could not find any possible fix for my problem.
This is my code:
try {
// send the transaction
ethereum.send({
method: 'eth_sendTransaction',
params: [
{
to: contractAddress,
from: userAddress,
value: amt
},
],
}, (error, transactionHash) => {
if (error) {
console.error(error);
} else {
// check the status of the transaction using the transaction hash
ethereum.request({
method: 'eth_getTransactionReceipt',
params: [transactionHash],
}).then((receipt) => {
// check if the transaction was successful
if (receipt.status === '0x1') {
console.log(`Transaction was successful`);
// redirect to another page
window.location.href = "page.php";
} else {
console.log(`Transaction failed`);
}
}).catch((error) => {
// This is the line of code the error is assigned to:
console.error(error);
});
}
});
} catch (error) {
console.error(error);
}
});
} else {
document.getElementById("bericht").innerHTML = "Install Metamask before you continue";
return;
}
I have tried looking the error up on internet, but nothing significant showed up. Could anyone help? Thank you in advance!

Refresh JWT once across mulitple browser windows/tabs

I have some code set up that refreshes JWT tokens successfully. A problem arises when the user opens multiple tabs, and they all trigger to refresh the tokens at the same time. Each tab gets new tokens that are different from each other and only the latest one will actually work. How can I run the token refresh function once across all browser tabs?
I figured this out. First think first you should store your token in local storage. Then when you request refresh token you should set first the Authorization header with the token in local storage then request it to the server. this is mandatory for getting up to date token. after you request, you will get response new token from server. set the new token to local storage and set the Authorization header (as default) with the new token. This way works for me.
created() {
const vm = this;
axios.interceptors.response.use(
function(response) {
if (response.headers.authorization != undefined) {
localStorage.setItem(
"token",
response.headers.authorization.replace("Bearer ", "")
);
axios.defaults.headers.common["Authorization"] =
response.headers.authorization;
}
return response.data;
},
function(error) {
if (error.response.status == 401) {
vm.$store.dispatch("logout").then(() => {
this.$router.push("/login").catch(err => {});
});
}
return Promise.reject(error);
}
);
},
async mounted() {
while (this.$store.getters.isLoggedIn) {
await new Promise(resolve => setTimeout(resolve, 60000)).then(v => {
axios.defaults.headers.common["Authorization"] =
"Bearer " + localStorage.getItem("token");
axios({ method: "get", url: "/login/refresh" });
});
}
}

Alexa intent is not waiting for the api response

We are developing alexa skill using alexa-app, in one of our intent we are trying to fetch albums from facebook and on success/failure we want alexa to respond accordingly. But intent is not waiting for FB call to complete. Below is the code snippet we are using:
function fetchAlbums(){
return new Promise(resolve =>{
FB.api("/me/albums", function (res) {
if (res && !res.error) {
// If we have data
if (res.data) {
resolve("Got Albums");
} else {
// REPORT PROBLEM WITH PARSING DATA
resolve("Error getting albums");
}
} else {
// Handle errors here.
resolve("Error hitting endpoint");
}
});
});
}
alexaApp.intent("readFeedIntent", {
"utterances": [
"read my facebook feed", "read facebook feed", "read feed"
]
},
function(request, res1) {
// Again check if we have an access token
if(request.hasSession() && !accessToken){
accessToken = request.data.session.user.accessToken;
FB.setAccessToken(accessToken);
}
if (accessToken) {
var session = request.getSession();
fetchAlbums().then(function(data){
console.log(data);
res1.say(data);
});
} else {
res1.say(noAccessToken, tryLaterText).send();
}
});
It is not throwing any errors, but Alexa is not speaking the anything where I can see the response in the console logs.
If I add: res1.say("Whatever!") at the end of function, then Alexa will speak 'Whatever' in response to this intent.
Got it solved my myself:
instead of this:
fetchAlbums().then(function(data){
console.log(data);
res1.say(data);
})
you have to return it, like:
return fetchAlbums().then(function(data){
console.log(data);
res1.say(data);
})

AWS Cognito: How should I handle PasswordResetRequiredException

I have clicked "Reset Password" in Cognito and now when I login I get "PasswordResetRequiredException", how should I handle this? I cant find anything in the docs that tell me what should I do?
check this http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-using-import-tool-password-reset.html
you need to call ForgotPassword()...
I figured out the exact way that you can handle this on (onFailure) callback:
// Create a cognito user instance
const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
// Trigger to authenticate the user
cognitoUser.authenticateUser(authenticationDetails, {
onFailure: function(err) {
if (err.code == "PasswordResetRequiredException") {
// Confirm user data
cognitoUser.confirmPassword(
"", // Put your verification code here
"", // Here is your new password
{
onSuccess: result => {
// Everything worked as expected
},
onFailure: err => {
// Trigger failure
}
}
);
} else {
// Trigger failure
}
}
});
I think that the specific user should have had an email or sms sent to them (if their email or phone number had been verified). In this email there should be a code which you can use with ConfirmForgotPassword
You would have to implement the newPasswordRequired callback for authenticateUser such as below:
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
// User authentication was successful
},
onFailure: function(err) {
// User authentication was not successful
},
mfaRequired: function(codeDeliveryDetails) {
// MFA is required to complete user authentication.
// Get the code from user and call
cognitoUser.sendMFACode(mfaCode, this)
},
newPasswordRequired: function(userAttributes, requiredAttributes) {
// User was signed up by an admin and must provide new
// password and required attributes, if any, to complete
// authentication.
// the api doesn't accept this field back
delete userAttributes.email_verified;
// Get these details and call
cognitoUser.completeNewPasswordChallenge(newPassword, userAttributes, this);
}
});

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();
});
}

Categories

Resources