Coder Social home page Coder Social logo

officedev / office-js-helpers Goto Github PK

View Code? Open in Web Editor NEW
124.0 32.0 56.0 1.94 MB

[ARCHIVED] A collection of helpers to simplify development of Office Add-ins & Microsoft Teams Tabs

License: MIT License

TypeScript 95.85% JavaScript 2.95% HTML 1.21%
dialog authentication localstorage office-addin microsoft-teams utilities

office-js-helpers's Introduction

❗️ Deprecation Notice ❗️ No Maintenance Intended

Thank you for all your efforts and contributions! office-js-helpers is a community-driven package of sample code that encapsulates a set of convenience functions. The package was initially developed as an example abstraction to common patterns found by developers. The community has been great at submitting ideas, issues, and fixes. As part of our latest campaign to ensure developers can quickly discover content and code, we are consolidating the many locations we post patterns and practices. To ensure we can focus our attention on the quality of content, we have deprecated the office-js-helpers package and archived this repository.

Can I still use this code?

Security vulnerabilities may exist in the project, or its dependencies. If you plan to reuse or run any code from this repo, be sure to perform appropriate security checks on the code or dependencies first. If you find these samples, patterns, and convenience functions useful, we encourage you to take the code under your wing, improve them, and use it on your own. Even though Microsoft will no longer be supporting this content going forward, you may use the code at your convenience, external to the package.

What will happen next?

To ensure that the community has some content and solutions for the common patterns and practices for Office Add-in, we have consolidated the content and will be providing additional material here soon.

Office JavaScript API Helpers

No Maintenance Intended

The current version includes the following helpers:

Getting Started

Installation

Development

This assumes you are using npm as your package manager.

To install the stable version:

npm install --save @microsoft/office-js-helpers

Production

You can access these files on unpkg, download them, or point your package manager to them.

You can also get the latest version from the releases tab

Usage

JavaScript

Ensure that the Office.js file is loaded inside of your .html page using:

<!-- Office.js -->
<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>

<!-- ES6 Shim of your choice -->
<script src="https://unpkg.com/core-js/client/core.min.js"></script>

Then reference the helpers library using one of the following:

<!-- Office JavaScript API Helpers (via CDN) -->
<script src="https://unpkg.com/@microsoft/[email protected]/dist/office.helpers.min.js"></script>

<!-- Office JavaScript API Helpers (via npm) -->
<script src="node_modules/@microsoft/office-js-helpers/dist/office.helpers.min.js"></script>

<!-- Office JavaScript API Helpers (via local) -->
<script src="office.helpers.js"></script>

TypeScript

If you are just referencing the library using a script tag then make sure to set your moduleResolution to node in your tsconfig.json to pickup the intellisense automatically. You will need to install the package via npm install @microsoft/office-js-helpers.

We will publish to DefinitelyTyped soon and then you can directly use typings to get access to the definitions.

If you are using any dependency loader such as RequireJS or SystemJS or module bundler such as browserify, webpack, you can use TypeScript import syntax to import specific modules. For example, one of the following:

import * as OfficeHelpers from '@microsoft/office-js-helpers';

import {Authenticator, DefaultEndpoints} from '@microsoft/office-js-helpers';

import {Authenticator, Storage} from '@microsoft/office-js-helpers';

import {Authenticator} from '@microsoft/office-js-helpers';

Helpers

Authentication

The Authentication helper is built for standards compliant OAuth Implicit Flow. Out of the box it directly integrates with Microsoft, AzureAD, Google, and Facebook authentication.

Microsoft integration uses the AzureAD AppModel v2 endpoints which uses Converged Authentication. It enables users to login using their Work, School, or Personal accounts.

Note on MSAL: This helper isn't a replacement for MSAL. When MSAL for JavaScript is released publicly, the helper will use MSAL.

For Office Add-ins

You need to meet the following requirements before you are able to successfully use the Authenticator inside Office Add-ins.

  1. You need to use https. This is important as we are using OAuth Implicit Flow and it is critical to secure the communication over the wire.
  2. Add the location of the provider in the AppDomains section of your add-in's manifest, as shown in the following example:
    <AppDomain>https://login.windows.net</AppDomain>
    <AppDomain>https://login.microsoftonline.com</AppDomain>

Setup the authenticator

Inside of your Office.initialize function add the following check:

if (OfficeHelpers.Authenticator.isAuthDialog()) return;

This to inform the Authenticator to automatically close the authentication dialog once the authentication is complete.

