From 599ba7effa0b0b0360eccfdd60dafe49e4a6dd28 Mon Sep 17 00:00:00 2001 From: Hector Morales Date: Tue, 11 Nov 2025 18:32:11 -0800 Subject: [PATCH 01/14] Update base readme --- README.md | 37 +++++++++++++++---------- docs/diagrams/png/PackageStructure.png | Bin 37955 -> 35472 bytes 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index c76fe21168..c662d944af 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ # Microsoft Authentication Library for JavaScript (MSAL.js) -The Microsoft Authentication Library for JavaScript enables both client-side and server-side JavaScript applications to authenticate users using [Azure AD](https://docs.microsoft.com/azure/active-directory/develop/v2-overview) for work and school accounts (AAD), Microsoft personal accounts (MSA), and social identity providers like Facebook, Google, LinkedIn, Microsoft accounts, etc. through [Azure AD B2C](https://docs.microsoft.com/azure/active-directory-b2c/active-directory-b2c-overview#identity-providers) service. It also enables your app to get tokens to access [Microsoft Cloud](https://www.microsoft.com/enterprise) services such as [Microsoft Graph](https://graph.microsoft.io). +The Microsoft Authentication Library for JavaScript enables both client-side and server-side JavaScript applications to authenticate users using [Microsoft Entra ID](https://docs.microsoft.com/azure/active-directory/develop/v2-overview) for work and school accounts, Microsoft personal accounts (MSA), and social identity providers like Facebook, Google, LinkedIn, Microsoft accounts, etc. through [Azure AD B2C](https://docs.microsoft.com/azure/active-directory-b2c/active-directory-b2c-overview#identity-providers) service. It also enables your app to get tokens to access [Microsoft Cloud](https://www.microsoft.com/enterprise) services such as [Microsoft Graph](https://graph.microsoft.io). ## Repository ### Core, wrapper and extensions libraries -The [`lib`](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib) folder contains the source code for our libraries in active development. You will also find all the details about **installing the libraries** in their respective README.md. +The [`lib`](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib) folder contains the source code for our libraries in active development. You will also find all the details about **installing the libraries** in their respective README.md.\ + +- [Microsoft Authentication Library for JavaScript](lib/msal-browser/): A browser-based, framework-agnostic browser library that enables authentication and token acquisition with the Microsoft Identity platform in JavaScript applications. Implements the OAuth 2.0 [Authorization Code Flow with PKCE](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow), and is [OpenID-compliant](https://docs.microsoft.com/azure/active-directory/develop/v2-protocols-oidc). - [Microsoft Authentication Library for Node.js](lib/msal-node/): A [Node.js](https://nodejs.org/en/) library that enables authentication and token acquisition with the Microsoft Identity platform in JavaScript applications. Implements the following OAuth 2.0 protocols and is [OpenID-compliant](https://docs.microsoft.com/azure/active-directory/develop/v2-protocols-oidc): @@ -17,7 +19,6 @@ The [`lib`](https://github.com/AzureAD/microsoft-authentication-library-for-js/t - [Silent Flow](https://docs.microsoft.com/azure/active-directory/develop/msal-acquire-cache-tokens#acquiring-tokens-silently-from-the-cache) - [On-behalf-of Flow](https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow) -- [Microsoft Authentication Library for JavaScript](lib/msal-browser/): A browser-based, framework-agnostic browser library that enables authentication and token acquisition with the Microsoft Identity platform in JavaScript applications. Implements the OAuth 2.0 [Authorization Code Flow with PKCE](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow), and is [OpenID-compliant](https://docs.microsoft.com/azure/active-directory/develop/v2-protocols-oidc). - [Native Authentication Support for JavaScript](lib/msal-browser/src/custom_auth/): MSAL also provides native authentication APIs that allow applications to implement a native experience with end-to-end customizable flows in their applications. With native authentication, users are guided through a rich, native, sign-up and sign-in journey without leaving the app. The native authentication feature is available for SPAs on [External ID for customers](https://learn.microsoft.com/en-us/entra/identity-platform/concept-native-authentication). It is recommended to always use the most up-to-date version of the SDK. @@ -27,33 +28,39 @@ The [`lib`](https://github.com/AzureAD/microsoft-authentication-library-for-js/t - [Microsoft Authentication Library for Angular](lib/msal-angular/): A wrapper of the msal-browser library for apps using Angular framework. - [Microsoft Authentication Extensions for Node](extensions/msal-node-extensions/): The Microsoft Authentication Extensions for Node offers secure mechanisms for client applications to perform cross-platform token cache serialization and persistence. It gives additional support to the Microsoft Authentication Library for Node (MSAL). -### Libraries in Long-term Support (LTS) +### Library Version Support Status + -The following libraries, hosted on the `msal-lts` branch, are no longer in active development, but they are still receiving critical security bug fix support. +| Package Name | Current Version | LTS Version | Critical Security Support | +|--------------|-----------------|-------------|---------------------------| +| @azure/msal-browser |v5 | v4 | v3, v2 | +| @azure/msal-node | v5 | v3 | v2, v1 | +| @azure/msal-react | v5 | v3 | v2, v1 | +| @azure/msal-angular | v5 | v4 | v3, v2, v1 | +| @azure/msal-node-extensions | v5 | v1 | - | +| ~~@azure/msal-core~~| | Fully Deprecated | | +| ~~@azure/msal-angularjs~~ | | Fully Deprecated | | + +**Disambiguation:** +- The MSAL team provides full support to the current version for each package in the table below. +- LTS (long-term support) versions will still receive support and bug-fixes but will not ship new features. +- Versions in Critical Security Support will only receive fixes for critical security bugs. -- [Microsoft Authentication Library for JavaScript v2.x](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/msal-lts/lib/msal-browser) -- [Microsoft Authentication Library for Node.js v1.x](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/msal-lts/lib/msal-node) -- [Microsoft Authentication Library for React v1.x](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/msal-lts/lib/msal-react) -- [Microsoft Authentication Library for Angular v2.x](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/msal-lts/lib/msal-angular) ### Package Structure -We ship a number of different packages which are meant for different platforms. You can see the relationship between packages and different authentication flows they implement below. +We ship a number of different packages which are meant for different platforms. You can see the relationship between packages and their dependencies below. ![Package Structure](docs/diagrams/png/PackageStructure.png) ### Samples -The [`samples`](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/samples) folder contains sample applications for our libraries. A complete list of samples can be found in the respective package folders or [on our wiki](https://github.com/AzureAD/microsoft-authentication-library-for-js/wiki/Samples). +The [`samples`](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/samples) folder contains sample applications for our libraries. A complete list of samples can be found in the respective package folders. ## Package versioning All of our libraries follow [semantic versioning](https://semver.org). We recommend using the latest version of each library to ensure you have the latest security patches and bug fixes. -## Roadmap - -Please check the [roadmap](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/roadmap.md) to see what we are working on and what we have planned for future releases. - ## Community Help and Support - [GitHub Issues](../../issues) is the best place to ask questions, report bugs, and new request features. diff --git a/docs/diagrams/png/PackageStructure.png b/docs/diagrams/png/PackageStructure.png index e4e4b32f51e6ae2efc614b4f07de5a8f7241d76a..2ed30309786e53d040b3bad21413187c9a78f62b 100644 GIT binary patch literal 35472 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 literal 37955 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 v_RZp%K| Date: Tue, 11 Nov 2025 18:34:21 -0800 Subject: [PATCH 02/14] Add note on v5 version jump --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c662d944af..3d66f4cfc8 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ The [`lib`](https://github.com/AzureAD/microsoft-authentication-library-for-js/t - The MSAL team provides full support to the current version for each package in the table below. - LTS (long-term support) versions will still receive support and bug-fixes but will not ship new features. - Versions in Critical Security Support will only receive fixes for critical security bugs. +- All supported packages were brought up to version parity as of `v5`. Packages with versions lower than `v4` in the LTS column skipped as many versions as required to jump directly to `v5`. ### Package Structure From 95a0cba87217560863de6fbb81fc0c097fdd9160 Mon Sep 17 00:00:00 2001 From: Hector Morales Date: Wed, 12 Nov 2025 13:58:09 -0800 Subject: [PATCH 03/14] Update msal-browser docs --- README.md | 4 +- lib/msal-browser/README.md | 49 +++--- lib/msal-browser/docs/cdn-usage.md | 234 -------------------------- lib/msal-browser/docs/events.md | 8 +- lib/msal-browser/docs/performance.md | 2 +- lib/msal-browser/docs/v2-migration.md | 2 +- 6 files changed, 29 insertions(+), 270 deletions(-) delete mode 100644 lib/msal-browser/docs/cdn-usage.md diff --git a/README.md b/README.md index 3d66f4cfc8..62f991e2d3 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ The [`lib`](https://github.com/AzureAD/microsoft-authentication-library-for-js/t | @azure/msal-react | v5 | v3 | v2, v1 | | @azure/msal-angular | v5 | v4 | v3, v2, v1 | | @azure/msal-node-extensions | v5 | v1 | - | -| ~~@azure/msal-core~~| | Fully Deprecated | | +| ~~@azure/msal (msal-core)~~| | Fully Deprecated | | | ~~@azure/msal-angularjs~~ | | Fully Deprecated | | **Disambiguation:** @@ -47,6 +47,8 @@ The [`lib`](https://github.com/AzureAD/microsoft-authentication-library-for-js/t - Versions in Critical Security Support will only receive fixes for critical security bugs. - All supported packages were brought up to version parity as of `v5`. Packages with versions lower than `v4` in the LTS column skipped as many versions as required to jump directly to `v5`. +> :warning: The `@azure/msal-browser` CDN has been fully deprecated as of `@azure/msal-browser@3.0.0` and is no longer supported. App developers using the MSAL CDN must upgrade to the latest possible version and consume MSAL through a package manager or bundling tool of their choice. For more information on version support, conslut the table in the project [README.md](../../README.md#library-version-support-status). + ### Package Structure diff --git a/lib/msal-browser/README.md b/lib/msal-browser/README.md index 9147f8ad9a..16cf964cb2 100644 --- a/lib/msal-browser/README.md +++ b/lib/msal-browser/README.md @@ -13,6 +13,9 @@ 1. [Roadmap](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/roadmap.md) 1. [Prerequisites](#prerequisites) 1. [Installation](#installation) + - [CDN Deprecation](#cdn-deprecation) + - [Via npm](#via-npm) + - [Via Yarn](#via-yarn) 1. [Usage](#usage) - [Migrating from Previous MSAL Versions](#migrating-from-previous-msal-versions) - [MSAL Basics](#msal-basics) @@ -27,20 +30,15 @@ ## About -The MSAL library for JavaScript enables client-side JavaScript applications to authenticate users using [Azure AD](https://docs.microsoft.com/azure/active-directory/develop/v2-overview) work and school accounts (AAD), Microsoft personal accounts (MSA) and social identity providers like Facebook, Google, LinkedIn, Microsoft accounts, etc. through [Azure AD B2C](https://docs.microsoft.com/azure/active-directory-b2c/active-directory-b2c-overview#identity-providers) service. It also enables your app to get tokens to access [Microsoft Cloud](https://www.microsoft.com/enterprise) services such as [Microsoft Graph](https://graph.microsoft.io). +The MSAL library for JavaScript enables client-side JavaScript applications to authenticate users using [Microsoft Entra ID](https://docs.microsoft.com/azure/active-directory/develop/v2-overview) work and school accounts (AAD), Microsoft personal accounts (MSA) and social identity providers like Facebook, Google, LinkedIn, Microsoft accounts, etc. through [Azure AD B2C](https://docs.microsoft.com/azure/active-directory-b2c/active-directory-b2c-overview#identity-providers) service. It also enables your app to get tokens to access [Microsoft Cloud](https://www.microsoft.com/enterprise) services such as [Microsoft Graph](https://graph.microsoft.io). The `@azure/msal-browser` package described by the code in this folder uses the [`@azure/msal-common` package](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-common) as a dependency to enable authentication in JavaScript Single-Page Applications without backend servers. This version of the library uses the OAuth 2.0 Authorization Code Flow with PKCE. To read more about this protocol, as well as the differences between implicit flow and authorization code flow, see the section [below](#implicit-flow-vs-authorization-code-flow-with-pkce). -This is an improvement upon the previous `@azure/msal` library which will utilize the authorization code flow in the browser. Most features available in the old library will be available in this one, but there are nuances to the authentication flow in both. The `@azure/msal-browser` package does NOT support the implicit flow. ## FAQ See [here](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/FAQ.md). -## Roadmap - -See [here](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/roadmap.md). - ## Prerequisites - `@azure/msal-browser` is meant to be used in [Single-Page Application scenarios](https://docs.microsoft.com/azure/active-directory/develop/scenario-spa-overview). @@ -49,18 +47,30 @@ See [here](https://github.com/AzureAD/microsoft-authentication-library-for-js/bl ## Installation +### CDN Deprecation + +> :warning: The `@azure/msal-browser` CDN has been fully deprecated as of `@azure/msal-browser@3.0.0` and is no longer supported. App developers using the MSAL CDN must upgrade to the latest possible version and consume MSAL through a package manager or bundling tool of their choice. For more information on version support, conslut the table in the project [README.md](../../README.md#library-version-support-status). + ### Via NPM ```javascript npm install @azure/msal-browser ``` +### Via Yarn + +```javascript +yarn add @azure/msal-browser +``` + ## Usage ### Migrating from Previous MSAL Versions -- [Migrating from MSAL v1.x to MSAL v2.x](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/v1-migration.md) +- [Migrating from MSAL v4.x to MSAL v5.x](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/v4-migration.md) +- [Migrating from MSAL v3.x to MSAL v4.x](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/v3-migration.md) - [Migrating from MSAL v2.x to MSAL v3.x](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/v2-migration.md) +- [Migrating from MSAL v1.x to MSAL v2.x](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/v1-migration.md) ### MSAL Basics @@ -132,11 +142,9 @@ npm test npm run test:coverage ``` -## Implicit Flow vs Authorization Code Flow with PKCE - -`@azure/msal-browser` implements the [OAuth 2.0 Authorization Code Flow with PKCE](https://tools.ietf.org/html/rfc7636) for browser-based applications. This is a significant improvement over the Implicit Flow that was used in `@azure/msal`, `msal` or `adal-angular`. +## Authorization Code Flow with Proof Key for Code Exchange -### Authorization Code Flow with PKCE +`@azure/msal-browser` implements the [OAuth 2.0 Authorization Code Flow with PKCE](https://tools.ietf.org/html/rfc7636) for browser-based applications. The Authorization Code Flow with Proof Key for Code Exchange (PKCE) is the current industry standard for securing OAuth 2.0 authorization in public clients, including single-page applications (SPAs). Key benefits include: @@ -145,28 +153,11 @@ The Authorization Code Flow with Proof Key for Code Exchange (PKCE) is the curre - **Refresh Token Support**: Enables long-lived sessions through refresh tokens - **OIDC Compliance**: Fully compliant with OpenID Connect standards -### Implicit Flow (Deprecated) - -The Implicit Flow was the previous standard for SPAs but has been deprecated due to security concerns: - -- **Tokens in URLs**: Access tokens are returned in URL fragments, making them visible in browser history and server logs -- **No Refresh Tokens**: Implicit flow cannot securely deliver refresh tokens to public clients -- **Increased Attack Surface**: Tokens are more susceptible to token leakage attacks - -### Migration Considerations - -- **`@azure/msal-browser` only supports Authorization Code Flow with PKCE** - Implicit Flow is not supported -- If you're migrating from `@azure/msal`, `msal` or `adal-angular`, see our [migration guide](./docs/v1-migration.md) -- Your Azure AD app registration needs to be configured for the Authorization Code Flow -- Existing applications using Implicit Flow should migrate to Authorization Code Flow for improved security - -For more technical details about these flows, refer to the [Microsoft identity platform documentation](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow). - ## Framework Wrappers If you are using a framework such as Angular or React you may be interested in using one of our wrapper libraries: -- Angular: [@azure/msal-angular v2](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-angular) +- Angular: [@azure/msal-angular](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-angular) - React: [@azure/msal-react](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-react) ## Security Reporting diff --git a/lib/msal-browser/docs/cdn-usage.md b/lib/msal-browser/docs/cdn-usage.md deleted file mode 100644 index b649f9398b..0000000000 --- a/lib/msal-browser/docs/cdn-usage.md +++ /dev/null @@ -1,234 +0,0 @@ -# CDN Usage for @azure/msal-browser - -In addition to npm, `msal` can be consumed from Microsoft-hosted CDNs. - -**_NOTE:_** Starting from MSAL.js v3 `msal-browser` is no longer hosted on the CDN. If you consume `msal-browser` from the CDN you will need to download `msal-browser` from npm and choose one of the following alternatives before upgrading: - -1. Consume the ESM build (preferred) -1. Extract `lib/msal-browser.js` or `lib/msal-browser.min.js` from the downloaded package and serve it as a static asset with your app or host it on your own CDN - -## Best Practices - -**_NOTE:_** We highly recommend using npm to consume MSAL.js (all versions). This documentation is maintained _only_ for existing legacy build support for CDNs until MSAL v2. CDN support is discontinued starting MSAL JS v3. - -When using the CDN, we recommend the following best practices: - -- Use the latest version of MSAL.js v2. -- Use the minified build in production, unminified build for development. -- Use the Microsoft CDN instead of third-party CDNs. -- Use the CDN region nearest to your users. -- Use the `async` or `defer` attributes to not block page rendering. -- Use the `integrity` attribute to ensure integrity of CDN builds. -- IE11 support requires a Promise polyfill ([more information](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/samples/msal-browser-samples/VanillaJSTestApp2.0/app/ie11-sample) on IE11 support). - -## Basic Usage - - - -```html - -``` - -## Unminified builds - -In addition to minified builds, unminified builds for each version are also available (as `msal-browser.js` instead of `msal-browser.min.js`) - -```html - - -``` - -## Domains supported - -Microsoft offers 2 top-level CDN domains for resilience. - -| CDN Domain | Example | -| -------------------- | --------------------------------------------------------------------- | -| `alcdn.msauth.net` | `https://alcdn.msauth.net/browser//js/msal-browser.min.js` | -| `alcdn.msftauth.net` | `https://alcdn.msftauth.net/browser//js/msal-browser.min.js` | - -### CDN fallback - -In the unlikely event that a CDN build is broken or the CDN itself is inaccessible, an application can use the other CDN region as a fallback: - -```html - - -``` - -**Note:** This method of using `document.write` may be blocked in certain browsers in certain situations. More information can be found [here](https://www.chromestatus.com/feature/5718547946799104). - -## Subresource Integrity - -From [MDN](https://developer.mozilla.org/docs/Web/Security/Subresource_Integrity): - -> Subresource Integrity (SRI) is a security feature that enables browsers to verify that resources they fetch (for example, from a CDN) are delivered without unexpected manipulation. It works by allowing you to provide a cryptographic hash that a fetched resource must match. - -> Using Content Delivery Networks (CDNs) to host files such as scripts and stylesheets that are shared among multiple sites can improve site performance and conserve bandwidth. However, using CDNs also comes with a risk, in that if an attacker gains control of a CDN, the attacker can inject arbitrary malicious content into files on the CDN (or replace the files completely) and thus can also potentially attack all sites that fetch files from that CDN. - -> Subresource Integrity enables you to mitigate some risks of attacks such as this, by ensuring that the files your web application or web document fetches (from a CDN or anywhere) have been delivered without a third-party having injected any additional content into those files — and without any other changes of any kind at all having been made to those files. - -It is highly recommended to use SRI Hashes with CDN builds of MSAL.js to help secure your application and the authentication artifacts (e.g. access tokens) that MSAL.js stores in the browser. - -### MSAL.js SRI Hash Example - -```html - -``` - -### SRI Hash Notes - -- Each hash will be unique to the version of MSAL.js v2, and will not change. -- SRI hash usage is optional for MSAL.js CDN builds. -- If the `integrity` attribute is used for MSAL.js v2 CDN builds, the `crossorigin` attribute must be set to `"anonymous"`. -- If you believe our CDN builds have been compromised, please [inform us](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/SECURITY.md#reporting-a-vulnerability) immediately. - -### SRI Hash History - - - -| Version | Build | SRI Hash | -| ------------ | ------------------- | ------------------------------------------------------------------------- | -| 2.35.0 | msal-browser.js | `sha384-+8A1rifuHuJxJgQn6UCxGgmo6Q2SvIeEAqtPOsXCpi0DpqZLtuDhxxnqjJZw/1ve` | -| 2.35.0 | msal-browser.min.js | `sha384-PARf28kmic36Ve+O3DnUerRXFtOQ7ZDqRDGpLcbljly5/N39T2OV3kt3QsWOKeAX` | -| 2.34.0 | msal-browser.js | `sha384-8TkGQjPkLg+rgblWRah3ZvrUIkKL7iDl8aYUAd/8xqSzwSpmOAtEPkE7eLQvs+Ru` | -| 2.34.0 | msal-browser.min.js | `sha384-oSX3mlcV2SGDE+ZhNgvgqV1xrCHF5lBDuFj1qGUIuCYg/OZzhuJmMSvXOuh1waW2` | -| 2.33.0 | msal-browser.js | `sha384-xfWQjvZ0VzT5Zvno0SgkPatOmGBEbU8nBL9PyHta/UR299kguq6f5AdiT7i4njhQ` | -| 2.33.0 | msal-browser.min.js | `sha384-sIyEdUUBfHyE7nRpvFHA2odaB/z+HNe9frVsvOKkncXSRPnyek6HeakhZhNdJLrj` | -| 2.32.2 | msal-browser.js | `sha384-FiPubKXaL8pr5mOhDJ06p9BG501EIJFxOxYWUfqLiUeSGIF2SWo8cWI3QnQEZ1FN` | -| 2.32.2 | msal-browser.min.js | `sha384-y1IcCD+XmMR+nTJWafnzQJt1pwQU6CT7CvoixQpAYX2LlSu0NG7KmE5KXnarCJLy` | -| 2.32.1 | msal-browser.js | `sha384-8M9Qh0U/bSYzHACsgrp8pVFDoPDH5C1Cm39aGMGXpQ2XzxnyMZbbQnnu8nEnj6vp` | -| 2.32.1 | msal-browser.min.js | `sha384-UrQz8fjd/68UVLcPZl2ZTrABZEfujnPqnuQt7CV6903eSw62F3KEsOwGudSw2A9Q` | -| 2.32.0 | msal-browser.js | `sha384-zT0cfnNK2YXRh/ickIdCtkvP0wUCA0jH2jgHuXuErJIDc2UXBt3iwS5eJaW0ZXVG` | -| 2.32.0 | msal-browser.min.js | `sha384-MkuKIg4TRd71anKVt5q1+USEhZ2N2tVOTgDwlOuysviT1CanXfuWB2P4B2X4jSXj` | -| 2.31.0 | msal-browser.js | `sha384-BO4qQ2RTxj2akCJc7t6IdU9aRg6do4LGIkVVa01Hm33jxM+v2G+4q+vZjmOCywYq` | -| 2.31.0 | msal-browser.min.js | `sha384-1vMI1nswvByekU8FrM4tFu+iue2XqjisDCQmalPH2vWX53szbpaLAQA/rI1p9mjz` | -| 2.30.0 | msal-browser.js | `sha384-o4ufwq3oKqc7IoCcR08YtZXmgOljhTggRwxP2CLbSqeXGtitAxwYaUln/05nJjit` | -| 2.30.0 | msal-browser.min.js | `sha384-HC34/sGr6mESU7p33Bo1s3lWvYOdfDnu05vmaJFpSvHZbTUdKWIOxIn5SuZnqafp` | -| 2.29.0 | msal-browser.js | `sha384-L8LyrNcolaRZ4U+N06atid1fo+kBo8hdlduw0yx+gXuACcdZjjquuGZTA5uMmUdS` | -| 2.29.0 | msal-browser.min.js | `sha384-CirgUajm2J/qIZ/u+TqkKMfxFdAhX0Q5UDQ0lJR0cMZam8SP6WASMDgG6ZuH9YU2` | -| 2.28.3 | msal-browser.js | `sha384-OnQxm8gBWqXtcrgb4TGKgQsKvNFDAVRb/LYrQ4SkYg6nYK+vg9oC/OF6+KRmqwGn` | -| 2.28.3 | msal-browser.min.js | `sha384-LTsAmgDln/CC82A+RiT/7SX65gRIMoqFU6jclq+TzHTa3ydfY6ex6J3LO1pyLC1/` | -| 2.28.2 | msal-browser.js | `sha384-bTszrDBNEw/vuvCJ58o9obswP5dg379zO8MJx53LyZCsKsSnrErje1LM+6Bk8Lkl` | -| 2.28.2 | msal-browser.min.js | `sha384-203jB5A+1LERtg89ajpErgNu5XzbM4Hye182KOJTVuHD19rezlVuwnwQ3WVbhZVF` | -| 2.28.1 | msal-browser.js | `sha384-M6geA+l92SitR/WGDtbiK0tt/MAv3qimyNK2vaOatn2c+OrHVbwYaG85IIlSq7eY` | -| 2.28.1 | msal-browser.min.js | `sha384-ei8xVSyFPTuRnbO1sdYy5qJT6Kd9neBfVG8AjZySEwdMG1GhCThbceSqxJnx0Ci3` | -| 2.28.0 | msal-browser.js | `sha384-q8S4bw8Wfzedv3LPXdOP0+IKu+LqXg4l9xZaOwTp3h40FYMw6YeO/6FX+aG6vgXx` | -| 2.28.0 | msal-browser.min.js | `sha384-dKtQ/y8SrxV+8eZsQnb3vQpwWP57fRau9cbe4FbFK6B+VSC5SaWTM9w6lwQdNhKG` | -| 2.27.0 | msal-browser.js | `sha384-CsXI9QUbEXvbc1SIiLQ1/sUNkZZfkQSamJ2YU4g/yDKQNDyn8D2HTgR1ww7QV5+U` | -| 2.27.0 | msal-browser.min.js | `sha384-IlUQkOwOI6mWk8GNIWu8hpPE1sasxSg3gGjZo0dncq6IhHsTlH51mp5mhFYS5po1` | -| 2.26.0 | msal-browser.js | `sha384-fitpJWrpyl840mvd9nBFLGulqR4BJzvim0fzrXQKdsVh2AQzE4rTTJ0o5o+x+dRK` | -| 2.26.0 | msal-browser.min.js | `sha384-VdtLJ4gW9+dszXDbJEzdUFYI+xq4hXfOGntgGlDve3qz/5WEzWjLeN1voiro74af` | -| 2.25.0 | msal-browser.js | `sha384-zezf4cRFK/02dUQFQjo+qA3OjwpHtgizVgd4wMyxG2bWNy2TxzKe1CqIyBYWRJxF` | -| 2.25.0 | msal-browser.min.js | `sha384-dDqLsp/gmQFrDNIjpyKi23AtweUuA2Hn3wnwxOr+IwWGC8Zock5gcEwvLAkvvXh/` | -| 2.24.0 | msal-browser.js | `sha384-NcVVwcZIMSdYk9wbu0m7mElxxmQMIMRVSXXkF53lT+d41bXftjpIs8neU7xry4ch` | -| 2.24.0 | msal-browser.min.js | `sha384-U+uxTX8q39oAXjbZ8Bp9eTNwAmwyS8Sq7afx4SiEUFTt4LRIEbZDcMmVE0K85Vze` | -| 2.23.0 | msal-browser.js | `sha384-dvhiAjRHm++5woziYGV/JQSredPVb/p0VCATrsE/Upv4VmhLrKo6MWW218QofKIG` | -| 2.23.0 | msal-browser.min.js | `sha384-QxXqndv+Kkjr1gNW8SQUIE2zG/UT8lHYvf6HYdAAUj56xs9utgJNWyknd0O1CrUl` | -| 2.22.1 | msal-browser.js | `sha384-cKDVz4ain64nzHeJR0vejySPl0i8A6c7YfJI5ehEDQDoA5SSlb/zoLAFvXTQvTQS` | -| 2.22.1 | msal-browser.min.js | `sha384-nCTmWvEOevLDR1A0WzHvi1PbktdL8pPPACO2UYs9NPp+TCEz0hE0c8JmMxRlNSjh` | -| 2.22.0 | msal-browser.js | `sha384-B46pTTVe+0LfqOtym4Ys6NnTk47DzGHgn83hf4JBDIUfgiZlYFaywZqzEYQYCg4b` | -| 2.22.0 | msal-browser.min.js | `sha384-JmIjzXWxZ0+8Zd5wAsqkE9EKmxRx1ikmsnABsK9yFAbMmjOv9kSK4j560FLjkCxn` | -| 2.21.0 | msal-browser.js | `sha384-928QQ3wSVfsx4ZV1MR0896l8lK21YX1xWK3gSl8AW/lMEAZ2GeYqvFkm/VPzgn4y` | -| 2.21.0 | msal-browser.min.js | `sha384-s/NxjjAgw1QgpDhOlVjTceLl4axrp5nqpUbCPOEQy1PqbFit9On6uw2XmEF1eq0s` | -| 2.20.0 | msal-browser.js | `sha384-Ky1dhcw3VPMuZV6VlVBcQBtWHs5Ry8rkG2LGdxdEOoaApfNShXhD3OQTgN3klUN5` | -| 2.20.0 | msal-browser.min.js | `sha384-WV/465aYIrPn7bcKutSAFz+3JedxtCaRXxYu5EEjgGKPaOz7gjN06C8tBoGEmlZm` | -| 2.19.0 | msal-browser.js | `sha384-qMZg1SlV+Gm/R5MbEArouisSUHYzmBo05auTya2W3UOOr2Mlr2UvzzP1+nw5zc01` | -| 2.19.0 | msal-browser.min.js | `sha384-VK+6hHt27itNFksZdEeXofJXdAhmlizHbC/a1TUUJm/Yq6gOuAjXKkiiCaGbFsnd` | -| 2.18.0 | msal-browser.js | `sha384-PERHHiF9DdKG6zSfxaBeyaXmEbHrKvJjvab6BjfKeufVnfveKzZLHGB6m213V4tT` | -| 2.18.0 | msal-browser.min.js | `sha384-h9/gGcqbtmiQLu/34PC5wXvlxf+ugeTXcotRfHcjAIwyIB7UzyxcfNBcz3ONQiTz` | -| 2.17.0 | msal-browser.js | `sha384-LgNKCUpBSQJW+dWsseosd8ZZ7GNGiO+9SbgDBYyfqFkGJGg29VAzMQDYjK76r7o5` | -| 2.17.0 | msal-browser.min.js | `sha384-nPvMTGGQIdPr+oK09URmAR99LAk9PEVLJE+RJfjIH/QADFbVgGlF9tFdVbgSYC+c` | -| 2.16.1 | msal-browser.js | `sha384-JNwcxoC2tyQMQnFA7pCGC8h4BSIlWY9ytKZv0tVvvFzlqsCj77gw9sa+0FlM5c0F` | -| 2.16.1 | msal-browser.min.js | `sha384-bPBovDNeUf0pJstTMwF5tqVhjDS5DZPtI1qFzQI9ooDIAnK8ZCYox9HowDsKvz4i` | -| 2.16.0 | msal-browser.js | `sha384-W29UmqhBlCkSR5sC6sGVNkUpnNBI2hYRwB0/3wiCixcjzpXRLyByZbNOrx+xPiR/` | -| 2.16.0 | msal-browser.min.js | `sha384-h/D+9sV4N/CFwWR6G+dv+dkByf17RfGMJZl5f9noj9QamUJdw6BW3xZPAVSWyG4A` | -| 2.15.0 | msal-browser.js | `sha384-dFzMiVGB5HpWZ+5w5VSif6jhWfNeplSw9ACYmQKZcY2azuT9kCxVWVI9HyfGdkHV` | -| 2.15.0 | msal-browser.min.js | `sha384-/weuqUPkC0P9JxnstihEV1GHdWrheU9Qo3MbdTuxxKJM8l/cSTE5zGP5VBIM4TZN` | -| 2.14.2 | msal-browser.js | `sha384-SeRoSpLefUsASd6PTJsFeKDwITzOJ6gxSmsl+Z9Fl/hY2PAn/rKcw3WzoaBGc4my` | -| 2.14.2 | msal-browser.min.js | `sha384-ggh+EF1aSqm+Y4yvv2n17KpurNcZTeYtUZUvhPziElsstmIEubyEB6AIVpKLuZgr` | -| 2.14.1 | msal-browser.js | `sha384-RRV2T1wXStSmpELGRUont/dBMwIOD45UU7pk2qP7msfNC5dBalYUq+7cO02NPSj1` | -| 2.14.1 | msal-browser.min.js | `sha384-U3GjPGP2DZIb7AJBXk4B2quSe+7i4Dos1SqrcBwXPUkgnEZtnUBobrvAGXxpH6Cj` | -| 2.14.0 | msal-browser.js | `sha384-BiEwq81GpEOSES/Zj2TjBInBOQjHki/s0Si4VLT6JK2XoFX0cJK6HjII3W3eJ7DS` | -| 2.14.0 | msal-browser.min.js | `sha384-WBY8oVVrEdSaZOKwHzdAhKjmFK8vz2bpQt90XIIBsBFJI8JtGteFQn6ngXmA3n9h` | -| 2.13.1 | msal-browser.js | `sha384-7hwr87O1w6buPsX92CwuRaz/wQzachgOEq+iLHv0ESavynv6rbYwKImSl7wUW3wV` | -| 2.13.1 | msal-browser.min.js | `sha384-2Vr9MyareT7qv+wLp1zBt78ZWB4aljfCTMUrml3/cxm0W81ahmDOC6uyNmmn0Vrc` | -| 2.13.0 | msal-browser.js | `sha384-8WE3wV17rmapJTrZubql1Rziv4aZmDrlb7F3iZbiQEuOT7nmK8UH39MN2cEIOWQy` | -| 2.13.0 | msal-browser.min.js | `sha384-vDONqKCGNcmVCJ/YQ6YHzbrhwKdihAE08TkDEHBZjgjqRYz5itQb7Rdst5Oy5GB+` | -| 2.12.1 | msal-browser.js | `sha384-QMpSjAFJzgh/J1zBL23Xx95KfVI1n9Je9GmB3byJbZ0/hj8o9CJTmxOK/BPZivil` | -| 2.12.1 | msal-browser.min.js | `sha384-cZM20w+KzsO/N+6IGI+U1e2zsBS1ciCc6VdEC5SZ1/pHGyvcpE6D2uk0XcFwgb1q` | -| 2.12.0 | msal-browser.js | `sha384-WqJE0XrCKXbaCrjTk1+pq6qArRvxmGqf6YUBgoqwCz4WDXJFCW2hZZN0HMLE7/XB` | -| 2.12.0 | msal-browser.min.js | `sha384-eD9W7ukFmFKtgjDgCWa6WpkuqKjQ5Q/EP686z9/t2DK93dQtdIx8LAhMc9Mjy3hA` | -| 2.11.2 | msal-browser.js | `sha384-Zr4eBs1XVPlVMD5df2RNBeFhTy62Z8nN//v8dOR8pAgf6iI9rBTuvRZJSGjGjOCQ` | -| 2.11.2 | msal-browser.min.js | `sha384-MkT8/EXqCzh7OVmmpVdg5H2Fhpbt9uNrQM7UMbTg+v8fJVcfQ0BWf16siodTYgF6` | -| 2.11.1 | msal-browser.js | `sha384-LIpmPPrsEE7hCBPf0k4nn8zf9h8Z1i69YnG8TmRLTnaMDI6B2nGzLIh/c51BHgpN` | -| 2.11.1 | msal-browser.min.js | `sha384-wgFLXq8mfWaFslz/C51m2NvUX7aBENCLEqRi9BNL+23HBfWkeFCGfvqaPGmAbrzC` | -| 2.11.0 | msal-browser.js | `sha384-4PutheeyrGgwghN7WV8QaHBshN673W9fDW3PDP0Zw1Wm9CVZIuU2RFSWfcxEWAR0` | -| 2.11.0 | msal-browser.min.js | `sha384-mxc9xXB8zELCYWdhT4JCez24AMsgk+uN7e991ek2TrQy9rBPVlUiuppobVCuja8S` | -| 2.10.0 | msal-browser.js | `sha384-h4/puysjUElY8ygLCfA1sWMW/y1DsRmX02pAa6Om71bq6qS/w9PzLjby6YTkgH6W` | -| 2.10.0 | msal-browser.min.js | `sha384-UiyYbBRwVt3gTqaQfkEn8ceYV1cB9KAofImJ8nOc/vdqHATCuzgGZhxWgkhPBjNe` | -| 2.9.0 | msal-browser.js | `sha384-+akJUidBAUlm36Zv/ib9eOD+CZDJ67/yVEPaDV9aNw7164awXZbuEjLnsxDXuQO1` | -| 2.9.0 | msal-browser.min.js | `sha384-MUSnn9XLYFUDadNpWJyizBT8WbNR2FGs9zcvZG1GbEwFSK59dFTUESMnAtN6Edgg` | -| 2.8.0 | msal-browser.js | `sha384-Mjsbb/z4VVY/1KEUcSY4zG2SObmLbGdEQp1a6qJ8x4Qkd8HqhBmkigPO1LO+ZKC8` | -| 2.8.0 | msal-browser.min.js | `sha384-b/qP1MqDbgDE3TTcBfXi4/r9pcSjPbT1lTVl5Q71LhQMpn95C4bDE8+83ImeSE+l` | -| 2.7.0 | msal-browser.js | `sha384-5Fqyq1ncNYhL2mXCdWAFXkf2wWtKeA0mXYp++ryAX1lowD0ctAHFdity37L/ULXh` | -| 2.7.0 | msal-browser.min.js | `sha384-isB7RsMD9bXfK4BK9pJHfTyTfQMM/KQ/1a58J/PVsDFbto29TgNxOP3ZyrhRyiTV` | -| 2.6.1 | msal-browser.js | `sha384-kHVR+hnKKUXpL5UEI3dgmdIKZgopBagC1RdQytFqglEGROvOSAGJRkaFWfu8VsSx` | -| 2.6.1 | msal-browser.min.js | `sha384-ry0iBug2qnSSs0YiS8IfxgvYZvgsCCXiplbiwrf9tQWkpCFMcezBMuLDbVtYrKIl` | -| 2.6.0 | msal-browser.js | `sha384-MOtTwBzAcbzhOnPuklGgFJINWfT6ekHPIhI0GkJdUihkt/AtO/ttlrT93yen631k` | -| 2.6.0 | msal-browser.min.js | `sha384-sGG/3pGinkV/9X/+VrbuRSSJmOaYKq9Bdyet6ICHajSN8wSG9DpJHda6vls5BkUd` | -| 2.5.2 | msal-browser.js | `sha384-ZOWQBoErNmfc9sfHh6PXYc9NZ+02cf5d+wdsnvfKHSEyQ2x+YSWaf12KInVhfurI` | -| 2.5.2 | msal-browser.min.js | `sha384-A9ludGsBPhx3Ec8zLyd3vZEqJrRbvD6fJWpasbzAFyaaa/AMR6rtCUtbUmP07rsj` | -| 2.5.1 | msal-browser.js | `sha384-MFZe/UOLz61FRpO06noy2uBkJEZUaxccyYYwrSrwBOEY59Fi0GxyRzPiiZKLvvkC` | -| 2.5.1 | msal-browser.min.js | `sha384-/cOXpDxWc4bzFZUDf49Sp31Im+bSjki6UxTPadEDitHw0277qGX5teCOdieziPZh` | -| 2.5.0 | msal-browser.js | `sha384-JtZbGQvK0HbNDG42cgeg3XxEllLbMW8aAiSCXoLdW7iJhkdC7v4Kzqvl4LWOSiFF` | -| 2.5.0 | msal-browser.min.js | `sha384-+sjqS/ee1BeZqojCMFh8gGTbZ0ATgrA/rEIANI0l0Y6QdA+MDwmXLhj3JGvHueL7` | -| 2.4.1 | msal-browser.js | `sha384-4Equw/X3Wp2XPnMSCbe2OQQRE/8MzlwepR53zKGbAz/6eO//yRXOcn3LKf1MnBWS` | -| 2.4.1 | msal-browser.min.js | `sha384-vazVaX5+cCJf+t0Dzdb8CxX9jLLvWuSZqEI2lBSMeLUBPQovS4IlwFQI6epI2tJD` | -| 2.4.0 | msal-browser.js | `sha384-Bz0kggjHC0kxcxxtRzWgjaF0JGsmHuO1atz26xKETeu5WgdarvGmr9Pr/f/pKtrq` | -| 2.4.0 | msal-browser.min.js | `sha384-tBRIK0qPn8yxGmyhpgVsVIFaJNa0EDL62hp+zvDu1vtT1bIqWU6HiYexMhtk52bP` | -| 2.3.1 | msal-browser.js | `sha384-khe4Bq8VcpAsK8zAycaYefEMHsLny9P/kgPF9Jy1afhFNZ4EODmrdq//+LFp1mWV` | -| 2.3.1 | msal-browser.min.js | `sha384-d6fJLwOshjtqjJPGMQ4XgIKOvx46EBeyiPxTBaNJlj0GWqXKCh09qA6SgpAPnqD8` | -| 2.3.0 | msal-browser.js | `sha384-ILJg8BOvXQwFGYEbkLVLYTYoNpTT7tP905UubLu2AqwksVdddAu5z9k3e6gMhqc5` | -| 2.3.0 | msal-browser.min.js | `sha384-o+Sncs5XJ3NEAeriM/FV8YGZrh7mZk4GfNutRTbYjsDNJxb7caCLeqiDabistgwW` | -| 2.2.1 | msal-browser.js | `sha384-M6zl9i1upj9LPj3zSUn/IejJwPyUCewu0+RD444XuWQiRomvb2ZUwanqc0c2XfCy` | -| 2.2.1 | msal-browser.min.js | `sha384-8LDT8A5GReznR7uR2KGWc1Ep/kTc0ErU3yVBKJMOmAMoSf+hMonk3y3BceQ1rvF6` | -| 2.2.0 | msal-browser.js | `sha384-DDogsvdm1j1csBm8TKIenLTaFJA+x0KjwdW0CAx6ZW8+5EOqSIasS3OKZ0aiq3RV` | -| 2.2.0 | msal-browser.min.js | `sha384-ywaKEa0KdH8yiwoKS+2hRMenFDilyhT/K0r3WTXBzUQj+RNlYGnLeecytOEdgHpR` | -| 2.1.0 | msal-browser.js | `sha384-M9bRB06LdiYadS+F9rPQnntFCYR3UJvtb2Vr4Tmhw9WBwWUfxH8VDRAFKNn3VTc/` | -| 2.1.0 | msal-browser.min.js | `sha384-EmYPwkfj+VVmL1brMS1h6jUztl4QMS8Qq8xlZNgIT/luzg7MAzDVrRa2JxbNmk/e` | -| 2.0.2 | msal-browser.js | `sha384-rQvomuvjVybeTxLQIpbtb6lqFsDuJparCjjUJZjRZjVDNzGRloXbPj9qbgf9YM/d` | -| 2.0.2 | msal-browser.min.js | `sha384-zHGbJmHXAWMXaREIK7qFkrJCcU2ktJd8G9DAp49Q+y/+H6ArVhvFUW5IbyTzbNnn` | -| 2.0.1 | msal-browser.js | `sha384-knPh00kvaT+k3+4TCD5S2ORDNVc2I3RVbqI/ksbTlpdSBh8ZnyAPxW2kkTSG0+mT` | -| 2.0.1 | msal-browser.min.js | `sha384-fbyYRj8H9iJU/JyncEbzW6WgVOaR5C+PU1dHsRBg2Ag2Q14F4IB8+T8BdknwjRQ8` | -| 2.0.0 | msal-browser.js | `sha384-BqIcDtzVkr3wRGsSrk+iJJNm9GSdUsP0I2MplbnhPPc+I1l1d+dkKbcnqgNddGWX` | -| 2.0.0 | msal-browser.min.js | `sha384-n3aacu1eFuIAfS3ZY4WGIZiQG/skqpT+cbeqIwLddpmMWcxWZwYdt+F0PgKyw+m9` | -| 2.0.0-beta.4 | msal-browser.js | `sha384-7sxY2tN3GMVE5jXH2RL9AdbO6s46vUh9lUid4yNCHJMUzDoj+0N4ve6rLOmR88yN` | -| 2.0.0-beta.4 | msal-browser.min.js | `sha384-j9+OYwF1QFM1A8/DNvWKqvTw+bc5alOXQ7IA2WvGAcLLLpN/tK9XRTbJtlTiSFJI` | -| 2.0.0-beta.3 | msal-browser.js | `sha384-iKgpFzdbMAsg695JG+EmHleQe5gRjoAAixuMf0jfM7pCOVuGqhyBuXO1Ai71fixx` | -| 2.0.0-beta.3 | msal-browser.min.js | `sha384-X2nv+6ViZGj+UCfGAbimHAXpBEAi0RA6GWuqCckbMLU5jVr8uDjf6pGUvTkq7wME` | -| 2.0.0-beta.2 | msal-browser.js | `sha384-CEQpk7EG1PVKCHHdoQzDdR5uU7nJ1PLlcdx1s7vi8Ta/Pndhr04imhqCUkZGimOj` | -| 2.0.0-beta.2 | msal-browser.min.js | `sha384-O3n9nwTefR6cSLikBQsCDYke2pWL5YWluwvp0RgGe+VK2eU0+RJC1cmMow5jD1OE` | -| 2.0.0-beta.0 | msal-browser.js | `sha384-r7Qxfs6PYHyfoBR6zG62DGzptfLBxnREThAlcJyEfzJ4dq5rqExc1Xj3TPFE/9TH` | -| 2.0.0-beta.0 | msal-browser.min.js | `sha384-OV4a42kPPZv7IxRWcyqoLn9Ohs0g1WXejuNceZxAE9usAfLVFBcdre9yqo4I03VN` | diff --git a/lib/msal-browser/docs/events.md b/lib/msal-browser/docs/events.md index d6a112253d..fac44eb36a 100644 --- a/lib/msal-browser/docs/events.md +++ b/lib/msal-browser/docs/events.md @@ -1,6 +1,6 @@ # Events -Msal-Browser (`@azure/msal-browser`) starting at version 2.4 now provides event APIs that are available to users of our core library and wrapper libraries. These events are related to auth and what MSAL is doing, and can be used in applications to update UI, show error messages, and so on. +Msal Browser (`@azure/msal-browser`) provides event APIs that are available to users of our core library and wrapper libraries. These events are related to auth and what MSAL is doing, and can be used in applications to update UI, show error messages, and so on. ## What events look like @@ -16,11 +16,11 @@ export type EventMessage = { You can consult the [EventPayload](https://azuread.github.io/microsoft-authentication-library-for-js/ref/types/_azure_msal_browser.EventPayload.html) and [EventError](https://azuread.github.io/microsoft-authentication-library-for-js/ref/types/_azure_msal_browser.EventError.html) type docs to understand how they are defined in MSAL. -## How events are emitted in msal-browser +## How events are emitted in MSAL Browser -Msal-browser has a protected function `emitEvent`, and emits events in major APIs. For the list of currently emitted events, see the table below. +Msal browser has a protected function `emitEvent`, and emits events in major APIs. For the list of currently emitted events, see the table below. -Here is an example of how msal-browser emits an event with a payload, or with an error: +Here is an example of how MSAL Browser emits an event with a payload, or with an error: ```javascript this.emitEvent(EventType.ACQUIRE_TOKEN_SUCCESS, InteractionType.Redirect, result); diff --git a/lib/msal-browser/docs/performance.md b/lib/msal-browser/docs/performance.md index 06e1e81787..bc324bf882 100644 --- a/lib/msal-browser/docs/performance.md +++ b/lib/msal-browser/docs/performance.md @@ -73,7 +73,7 @@ const event: PerformanceEvent = { clientId: "b50703d7-d12b-4ddc-8758-91053fe0aba4", authority: "https://login.microsoftonline.com/common", libraryName: "@azure/msal-browser-1p", - libraryVersion: "2.22.2-beta.2", + libraryVersion: "5.0.0", appName: "my-application", appVersion: "1.0.0" } diff --git a/lib/msal-browser/docs/v2-migration.md b/lib/msal-browser/docs/v2-migration.md index 721500489e..691834dd79 100644 --- a/lib/msal-browser/docs/v2-migration.md +++ b/lib/msal-browser/docs/v2-migration.md @@ -104,4 +104,4 @@ Module/target versions were bumped from `es6`/`es5` to `es2020`/`es2020` respect ### CDN -MSAL.js is no longer hosted on a CDN. Check [this doc](cdn-usage.md) for more details. +> :warning: The `@azure/msal-browser` CDN has been fully deprecated as of `@azure/msal-browser@3.0.0` and is no longer supported. App developers using the MSAL CDN must upgrade to the latest possible version and consume MSAL through a package manager or bundling tool of their choice. For more information on version support, conslut the table in the project [README.md](../../README.md#library-version-support-status). From 49ac2442077d346f03782c22fcd262601528fe54 Mon Sep 17 00:00:00 2001 From: Hector Morales Date: Wed, 12 Nov 2025 14:02:44 -0800 Subject: [PATCH 04/14] Update incorrect doc link --- lib/msal-browser/docs/v2-migration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msal-browser/docs/v2-migration.md b/lib/msal-browser/docs/v2-migration.md index 691834dd79..52ca42404c 100644 --- a/lib/msal-browser/docs/v2-migration.md +++ b/lib/msal-browser/docs/v2-migration.md @@ -104,4 +104,4 @@ Module/target versions were bumped from `es6`/`es5` to `es2020`/`es2020` respect ### CDN -> :warning: The `@azure/msal-browser` CDN has been fully deprecated as of `@azure/msal-browser@3.0.0` and is no longer supported. App developers using the MSAL CDN must upgrade to the latest possible version and consume MSAL through a package manager or bundling tool of their choice. For more information on version support, conslut the table in the project [README.md](../../README.md#library-version-support-status). +> :warning: The `@azure/msal-browser` CDN has been fully deprecated as of `@azure/msal-browser@3.0.0` and is no longer supported. App developers using the MSAL CDN must upgrade to the latest possible version and consume MSAL through a package manager or bundling tool of their choice. For more information on version support, conslut the table in the project [README.md](../../../README.md#library-version-support-status). From 927b2cabab048709d2a6eeed3d5042432e786d5b Mon Sep 17 00:00:00 2001 From: Hector Morales Date: Wed, 12 Nov 2025 15:23:56 -0800 Subject: [PATCH 05/14] Update docs --- README.md | 23 ++++++++++++----------- lib/msal-browser/README.md | 2 +- lib/msal-browser/docs/cdn-usage.md | 6 ++++++ lib/msal-browser/docs/v2-migration.md | 2 +- 4 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 lib/msal-browser/docs/cdn-usage.md diff --git a/README.md b/README.md index 62f991e2d3..f8666fa0b6 100644 --- a/README.md +++ b/README.md @@ -31,23 +31,24 @@ The [`lib`](https://github.com/AzureAD/microsoft-authentication-library-for-js/t ### Library Version Support Status -| Package Name | Current Version | LTS Version | Critical Security Support | -|--------------|-----------------|-------------|---------------------------| -| @azure/msal-browser |v5 | v4 | v3, v2 | -| @azure/msal-node | v5 | v3 | v2, v1 | -| @azure/msal-react | v5 | v3 | v2, v1 | -| @azure/msal-angular | v5 | v4 | v3, v2, v1 | -| @azure/msal-node-extensions | v5 | v1 | - | -| ~~@azure/msal (msal-core)~~| | Fully Deprecated | | -| ~~@azure/msal-angularjs~~ | | Fully Deprecated | | +| Package Name | Current Version | LTS Version | +|--------------|-----------------|-------------| +| @azure/msal-browser |v5 | v4 | +| @azure/msal-node | v5 | v3 | +| @azure/msal-react | v5 | v3 | +| @azure/msal-angular | v5 | v4 | +| @azure/msal-node-extensions | v5 | v1 | +| ~~@azure/msal (msal-core)~~| | Fully Deprecated | +| ~~@azure/msal-angularjs~~ | | Fully Deprecated | **Disambiguation:** - The MSAL team provides full support to the current version for each package in the table below. - LTS (long-term support) versions will still receive support and bug-fixes but will not ship new features. -- Versions in Critical Security Support will only receive fixes for critical security bugs. - All supported packages were brought up to version parity as of `v5`. Packages with versions lower than `v4` in the LTS column skipped as many versions as required to jump directly to `v5`. -> :warning: The `@azure/msal-browser` CDN has been fully deprecated as of `@azure/msal-browser@3.0.0` and is no longer supported. App developers using the MSAL CDN must upgrade to the latest possible version and consume MSAL through a package manager or bundling tool of their choice. For more information on version support, conslut the table in the project [README.md](../../README.md#library-version-support-status). +#### MSAL Browser CDN Deprecation + +> :warning: The `@azure/msal-browser` CDN has been fully deprecated as of `@azure/msal-browser@3.0.0` and is no longer supported. App developers using the MSAL CDN must upgrade to the latest possible version and consume MSAL through a package manager or bundling tool of their choice. For more information on version support, consult the table above. ### Package Structure diff --git a/lib/msal-browser/README.md b/lib/msal-browser/README.md index 16cf964cb2..a2c774616c 100644 --- a/lib/msal-browser/README.md +++ b/lib/msal-browser/README.md @@ -49,7 +49,7 @@ See [here](https://github.com/AzureAD/microsoft-authentication-library-for-js/bl ### CDN Deprecation -> :warning: The `@azure/msal-browser` CDN has been fully deprecated as of `@azure/msal-browser@3.0.0` and is no longer supported. App developers using the MSAL CDN must upgrade to the latest possible version and consume MSAL through a package manager or bundling tool of their choice. For more information on version support, conslut the table in the project [README.md](../../README.md#library-version-support-status). +> :warning: The `@azure/msal-browser` CDN has been fully deprecated as of `@azure/msal-browser@3.0.0` and is no longer supported. App developers using the MSAL CDN must upgrade to the latest possible version and consume MSAL through a package manager or bundling tool of their choice. For more information on version support, consult the table in the project [README.md](../../README.md#library-version-support-status). ### Via NPM diff --git a/lib/msal-browser/docs/cdn-usage.md b/lib/msal-browser/docs/cdn-usage.md new file mode 100644 index 0000000000..aab3755b5f --- /dev/null +++ b/lib/msal-browser/docs/cdn-usage.md @@ -0,0 +1,6 @@ +# CDN Usage for @azure/msal-browser + +**_NOTE:_** Starting from MSAL.js v3 `msal-browser` is no longer hosted on the CDN. If you consume `msal-browser` from the CDN you will need to download `msal-browser` from npm and choose one of the following alternatives before upgrading: + +1. Consume the ESM build (preferred) +1. Extract `lib/msal-browser.js` or `lib/msal-browser.min.js` from the downloaded package and serve it as a static asset with your app or host it on your own CDN \ No newline at end of file diff --git a/lib/msal-browser/docs/v2-migration.md b/lib/msal-browser/docs/v2-migration.md index 52ca42404c..23f82412b4 100644 --- a/lib/msal-browser/docs/v2-migration.md +++ b/lib/msal-browser/docs/v2-migration.md @@ -104,4 +104,4 @@ Module/target versions were bumped from `es6`/`es5` to `es2020`/`es2020` respect ### CDN -> :warning: The `@azure/msal-browser` CDN has been fully deprecated as of `@azure/msal-browser@3.0.0` and is no longer supported. App developers using the MSAL CDN must upgrade to the latest possible version and consume MSAL through a package manager or bundling tool of their choice. For more information on version support, conslut the table in the project [README.md](../../../README.md#library-version-support-status). +> :warning: The `@azure/msal-browser` CDN has been fully deprecated as of `@azure/msal-browser@3.0.0` and is no longer supported. App developers using the MSAL CDN must upgrade to the latest possible version and consume MSAL through a package manager or bundling tool of their choice. For more information on version support, consult the table in the project [README.md](../../../README.md#library-version-support-status). From 03a4ef4b12b5ad068acc31580c888d92319ff0bb Mon Sep 17 00:00:00 2001 From: Hector Morales Date: Tue, 18 Nov 2025 15:12:12 -0800 Subject: [PATCH 06/14] Update lib/msal-browser/docs/events.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- lib/msal-browser/docs/events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msal-browser/docs/events.md b/lib/msal-browser/docs/events.md index fac44eb36a..495a0c5f23 100644 --- a/lib/msal-browser/docs/events.md +++ b/lib/msal-browser/docs/events.md @@ -18,7 +18,7 @@ You can consult the [EventPayload](https://azuread.github.io/microsoft-authentic ## How events are emitted in MSAL Browser -Msal browser has a protected function `emitEvent`, and emits events in major APIs. For the list of currently emitted events, see the table below. +Msal Browser has a protected function `emitEvent`, and emits events in major APIs. For the list of currently emitted events, see the table below. Here is an example of how MSAL Browser emits an event with a payload, or with an error: From 3ad8f114f1c0a8e7e51c210505072bc796f21ce0 Mon Sep 17 00:00:00 2001 From: Hector Morales Date: Tue, 18 Nov 2025 15:16:57 -0800 Subject: [PATCH 07/14] Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f8666fa0b6..9ba611664a 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ The [`lib`](https://github.com/AzureAD/microsoft-authentication-library-for-js/t | ~~@azure/msal-angularjs~~ | | Fully Deprecated | **Disambiguation:** -- The MSAL team provides full support to the current version for each package in the table below. +- The MSAL team provides full support to the current version for each package in the table above. - LTS (long-term support) versions will still receive support and bug-fixes but will not ship new features. - All supported packages were brought up to version parity as of `v5`. Packages with versions lower than `v4` in the LTS column skipped as many versions as required to jump directly to `v5`. From ea44678808f1ac756eb6c46fbe1c7b08280ac471 Mon Sep 17 00:00:00 2001 From: Hector Morales Date: Tue, 18 Nov 2025 15:20:50 -0800 Subject: [PATCH 08/14] Remove roadmap doc --- roadmap.md | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 roadmap.md diff --git a/roadmap.md b/roadmap.md deleted file mode 100644 index 3a3aa1bc06..0000000000 --- a/roadmap.md +++ /dev/null @@ -1,23 +0,0 @@ -# Roadmap - -The MSAL.js team's roadmap is presented as _In Development_, _Up Next_, and _Under Consideration_ to give you a better idea of what we are currently working on, what is up next for us, and what we are considering for the future. These are not guaranteed timelines or commitments, but instead intended to provide insight into the team's current direction. As an open-source library, you can already view changes the team is actively working on. This roadmap is focused on big features or focus areas; it may not call out each individual work item that is added to the library. While we try to stay consistent with our plans, things can change quickly. Do not write code reliant on these features until they are officially shipped. - -If you don't see a feature listed on the roadmap, check our [Release Notes](https://github.com/AzureAD/microsoft-authentication-library-for-js/releases) to see if it has already been released. If not, please open a [Feature Request](https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/new?assignees=&labels=feature-unconfirmed%2Cquestion&template=feature_request.yml). - -## Terminology -- *In Development*: These items are well-defined and actively in development. -- *Up Next*: These items are next to be picked up for development when capacity allows. The problem space and solution are known but we may still be refining design details or prioritizing capacity for other items already In Development. -- *Under Consideration*: These are general topic areas the team is considering for future investigation but we have no timelines or prioritization. If you have thoughts or suggestions on these areas, please add them to an existing Feature Request. - -## Focus Areas - -### In Development - -### Up Next -- Improve support for use in Teams Apps (Tabs) and Office Add-Ins - -### Under Consideration -- Identity provider agnostic support -- Supporting more JavaScript frameworks: [Ionic](https://github.com/AzureAD/microsoft-authentication-library-for-js/.issues/4290), [Flutter](https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/5409), [React Native](https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/4735) -- Browsers' solutions to federated identity without 3p cookie access (FedCM, Storage Access API, First Party Sets, etc) - From 862813492ce87f5f2257e28f3819ff22ce4888d0 Mon Sep 17 00:00:00 2001 From: Hector Morales Date: Tue, 18 Nov 2025 15:22:32 -0800 Subject: [PATCH 09/14] Update readmes based on feedback --- README.md | 2 +- lib/msal-browser/README.md | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f8666fa0b6..643e01734c 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ The [`lib`](https://github.com/AzureAD/microsoft-authentication-library-for-js/t **Disambiguation:** - The MSAL team provides full support to the current version for each package in the table below. -- LTS (long-term support) versions will still receive support and bug-fixes but will not ship new features. +- LTS (long-term support) versions will still receive some support and critical bug-fixes but will not ship new features. Our recommendation if you encounter any issues will always be to upgrade to the latest version of the library. - All supported packages were brought up to version parity as of `v5`. Packages with versions lower than `v4` in the LTS column skipped as many versions as required to jump directly to `v5`. #### MSAL Browser CDN Deprecation diff --git a/lib/msal-browser/README.md b/lib/msal-browser/README.md index a2c774616c..91b2db22a2 100644 --- a/lib/msal-browser/README.md +++ b/lib/msal-browser/README.md @@ -34,6 +34,8 @@ The MSAL library for JavaScript enables client-side JavaScript applications to a The `@azure/msal-browser` package described by the code in this folder uses the [`@azure/msal-common` package](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-common) as a dependency to enable authentication in JavaScript Single-Page Applications without backend servers. This version of the library uses the OAuth 2.0 Authorization Code Flow with PKCE. To read more about this protocol, as well as the differences between implicit flow and authorization code flow, see the section [below](#implicit-flow-vs-authorization-code-flow-with-pkce). +The `@azure/msal-browser` package **does NOT** support the implicit flow. + ## FAQ @@ -142,7 +144,7 @@ npm test npm run test:coverage ``` -## Authorization Code Flow with Proof Key for Code Exchange +## Authorization Code Flow with Proof Key for Code Exchange (PKCE) `@azure/msal-browser` implements the [OAuth 2.0 Authorization Code Flow with PKCE](https://tools.ietf.org/html/rfc7636) for browser-based applications. From 3c32d3d8327ccc61b303ccae29f1fb8b26bc5a19 Mon Sep 17 00:00:00 2001 From: Hector Morales Date: Tue, 18 Nov 2025 15:25:48 -0800 Subject: [PATCH 10/14] Update lib/msal-browser/docs/cdn-usage.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- lib/msal-browser/docs/cdn-usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msal-browser/docs/cdn-usage.md b/lib/msal-browser/docs/cdn-usage.md index aab3755b5f..dc023d80a1 100644 --- a/lib/msal-browser/docs/cdn-usage.md +++ b/lib/msal-browser/docs/cdn-usage.md @@ -3,4 +3,4 @@ **_NOTE:_** Starting from MSAL.js v3 `msal-browser` is no longer hosted on the CDN. If you consume `msal-browser` from the CDN you will need to download `msal-browser` from npm and choose one of the following alternatives before upgrading: 1. Consume the ESM build (preferred) -1. Extract `lib/msal-browser.js` or `lib/msal-browser.min.js` from the downloaded package and serve it as a static asset with your app or host it on your own CDN \ No newline at end of file +1. Extract `lib/msal-browser.js` or `lib/msal-browser.min.js` from the downloaded package and serve it as a static asset with your app or host it on your own CDN. \ No newline at end of file From 05d6c6ca07a3b4f1c11322202d83f65874cd195a Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 18 Nov 2025 15:27:31 -0800 Subject: [PATCH 11/14] Add introductory statement to migration guides section (#8152) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses feedback on #8141 to clarify migration guide selection for users. ## Changes - Added introductory statement "Select the guide that matches your current MSAL version:" before the migration guides list in `lib/msal-browser/README.md` The statement precedes the reverse-chronological list of migration guides (v4→v5, v3→v4, v2→v3, v1→v2) to help users quickly identify which guide applies to their current version. --- 💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey). --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: hectormmg <5218163+hectormmg@users.noreply.github.com> Co-authored-by: Hector Morales --- lib/msal-browser/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/msal-browser/README.md b/lib/msal-browser/README.md index 91b2db22a2..293320aec1 100644 --- a/lib/msal-browser/README.md +++ b/lib/msal-browser/README.md @@ -69,6 +69,8 @@ yarn add @azure/msal-browser ### Migrating from Previous MSAL Versions +Select the guide that matches your current MSAL version: + - [Migrating from MSAL v4.x to MSAL v5.x](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/v4-migration.md) - [Migrating from MSAL v3.x to MSAL v4.x](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/v3-migration.md) - [Migrating from MSAL v2.x to MSAL v3.x](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/v2-migration.md) From e55e00b891b31fcff8adaf097a407c21a0e8859d Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 18 Nov 2025 15:29:01 -0800 Subject: [PATCH 12/14] Remove unintentional backslash from README.md (#8151) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses review feedback from PR #8141 to remove a stray backslash character at the end of line 9 in README.md. The backslash (`\`) was a formatting artifact with no semantic purpose that could cause rendering issues in some markdown parsers. **Change:** - Line 9: `README.md.\` → `README.md.` --- ✨ Let Copilot coding agent [set things up for you](https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: hectormmg <5218163+hectormmg@users.noreply.github.com> Co-authored-by: Hector Morales --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 643e01734c..3aab36fa00 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ The Microsoft Authentication Library for JavaScript enables both client-side and ### Core, wrapper and extensions libraries -The [`lib`](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib) folder contains the source code for our libraries in active development. You will also find all the details about **installing the libraries** in their respective README.md.\ +The [`lib`](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib) folder contains the source code for our libraries in active development. You will also find all the details about **installing the libraries** in their respective README.md. - [Microsoft Authentication Library for JavaScript](lib/msal-browser/): A browser-based, framework-agnostic browser library that enables authentication and token acquisition with the Microsoft Identity platform in JavaScript applications. Implements the OAuth 2.0 [Authorization Code Flow with PKCE](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow), and is [OpenID-compliant](https://docs.microsoft.com/azure/active-directory/develop/v2-protocols-oidc). From dbd435551660640ec0e8ed8120f5e619d42c4fb3 Mon Sep 17 00:00:00 2001 From: Hector Morales Date: Tue, 18 Nov 2025 15:38:15 -0800 Subject: [PATCH 13/14] Removed security support section from SECURITY.md --- SECURITY.md | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 5ef49610e5..58a58f9965 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,21 +1,5 @@ # Security Policy -## Supported Versions - -The following versions of our libraries are receiving security updates: - -| Version | Supported | -| ------- | ------------------ | -| `@azure/msal-browser@2.x.x` | :white_check_mark: | -| `msal@1.x.x` | :white_check_mark: | -| `msal@0.x.x` | :x: | -| `@azure/msal-angular@2.x.x` | :white_check_mark: | -| `@azure/msal-angular@1.x.x` | :white_check_mark: | -| `@azure/msal-angular@0.x.x` | :x: | -| `@azure/msal-angularjs@0.1.x` | :white_check_mark: | -| `@azure/msal-react@1.x.x` | :white_check_mark: | -| `@azure/msal-node@1.x.x` | :white_check_mark: | - ## Reporting a Vulnerability If you find a security issue with our libraries or services [please report it to the Microsoft Security Response Center (MSRC)](https://aka.ms/report-security-issue) with as much detail as possible. Your submission may be eligible for a bounty through the [Microsoft Bounty](http://aka.ms/bugbounty) program. Please do not post security issues to GitHub Issues or any other public site. We will contact you shortly upon receiving the information. We encourage you to get notifications of when security incidents occur by visiting [this page](https://www.microsoft.com/msrc/technical-security-notifications) and subscribing to Security Advisory Alerts. From 991372c286ce6e7593086d1ec51619f6c8002c27 Mon Sep 17 00:00:00 2001 From: Hector Morales Date: Sun, 23 Nov 2025 23:32:05 -0800 Subject: [PATCH 14/14] Update common docs --- lib/msal-common/docs/Response.md | 6 ------ lib/msal-common/docs/Throttling.md | 28 ---------------------------- lib/msal-common/docs/authority.md | 4 ++-- 3 files changed, 2 insertions(+), 36 deletions(-) delete mode 100644 lib/msal-common/docs/Response.md delete mode 100644 lib/msal-common/docs/Throttling.md diff --git a/lib/msal-common/docs/Response.md b/lib/msal-common/docs/Response.md deleted file mode 100644 index 4b69f251f7..0000000000 --- a/lib/msal-common/docs/Response.md +++ /dev/null @@ -1,6 +0,0 @@ -MSAL will return an `AuthenticationResult.ts` object as a response to all acquire token APIs: - -#### `msal-browser` public APIs for token acquisition: -`loginPopup`, `acquireTokenPopup`, `acquireTokenSilent` or `handleRedirectPromise` - -Reference docs for `AuthenticationResult` expanding on each parameter can be found [here](https://azuread.github.io/microsoft-authentication-library-for-js/ref/msal-common/classes/_src_response_authenticationresult_.authenticationresult.html). diff --git a/lib/msal-common/docs/Throttling.md b/lib/msal-common/docs/Throttling.md deleted file mode 100644 index c96136836c..0000000000 --- a/lib/msal-common/docs/Throttling.md +++ /dev/null @@ -1,28 +0,0 @@ -# Client-side throttling -`msaljs` implements protection measures against the AAD backend through client-side throttling. It blocks requests that will only result in erroneous calls, and can often be alleviated with user interaction. It identifies a unique call based on a `RequestThumbprint` type: - -```ts -export type RequestThumbprint = { - clientId: string; - authority: string; - scopes: Array; - homeAccountIdentifier?: string; -}; -``` - -`msaljs` will throttle a specific `RequestThumbprint` if the server returns one of the following cases after making a call: - -* Response contains a 429 or 5xx HTTP status. -* Response contains a `Retry-After` header *and* does not have a 2xx HTTP status. -* The request requires user interaction, represented in `msaljs` as `UserInteractionRequiredError`. - -Before making a silent call, `msaljs` checks to see if a unique `RequestThumbprint` is currently being throttled, and if so, will not make that call and return an error back to the user. Interactive calls bypass this gate as they are made to alleviate the problem. Additionally, a throttled `RequestThumbprint` will be cleared upon a successful interactive response from the server. - -If the server does not provide a time to throttle a `RequestThumbprint`, the default length is 60 seconds. The maximum possible length is 3600 seconds, which `msaljs` will use to override if the server provides something longer. - -```ts -export const ThrottleConstants = { - DEFAULT_THROTTLE_TIME_SECONDS: 60, - DEFAULT_MAX_THROTTLE_TIME_SECONDS: 3600 -} -``` \ No newline at end of file diff --git a/lib/msal-common/docs/authority.md b/lib/msal-common/docs/authority.md index 93597df05e..3f866944f1 100644 --- a/lib/msal-common/docs/authority.md +++ b/lib/msal-common/docs/authority.md @@ -40,9 +40,9 @@ The correct authority URL that you need pass to MSAL is ultimately determined by - Who are the users you want your app to sign-in? - What are the web APIs you want your app to acquire tokens for? -### Azure AD +### Microsoft Entra ID -The authority domain for the global Azure AD instance is `login.microsoftonline.com`. This domain has several aliases (e.g. `login.microsoft.com`) published on the [discovery endpoint](https://login.microsoftonline.com/common/discovery/instance?api-version=1.1&authorization_endpoint=https://login.microsoftonline.com/common/oauth2/v2.0/authorize). For resiliency and performance, MSAL keeps a record of these in cache (see: [AuthorityMetadata.ts](../src/authority/AuthorityMetadata.ts)). MSAL trusts authority URLs with any of these aliases by default. +The authority domain for the global Entra ID instance is `login.microsoftonline.com`. This domain has several aliases (e.g. `login.microsoft.com`) published on the [discovery endpoint](https://login.microsoftonline.com/common/discovery/instance?api-version=1.1&authorization_endpoint=https://login.microsoftonline.com/common/oauth2/v2.0/authorize). For resiliency and performance, MSAL keeps a record of these in cache (see: [AuthorityMetadata.ts](../src/authority/AuthorityMetadata.ts)). MSAL trusts authority URLs with any of these aliases by default. > :warning: The authority domain differs for national/regional Azure deployments, such as Azure China. See [National clouds](https://docs.microsoft.com/azure/active-directory/develop/authentication-national-cloud) for more.