diff --git a/Samples/auth/Office-Add-in-SSO-NAA/README.md b/Samples/auth/Office-Add-in-SSO-NAA/README.md index 47ca61eb5..00a86a8a1 100644 --- a/Samples/auth/Office-Add-in-SSO-NAA/README.md +++ b/Samples/auth/Office-Add-in-SSO-NAA/README.md @@ -56,6 +56,11 @@ For a list of supported hosts, see [NAA supported accounts and hosts](https://le - Select **Register**. 1. On the **Office-Add-in-SSO-NAA** page, copy and save the value for the **Application (client) ID**. You'll use it in the next section. +1. Under **Manage** select **Authentication**. +1. In the **Single-page application** pane, select **Add URI**. +1. Enter the value `https://localhost:3000/auth.html` and select **Save**. This redirect handles the fallback scenario when browser auth is used from add-in. +1. In the **Single-page application** pane, select **Add URI**. +1. Enter the value `https://localhost:3000/dialog.html` and select **Save**. This redirect handles the fallback scenario when the Office dialog API is used. For more information on how to register your application, see [Register an application with the Microsoft Identity Platform](https://learn.microsoft.com/graph/auth-register-app-v2). @@ -63,7 +68,7 @@ For more information on how to register your application, see [Register an appli 1. Clone or download this repository. 1. From the command line, or a terminal window, go to the root folder of this sample at `/samples/auth/Office-Add-in-SSO-NAA`. -1. Open the `src/taskpane/authConfig.ts` file. +1. Open the `src/taskpane/msalconfig.ts` file. 1. Replace the placeholder "Enter_the_Application_Id_Here" with the Application ID that you copied. 1. Save the file. @@ -74,9 +79,9 @@ For more information on how to register your application, see [Register an appli `npm install` `npm run start` -This will start the web server and sideload the add-in to Excel. +This will start the web server and sideload the add-in to Word. -1. In Excel, look for the **Show task pane** button and select it. +1. In Word, look for the **Show task pane** button and select it. 1. When the task pane opens, there are two buttons: **Get user data** and **Get user files**. 1. To see the signed in user's name and email, select **Get user data**. 1. To insert the first 10 filenames from the signed in user's Microsoft OneDrive, select **Get user files**. @@ -85,9 +90,9 @@ You'll be prompted to consent to the scopes the sample needs when you select the ## Selecting hosts and debugging steps -If you want to choose Word or PowerPoint, modify the `start` command in the `package.json` file to match one of the following entries. +If you want to choose Excel or PowerPoint, modify the `start` command in the `package.json` file to match one of the following entries. -- For Word: `"start": "office-addin-debugging start manifest.xml desktop --app word",` +- For Word: `"start": "office-addin-debugging start manifest.xml desktop --app excel",` - For PowerPoint: `"start": "office-addin-debugging start manifest.xml desktop --app powerpoint",` You can also debug the sample by opening the project in VS Code. @@ -105,8 +110,7 @@ For more information on debugging with VS Code, see [Debugging](https://code.vis The `src/taskpane/authConfig.ts` file contains the MSAL code for configuring and using NAA. It contains a class named AccountManager which manages getting user account and token information. - The `initialize` function is called from Office.onReady to configure and initialize MSAL to use NAA. -- The `ssoGetToken` function gets an access token for the signed in user to call Microsoft Graph APIs. -- The `ssoGetUserIdentity` function gets the account information of the signed in user. This can be used to get user details such as name and email. +- The `ssoGetAccessToken` function gets an access token for the signed in user to call Microsoft Graph APIs. The `src/taskpane/document.ts` file contains code to write a list of file names, retrieved from Microsoft Graph, into the document. This works for Word, Excel, and PowerPoint documents. diff --git a/Samples/auth/Office-Add-in-SSO-NAA/package-lock.json b/Samples/auth/Office-Add-in-SSO-NAA/package-lock.json index 6048a33d4..9477e8377 100644 --- a/Samples/auth/Office-Add-in-SSO-NAA/package-lock.json +++ b/Samples/auth/Office-Add-in-SSO-NAA/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "license": "MIT", "dependencies": { - "@azure/msal-browser": "^3.24.0", + "@azure/msal-browser": "^4.12.0", "core-js": "^3.37.1", "regenerator-runtime": "^0.14.1" }, @@ -497,6 +497,31 @@ "node": ">=18.0.0" } }, + "node_modules/@azure/identity/node_modules/@azure/msal-browser": { + "version": "3.28.1", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.28.1.tgz", + "integrity": "sha512-OHHEWMB5+Zrix8yKvLVzU3rKDFvh7SOzAzXfICD7YgUXLxfHpTPX2pzOotrri1kskwhHqIj4a5LvhZlIqE7C7g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@azure/msal-common": "14.16.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/identity/node_modules/@azure/msal-common": { + "version": "14.16.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.16.0.tgz", + "integrity": "sha512-1KOZj9IpcDSwpNiQNjt0jDYZpQvNZay7QAEi/5DLubay40iGYtLzya/jbjRPLyOTZhEKyL1MzPuw2HqBCjceYA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/@azure/logger": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.2.tgz", @@ -511,20 +536,22 @@ } }, "node_modules/@azure/msal-browser": { - "version": "3.24.0", - "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.24.0.tgz", - "integrity": "sha512-JGNV9hTYAa7lsum9IMIibn2kKczAojNihGo1hi7pG0kNrcKej530Fl6jxwM05A44/6I079CSn6WxYxbVhKUmWg==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.13.0.tgz", + "integrity": "sha512-n2ySryLd+wHmm/0Y1mwFI4J9UXVCu2DeWKtoWNWLVcpvK2k0Ez1qIigKleUm2ZfTbfAXdue+V8htmFft0qgyGQ==", + "license": "MIT", "dependencies": { - "@azure/msal-common": "14.15.0" + "@azure/msal-common": "15.7.0" }, "engines": { "node": ">=0.8.0" } }, "node_modules/@azure/msal-browser/node_modules/@azure/msal-common": { - "version": "14.15.0", - "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.15.0.tgz", - "integrity": "sha512-ImAQHxmpMneJ/4S8BRFhjt1MZ3bppmpRPYYNyzeQPeFN288YKbb8TmmISQEbtfkQ1BPASvYZU5doIZOPBAqENQ==", + "version": "15.7.0", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.7.0.tgz", + "integrity": "sha512-m9M5hoFoxhe/HlXNVa4qBHekrX60CVPkWzsjhKQGuzw/OPOmurosKRPDIMn8fug/E1hHI5v33DvT1LVJfItjcg==", + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -12047,9 +12074,9 @@ } }, "node_modules/tar-fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", - "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", + "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", "dev": true, "license": "MIT", "optional": true, diff --git a/Samples/auth/Office-Add-in-SSO-NAA/package.json b/Samples/auth/Office-Add-in-SSO-NAA/package.json index 8fba2a6bf..9fea346d6 100644 --- a/Samples/auth/Office-Add-in-SSO-NAA/package.json +++ b/Samples/auth/Office-Add-in-SSO-NAA/package.json @@ -20,7 +20,7 @@ "prettier": "office-addin-lint prettier", "signin": "office-addin-dev-settings m365-account login", "signout": "office-addin-dev-settings m365-account logout", - "start": "office-addin-debugging start manifest.xml desktop --app word", + "start": "office-addin-debugging start manifest.xml desktop --app excel", "start:desktop": "office-addin-debugging start manifest.xml desktop", "start:web": "office-addin-debugging start manifest.xml web", "stop": "office-addin-debugging stop manifest.xml", @@ -28,7 +28,7 @@ "watch": "webpack --mode development --watch" }, "dependencies": { - "@azure/msal-browser": "^3.24.0", + "@azure/msal-browser": "^4.12.0", "core-js": "^3.37.1", "regenerator-runtime": "^0.14.1" }, diff --git a/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/authConfig.ts b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/authConfig.ts index e455c42a7..d126ac960 100644 --- a/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/authConfig.ts +++ b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/authConfig.ts @@ -3,71 +3,169 @@ /* This file provides MSAL auth configuration to get access token through nested app authentication. */ -/* global console */ +/* global Office, console, document*/ -import { PublicClientNext, type IPublicClientApplication } from "@azure/msal-browser"; +import { + BrowserAuthError, + createNestablePublicClientApplication, + type IPublicClientApplication, +} from "@azure/msal-browser"; +import { msalConfig } from "./msalconfig"; +import { createLocalUrl } from "./util"; +import { getTokenRequest } from "./msalcommon"; -export { AccountManager }; - -const applicationId = "Enter_the_Application_Id_Here"; - -const msalConfig = { - auth: { - clientId: applicationId, - authority: "https://login.microsoftonline.com/common", - supportsNestedAppAuth: true, - }, +export type AuthDialogResult = { + accessToken?: string; + error?: string; }; +type DialogEventMessage = { message: string; origin: string | undefined }; +type DialogEventError = { error: number }; +type DialogEventArg = DialogEventMessage | DialogEventError; + // Encapsulate functions for getting user account and token information. -class AccountManager { - pca: IPublicClientApplication | undefined = undefined; +export class AccountManager { + private pca: IPublicClientApplication | undefined = undefined; + private _dialogApiResult: Promise | null = null; + private _usingFallbackDialog = false; + + private getSignOutButton() { + return document.getElementById("signOutButton"); + } + + private setSignOutButtonVisibility(isVisible: boolean) { + const signOutButton = this.getSignOutButton(); + if (signOutButton) { + signOutButton.style.visibility = isVisible ? "visible" : "hidden"; + } + } + + private isNestedAppAuthSupported() { + return Office.context.requirements.isSetSupported("NestedAppAuth", "1.1"); + } // Initialize MSAL public client application. async initialize() { - this.pca = await PublicClientNext.createPublicClientApplication(msalConfig); + // Make sure office.js is initialized + await Office.onReady(); + + // If auth is not working, enable debug logging to help diagnose. + this.pca = await createNestablePublicClientApplication(msalConfig); + + // If Office does not support Nested App Auth provide a sign-out button since the user selects account + if (!this.isNestedAppAuthSupported() && this.pca.getActiveAccount()) { + this.setSignOutButtonVisibility(true); + } + this.getSignOutButton()?.addEventListener("click", () => this.signOut()); } - async ssoGetToken(scopes: string[]) { - const userAccount = await this.ssoGetUserIdentity(scopes); - return userAccount.accessToken; + private async signOut() { + if (this._usingFallbackDialog) { + await this.signOutWithDialogApi(); + } else { + await this.pca?.logoutPopup(); + } + + this.setSignOutButtonVisibility(false); } /** - * Uses MSAL and nested app authentication to get the user account from Office SSO. - * This demonstrates how to work with user identity from the token. * - * @returns The user account data (identity). + * @param scopes the minimum scopes needed. + * @returns An access token. */ - async ssoGetUserIdentity(scopes: string[]) { + async ssoGetAccessToken(scopes: string[]) { + if (this._dialogApiResult) { + return this._dialogApiResult; + } + if (this.pca === undefined) { throw new Error("AccountManager is not initialized!"); } - // Specify minimum scopes needed for the access token. - const tokenRequest = { - scopes: scopes - }; - try { console.log("Trying to acquire token silently..."); - const userAccount = await this.pca.acquireTokenSilent(tokenRequest); + const authResult = await this.pca.acquireTokenSilent(getTokenRequest(scopes, false)); console.log("Acquired token silently."); - return userAccount; + return authResult.accessToken; } catch (error) { - console.log(`Unable to acquire token silently: ${error}`); + console.warn(`Unable to acquire token silently: ${error}`); } // Acquire token silent failure. Send an interactive request via popup. try { console.log("Trying to acquire token interactively..."); - const userAccount = await this.pca.acquireTokenPopup(tokenRequest); + const selectAccount = this.pca.getActiveAccount() ? false : true; + const authResult = await this.pca.acquireTokenPopup(getTokenRequest(scopes, selectAccount)); console.log("Acquired token interactively."); - return userAccount; + if (selectAccount) { + this.pca.setActiveAccount(authResult.account); + } + if (!this.isNestedAppAuthSupported()) { + this.setSignOutButtonVisibility(true); + } + return authResult.accessToken; } catch (popupError) { - // Acquire token interactive failure. - console.log(`Unable to acquire token interactively: ${popupError}`); - throw new Error(`Unable to acquire access token: ${popupError}`); + // Optional fallback if about:blank popup should not be shown + if (popupError instanceof BrowserAuthError && popupError.errorCode === "popup_window_error") { + const accessToken = await this.getTokenWithDialogApi(); + this.setSignOutButtonVisibility(true); + return accessToken; + } else { + // Acquire token interactive failure. + console.error(`Unable to acquire token interactively: ${popupError}`); + throw new Error(`Unable to acquire access token: ${popupError}`); + } } } + + /** + * Gets an access token by using the Office dialog API to handle authentication. Used for fallback scenario. + * @returns The access token. + */ + async getTokenWithDialogApi(): Promise { + this._dialogApiResult = new Promise((resolve, reject) => { + Office.context.ui.displayDialogAsync(createLocalUrl(`dialog.html`), { height: 60, width: 30 }, (result) => { + result.value.addEventHandler(Office.EventType.DialogEventReceived, (arg: DialogEventArg) => { + const errorArg = arg as DialogEventError; + if (errorArg.error == 12006) { + this._dialogApiResult = null; + reject("Dialog closed"); + } + }); + result.value.addEventHandler(Office.EventType.DialogMessageReceived, (arg: DialogEventArg) => { + const messageArg = arg as DialogEventMessage; + const parsedMessage = JSON.parse(messageArg.message); + result.value.close(); + + if (parsedMessage.error) { + reject(parsedMessage.error); + this._dialogApiResult = null; + } else { + resolve(parsedMessage.accessToken); + this.setSignOutButtonVisibility(true); + this._usingFallbackDialog = true; + } + }); + }); + }); + return this._dialogApiResult; + } + + signOutWithDialogApi(): Promise { + return new Promise((resolve) => { + Office.context.ui.displayDialogAsync( + createLocalUrl(`dialog.html?logout=1`), + { height: 60, width: 30 }, + (result) => { + result.value.addEventHandler(Office.EventType.DialogMessageReceived, () => { + this.setSignOutButtonVisibility(false); + this._dialogApiResult = null; + resolve(); + result.value.close(); + }); + } + ); + }); + } } diff --git a/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/fallback/auth.html b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/fallback/auth.html new file mode 100644 index 000000000..eb556cc62 --- /dev/null +++ b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/fallback/auth.html @@ -0,0 +1,13 @@ + + + + + + + + + + Auth Page + + + diff --git a/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/fallback/dialog.html b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/fallback/dialog.html new file mode 100644 index 000000000..52eeb38a2 --- /dev/null +++ b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/fallback/dialog.html @@ -0,0 +1,17 @@ + + + + + + + + + + Dialog + + + + + + + diff --git a/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/fallback/fallbackauthdialog.ts b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/fallback/fallbackauthdialog.ts new file mode 100644 index 000000000..330ec6ecb --- /dev/null +++ b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/fallback/fallbackauthdialog.ts @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/* This file handles MSAL auth for the fallback dialog page. */ + +/* global Office, window, URLSearchParams */ + +import { + AuthenticationResult, + createStandardPublicClientApplication, + IPublicClientApplication, +} from "@azure/msal-browser"; +import { getTokenRequest } from "../msalcommon"; +import { createLocalUrl } from "../util"; +import { defaultScopes, msalConfig } from "../msalconfig"; +import type { AuthDialogResult } from "../authConfig"; + +// read querystring parameter +function getQueryParameter(param: string) { + const params = new URLSearchParams(window.location.search); + return params.get(param); +} + +async function sendDialogMessage(message: string) { + await Office.onReady(); + Office.context.ui.messageParent(message); +} +async function returnResult(publicClientApp: IPublicClientApplication, authResult: AuthenticationResult) { + publicClientApp.setActiveAccount(authResult.account); + + const authDialogResult: AuthDialogResult = { + accessToken: authResult.accessToken, + }; + + sendDialogMessage(JSON.stringify(authDialogResult)); +} + +export async function initializeMsal() { + // Use standard Public Client instead of nested because this is a fallback path when nested app authentication isn't available. + const publicClientApp = await createStandardPublicClientApplication(msalConfig); + try { + if (getQueryParameter("logout") === "1") { + await publicClientApp.logoutRedirect({ postLogoutRedirectUri: createLocalUrl("dialog.html?close=1") }); + return; + } else if (getQueryParameter("close") === "1") { + sendDialogMessage("close"); + return; + } + const result = await publicClientApp.handleRedirectPromise(); + + if (result) { + return returnResult(publicClientApp, result); + } + } catch (ex: any) { + const authDialogResult: AuthDialogResult = { + error: ex.name, + }; + sendDialogMessage(JSON.stringify(authDialogResult)); + return; + } + + try { + if (publicClientApp.getActiveAccount()) { + const result = await publicClientApp.acquireTokenSilent(getTokenRequest(defaultScopes, false)); + if (result) { + return returnResult(publicClientApp, result); + } + } + } catch { + /* empty */ + } + + publicClientApp.acquireTokenRedirect(getTokenRequest(defaultScopes, true, createLocalUrl("dialog.html"))); +} + +initializeMsal(); diff --git a/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/msalcommon.ts b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/msalcommon.ts new file mode 100644 index 000000000..9cd2fc9b2 --- /dev/null +++ b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/msalcommon.ts @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +// This file provides common MSAL functions for use in the add-in project. + +import { + createNestablePublicClientApplication, + type IPublicClientApplication, + type RedirectRequest, +} from "@azure/msal-browser"; +import { msalConfig } from "./msalconfig"; + +/** + * Gets a token request for a given account context. + * @param accountContext The account context to get the token request for. + * @returns The token request. + */ +export function getTokenRequest(scopes: string[], selectAccount: boolean, redirectUri?: string): RedirectRequest { + let additionalProperties: Partial = {}; + if (selectAccount) { + additionalProperties = { prompt: "select_account" }; + } + if (redirectUri) { + additionalProperties.redirectUri = redirectUri; + } + return { scopes, ...additionalProperties }; +} + +let _publicClientApp: IPublicClientApplication; + +/** + * Returns the existing public client application. Returns a new public client application if it did not exist. + * @returns The nested public client application. + */ +export async function ensurePublicClient() { + if (!_publicClientApp) { + _publicClientApp = await createNestablePublicClientApplication(msalConfig); + } + return _publicClientApp; +} diff --git a/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/msalconfig.ts b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/msalconfig.ts new file mode 100644 index 000000000..4bb93ec93 --- /dev/null +++ b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/msalconfig.ts @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +// This file provides the default MSAL configuration for the add-in project. + +import { LogLevel } from "@azure/msal-browser"; +import { createLocalUrl } from "./util"; + +/* global console */ + +export const clientId = "Enter_the_Application_Id_Here"; // Replace with your actual Application ID +export const msalConfig = { + auth: { + clientId, + redirectUri: createLocalUrl("auth.html"), + postLogoutRedirectUri: createLocalUrl("auth.html"), + }, + cache: { + cacheLocation: "localStorage", + }, + system: { + loggerOptions: { + logLevel: LogLevel.Verbose, + loggerCallback: (level: LogLevel, message: string) => { + switch (level) { + case LogLevel.Error: + console.error(message); + return; + case LogLevel.Info: + console.info(message); + return; + case LogLevel.Verbose: + console.debug(message); + return; + case LogLevel.Warning: + console.warn(message); + return; + } + }, + piiLoggingEnabled: true, + }, + }, +}; + +// Default scopes to use in the fallback dialog. +export const defaultScopes = ["user.read", "files.read"]; diff --git a/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/taskpane.html b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/taskpane.html index 156344fdc..32023153e 100644 --- a/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/taskpane.html +++ b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/taskpane.html @@ -49,6 +49,11 @@

SSO with nested app authentication

Get user files Gets the first 10 items from the user's OneDrive and inserts them in the document. +

diff --git a/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/taskpane.ts b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/taskpane.ts index 92774609c..953d78f04 100644 --- a/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/taskpane.ts +++ b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/taskpane.ts @@ -46,19 +46,19 @@ Office.onReady((info) => { async function getUserData() { try { const userDataElement = document.getElementById("userData"); - const userAccount = await accountManager.ssoGetUserIdentity(["user.read"]); - const idTokenClaims = userAccount.idTokenClaims as { name?: string; preferred_username?: string }; - - console.log(userAccount); + const accessToken = await accountManager.ssoGetAccessToken(["User.Read"]); + const response: { displayName: string; mail: string } = await makeGraphRequest(accessToken, "/me", ""); + + console.log(response); if (userDataElement) { userDataElement.style.visibility = "visible"; } if (userName) { - userName.innerText = idTokenClaims.name ?? ""; + userName.innerText = response.displayName ?? ""; } if (userEmail) { - userEmail.innerText = idTokenClaims.preferred_username ?? ""; + userEmail.innerText = response.mail ?? ""; } } catch (error) { console.error(error); @@ -80,7 +80,7 @@ async function getUserFiles() { } async function getFileNames(count = 10) { - const accessToken = await accountManager.ssoGetToken(["Files.Read"]); + const accessToken = await accountManager.ssoGetAccessToken(["Files.Read"]); const response: { value: { name: string }[] } = await makeGraphRequest( accessToken, "/me/drive/root/children", diff --git a/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/util.ts b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/util.ts new file mode 100644 index 000000000..e777e142b --- /dev/null +++ b/Samples/auth/Office-Add-in-SSO-NAA/src/taskpane/util.ts @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +/* global window */ + +/** + * Constructs a local URL for the web page for the given path. + * @param path The path to construct a local URL for. + * @returns + */ +export function createLocalUrl(path: string) { + return `${window.location.origin}/${path}`; +} diff --git a/Samples/auth/Office-Add-in-SSO-NAA/webpack.config.js b/Samples/auth/Office-Add-in-SSO-NAA/webpack.config.js index 2c0d47144..4c3961c65 100644 --- a/Samples/auth/Office-Add-in-SSO-NAA/webpack.config.js +++ b/Samples/auth/Office-Add-in-SSO-NAA/webpack.config.js @@ -19,6 +19,7 @@ module.exports = async (env, options) => { entry: { polyfill: ["core-js/stable", "regenerator-runtime/runtime"], taskpane: ["./src/taskpane/taskpane.ts", "./src/taskpane/taskpane.html"], + dialog: ["./src/taskpane/fallback/fallbackauthdialog.ts"], }, output: { clean: true, @@ -58,6 +59,16 @@ module.exports = async (env, options) => { template: "./src/taskpane/taskpane.html", chunks: ["polyfill", "taskpane"], }), + new HtmlWebpackPlugin({ + filename: "auth.html", + template: "./src/taskpane/fallback/auth.html", + chunks: [], + }), + new HtmlWebpackPlugin({ + filename: "dialog.html", + template: "./src/taskpane/fallback/dialog.html", + chunks: ["dialog"], + }), new CopyWebpackPlugin({ patterns: [ {