You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Microsoft Office add-ins require that any popups be opened using a special API instead of window.open. A few unusual constraints of that API are:
The popup must start in the same domain (it can redirect out of it).
There isn't a reliable, cross-platform way to send information to the dialog after it's opened (i.e., you should package everything you need to send into the query string)
Sending data back from the popup also requires a custom API.
Describe the ideal solution
I've done some gymnastics (see below) to make this API work with loginWithPopup, but it would be much easier if the user of the library could provide a custom dialog API. For example, something like:
where I've imagined asyncified versions of the Office dialog code.
Alternatives and current workarounds
My workaround code currently looks like:
letdialog: Office.Dialog;constprocessMessage=async(args:
|{message: string; origin: string|undefined}|{ error: number})=>{if('error'inargs){// eslint-disable-next-line no-consoleconsole.error('Error:',args.error);return;}// eslint-disable-next-line prefer-constletmessageFromDialog=JSON.parse(args.message);dialog.close();if(messageFromDialog.status==='success'){// The dialog reported a successful login.// eslint-disable-next-line prefer-constlettoken=messageFromDialog.auth0Token;// eslint-disable-next-line no-consoleconsole.log('Login successful.',token);// Mock the window message event that auth0-spa-js expects// see https://github.com/auth0/auth0-spa-js/blob/f2e566849efa398ca599daf9ebdfbbd62fcb1894/__tests__/utils.test.ts#L234letmessageEvent=newMessageEvent('message',{data: {type: 'authorization_response',response: {id_token: token}}})window.dispatchEvent(messageEvent);}else{// eslint-disable-next-line no-consoleconsole.error('Login failed.',messageFromDialog);}};// Make the href of the popup be a setter so that we can actually launch the dialog with the correct url to begin withconstmockPopup={location: {sethref(url: string){console.log("Setting location.href to",url);// Set up an Office dialog to do the login flow// height and width are percentages of the size of the screen.// How MS use it: https://github.com/OfficeDev/Office-Add-in-samples/blob/main/Samples/auth/Office-Add-in-Microsoft-Graph-React/utilities/office-apis-helpers.ts#L38// Bounce off /popup.html?redirect=... to get the tokenletredirect=encodeURIComponent(url);letbounceURL=location.protocol+'//'+location.hostname+(location.port ? ':'+location.port : '')+'/popup.html?redirect='+redirect;console.log("Bouncing to",bounceURL);Office.context.ui.displayDialogAsync(bounceURL,{height: 45,width: 55},function(result){dialog=result.value;dialog.addEventHandler(Office.EventType.DialogMessageReceived,processMessage);});}},closed: false,close: ()=>{mockPopup.closed=true},};
...
awaitloginWithPopup({},{popup: mockPopup});
Additional context
No response
The text was updated successfully, but these errors were encountered:
Nevermind, the popup approach doesn't actually work here at all because auth0 tries to use a webmessage response, and Office doesn't allow cross-origin messages from dialogs without its special API too.
But I realized that loginWithRedirect is a more robust flow. Our WIP approach:
if(!isAuthenticated){letdialog: Office.Dialog;// Strategy: the popup will pass its redirect-callback data here, so we can pass it on to handleRedirectCallbackconstprocessMessage=async(args:
|{message: string; origin: string|undefined}|{ error: number})=>{if('error'inargs){console.error('Error:',args.error);return;}letmessageFromDialog=JSON.parse(args.message);dialog.close();if(messageFromDialog.status==='success'){// The dialog reported a successful login.handleRedirectCallback(messageFromDialog.urlWithAuthInfo);}else{console.error('Login failed.',messageFromDialog);}};// Actually make a popup using MS dialog API// hook the message event from the popup to set close false and get the tokenreturn(<div>
Login here:
<buttononClick={async()=>{// Use this dialog for the Auth0 client library.awaitloginWithRedirect({openUrl: async(url: string)=>{constredirect=encodeURIComponent(url);constbounceURL=location.protocol+'//'+location.hostname+(location.port ? ':'+location.port : '')+'/popup.html?redirect='+redirect;// height and width are percentages of the size of the screen.// How MS use it: https://github.com/OfficeDev/Office-Add-in-samples/blob/main/Samples/auth/Office-Add-in-Microsoft-Graph-React/utilities/office-apis-helpers.ts#L38Office.context.ui.displayDialogAsync(bounceURL,{height: 45,width: 55},function(result){dialog=result.value;dialog.addEventHandler(Office.EventType.DialogMessageReceived,processMessage);});}});}}>Log in
</button></div>);}
Handling log-out is a different story... we haven't figured that out yet!
Checklist
Describe the problem you'd like to have solved
Microsoft Office add-ins require that any popups be opened using a special API instead of
window.open
. A few unusual constraints of that API are:Describe the ideal solution
I've done some gymnastics (see below) to make this API work with
loginWithPopup
, but it would be much easier if the user of the library could provide a custom dialog API. For example, something like:where I've imagined asyncified versions of the Office dialog code.
Alternatives and current workarounds
My workaround code currently looks like:
Additional context
No response
The text was updated successfully, but these errors were encountered: