Callback after Login() of ADAL.js is not called in Edge - azure

I am using ADAL.js(which calls Azure Active Directory) as javascript library for verifying the user. I am using the following code for this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.15/js/adal.min.js"></script>
<script>
var endpoints = {
"https://management.core.windows.net": "https://management.core.windows.net"
};
var config = {
clientId: 'e333d3fe-a73a-4476-8121-8a57f9a972ca',
endpoints: endpoints,
};
var authContext = new AuthenticationContext(config);
authContext.handleWindowCallback();
function onSuccessLogin(error, token, msg) {
console.log("Inside Call back");
if (!!token) {
console.log("Log-in to Azure successfully done", token);
}
else {
console.log("Error while log-in to Azure", error);
}
if (!!authContext._user) {
console.log("You are connected to Azure ")
}
}
function login() {
authContext.popUp = true;
authContext.callback = onSuccessLogin;
authContext.login();
// authContext.handleWindowCallback();
var user = authContext.getCachedUser();
console.log(user);
};
function logout () {
authContext.logout();
};
</script>
<input id="Button1" type="button" value="clickme" onclick="clickme()" />
<input id="Button3" type="button" value="login" onclick="login()" />
<input id="Button2" type="button" value="logout" onclick="logout()" />
// These are the text-boxes whose value I want to retain.
First name:<br>
<input id=fname" type="text" name="firstname" value="Mickey">
<br>
Last name:<br>
<input id="lname" type="text" name="lastname" value="Mouse">
</body>
</html>
These are few issue with this code in Edge, although everything is working fine in chrome:
Why the onSuccessLogin() is not always called on edge?
Why the pop window for log-in is not appearing always?
Sometime after entering the credential the pop won't close.