Note: This code needs to be run in the page that is redirected to from the provider. By default we assume the root url of your website. The code ensures that if an access_token, code, or error was received inside of the dialog, then it will parse it and close the dialog automatically. Also as an additional step it ensures that the state sent to the provider is the same as what was returned, to prevent Cross Site Request Forgery (CSRF).

Note: If using in an AngularJS/Angular/React project, please take a look #19 for information around bootstrapping your application correctly.

Initialize the authenticator

Create a new instance of Authenticator and register the endpoints. An endpoint corresponds to a service that allows the user to authenticate with.

var authenticator = new OfficeHelpers.Authenticator();

Then use one of the following:

// register Microsoft (Azure AD 2.0 Converged auth) endpoint using
authenticator.endpoints.registerMicrosoftAuth('client id here');

// register Azure AD 1.0 endpoint using
authenticator.endpoints.registerAzureADAuth('client id here', 'tenant here');

// register Google endpoint using
authenticator.endpoints.registerGoogleAuth('client id here');

// register Facebook endpoint using
authenticator.endpoints.registerFacebookAuth('client id here');

// register any 3rd-Party OAuth Implicit Provider using
authenticator.endpoints.add('Name of provider', { /* Endpoint Configuration - see office-js-helpers/src/authentication/endpoint.manager.ts */ })

// register Microsoft endpoint by overriding default values
authenticator.endpoints.registerMicrosoftAuth('client id here', {
    redirectUrl: 'redirect url here',
    scope: 'list of valid scopes here'
});

Authentication

To authenticate against the registered endpoint, do one of the following:

authenticator
    .authenticate('name of endpoint')
    .then(function(token) { /* handle success here */ })
    .catch(OfficeHelpers.Utilities.log);

// for the default Microsoft endpoint
authenticator
    .authenticate(OfficeHelpers.DefaultEndpoints.Microsoft)
    .then(function (token) { /* Microsoft Token */ })
    .catch(OfficeHelpers.Utilities.log);

// for the default AzureAD endpoint
authenticator
    .authenticate(OfficeHelpers.DefaultEndpoints.AzureAD)
    .then(function (token) { /* Microsoft Token */ })
    .catch(OfficeHelpers.Utilities.log);

// for the default Google endpoint
authenticator
    .authenticate(OfficeHelpers.DefaultEndpoints.Google)
    .then(function (token) { /* Google Token */ })
    .catch(OfficeHelpers.Utilities.log);

// for the default Facebook endpoint
authenticator
    .authenticate(OfficeHelpers.DefaultEndpoints.Facebook)
    .then(function (token) { /* Facebook Token */ })
    .catch(OfficeHelpers.Utilities.log);

If the user rejects the grant to the application then you will receive an error in the catch function.

Getting a cached token

By default the tokens are cached to the LocalStorage and upon expiry the AuthDialog is invoked again. You can also pass the force parameter as true as the second input to authenticator.authenticate() to re-authenticate the user.

authenticator
    .authenticate('name of endpoint')
    .then(function(token) {
    /*
        `token` is either cached or newly obtained upon expiry.
    */
    })
    .catch(OfficeHelpers.Utilities.log);

authenticator
    .authenticate('name of endpoint', true /* force re-authentication */)
    .then(function(token) {
    /*
        `token` is newly obtained.
    */
    })
    .catch(OfficeHelpers.Utilities.log);

// get the cached token if any. returns null otherwise.
var token = authenticator.tokens.get('name of endpoint');

If a cached token expires, then the dialog is automatically launched to re-authenticate the user.

Note on Refresh Tokens: By default, Implicit OAuth does not support Token Refresh as a security measure. This is because Access Tokens cannot be securely stored inside a JavaScript client.

Contributing

Please read Contributing for details on our code of conduct, and the process for submitting pull requests to us.

This project has adopted the Microsoft Open Source Code of Conduct. For more information, see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

License

This project is licensed under the MIT License - see the License file for details.

office-js-helpers's People

Contributors

akrantz avatar alexjerabek avatar casieber avatar darcyparker avatar davidchesnut avatar dependabot[bot] avatar elizabethsamuel-msft avatar glittle avatar ianvs avatar karma-design avatar lindalu-msft avatar loumm avatar m1chaeldg avatar millerds avatar mkuleshov avatar o365devx avatar rick-kirkham avatar sumurthy avatar umasubra avatar wrathofzombies avatar zlatkovsky avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

office-js-helpers's Issues

endpointmanager.ts extend config not working as expected

