OfficeDev / office-js

A repo and NPM package for Office.js, corresponding to a copy of what gets published to the official "evergreen" Office.js CDN, at https://appsforoffice.microsoft.com/lib/1/hosted/office.js.
https://learn.microsoft.com/javascript/api/overview
Other
686 stars 95 forks source link

Outlook Addin iOS error "ReferenceError: Can't find variable: OfficeRuntime" #1962

Closed 4kochi closed 3 years ago

4kochi commented 3 years ago

Provide required information needed to triage your issue

We have created an Outlook addin wit SSO based on the yeoman generator yo office. It works fine in Outlook for Mac/Windows and in Outlook Online. However, on Outlook for iOS the plugin loads but then we get the following error:

ReferenceError: Can't find variable: OfficeRuntime

This is because we need some authentication and the first thing done is to get the Bootstrap token from Outlook. It was generated by the yeoman generator and is placed in the file src/helpers/ssoauthhelper.ts:

 let bootstrapToken: string = await OfficeRuntime.auth.getAccessToken({ allowSignInPrompt: true });

So it seems like the variable OfficeRuntime is not set on Outlook in iOS.

Here is the office js lib we include in the addin html file:

<!-- Load the Office JavaScript APIs -->
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>

So could it be that the auth is not supported on iOS? According to the documentation of the requirement sets it seems the IdentityAPI 1.3 is needed and the current state for iOS is Coming soon (https://docs.microsoft.com/en-us/office/dev/add-ins/reference/requirement-sets/identity-api-requirement-sets). Is this still the case?

Your Environment

exextoc commented 3 years ago

Yes, it is still not supported.

4kochi commented 3 years ago

Ok, thx for the fast feedback. Is there already some timeline when or if this will be available?

Or is there another way to get some auth data of the currently logged in user which we then can use?

4kochi commented 3 years ago

I tried this approach to get a token for the REST API (https://docs.microsoft.com/en-us/office/dev/add-ins/outlook/use-rest-api)

That worked, but actually i need a GRAPH token. Is there a way to convert this REST token to a bootstrap/GRAPH token?

exextoc commented 3 years ago

The callback token does not work with the Microsoft Graph. You can go through this doc “Compare Microsoft Graph and Outlook REST API endpoints (https://docs.microsoft.com/en-us/outlook/rest/compare-graph)” to get the detail.

You can look at the dialog APIs (https://docs.microsoft.com/en-us/office/dev/add-ins/develop/auth-with-office-dialog-api) to get auth token.

ghost commented 3 years ago

This issue has been automatically marked as stale because it is marked as needing author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. Thank you for your interest in Office Add-ins!

4kochi commented 3 years ago

Thank you for the response. We tried that approach.

Basically the yo office generator has already created the fallbackauthdialog.html which can handle the login with msal.js. So now we check if the client has the needed capabilities (Office.context.requirements.isSetSupported("IdentityAPI", "1.3");) If not, then we show the fallback auth dialog. This works fine until the point where the dialog ask if you want to stay logged in. Pressing yes or no does not have any affect and you are stuck in the dialog. If you then closed the Add-In and open it again, you are redirected to a white page in the dialog and there is nothing you can doo.

So i wonder if the fallbackauthdialog logic in the Add-In might also not work on mobile devices?

Here is our msal configuration:

const msalConfig: Msal.Configuration = {
  auth: {
    clientId: environment.clientId, //This is your client ID
    authority: "https://login.microsoftonline.com/common",
    redirectUri: "https://localhost:3000/fallbackauthdialog.html",
    navigateToLoginRequestUrl: false,
  },
  cache: {
    cacheLocation: "localStorage", // Needed to avoid "User login is required" error.
    storeAuthStateInCookie: true, // Recommended to avoid certain IE/Edge issues.
  },
};

var requestObj: Object = {
  scopes: [`${environment.clientId}/.default openid`],
};

The configuration was generated by the generator, we only changed the clientId. And the scope is different.

exextoc commented 3 years ago

Please find a document which has complete details about creating and customizing a sso-enabled add-in https://docs.microsoft.com/en-us/office/dev/add-ins/quickstarts/sso-quickstart-customize and this as well https://docs.microsoft.com/en-us/office/dev/add-ins/quickstarts/sso-quickstart. Hope this helps

4kochi commented 3 years ago

Thanks, i will try that.

But in the prerequisites is say A build of Microsoft 365 that supports the IdentityAPI 1.3 requirement set.. So i am not sure if this will work in the mobile Outlook App

exextoc commented 3 years ago

Please follow this https://docs.microsoft.com/en-us/office/dev/add-ins/quickstarts/sso-quickstart document as well ,this doesnot have "A build of Microsoft 365 that supports the IdentityAPI 1.3 requirement set" prerequisites

4kochi commented 3 years ago

Ok, so we resolved the issue. The problem was the redirectUri

Since our Add-In only has a client part, which is hosted on a static server and no backend (node.js) part, the call to https://localhost:3000/fallbackauthdialog.html is not correct. We had to make the redirectUri dynamic.

Here is our changed config:

const redirectUri = `${location.origin}/${environment.appNameUri}/fallbackauthdialog.html`;

const msalConfig: Msal.Configuration = {
  auth: {
    clientId: environment.clientId, //This is your client ID
    authority: "https://login.microsoftonline.com/common",
    redirectUri,
    navigateToLoginRequestUrl: false,
  },
  cache: {
    cacheLocation: "localStorage", // Needed to avoid "User login is required" error.
    storeAuthStateInCookie: true, // Recommended to avoid certain IE/Edge issues.
  },
};

var requestObj: Object = {
  scopes: [`${environment.clientId}/.default openid`],
};