What worked for me is:
set the config.callback and popUp=true before calling AuthenticationContext(config)
Also you should not call handleWindowCallback() if the URL does not contain a #. The code should be:
if (authenticationContext.isCallback(window.location.hash)) {
authenticationContext.handleWindowCallback();
I suggest that you have a look and adapt the following sample I tested and worked in Edge (and of course Chrome) in both cases (with and without popup):
https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof-ca/blob/master/TodoListSPA/app.js
(the configuration is in https://github.com/Azure-Samples/active-directory-dotnet-webapi-onbehalfof-ca/blob/master/TodoListSPA/appconfig.js)

Related

With IdentityServer3 I'm unable to display the loaded user details as per their sample

I'm following the IdentityServer3 jsGettingStarted sample github sample
But I'm trying to do so using MVC.
(The IdentityServer itself is in a separate project and solution as per the sample documentation.)
Providing the index.html page is via a Controller-Action, which is fine.
The login popup "popup.html" which is actually "popup.cshtml" is also via a Controller action and it also displays, but it won't close and display the user credentials in the index page as shown in the Sample.
But putting a few alerts in, .. the user is definitely logged in.
I also tried moving the popup.html into the root of the project (as .html and not as .cshtml and changing the server's Client.cs' RedirectUris to reflect that change) but without success.
Is it because of the cshtml pages being served from my controller actions ?
The documentation says that this should display by calling the display function, but the "manager.events.addUserLoaded" function is not firing, which calls the display function.
I am using VS2017 MVC5 with Framework 4.8.
Thanks
<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css" />
<script src="~/Scripts/jquery.js"></script>
<script src="~/Scripts/bootstrap.js"></script>
<script src="~/Scripts/oidc-client.js"></script>
<div>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">JS Application</a>
</div>
</div>
</nav>
<div class="container main-container">
<div class="row">
<div class="col-xs-12">
<ul class="list-inline list-unstyled requests">
<li>Home</li>
<li><button type="button" class="btn btn-default js-login">Login</button></li>
</ul>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="panel panel-default">
<div class="panel-heading">User data</div>
<div class="panel-body">
<pre class="js-user"></pre>
</div>
</div>
</div>
</div>
</div>
<script language="javascript" type="text/javascript">
// helper function to show data to the user
function display(selector, data)
{
if (data && typeof data === 'string')
{
data = JSON.parse(data);
}
if (data)
{
data = JSON.stringify(data, null, 2);
}
alert("selector=" + data);
$(selector).text(data);
}
var settings = {
authority: 'https://localhost:44302', // The url of the IdentityServer
client_id: 'js',
popup_redirect_uri: 'http://localhost:44888/Account/Popup',
response_type: 'id_token token',
scope: 'openid profile email',
filterProtocolClaims: true
};
var manager = new Oidc.UserManager(settings);
var user;
manager.events.addUserLoaded(function (loadedUser)
{
alert("userManager");
user = loadedUser;
display('.js-user', user);
});
$('.js-login').on('click', function ()
{
manager
.signinPopup()
.catch(function (error)
{
console.error('error while logging in through the current window or popup', error);
});
});
</script>
By creating a standalone project rather than trying to do it in already established project, I managed to get it to work. There were clashes in the scripts and css we were already using.

chrome.storage.sync failed to SET and GET

I am unable to save and get data when I put any data and click button nothing happen and not saving data.
Just want to save 2 value
APIkey
enabled or not a checkbox
and save them
My main.js for options
function saveSettings(e) {
chrome.storage.sync.set({
apiKey: apiKey.value,
isEnabled: isEnabled.checked
});
}
function restoreSettings(e) {
chrome.storage.sync.get("apiKey").then(
function(result) {
alert('working');
apiKey.value = result.apiKey || "";
},
function(error) {
console.log(error);
}
);
chrome.storage.sync.get("isEnabled").then(
function(result) {
isEnabled.checked = result.isEnabled
},
function(error) {
console.log(error);
}
);
}
//restoreSettings();
//saveButton.addEventListener("click", saveSettings);
document.addEventListener('DOMContentLoaded', restoreSettings);
document.getElementById('saveButton').addEventListener('click',
saveSettings);
And my html
<!DOCTYPE html>
<html>
<head>
<title>Plugin Options</title>
</head>
<body>
<img src="/icons/img1.png">
<div>
<form style="background-color:#000a1a">
<h3>Change Settings</h3>
<label>API Key : <input type="text" id="apiKey" /></label><br />
<label>Enabled : <input type="checkbox" id="isEnabled" /></label><br />
<input type="button" value="Save Settings" id="saveButton" class="button" />
</form>
</div>
<script src="main.js"></script>
</body>
</html>
I tried chrome.storage.local as well thanks for helping
First make sure you have set the right permissions in your manifest:
"permissions": [
"storage"
]
then to get a value:
chrome.storage.sync.get('myvalue', function(res){
})
where res.myvalue will be the content you are looking for.
To set a value do:
chrome.storage.sync.set({'myvalue': true})

Worldpay Token Confusion

Trying to implement Worldpay integration. The docs at https://online.worldpay.com/docs/take-card-details-templates mention a token. I have tested the page and I dont get any token. Wandering how i can get this token.
<%# Page Language="C#" AutoEventWireup="true" CodeFile="payment2.aspx.cs" Inherits="payment2" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src= "https://cdn.worldpay.com/v1/worldpay.js">
</script>
<script type='text/javascript'>
window.onload = function () {
Worldpay.setClientKey('T_C_a453a70e-c5e6-4618-9c7b-96f787f0fa04');
Worldpay.reusable = false;
Worldpay.useTemplate('payment-form', 'my_payment_section', 'inline');
}
</script>
</head>
<body>
<form action="/complete" id="payment-form" method="post">
<!— all other fields you want to collect, e.g. name
and shipping address -->
<div id='my_payment_section'></div>
<div>
<input type="submit" value="Place Order" />
</div>
</form>
</body>
</html>
When the window.onload executes, it puts the WorldPay card capture form on your page. By the looks of it, you haven't disabled their Save Payment button, so are you trying to use your own submit button?? If you are trying to use your submit button, then you should add the onclick attribute to submit the worldpay template.
<input type="submit" value="Place Order" />
<form action="/complete" id="payment-form" method="post">
<div id="my_payment_section"></div>
<div>
<input id="submitCard" onclick="Worldpay.submitTemplateForm()" value="Confirm Payment" />
</div>
</form>
Once the form submits, worldpay.js takes over, and it will handle the sensitive card information, validate it and if all is ok, it will replace the cardDetails div with a single hidden input field which is the token.
If that all happens correctly, with no errors, after the token input has been placed in the DOM, the form will submit to your action "/complete", and the token will be part of the submitted values of the form.
Hope that helps.
Your script is missing the callback to generate the token in useTemplate()
See: https://developer.worldpay.com/jsonapi/docs/template-form
The callback generates the hidden input with the token value for you which posts to worldpay.
your script should be:
<script type='text/javascript'>
window.onload = function() {
Worldpay.useTemplateForm({
'clientKey':'T_C_a453a70e-c5e6-4618-9c7b-96f787f0fa04',
'form':'paymentForm',
'paymentSection':'paymentSection',
'display':'inline',
'reusable':false,
'callback': function(obj) {
if (obj && obj.token) {
var _el = document.createElement('input');
_el.value = obj.token;
_el.type = 'hidden';
_el.name = 'token';
document.getElementById('paymentForm').appendChild(_el);
document.getElementById('paymentForm').submit();
}
}
});
}
</script>
You also need the onclick="Worldpay.submitTemplateForm()" attribute on your submit too.

GET request: how to send query?

I would like to know what is the correct procedure for making a GET request inside the application code. I mean, not in the URL (is that a good practice?).
As always, I like to give you examples on what I'm looking for. So here it is:
HTML:
(...)
<div class="input-area">
<input type="text" value="SOME VALUE" id="text-field">
<input type="submit" value="Submit" id="button">
</div>
(...)
Let's assume that the #button action is "submitForm".
DART (it's incomplete):
void submitForm(Event e) {
e.preventDefault();
request = new HttpRequest();
request.onReadyStateChange.listen(dataIsReady);
request.open("GET", "http://127.0.0.1:8123");
(???)
}
What I would like to happen is the value on the text-field to be sent to the server as a parameter. Just to clarify, I'll be using that parameter to search for some entries in a MySQL database (and return some JSON data).
So how can I do that with Dart?
library x;
import 'dart:html';
void main() {
// you can create an URI and use the toString() method to create a
// String you can pass to the request
Map query = {
'xx': 'yy',
'zz': 'ss'
};
Uri uri =
new Uri(
path: "http://localhost:8080/myapp/signinService",
queryParameters: query);
print('URI: ${uri.toString()}');
querySelector("#signinForm")..onSubmit.listen(handle);
}
void handle(Event event) {
event.preventDefault();
// or you can use the form elements formdata
FormElement formElement = event.target as FormElement;
var url = "http://localhost:8080/myapp/signinService";
HttpRequest.request(
url,
method: formElement.method,
sendData: new FormData(formElement)).then(onDataLoaded);
}
void onDataLoaded(HttpRequest req) {
String response = req.responseText;
if (response == 1) {
window.alert("You are signed in!");
} else {
window.alert("Sign in failed. Check credentials.");
}
}
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="packages/browser/dart.js"></script>
</head>
<body>
<h1>Alarm</h1>
<!-- I used a form element and set the request method here. It can be set in code too -->
<form id="signinForm" class="form-signin" method="GET">
<h2 class="form-signin-heading">Please sign in</h2>
<input type="text" class="input-block-level" name="email" placeholder="Email address">
<input type="password" class="input-block-level" name="password" placeholder="Password">
<button class="btn btn-large btn-primary" id="signinBtn" type="submit">Sign in</button>
</form>
<script type="application/dart" src="alarm.dart"></script>
</body>
</html>

model undefined on page reload

I'm trying example from this site. It works fine. But if i separate views,models,routers into separate file it gives me a problem. There is 3 views. WineList view, WineListItemView and winedetails view. WineList view takes collection of wine models as model and winelistItem and winedetails view takes wine as a model.
Router's code is like this
var app = app || {};
app.AppRouter = Backbone.Router.extend({
routes:{
"":"list",
"wines/:id":"wineDetails"
},
initialize:function () {
$('#header').html(new app.HeaderView().render().el);
},
list:function () {
this.wineList = new app.WineCollection();
this.wineListView = new app.WineListView({model:this.wineList});
this.wineList.fetch();
$('#sidebar').html(this.wineListView.render().el);
},
wineDetails:function (id) {
if(this.wineList == undefined)
{
this.wineList = new app.WineCollection();
this.wineListView = new app.WineListView({model:this.wineList});
this.wineList.fetch();
$('#sidebar').html(this.wineListView.render().el);
}
this.wine = this.wineList.get(id);
if (app.router.wineView) app.router.wineView.close();
this.wineView = new app.WineView({model:this.wine});
$('#content').html(this.wineView.render().el);
}
});
On page load it fetches models from server and displays list of wines in sidebar div of page. When i click on particular wine item its details will be displayed in content div of page. That all works fine. But when i reload that page which now contains details of particular,wine model of Winedetails view gives undefined .
I'm intializing the router on main page like this
app.js
var app = app || {};
$(function() {
})
app.router = new app.AppRouter();
Backbone.history.start();
index.html
<!DOCTYPE HTML>
<html>
<head>
<title>Backbone Cellar</title>
<link rel="stylesheet" href="../css/styles.css" />
</head>
<body>
<div id="header"><span class="title">Backbone Cellar</span></div>
<div id="sidebar"></div>
<div id="content">
<h2>Welcome to Backbone Cellar</h2>
<p>
This is a sample application part of of three-part tutorial showing how to build a CRUD application with Backbone.js.
</p>
</div>
<div>
Next page
</div>
<!-- Templates -->
<script type="text/template" id="tpl-header">
<span class="title">Backbone Cellar</span>
<button class="new">New Wine</button>
</script>
<script type="text/template" id="tpl-wine-list-item">
<a href='#wines/<%= id %>'><%= name %></a>
</script>
<script type="text/template" id="tpl-wine-details">
<div class="form-left-col">
<label>Id:</label>
<input type="text" id="wineId" name="id" value="<%= id %>" disabled />
<label>Name:</label>
<input type="text" id="name" name="name" value="<%= name %>" required/>
<label>Grapes:</label>
<input type="text" id="grapes" name="grapes" value="<%= grapes %>"/>
<label>Country:</label>
<input type="text" id="country" name="country" value="<%= country %>"/>
<label>Region:</label>
<input type="text" id="region" name="region" value="<%= region %>"/>
<label>Year:</label>
<input type="text" id="year" name="year" value="<%= year %>"/>
<button class="save">Save</button>
<button class="delete">Delete</button>
</div>
<div class="form-right-col">
<img height="300" src="../pics/<%= picture %>"/>
<label>Notes:</label>
<textarea id="description" name="description"><%= description %></textarea>
</div>
</script>
<!-- JavaScript -->
<script src="js/lib/jquery.min.js"></script>
<script src="js/lib/underscore.js"></script>
<script src="js/lib/backbone.js"></script>
<script src="js/models/WineModel.js"></script>
<script src="js/collections/WineListCollection.js"></script>
<script src="js/Views/WineListView.js"></script>
<script src="js/Views/WineListItemView.js"></script>
<script src="js/Views/WineDetailsView.js"></script>
<script src="js/Views/HeaderView.js"></script>
<script src="js/routers/routers.js"></script>
<script src="js/app.js"></script>
</body>
</html>
I'm new to this backbone technology. please tell me what am i missing
this.wineList.fetch();
fires an asynchronous request to your server, which means that the content will arrive (or not) at some point after executing this line, but your application execution continues whether the response arrived or not. On page reload (assume you have wines/:id in the URL) first you have to fetch the complete list of wines before accessing any particular wine from the collection.
You have to wait until is download the collection, and access the wine with id, after this request is finished.
So after initiating the request continue your application logic in the success callback:
this.wineList.fetch({
success: function(model) {
...
this.wine = model.get(id);
...
}
});

Resources