There are 4 occurrences where the config object is extended using the Lodash 'extend' method.
In each of these, the initial empty object is extended first with the overrides, then with the defaults. Doesn't this mean that any custom setting defined in the overrides will be actually overridden by an existing default value ?

Entire lodash is being added to dependent projects

I noticed that my bundle for my add-in has 74kb (gzipped) of lodash in it, even though I don't use lodash in my project. It seems that it's being pulled in because of office-js-helpers and the way that it imports from lodash.

I did a little investigating, and it seems that as of today, it's not super simple to tree-shake lodash with typescript. https://medium.com/@martin_hotell/tree-shake-lodash-with-webpack-jest-and-typescript-2734fa13b5cd has a good rundown of the challenges and various approaches that can be taken. It seems that there's upcoming support for a pure-modules flag that lodash can/will use, but it doesn't seem to be released in webpack yet:
https://twitter.com/jdalton/status/893109185264500737, and it also seems this project uses browserify. Also, I think you'd need to compile down to ES2015 modules, which I'm not sure all your consumers would be able to handle, so you'd need to perhaps have multiple different builds.

One sure-fire way of ensuring that you do not ship extra code to consumers is to depend on individual lodash modules like lodash.iserror. Then, no matter what kind of build process the consuming add-ins use, they are guaranteed not to get too much code.

I attempted various approaches like importing from lodash-es instead of lodash, more focused imports like import debounce from 'lodash/debounce';, etc. But I ran into trouble with either typescript or browserify, neither of which I have much experience with.

So, I guess I would ask if you could find some way to avoid consumers from pulling in all of lodash because of office-js-helpers.

office-js-helper

I have been trying to implement a custom app in Teams. As part of the app i am making a call to an external web API. I am trying to use the office-js-helpers library to obtain a id_token, but I am seeing that the _handleTokenResult does not handle the id_token responsetype result, even though the library allows for providing a responseType. Am I missing something obvious? Or is not supporting this auth pattern intentional within the library. Also, i am using this library to handle the team situation with the popup as opposed to hidden IFRAME that the adal.js library uses.

Unable to get property 'registerForEvent' of undefined or null reference

When I use OfficeHelpers.Authenticator.isAuthDialog() throw this error and IE doesn't close de dialog
Example:
Office.initialize = function (){

		if (OfficeHelpers.Authenticator.isAuthDialog()) return;
		var authenticator = new OfficeHelpers.Authenticator();
		 authenticator.endpoints.add("endpoint", {
			baseUrl: "BASE_URL",
			authorizeUrl: "Authorize_URL",
			clientId: "Client_id",
			responseType: "token",
			scope: "user",
			redirectUrl: "redirect",
		});

		var t = authenticator.authenticate("endpoint");
		t.then(function(token){

			console.log("logged");
		})
		.catch(function(error){

			console.log(error);
		})
	}

Samples for OfficeJSHelper

Hi,
There should be samples to implement OfficeJSHelper.
Samples Like : Javascript Samples - SPA, C# .NET and NodeJS implementation.

ng build Error

Hi,

I am building an OfficeJS add-in for Word that is using Angular 4.

I installed @microsoft/office-js-helpers from NPM:

npm install @microsoft/office-js-helpers --save

Then, as soon as I reference it:

import { Utilities } from '@microsoft/office-js-helpers';

and then ng build I get the following:

webpack: Compiling...
Hash: cdde99e2c228a80bddc3
Time: 385ms
chunk    {0} polyfills.bundle.js, polyfills.bundle.js.map (polyfills) 232 kB {4} [initial]
chunk    {1} styles.bundle.js, styles.bundle.js.map (styles) 65.2 kB {4} [initial]
chunk    {2} main.bundle.js, main.bundle.js.map (main) 5.09 kB {3} [initial] [rendered]
chunk    {3} vendor.bundle.js, vendor.bundle.js.map (vendor) 2.73 MB [initial]
chunk    {4} inline.bundle.js, inline.bundle.js.map (inline) 0 bytes [entry]

ERROR in [PATH]/node_modules/@microsoft/office-js-helpers/dist/office.helpers.d.ts (303,41): Cannot find namespace 'Excel'.

ERROR in [PATH]/node_modules/@microsoft/office-js-helpers/dist/office.helpers.d.ts (303,106): Cannot find namespace 'Excel'.
webpack: Failed to compile.

What am I doing wrong?

Need to increase the oauth2 token expiration

