Hi @CleberM / @BoLi / @renatoromao ,
I am still not able to configure SSO. I am try to achieve this on a Sharepoint Webpage. I have posted the issue through multiple thread but no luck.
I am still being asked to pass the token id.
Can you please help me out with this? Any help is much appreciated.
https://powerusers.microsoft.com/t5/General/PVA-SSO-Configuration/td-p/650994/jump-to/first-unread-message


Below is the code that i am using. I have added a button on the Sharepoint site so the chat bot come up in clicking on it. The same Home page URL were the button is added is the redirect URL that is added on Azure AD App registration.
<!DOCTYPE html>
<html>
<head>
<title>Contoso Sample Web Chat</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
<script type="text/javascript" src="https://alcdn.msauth.net/lib/1.2.0/js/msal.js"></script>
<script src="https://unpkg.com/@azure/storage-blob@10.3.0/browser/azure-storage.blob.min.js"
integrity="sha384-fsfhtLyVQo3L3Bh73qgQoRR328xEeXnRGdoi53kjo1uectCfAHFfavrBBN2Nkbdf"
crossorigin="anonymous"></script>
<script type="text/javascript">
if (typeof Msal === 'undefined') document.write(unescape("%3Cscript src='https://alcdn.msftauth.net/lib/1.2.0/js/msal.js' type='text/javascript' %3E%3C/script%3E"));
</script>
<style>
body {
font-family: Arial, Helvetica, sans-serif;
}
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 100px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content */
.modal-content {
background-color: #fefefe;
margin: auto;
padding: 10px;
border: 1px solid #888;
width: 500px;
height: 575px;
}
/* The Close Button */
.close {
color: black;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
html, body {
height: 100%;
}
body {
margin: 0;
}
div[role="form"] {
background-color: #3392FF;
}
#webchat {
position: center;
height: 530px;
width: 100%;
top: 60px;
overflow: hidden;
}
.heading{
padding-bottom: 5px;
}
.span{
font-weight: bold;
}
</style>
</head>
<body>
<!--Button and ChatBot View-->
<button id="myBtn" type="button" >Power Virtual Agent</button>
<div id="myModal" class="modal">
<!-- Modal content -->
<div class="modal-content" style=" background-color: #FFD933">
<span class="close">×</span>
<div class="chat">
<div class="heading">
<!-- Change the h1 text to change the bot name -->
<img src="heading image added here" width="42" height="30" alt="logo">
<span class="span"><strong>Heading</strong></span>
</div>
<div id="webchat" role="main"></div><br>
</div>
</div>
</div>
<!--Button code begins here-->
<script>
// Get the modal
var modal = document.getElementById("myModal");
// Get the button that opens the modal
var btn = document.getElementById("myBtn");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks the button, open the modal
btn.onclick = function () {
modal.style.display = "block";
}
// When the user clicks on <span> (x), close the modal
span.onclick = function () {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
<!--Button code ends here-->
<!--SSO Code is added here-->
<script>
function getOAuthCardResourceUri(activity)
{
//alert("activity var inside getOAuthCardResourceUri: " + JSON.stringify(activity));
if (activity && activity.attachments && activity.attachments[0] && activity.attachments[0].contentType === 'application/vnd.microsoft.card.oauth' && activity.attachments[0].content.tokenExchangeResource)
{
// asking for token exchange with AAD
//alert("Inside if condition of activity: " + JSON.stringify(activity.attachments[0].content.tokenExchangeResource.uri));
return activity.attachments[0].content.tokenExchangeResource.uri;
}
}
function exchangeTokenAsync(resourceUri)
{
let user = clientApplication.getAccount();
//alert("user value inside exchangeTokenAsync: " + JSON.stringify(user));
debugger;
if (user)
{
let requestObj =
{
scopes: [resourceUri]
};
//alert("requestObj inside exchangeTokenAsync: " + JSON.stringify(requestObj));
return clientApplication.acquireTokenSilent(requestObj)
.then(function (tokenResponse)
{
return tokenResponse.accessToken;
})
.catch(function (error)
{
console.log(error);
});
}
else
{
return Promise.resolve(null);
}
}
async function fetchJSON(url, options = {})
{
//alert("url inside fetchJSON: " + JSON.stringify(url));
const res = await fetch(url, {
...options,
headers:
{
...options.headers,
accept: 'application/json'
}
});
//alert("res inside fetchJSON: " + JSON.stringify(res));
if (!res.ok)
{
throw new Error(`Failed to fetch JSON due to ${res.status}`);
}
return await res.json();
}
</script>
<script>
var clientApplication;
(function ()
{
var msalConfig = {
auth:
{
clientId: '<Client Id of canvas>',
authority: 'https://login.microsoftonline.com/<Directory ID>'
},
cache:
{
cacheLocation: 'localStorage',
storeAuthStateInCookie: false
}
};
if (!clientApplication)
{
//alert("msalConfig: " + JSON.stringify(msalConfig));
clientApplication = new Msal.UserAgentApplication(msalConfig);
//alert("clientApplication inside if: " + JSON.stringify(clientApplication));
}
}());
(async function main() {
// Add your BOT ID below
var BOT_ID = "ABC";
var theURL = "https://powerva.microsoft.com/api/botmanagement/v1/directline/directlinetoken?botId=" + BOT_ID;
const styleOptions = {
botAvatarImage: "BOT image",
userAvatarImage: "user image",
hideUploadButton: true
};
const { token } = await fetchJSON(theURL);
const directLine = window.WebChat.createDirectLine({ token });
var userID = clientApplication.account?.accountIdentifier != null ?
("mypva" + clientApplication.account.accountIdentifier).substr(0, 64)
: (Math.random().toString() + Date.now().toString()).substr(0,64);
//alert("userID inside async function is " + userID);
//alert("Token:" + JSON.stringify(token));
const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
const {
type
} = action;
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'startConversation',
type: 'event',
value: {
text: "hello"
}
}
});
return next(action);
}
if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
const activity = action.payload.activity;
let resourceUri;
if (activity.from && activity.from.role === 'bot' &&
(resourceUri = getOAuthCardResourceUri(activity))) {
//alert("Inside if DIRECT_LINE/INCOMING_ACTIVITY");
exchangeTokenAsync(resourceUri).then(function (token) {
if (token) {
directLine.postActivity({
type: 'invoke',
name: 'signin/tokenExchange',
value: {
id: activity.attachments[0].content.tokenExchangeResource.id,
connectionName: activity.attachments[0].content.connectionName,
token,
},
"from": {
id: userID,
name: clientApplication.account.name,
role: "user"
}
}).subscribe(
id => {
if (id === 'retry') {
// bot was not able to handle the invoke, so display the oauthCard
return next(action);
}
// else: tokenexchange successful and we do not display the oauthCard
},
error => {
// an error occurred to display the oauthCard
return next(action);
}
);
return;
} else
return next(action);
});
} else
return next(action);
} else
return next(action);
});
window.WebChat.renderWebChat({
directLine: directLine,
store,
userID: userID,
styleOptions
},
document.getElementById('webchat')
);
})().catch(err => console.error("An error occurred: " + err));
</script>
<!--SSO Code ends here-->
</body>
</html>
Regards,
Hemanth