Closed Issa-projects closed 9 months ago
Sounds like each instance of the dialog has its own storage - if you manually put something in localstorage is it still there in the 2nd dialog?
If that's the case I'd recommend calling the MSAL APIs in your main frame so cache is stored there instead. You can use the onRedirectNavigate
request parameter on loginRedirect to open the dialog and perform the interaction there, then message the url hash back to your main frame and have your main frame invoke handleRedirectPromise with that hash.
@tnorling could you please give example code on how this would be implemented?
Rough pseudo code, you'll need to fill in the blanks with the specific APIs you need to use
// Main Window
onMessageFromDialog((responseHash) => {
// Message received from dialog
pca.handleRedirectPromise(responseHash);
});
pca.loginRedirect({
scopes: [User.Read],
onRedirectNavigate: (url) => {
// Open dialog and send it the url
return false; // Prevent main window from attempting to redirect
}
});
// Dialog box
if (window.location.hash) {
// Returning from auth flow
sendMessageBacktoParent(window.location.hash);
closeDialog();
} else {
// Beginning of auth flow, redirect
window.location.href = url; // url from parent
}
This does not work since the dialog should prompt the user to login/select account and then closes from the parent on success login. I will show what i am currentlig doing:
Actions to trigger and comunicate with the dialog:
async dialog({commit, dispatch, state}, refresh = false) {
const dialogLoginUrl = import.meta.env.VITE_APP_MSAL_DIALOG_URI;
let loginDialog: Office.Dialog;
await commit("setLoading", true);
Office.context.ui.displayDialogAsync(
dialogLoginUrl,
{height: 45, width: 25},
async (result) => {
loginDialog = result.value;
if (result.status === Office.AsyncResultStatus.Failed) {
loginDialog.close()
commit("setAlert", {message: "message", type: "error"});
} else {
loginDialog.addEventHandler(Office.EventType.DialogMessageReceived, processLoginMessage);
loginDialog.addEventHandler(Office.EventType.DialogEventReceived, processDialogEvent);
}
}
);
const processDialogEvent = async (arg:any) => {
console.log({arg})
if(arg.error == 12006){
loginDialog.close()
}
}
const processLoginMessage = async (arg: { message: string, origin: string } | { error: number }) => {
if ("error" in arg) {
commit("setAlert", {message: "message", type: "error"});
return;
}
const message = JSON.parse(arg.message);
if (message.status == "error") {
commit("setAlert", {message: "message", type: "error"});
return;
}
/**
* login success. Parse the success message
*/
loginDialog.close()
};
await commit("setLoading", false);
},```
The dialog:
```typescript
<template>
<div class="flex items-center justify-center h-full w-full p-3" >
<Loader size="lg" ></Loader>
</div>
</template>
<script lang="ts" setup>
import {loginRequest} from "@/config/authConfig";
import {useMsal} from "@/utils/useMsal";
import {onMounted} from "vue";
import Loader from "@/Components/Loader.vue";
const { instance } = useMsal();
const login = async () => {
await instance.handleRedirectPromise()
.then((response:any) => {
// If response is non-null, it means page is returning from AAD with a successful response
if (response) {
instance.setActiveAccount(response.account)
Office.context.ui.messageParent( JSON.stringify({ status: 'success', payload : response }) );
} else {
console.log({catch: response})
instance.loginRedirect(loginRequest);
}
})
.catch((error) => {
Office.context.ui.messageParent( JSON.stringify({ status: 'error', payload: error }));
});
}
login();
</script>```
That's the point of the onRedirectNavigate
parameter. This enables the dialog to handle user prompts while still allowing the parent to do the rest of the heavy lifting and hold the token cache
async dialog({commit, dispatch, state}, refresh = false) {
const dialogLoginUrl = import.meta.env.VITE_APP_MSAL_DIALOG_URI;
let loginDialog: Office.Dialog;
await commit("setLoading", true);
pca.loginRedirect({...loginRequest, onRedirectNavigate: (url) => {
Office.context.ui.displayDialogAsync(
url,
{height: 45, width: 25},
async (result) => {
pca.handleRedirectPromise(result.value);
loginDialog.close()
}
);
return false;
}});
await commit("setLoading", false);
},
The dialog:
```typescript
<template>
<div class="flex items-center justify-center h-full w-full p-3" >
<Loader size="lg" ></Loader>
</div>
</template>
<script lang="ts" setup>
Office.context.ui.messageParent( JSON.stringify({ status: 'success', payload : window.location.hash }) );
</script>
I am getting an error indicating that the dialog couldn't open with that url:
Error: "The domain of the URL is not included in the AppDomains element in the manifest, and is not subdomain of source location."
I see the onRedirectNavigate callback url is the authorize login url, but the dialog expected a url to open on the same domain.
I added the domain https://login.microsoftonline.com to appDomains in the manifest file, and it looks like it is working. Thanks for help @tnorling
Core Library
MSAL.js (@azure/msal-browser)
Core Library Version
3.7.0
Wrapper Library
Not Applicable
Wrapper Library Version
None
Public or Confidential Client?
Public
Description
I am working on developing a new outlook addin (taskpane) with vue 3 that will ask the user to choose and log in with one of their accounts. For the login , the user clicks "Get started" button, a dialog opens (Office dialog api) where the user chooses an account. When they log in i use messageParent from the Office.context.ui to communicate with the main component. The main component receives the message from the dialog and store it in vuex state manager. msal browser works just fine while the taskpane is open. I get the authenticated user and the access token, but when i close the taskpane, and open again, and try to check if there is an active account, the gerAcctiveAccount and getAllAccounts return empty/null. I noticed when checking the local storage that there are only two enteries: msal.[tenant_id].active-account-filters msal.[tenant_id].active-account
Error Message
no errors
MSAL Logs
No response
Network Trace (Preferrably Fiddler)
MSAL Configuration
Relevant Code Snippets
Reproduction Steps
Expected Behavior
array og all the accounts and get active account should return the logged in user account
Identity Provider
Entra ID (formerly Azure AD) / MSA
Browsers Affected (Select all that apply)
Other
Regression
No response
Source
Internal (Microsoft)