When I trying to authenticate using registerMicrosoftAuth I notice that the token expire by default in 3600 seconds.

I was reviewing the library and I'm seeing a method setExpiry inside TokenStorage class

static setExpiry(token: IToken) {
let expire = seconds => seconds == null ? null : new Date(new Date().getTime() + ~~seconds * 1000);
if (!(token == null) && token.expires_at == null) {
token.expires_at = expire(token.expires_in);
}
}

Is there any easy way to set the desired expiration date before request the authenticate method?

This is how I'm requesting the token:

OutlookAuthenticate() {
    const authenticator = new Authenticator();
    authenticator.endpoints.registerMicrosoftAuth(microsoftApplicationClientId, {
      scope: 'User.Read User.ReadBasic.All Contacts.Read Contacts.ReadWrite',
    });
    return authenticator.authenticate(DefaultEndpoints.Microsoft)
      .then(this.parseResponse);
  }

Authentication fails for web scenario (non-add-in) on IE 11

Today's readme says the following:

Inside of your Office.initialize function add the following check:

if (OfficeHelpers.Authenticator.isAuthDialog()) return;

This to inform the Authenticator to automatically close the authentication dialog once the
authentication is complete.

This works great for an Office Add-in. But what about the web scenario? There the function returns "false" because host is web, and so the dialog flow -- including messaging back to the parent -- fails to complete.

You can actually see this in Script Lab itself, when using it on the web. Just try signing in to https://script-lab.azureedge.net/

Note that the issue only manifests itself on Internet Explorer (IE 11), not Chrome.

Suggestion: Rather (or in addition) to having the isAuthDialog method (which is actually a bit weird anyway, having it be an is but having sideffects), can we have a closeAuthDialog method? Ideally the authenticate method would just add some query string parameter (e.g., ?isAuthDialog=true to the return URI, and read it off from there). I am also ok with that method requiring a parameter, I can do the query string myself. But in any case, I need to be able to close the dialog even when running in IE11 in a web-only context.

Thanks!

Is there anything difference settings between Azure AD only App and Converaged App?

Under Application Registration Portal, there are 2 types of applications, converaged app and Azure AD only app.

I followed the steps and successfully get the token from the app in "converaged app" type.
However the same code same settings, it does not work when the app in "Azure AD only applications" type. The returned error when calling the authenticator.authenticate method is,

AADSTS90130 : Application'[My App ID]' ([My App Name]) is not supported over the /common or /consumers endpoints. Please use the /organizations or tenant-specific endpoint.

I also tried to use the Azure AD by adding the following to authenticator.endpoints.registerMicrosoftAuth, but it does not work too and the new error is

baseUrl: "https://login.microsoftonline.com/[My Tenant ID]/oauth2"

Error Message is:
AADSTS50001 : Resource identifier is not provided.

0.8.0-beta.1 includes `.html` require in dist file

@WrathOfZombies thanks for the beta to address #35. I tried using it, and after yarn add @microsoft/[email protected], I'm getting the following error when I try to build my extension:

Module not found: Error: Can't resolve './message-banner.html' in 'node_modules/@microsoft/office-js-helpers/dist/ui'

