HTTP basic authentication method to authenticate the mobile client through Datapower - authentication

I am using Mobilefirst Platform 8.0 for my app development.
How can we use HTTP basic authentication method to authenticate the mobile client through datapower. Please help me out with challnegHandler sample code.
I tried the below code in challengeHandler but Datapower always returning 401.
var DataPowerChallengeHandler = function() {
var dataPowerChallengeHandler = WL.Client.createGatewayChallengeHandler("LtpaBasedSSO");
dataPowerChallengeHandler.canHandleResponse = function(response) {
if (!response || response.responseText === null) {
return false;
}
if (response.status=="401") {{
return true;
}
return false;
};
dataPowerChallengeHandler.handleChallenge = function(response) {
document.getElementById('result').style.display = 'none';
document.getElementById('auth').style.display = 'block';
};
dataPowerChallengeHandler.submitLoginFormCallback = function(response) {
var isLoginFormResponse = dataPowerChallengeHandler.canHandleResponse(response);
if (isLoginFormResponse) {
dataPowerChallengeHandler.handleChallenge(response);
} else {
document.getElementById('result').style.display = 'block';
document.getElementById('auth').style.display = 'none';
dataPowerChallengeHandler.submitSuccess();
}
};
document.getElementById("AuthSubmitButton").addEventListener("click", function() {
var username = document.getElementById('txtusername').value;
var password = document.getElementById('txtpassword').value;
var mystring = convertBase64(username+":"+password);
var headerString = "Basic "+ mystring;
WL.Client.addGlobalHeader("Authorization",headerString);
dataPowerChallengeHandler.submitSuccess();
});
document.getElementById("logout").addEventListener("click", function() {
WLAuthorizationManager.logout("LtpaBasedSSO").then(
function() {
WL.Logger.debug("logout onSuccess");
alert("Success logout");
},
function(response) {
WL.Logger.debug("logout onFailure: " + JSON.stringify(response));
});
});
document.getElementById('AuthCancelButton').addEventListener("click",function(){
document.getElementById('result').style.display = 'block';
document.getElementById('auth').style.display = 'none';
dataPowerChallengeHandler.cancel();
});
return dataPowerChallengeHandler;
};

Your gateway challenge handler code is improper and causing all these issues.
canHandleResponse method is used to determine whether it is a challenge thrown by datapower or not. Your client code is returning true whenever there is a 401 challenge. This will return true even though for non-datapower challenges which should be corrected.
and handleChallenge is explicitly getting called in submitLoginFormCallback method which is wrong. handleChallenge will get called by SDK only when canHandleResponse method returns true.
Kindly go through this tutorial for more information on how to use gateway challenge handler in your client application.

Related

API Request in Dialogflow Fulfillment (Javascript)

So I'm trying to make a google action using Dialogflow that requires an external API. I've always used jQuery .getJSON() to make API calls, so I had no idea how to do this. After searching this up online, I found a way to do this using vanilla javascript (I also tested the way on my website and it worked fine). The code for that is below:
function loadXMLDoc() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
console.log(xmlhttp.responseText);
}
};
xmlhttp.open("GET", "https://translate.yandex.net/api/v1.5/tr.json/translate?lang=en-es&key=trnsl.1.1.20190105T052356Z.7f8f950adbfaa46e.9bb53211cb35a84da9ce6ef4b30649c6119514a4&text=eat", true);
xmlhttp.send();
}
The code worked fine on my website, but as soon as I added it to the Dialogflow, it would give me the error
XMLHttpRequest is not defined
Obviously that happened because I never defined it (using var), except it worked without me doing anything. So then, I tried adding this line
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
to the code, and it stopped giving me the error (because I defined XMLHttpRequest). But then, my code wouldn't work.
TL;DR: How can I make an external API call using Dialogflow fulfillment?
You can use https. But make sure that you upgrade to Blaze Pay(or any other plans) to make external API calls, else you will receive an error such as
Error:
Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions.
Code to make external api call,
// See https://github.com/dialogflow/dialogflow-fulfillment-nodejs
// for Dialogflow fulfillment library docs, samples, and to report issues
"use strict";
const functions = require("firebase-functions");
const { WebhookClient } = require("dialogflow-fulfillment");
const { Card, Suggestion } = require("dialogflow-fulfillment");
const https = require("https");
process.env.DEBUG = "dialogflow:debug"; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(
(request, response) => {
const agent = new WebhookClient({ request, response });
console.log(
"Dialogflow Request headers: " + JSON.stringify(request.headers)
);
console.log("Dialogflow Request body: " + JSON.stringify(request.body));
function getWeather() {
return weatherAPI()
.then(chat => {
agent.add(chat);
})
.catch(() => {
agent.add(`I'm sorry.`);
});
}
function weatherAPI() {
const url =
"https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22";
return new Promise((resolve, reject) => {
https.get(url, function(resp) {
var json = "";
resp.on("data", function(chunk) {
console.log("received JSON response: " + chunk);
json += chunk;
});
resp.on("end", function() {
let jsonData = JSON.parse(json);
let chat = "The weather is " + jsonData.weather[0].description;
resolve(chat);
});
});
});
}
function welcome(agent) {
agent.add(`Welcome to my agent!`);
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
let intentMap = new Map();
intentMap.set("Default Welcome Intent", welcome);
intentMap.set("Default Fallback Intent", fallback);
intentMap.set("Weather Intent", getWeather);
agent.handleRequest(intentMap);
}
);
This article is a diamond! It really helped to clarify what's going on and what's required in Dialogflow fullfilments.
A small suggestion is to gracefully catch the error in the connection to the webservice:
function weatherAPI() {
const url = "https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22";
return new Promise((resolve, reject) => {
https.get(url, function(resp) {
var json = "";
resp.on("data", function(chunk) {
console.log("received JSON response: " + chunk);
json += chunk;
});
resp.on("end", function() {
let jsonData = JSON.parse(json);
let chat = "The weather is " + jsonData.weather[0].description;
resolve(chat);
});
}).on("error", (err) => {
reject("Error: " + err.message);
});
});
}

Twitter OAuth Ionic 2

Its possible generate a Twitter token and secret token in Nodejs and after use it to open the browser for authenticate with "https://api.twitter.com/oauth/authenticate"?
I use this way to get the token:
app.get('/auth/twitter/token', function (req, res) {
var requestTokenUrl = 'https://api.twitter.com/oauth/request_token';
var requestTokenOauth = {
consumer_key: "2z8MTR8KAZuFafPHsEQ0ZBgo1",
consumer_secret: "ksPiaQz7ihCrOh3m4iRCsXZzQuSkkmcv4CLGiJQwREWeaQl7St"
};
request.post({
url: requestTokenUrl,
oauth: requestTokenOauth
}, function (err, response, body) {
var oauthToken = qs.parse(body);
res.send(oauthToken);
});
});
When I get this token in the client "https://api.twitter.com/oauth/authenticate?oauth_token=TOKEN" I got this problem: "This page is no longer valid. It's looks like someone already used the token information your provider, blabla.."
The problem is due to the way that I get the Token?
I'm using ng2-cordova-auth but this lib dont have twitter auth, I'm just trying to implement
This is my implementation:
"use strict";
var utility_1 = require("../utility");
var PROVIDER_NAME = "Twitter";
var Twitter = (function () {
function Twitter(options) {
this.twitterOptions = options;
this.flowUrl = ""
}
Twitter.prototype.login = function (token, tokenSecret) {
var _this = this;
return new Promise(function (resolve, reject) {
_ this.flowUrl = "https://api.twitter.com/oauth/authenticate?oauth_token="+token;
var browserRef = window.cordova.InAppBrowser.open(_this.flowUrl);
browserRef.addEventListener("loadstart", function (event) {
if ((event.url).indexOf(_this.twitterOptions.redirectUri) === 0) {
browserRef.removeEventListener("exit", function (event) { });
browserRef.close();
var parsedResponse = event.url.split("?")[1].split("&");
if (parsedResponse) {
resolve(parsedResponse);
}
else {
reject("Problem authenticating with " + PROVIDER_NAME);
}
}
});
browserRef.addEventListener("exit", function (event) {
reject("The " + PROVIDER_NAME + " sign in flow was canceled");
});
});
};
return Twitter;
}());
exports.Twitter = Twitter;
In my component/controller I make this:
//With twitterToken I get the token from NodeJs
this.API.twitterToken().subscribe(
data => {
this.twitterOAuth.login(data.oauth_token, data.oauth_token_secret).then((success) => {
alert(JSON.stringify(success))
}, (error) => {
alert(JSON.stringify(error));
});
},
err => alert(JSON.stringify(err))
);
Have you tried the Twitter Connect plugin? Does this help?
Plugin to use Twitter Single Sign On Uses Twitter's Fabric SDK
An example of use is
import {TwitterConnect} from 'ionic-native';
function onSuccess(response) {
console.log(response);
// Will console log something like:
// {
// userName: 'myuser',
// userId: '12358102',
// secret: 'tokenSecret'
// token: 'accessTokenHere'
// }
}
TwitterConnect.login().then(onSuccess, onError);

Anonymous meeting join - Skype UCWA for online

I am trying to join a meeting anonymously through a meeting URI and this does not seem to work. I went to the SKYPE UCWA site and went to the interactive SDK - and tried to join a meeting anonymously from there but the page does not do anything.
https://ucwa.skype.com/websdk
Below is the code that I am trying to join a meeting anonymously, but the call to client.signInManager.signIn never completes and neither any exception is thrown.
Looking for suggestions to resolve this issue. Also, if someone has working code of joining a meeting anonymously using SKYPE web sdk (UCWA), please share the same. Thanks.
function InitialiseSkype() {
Skype.initialize({ apiKey: config.apiKey }, function (api) {
window.skypeWebAppCtor = api.application;
window.skypeWebApp = new api.application();
client = new window.skypeWebAppCtor;
//once intialised, sign in
alert("Skype SDK Initialized");
JoinAnonymous();
}, function (err) {
console.log(err);
alert('Cannot load the SDK.');
});
}
function JoinAnonymous(){
client.signInManager.signIn({
version: config.Version,
name: $('#name').val(),
meeting: $('#meetingUri').val()
}).then(function () {
alert('Signed In, Anonymously');
var conversation = application.conversationsManager.getConversationByUri(uri);
}, function (error) {
alert(error);
});
}
Actually I did sign in anonymously using that code :
//Init
var config = {apiKey: 'a42fcebd-5b43-4b89-a065-74450fb91255', // SDK
apiKeyCC: '9c967f6b-a846-4df2-b43d-5167e47d81e1' // SDK+UI
};
Skype.initialize({ apiKey: config.apiKey }, function (api) {
window.skypeWebApp = new api.application;
}, function (err) {
console.log("cannot load the sdk package", err);
});
//Actual code
var uri ="sip:xxxxxxxx;gruu;opaque=app:conf:focus:id:xxxxxxxx";
window.skypeWebApp.signInManager.signIn({
name: "pseudo",
meeting:uri
}).then(function () {
alert('Signed In, Anonymously');
}, function (error) {
alert(error);
});
I did connect with the uri given in the ucwa.skype interactive web sdk page.
But I did not manage to join the conversation after that, probably because the interactive sample does not really create the room.
I can join a meeting from a office365 account while logged in with a sample account. However I can not join anonymously my meeting room.
Do you try with an on-premise account or with a office365 account ?
Looks like Anonymous join for a meeting is not yet available for Skype For Business online.
New update of WebSDK now support anonymous meeting join for SfB Online
(function () {
'use strict';
// this will be populated when the auth token is fetched
// it is later needed to sign into Skype for Business
var authDetails = {};
// A reference to the Skype SDK application object
// set during initialization
var app;
displayStep(0);
registerUIListeners();
// Initializing the Skype application
Skype.initialize({
apiKey: '9c967f6b-a846-4df2-b43d-5167e47d81e1'
}, function (api) {
console.log('Skype SDK initialization successful');
app = api.UIApplicationInstance;
// Once it is initialized, display a UI prompt for a meeting URL
displayStep(1);
}, function (err) {
console.error('Skype SDK initialization error:', err);
});
// After the user submits the meeting URL the next step is to
// fetch an auth token
function getToken(evt) {
var input = evt.target.querySelector('input'),
meetingUrl = input.value,
request = new XMLHttpRequest(),
data;
evt.preventDefault();
console.log('Fetching auth token from meeting url:', meetingUrl);
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
var sessionId = guid();
data = 'ApplicationSessionId=' + sessionId +
'&AllowedOrigins=' + encodeURIComponent(window.location.href) +
'&MeetingUrl=' + encodeURIComponent(meetingUrl);
request.onreadystatechange = function () {
if (request.readyState === XMLHttpRequest.DONE) {
if (request.status === 200) {
var response = JSON.parse(request.response);
authDetails.discoverUrl = response.DiscoverUri;
authDetails.authToken = "Bearer " + response.Token;
console.log('Successfully fetched the anonymous auth token and discoverUrl', authDetails);
displayStep(2);
}
else {
console.error('An error occured, fetching the anonymous auth token', request.responseText);
}
}
};
request.open('post', 'http://webrtctest.cloudapp.net/getAnonTokenJob');
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.send(data);
}
// This uses the auth token and discovery URL to sign into Skype
// and join the meeting
function joinAVMeeting(evt) {
var input = evt.target.querySelector('input'),
name = input.value;
evt.preventDefault();
console.log('Joinig meeting as:', name);
app.signInManager.signIn({
name: name,
cors: true,
root: { user: authDetails.discoverUrl },
auth: function (req, send) {
// Send token with all requests except for the GET /discover
if (req.url != authDetails.discoverUrl)
req.headers['Authorization'] = authDetails.authToken;
return send(req);
}
}).then(function () {
// When joining a conference anonymously, the SDK automatically creates
// a conversation object to represent the conference being joined
var conversation = app.conversationsManager.conversations(0);
console.log('Successfully signed in with anonymous online meeting token');
registerAppListeners(conversation);
// This turns on local video and joins the meeting
startVideoService(conversation);
}).catch(function (error) {
console.error('Unable to join conference anonymously:', error);
});
function registerAppListeners(conversation) {
conversation.selfParticipant.video.state.when('Connected', function () {
console.log('Showing self video');
document.querySelector('.self').style.display = 'inline-block';
setupContainer(conversation.selfParticipant.video.channels(0), document.querySelector('.self .video'));
displayName(document.querySelector('.self'), conversation.selfParticipant);
console.log('The video mode of the application is:', conversation.videoService.videoMode());
if (conversation.videoService.videoMode() === 'MultiView') {
// Loading the sample in any other browser than Google Chrome means that
// the videoMode is set to 'MultiView'
// Please refer to https://msdn.microsoft.com/en-us/skype/websdk/docs/ptvideogroup
// on an example on how to implement group video.
}
// When in active speaker mode only one remote channel is available.
// To display videos of multiple remote parties the video in this one channel
// is switched out automatically, depending on who is currently speaking
if (conversation.videoService.videoMode() === 'ActiveSpeaker') {
var activeSpeaker = conversation.videoService.activeSpeaker;
setupContainer(activeSpeaker.channel, document.querySelector('.remote .video'));
activeSpeaker.channel.isVideoOn.when(true, function () {
document.querySelector('.remote').style.display = 'inline-block';
activeSpeaker.channel.isStarted(true);
console.log('ActiveSpeaker video is available and has been turned on.');
});
activeSpeaker.channel.isVideoOn.when(false, function () {
document.querySelector('.remote').style.display = 'none';
activeSpeaker.channel.isStarted(false);
console.log('ActiveSpeaker video is not available anymore and has been turned off.');
});
// the .participant object changes when the active speaker changes
activeSpeaker.participant.changed(function (newValue, reason, oldValue) {
console.log('The ActiveSpeaker has changed. Old ActiveSpeaker:', oldValue && oldValue.displayName(), 'New ActiveSpeaker:', newValue && newValue.displayName());
if (newValue) {
displayName(document.querySelector('.remote'), newValue);
}
});
}
});
conversation.state.changed(function (newValue, reason, oldValue) {
if (newValue === 'Disconnected' && (oldValue === 'Connected' || oldValue === 'Connecting')) {
console.log('The conversation has ended.');
reset();
}
});
}
function setupContainer(videoChannel, videoDiv) {
videoChannel.stream.source.sink.format('Stretch');
videoChannel.stream.source.sink.container(videoDiv);
}
function displayName(container, person) {
container.querySelector('.displayName .detail').innerHTML = person.displayName();
}
function startVideoService(conversation) {
conversation.videoService.start().then(null, function (error) {
console.error('An error occured joining the conversation:', error);
});
displayStep(3);
}
}
function endConversation(evt) {
var conversation = app.conversationsManager.conversations(0);
evt.preventDefault();
conversation.leave().then(function () {
console.log('The conversation has ended.');
reset();
}, function (error) {
console.error('An error occured ending the conversation:', error);
}).then(function () {
reset();
});
}
//-----------------------------------------------------------------------
//UI helper functions
function displayStep(step) {
var nodes = document.querySelectorAll('.step');
for (var i = 0; i < nodes.length; ++i) {
var node = nodes[i];
node.style.display = 'none';
if (i === step) {
node.style.display = 'block';
}
}
}
function registerUIListeners() {
document.querySelector('.step1').onsubmit = getToken;
document.querySelector('.step2').onsubmit = joinAVMeeting;
document.querySelector('.step3').onsubmit = endConversation;
}
function reset() {
window.location = window.location.href;
}
})();
https://github.com/OfficeDev/skype-docs/blob/master/Skype/WebSDK/samples/Meetings/Anonymous%20Online/standalone/index.js

Google api revoke token issue

I've created an application using google drive API to list and manage all my drive files.
Everything goes fine, except the log out part. I've searched for two days for a solution without a result.
The following is code related to login and works fine:
function checkAuth() {
gapi.auth.authorize(
{
'client_id': CLIENT_ID,
'scope': SCOPES.join(' '),
'immediate': true,
'authuser': '-1'
}, handleAuthResult);
}
function handleAuthResult(authResult) {
var authorizeDiv = document.getElementById('authorize-div');
if (authResult && !authResult.error) {
// Hide auth UI, then load client library.
authorizeDiv.style.display = 'none';
loadDriveApi();
} else {
authorizeDiv.style.display = 'inline';
}
}
function handleAuthClick(event) {
gapi.auth.authorize(
{client_id: CLIENT_ID, scope: SCOPES, immediate: false},
handleAuthResult);
return false;
}
function loadDriveApi() {
gapi.client.load('drive', 'v2', listFiles);
}
I'm able to login and work with files, but when I try to logout with following I get No 'Access-Control-Allow-Origin' error
$(document).on('click', '.logout', function(){
var token = gapi.auth.getToken();
if (token) {
var accessToken = gapi.auth.getToken().access_token;
if (accessToken) {
var revokeToken = 'https://accounts.google.com/o/oauth2/revoke?token=' + accessToken;
jQuery.getJSON(revokeToken).success(function(data) {
console.log(data);
}).error(function(message) {
console.error('error' + message);
}).complete(function() {
console.log('completed!');
});
}
}
gapi.auth.setToken(null);
gapi.auth.signOut();
});
In Google Developers Console I've regitred my website to Authorized JavaScript origins.
Thanks

Worklight - How to check if a client is already logged in

LoginViewModel.js
function login(){
var username='worklight';
var password = 'worklight';
var invocationData = {
adapter : "AuthenticationAdapter",
procedure : "submitAuthentication",
parameters : [ username, password ]
};
adapterAuthRealmChallengeHandler.submitAdapterAuthentication(invocationData, {});
AdapterAuthRealmChallengeProcessor.js
var adapterAuthRealmChallengeHandler = WL.Client.createChallengeHandler("AdapterAuthRealm");
adapterAuthRealmChallengeHandler.isCustomResponse = function(response) {
if (!response || !response.responseJSON || response.responseText === null) {
return false;
}
if (typeof(response.responseJSON.authRequired) !== 'undefined'){
return true;
} else {
return false;
}
};
adapterAuthRealmChallengeHandler.handleChallenge = function(response){
var authRequired = response.responseJSON.authRequired;
if (authRequired == true){
window.location = "#login";
alert(response.responseJSON.errorMessage);
} else if (authRequired == false){
adapterAuthRealmChallengeHandler.submitSuccess();
window.location = "#Home";
}
};
AuthenticationAdapter-impl.js
function onAuthRequired(headers, errorMessage){
errorMessage = errorMessage ? errorMessage : null;
return {
authRequired: true,
errorMessage: errorMessage
};
}
function submitAuthentication(username, password){
var userIdentity = {
userId: username,
displayName: username,
attributes: {
foo: "bar"
}
};
WL.Server.setActiveUser("AdapterAuthRealm", userIdentity);
return {
authRequired: false
};
}
I am not able to set setActiveUser. How to set it and get it. Above wat I have to done for maintaining session. Is it right way to do it. Sometimes I got error Illegal State: Cannot change identity of an already logged in user in realm 'Adapter AuthRealm'. The application must logout first. If I tried to set it null first then it causes my application to enter an infinite loop of attempting to authenticate. Any idea why I would see this behavior?
Anything I am doing wrong?
please help mi out.
Check the SO answer for Worklight logout does not clear active user
Try reloading app onSuccess of Logout.
WL.Client.logout("AdapterAuthRealm",{
onSuccess: function(){ WL.Client.reloadApp(); },
onFailure: function(){ WL.Logger.debug("Error on logout");}
});
And you can check realm is authenticated or not by using wl client Java script API
WL.Client.isUserAuthenticated("AdapterAuthRealm");