I believe you need to use file-loader in addition to html-loader to get the contents of the html file. (But that's just a guess).

How to handle "Uncaught Error: The user chose to ignore the dialog box"?

Is there a way to catch or handle this error (thrown if the user clicks "Ignore" when prompted to open a new window for oauth)?

I've got a .catch in place which is reached if the user closes the opened dialog prematurely, but there doesn't seem to be any higher level with which to wrap the call to authenticate.

authenticator
    .authenticate(`${subdomain}.${domain}`, force)
    .then(function(token) {
      console.log("got token", token)
      return token
    })
    .catch(function(err) {
      console.log("error authenticating (user closed dialog)", err)
    })

Unit testing

Do you have samples of unit tests for this framework, where we can supply test user credentials
and more generally how do we test any office js addins?
Ta

Unpin rxjs if possible

Hi, I see that you've pinned to rxjs version 5.2.0 instead of following semver with something like ^5.2.0. I am also using rxjs in my add-in, but at a different (more recent) version. Because of this, I now have two versions of the same package being bundled. Is it possible to use a more generous range for rxjs in this package?

Thanks!

Dialog error 12002

I started new office JS project , the default Word sample, removed all code in Office.initialize, to the point where I only get the following code in Home.js:

`(function () {
"use strict";

// The initialize function must be run each time a new page is loaded.
Office.initialize = function (reason) {
    $(document).ready(function () {
        
        if (OfficeHelpers.Authenticator.isAuthDialog())
            return;

        var authenticator = new OfficeHelpers.Authenticator();
        authenticator.endpoints.registerAzureADAuth('##MYAPPID##', '##MYTENANT##');
        authenticator
            .authenticate(OfficeHelpers.DefaultEndpoints.AzureAD, true)
            .then(function(token) {
                console.log(token);
            })
            .catch(OfficeHelpers.Utilities.log);
    });
};

})();`

I know this appId and tenant work fine since I can get the same code to work with ADAL outside office JS, and already ironed out all reply urls and other issues,

The call to _openAuthDialog inside authenticator.authenticate never returns to the promise, and I experience the following error in JS console:

oauthdialog

The Auth popup does appear on top of Web Add-ins, but closes immediately after echoing this error,

Any ideas what is going wrong?

Second question: Am I correct to assume I can use this library for something else than MS Graph, such as Microsoft Dynamics 365 OData endpoint which supports OAuth 2.0 as well, or is this just for Office365 and MSGraph?

Thanks

Loading https://...?_host__Info=... disturbs future loading of other pages

Hello,

I just discovered OfficeJSHelpers. I added console.log("OfficeHelpers.Utilities.host: " + OfficeHelpers.Utilities.host) and console.log("OfficeHelpers.Utilities.platform: " + OfficeHelpers.Utilities.platform) to my website. It works fine, but when I load in a browser https://localhost:3000/try?_host_Info=excel|web|16.00|en-us|7fe9b4e9-d51e-bea5-d194-c817bc5ed4bc|isDialog#%2Ftry%3F_host_Info=excel%7Cweb%7C16.00%7Cen-us%7C7fe9b4e9-d51e-bea5-d194-c817bc5ed4bc%7CisDialog (see why I have this url here), it considers EXCEL as host and OFFICE_ONLINE as platform, and raised an error Uncaught TypeError: Cannot read property '_appName' of null in excel-web-16.00.js.

What is worse is that, it disturbs the loading of other pages. Now, all the pages like https://localhost:3000/home or https://localhost:3000/try in a browser returns EXCEL as host and OFFICE_ONLINE as platform, and raised an error Uncaught Error: Sys.ArgumentNullException: Value cannot be null. Parameter name: conversationId in excel-web-16.00.js. The only solution is to clearing browser history data.

I think it is a bug...

Thank you

Logout - Azure AD?

Following advice from #41 on logout, I implemented logout of Azure AD using this code:
function Logout() {
window.location.replace("https://login.microsoftonline.com/" + Tenant + "/oauth2/logout?post_logout_redirect_uri=" + encodeURIComponent(location.origin + location.pathname));
}

This takes me to the Azure AD logout page and seems to be doing logoff...

Then I'm redirected to the post_logout_redirect_uri, which is my main page from SPA office web addins, and the following calls are made again:

authenticator.endpoints.registerAzureADAuth(...)
authenticator.authenticate(OfficeHelpers.DefaultEndpoints.AzureAD)

This brings up the Azure AD login dialog, which immediately closes and reauthenticates with same user... So I'm unable to login with a different user, and entering a loop of login/logout...

Am I missing something here? Do I need to also clear cookies or localstorage or sessionstorage or else?
Where are the tokens saved? Can I delete them from my code?

Thanks

Avoid ugly/scary `X wants to display a new window.`

We are using this library to handle authentication, but when clicking our Log in button, users are shown a App wants to display a new window. dialog which they can choose to Allow or Ignore. Is there any way to avoid this clunky interaction? I am concerned that it will cause confusion and abandonment among our users.

If there's currently no way (it seems there isn't), is there a chance that any changes could be made so that it can be avoided/eliminated?

Incompatible with Office 2013?

I found that this library is not working when I try to use it in Outlook 2013, and it seems to be due to the use of displayDialogAsync. Is this a known limitation? If so, perhaps it is something good to list in the readme?

12007 error when using authenticator.authenticate to authenticate to Azure Active Directory

I'm receiving an error when calling authenticator.authenticate to authenticate to AAD. If I debug into line 257 of officehelpers.js, I see that the error code is a 12007, which according to the office docs corresponds to multiple dialog boxes opened, but no dialog has been opened. Do I have something wrong with the configuration? I've also added login.windows.net as an app domain to my manifest. My code making the call is below.

            let authenticator = new OfficeHelpers.Authenticator();        
            authenticator.endpoints.registerAzureADAuth("<clientId>", "<tenantName>")
            console.log(authenticator)
            authenticator
                .authenticate(OfficeHelpers.DefaultEndpoints.AzureAD)
                .then(function (token) { console.log("Successfully authenticated", token) })
                .catch(function(error) { console.log("Failed to authenticate", error) })      

Got and solved an Error in Google Chrome Browser

The state was undefined because in "params" the "state" got saved like this: "result./state"

`Authenticator.extractParams = function (segment) {
if (segment == null || segment.trim() === '') {
return null;
}
var params = {}, regex = /([^&=]+)=([^&]*)/g, matchParts;
while ((matchParts = regex.exec(segment)) !== null) {

        // NEXT LINE GOT ADDED
        if (matchParts[1] === "/state") matchParts[1] = matchParts[1].replace("/", "");
        params[decodeURIComponent(matchParts[1])] = decodeURIComponent(matchParts[2]);
    }
    return params;
};`

Do we have SAML2 support ?

I am using the AzureAD SAML2 for My WebApp which we are soon going to integrate with Office 365.

We have SAML2 in office-js-helpers

OfficeHelpers.Utilities.platform returns null in Excel for Windows

Hello,

I load the following page as an Excel add-in in Excel (Office 365 Version 1706) for Windows 7. It shows EXCEL as host, but null as platform. I cleared my browser history before the tests...

It seems that for the same code, it showed PC yesterday...

Shouldn't it be always PC in Excel for Windows?

Thank you

<html>
    <head>
        <script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
        <script src="https://unpkg.com/@microsoft/[email protected]/dist/office.helpers.min.js"></script>
    </head>
    <body>
        <div id="console"></div>
        <script>
            debug("OfficeHelpers.Utilities.host: " + OfficeHelpers.Utilities.host + "<br/>");
            debug("OfficeHelpers.Utilities.platform: " + OfficeHelpers.Utilities.platform);

            function debug(msg) {
                if (document.getElementById("console") !== null)
                    document.getElementById("console").innerHTML += msg;
            }
        </script>
    </body>
</html>

Guidance for use in Outlook

I'm having issues trying to use this library in an Outlook web add-in with Azure AD. I can get the auth dialog to popup and have the user login and then authorize the application. However after that step (and subsequent retries) the auth page displays the "Sorry, but we're having trouble signing you in" page with this error:

AADSTS50011: The reply address 'https://mywebapp.azurewebsites.net' does not match the reply addresses configured for the application

The full issue is documented here: https://stackoverflow.com/questions/47276315/problems-with-azure-application-manifest-trying-to-authenticate-with-office-js-h.

What exactly is the relationship between the add-in's url and the Reply URL for the application manifest (I have the same for both)? That seems to be the core of the problem but I can't figure out what else it should be.

A secondary issue is that the auth popup doesn't appear when the add-in is hosted in a browser (it only works with Outlook desktop). I see a DOM error about blocking a cross-origin frame. Can the helpers be used at all from the browser?

Get User Name?

Hi office-js-helpers,

Great tool, I just can't figure out where to get the username after receiving the token?
I know ADAL.js gives us the username, but can't find it in this lib.

Any advice?

Is it possible to refresh an access token without requesting user login?

Using adal.js with implicit flow it is possible to refresh the obtained access token (without a refresh token) and thus prolong the user session without requiring user login. This is possible until the Azure AD session cookies expire.
Is this possible with office-js-helpers? I would like to keep the user logged in as long as possible.

Getting id_token fails

I am right now trying to get an id_token through Office-js-helpers, because this seems compatible with ADAL.js behaviour for my app:

me.Authenticator = new OfficeHelpers.Authenticator();
me.Authenticator.endpoints.registerAzureADAuth(settings.clientId, settings.tenant, {
responseType: 'id_token',
redirectUrl: window.location.origin + window.location.pathname
});
me.Authenticator
.authenticate(OfficeHelpers.DefaultEndpoints.AzureAD)
.then(function (token) {
me.successCallback(token.id_token);
})
.catch(OfficeHelpers.Utilities.log);

This fails in Office-js-helpers because authenticator._handleTokenResult does not handle the "id_token" case.

How to correctly check the host: Office, Office online and web browser.

*** Sorry in advance if this is not the right forum for this question! ***
I would like to detect whether a user has hit the URL of my add-in from a browser, outside of Office and Office online.

I've looked at the utility functions OfficeHelpers.Utilities.host and OfficeHelpers.Utilities.isAddin but the docs say these will only work after Office.initialize is called. If the URL has been navigated to from outside of an Office client then this won't be the case (?).

So I need to perform the same check as whatever is being done when you get the warning:
image

A simple use of this, would be to direct users to a page that displays explains they cannot access this without loading it as an add-in, and instructions on how to load the add-in etc.

The actual result I am trying to get is to handle both cases as:

  1. From within an Office client: "GetData" will return some values and write them to a document.
  2. If accessed from a browser: "GetData" will return some value and redirect to a View to display these.

Is there anything wrong with doing this? And how should it be done?

Please add npm script to run tests

How do you run your tests? I did not find npm run test.

On a related note, typings is required for npm run build. I see you install it for travis... I suspect it was an oversight to not including installing typings with npm install. I can see why you wouldn't put it in definition for npm run build because you don't need to keep installing typings. I suspect you want to add:
"postinstall": "npm run typings install" to the scripts section of your package.json?

Adding a new endpoint fails in Excel Add-In in Chrome

I'm trying to use the Office Helpers to authenticate against a private OAuth2 endpoint with implicit flow in a React based Add-In for Excel.

When I run the following code in the add-in within the Office.initialize callback and my add-in is side loaded in Excel 365 :

const authenticator = new Authenticator();
authenticator.endpoints.add('MyID', {
    ...config options...
});

I always get the following error from chrome in the debug console:

Uncaught DOMException: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.
    at EndpointStorage.Storage.switchStorage (eval at ../node_modules/@microsoft/office-js-helpers/dist/helpers/storage.js (https://localhost:3100/app.d84d4783b7237d4a074c.js:871:1), <anonymous>:121:61)
    at EndpointStorage.Storage [as constructor] (eval at ../node_modules/@microsoft/office-js-helpers/dist/helpers/storage.js (https://localhost:3100/app.d84d4783b7237d4a074c.js:871:1), <anonymous>:104:15)
    at new EndpointStorage (eval at ../node_modules/@microsoft/office-js-helpers/dist/authentication/endpoint.manager.js (https://localhost:3100/app.d84d4783b7237d4a074c.js:815:1), <anonymous>:38:23)
    at new Authenticator (eval at ../node_modules/@microsoft/office-js-helpers/dist/authentication/authenticator.js (https://localhost:3100/app.d84d4783b7237d4a074c.js:807:1), <anonymous>:87:30)
    at Object.eval (eval at ./main.tsx (https://localhost:3100/app.d84d4783b7237d4a074c.js:6972:1), <anonymous>:18:21)
    at Object.eval (eval at ./main.tsx (https://localhost:3100/app.d84d4783b7237d4a074c.js:6972:1), <anonymous>:50:27)
    at eval (eval at ./main.tsx (https://localhost:3100/app.d84d4783b7237d4a074c.js:6972:1), <anonymous>:51:30)
    at Object../main.tsx (https://localhost:3100/app.d84d4783b7237d4a074c.js:6972:1)
    at __webpack_require__ (https://localhost:3100/app.d84d4783b7237d4a074c.js:693:30)
    at fn (https://localhost:3100/app.d84d4783b7237d4a074c.js:112:20)

Is there a way to prevent the EndpointManager from using the localStorage ?

I tried both version 0.7.4 and 0.8.0-beta.4 without success.

excel add-in opens new tab in chrome instead of pop-up

I'm using a Mac - behavior is as expected if opened via Chrome itself (opens a pop-up), but when opened as an add-in within excel, it instead opens a new tab in Chrome preventing the user from completing the sign-in process.

Perhaps related to firebase/firebase-js-sdk#63 (though I'm using Chrome 64, which should be fixed)

Also is there any documentation on how to debug an add-in when it's opened within an Office product?

Azure AD B2C - presenting wrong login page.

Is it possible to use it for Azure Active Directory B2C ? When i try to use the library with following code:

this.authenticator = new OfficeHelpers.Authenticator();
this.authenticator.endpoints.registerAzureADAuth('myClientId', 'myTenant');
...
this.authenticator.authenticate(OfficeHelpers.DefaultEndpoints.AzureAD)

It's opening the "general" microsoft login page instead of my tenant's login page.

Unhandled exception in https://localhost:*****/office.helpers.min.js 0x800a1391 - JavaScript runtime error: 'Promise' is undefined occurred

Hi,
I have done following code in Home.js. It returns following exception.

Unhandled exception at line 1, column 1149 in https://localhost:44365/office.helpers.min.js
0x800a1391 - JavaScript runtime error: 'Promise' is undefined occurred

sample.zip

Solution : Add following code before OfficeJSHelper.js

<!-- IE support: add promises polyfill before msal.js  -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.4/bluebird.min.js" class="pre"></script>

newWindowNotificaiton dialog

Hi!

Is there any easy task to get past the "issue" of having to approve opening of a new window?

newwindownotification
Thanks in advance
(The misspelling -> newWindowNotificaiton is actually copied from the webinspector)

IE11 does not send token back to add-in

I seem to be having the same problems as described in #5, but I'm using the latest version of this package (0.7.4). I've made sure that all domains are in my manifest, and all the self-signed certs are installed correctly. I don't see any error messages, so it's difficult to troubleshoot, but after authentication succeeds, the redirect url is loaded into the existing auth popup instead of closing and sending the token back to the add-in. Is there anything else I can try to troubleshoot this?

container params colliding for endpoints and token storage

See:

If you set up an OAuth endpoint via:

const authenticator = new Authenticator();
authenticator.endpoints.add(OAUTH_CLIENT.clientName, {
  clientId: OAUTH_CLIENT.clientId,
  baseUrl: OAUTH_CLIENT.baseUrl,
  authorizeUrl: OAUTH_CLIENT.authorizeUrl,
  responseType: 'token'
});

And try to print out a token (should be null), via:

console.log(authenticator.tokens.get(OAUTH_CLIENT.clientName));

You get the endpoint configuration back.

Suggested fix:
Change line 36 in token.manager.ts to super('OAuth2Tokens', storageType);

Need help with authenticator(Popup is not closing)

Hi,

So far I followed all the steps on how to setup this. Like adding the IDP/SSO in app domain list in the manifest file. Setting the Requirement set MinVersion to 1.4 of Mailbox. Using https and trusted cert.

The authentication popup is working and redirecting to our SSO eg google and custom SSO (Identity Server 4). The user can login but when it comes to close or send a message from popup dialog to the parent windows it always says :

Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://outlook.office.com') does not match the recipient window's origin ('https://localhost:3000').
invoke @ outlook-web-16.01.js:9

Btw, the popup or the invoke of authenticate was fired from the web outlook addin.

Any idea or tips on how to solve this?

Thanks
Mike

Popup window authentication on IE and Edge is left open instead of closed

Hi,

Running over IE or Edge has different behavior than running on Firefox or Chrome. While Chrome and Firefox authentication popup window closes once authentication is done, and data is retrieved back in the original window, this is not the case within Internet Explorer or Edge.
IE and Edge popup window won't close which causes retrieved token to remain in new popup window rather than return to original caller window. Once authentication is done, the new popup window is redirected to the "redirection URL" assigned in endpoint.

Opening SSO popup fails

I got the SSO login working in Chrome with popup, and now I am trying the Outlook plugin against Outlook 2016 (EXE version 16.0.8431.2107). When I open F12 Developer Tools and call

Authenticator.authenticate("AzureAD")

I get

Script 5022: Die Domäne der URL ist nicht im "AppDomains"-Element im Manifest enthalten.

but the endpoint's baseUrl is

https://login.windows.net/09265c06-...-1c39

and my AddIn's AppDomains are (copied from a Microsoft list):

``
api.login.microsoftonline.com
clientconfig.microsoftonline-p.net
device.login.microsoftonline.com
hip.microsoftonline-p.net
hipservice.microsoftonline.com
login.microsoft.com
login.microsoftonline.com
logincert.microsoftonline.com
loginex.microsoftonline.com
login-us.microsoftonline.com
login.microsoftonline-p.com
nexus.microsoftonline-p.com
stamp2.login.microsoftonline.com
login.windows.net

I now found this comment by a Microsoft employee:

https://stackoverflow.com/questions/45438165/domain-is-not-trusted-using-word-2016-while-opening-dialog-to-remote-url

The page, controller method, or other resource that is passed to the displayDialogAsync method must be in the same domain as the host page.

It seems that you call displayDialogAsync with the remote URL; is that correct, and did that work for anyone at all?

Issue with AngularJS $state.provider and redirecting.

It's more an information than an issue.

If you are using angularjs router or stateprovider with redirecting, the popup url will immediately redirected to the default url you set.

The result of that is, that the token couldn't read out of the URL from the popup. Additionally the popup doesn't close automatically.

Sometimes it works because in this case the read out was faster than the redirection of angularjs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.