From a881842382200781a168f009f687144cf8e42db1 Mon Sep 17 00:00:00 2001 From: Konstantin Shabelko Date: Mon, 12 May 2025 10:45:35 -0400 Subject: [PATCH 1/5] - Move auth error messages out of the bundle --- lib/msal-browser/docs/errors.md | 231 ++++++++++++------ .../src/error/BrowserAuthError.ts | 97 +------- .../error/BrowserConfigurationAuthError.ts | 13 +- lib/msal-browser/src/error/NativeAuthError.ts | 7 +- .../src/error/NativeAuthErrorCodes.ts | 1 + .../src/error/NestedAppAuthError.ts | 14 +- lib/msal-browser/src/index.ts | 3 - lib/msal-common/docs/errors.md | 221 +++++++++++++++++ lib/msal-common/src/error/AuthError.ts | 12 +- lib/msal-common/src/error/CacheError.ts | 17 +- lib/msal-common/src/error/ClientAuthError.ts | 84 ------- .../src/error/ClientConfigurationError.ts | 48 +--- .../src/error/InteractionRequiredAuthError.ts | 14 +- lib/msal-common/src/error/JoseHeaderError.ts | 9 +- lib/msal-common/src/exports-common.ts | 3 - lib/msal-node/src/index.ts | 3 - 16 files changed, 394 insertions(+), 383 deletions(-) create mode 100644 lib/msal-common/docs/errors.md diff --git a/lib/msal-browser/docs/errors.md b/lib/msal-browser/docs/errors.md index 70d7305439..157b1b1442 100644 --- a/lib/msal-browser/docs/errors.md +++ b/lib/msal-browser/docs/errors.md @@ -1,41 +1,43 @@ -# Errors +# MSAL.js errors ---- +### `pkce_not_created` +- The PKCE code challenge and verifier could not be generated. -**[BrowserConfigurationAuthErrors](#browserconfigurationautherrors)** +### `ear_jwk_empty` +- No EAR encryption key provided. This is unexpected. -1. [stubbed_public_client_application_called](#stubbed_public_client_application_called) +### `ear_jwe_empty` +- Server response does not contain ear_jwe property. This is unexpected. -**[BrowserAuthErrors](#browserautherrors)** +### `crypto_nonexistent` +- The crypto object or function is not available. -1. [interaction_in_progress](#interaction_in_progress) -1. [block_iframe_reload](#block_iframe_reload) -1. [monitor_window_timeout](#monitor_window_timeout) -1. [hash_empty_error](#hash_empty_error) -1. [hash_does_not_contain_known_properties](#hash_does_not_contain_known_properties) -1. [unable_to_acquire_token_from_native_platform](#unable_to_acquire_token_from_native_platform) -1. [native_connection_not_established](#native_connection_not_established) -1. [uninitialized_public_client_application](#uninitialized_public_client_application) +### `empty_navigate_uri` +- Navigation URI is empty. Please check stack trace for more info. -**[Other](#other)** +### `hash_empty_error` +- Hash value cannot be processed because it is empty. Please verify that your redirectUri is not clearing the hash. -1. [Access to fetch at [url] has been blocked by CORS policy](#access-to-fetch-at-url-has-been-blocked-by-cors-policy) - ---- +This error occurs when the page you use as your redirectUri is removing the hash, or auto-redirecting to another page. This most commonly happens when the application implements a router which navigates to another route, dropping the hash. -## BrowserConfigurationAuthErrors +To resolve this error we recommend using a dedicated redirectUri page which is not subject to the router. For silent and popup calls it's best to use a blank page. If this is not possible please make sure the router does not navigate while MSAL token acquisition is in progress. You can do this by detecting if your application is loaded in an iframe for silent calls, in a popup for popup calls or by awaiting `handleRedirectPromise` for redirect calls. -### stubbed_public_client_application_called +### `no_state_in_hash` +- Hash does not contain state. Please verify that the request originated from msal -**Error Message**: Stub instance of Public Client Application was called. If using msal-react, please ensure context is not used without a provider. +### `hash_does_not_contain_known_properties` +- Hash does not contain known properties. Please verify that your redirectUri is not changing the hash. -See [msal-react errors](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-react/docs/errors.md) +Please see explanation for [hash_empty_error](#hash_empty_error) above. The root cause for this error is similar, the difference being the hash has been changed, rather than dropped. -## BrowserAuthErrors +### `unable_to_parse_state` +- Unable to parse state. Please verify that the request originated from msal. -### Interaction_in_progress +### `state_interaction_type_mismatch` +- Hash contains state but the interaction type does not match the caller. -**Error Message**: Interaction is currently in progress. Please ensure that this interaction has been completed before calling an interactive API. +### `interaction_in_progress` +- Interaction is currently in progress. Please ensure that this interaction has been completed before calling an interactive API. This error is thrown when an interactive API (`loginPopup`, `loginRedirect`, `acquireTokenPopup`, `acquireTokenRedirect`) is invoked while another interactive API is still in progress. The login and acquireToken APIs are async so you will need to ensure that the resulting promises have resolved before invoking another one. @@ -234,27 +236,20 @@ If you are unable to figure out why this error is being thrown please [open an i - Refresh the page. Does the error go away? - Open your application in a new tab. Does the error go away? -### block_iframe_reload - -**Error Message**: Request was blocked inside an iframe because MSAL detected an authentication response. - -This error is thrown when calling `ssoSilent` or `acquireTokenSilent` and the page used as your `redirectUri` is attempting to invoke a login or acquireToken function. -Our recommended mitigation for this is to set your `redirectUri` to a blank page that does not implement MSAL when invoking silent APIs. This will also have the added benefit of improving performance as the hidden iframe doesn't need to render your page. - -✔️ You can do this on a per request basis, for example: +### `popup_window_error` +- Error opening popup window. This can happen if you are using IE or if popups are blocked in the browser. -```javascript -msalInstance.acquireTokenSilent({ - scopes: ["User.Read"], - redirectUri: "http://localhost:3000/blank.html", -}); -``` +### `empty_window_error` +- window.open returned null or undefined window object. -Remember that you will need to register this new `redirectUri` on your App Registration. +### `user_cancelled` +- User cancelled the flow. -If you do not want to use a dedicated `redirectUri` for this purpose, you should instead ensure that your `redirectUri` is not attempting to call MSAL APIs when rendered inside the hidden iframe used by the silent APIs. +### `monitor_popup_timeout` +- Token acquisition in popup failed due to timeout. For more visit: https://aka.ms/msaljs/browser-errors#monitor_popup_timeout -### monitor_window_timeout +### `monitor_window_timeout` +- Token acquisition in iframe failed due to timeout. For more visit: https://aka.ms/msaljs/browser-errors#monitor_window_timeout **Error Messages**: @@ -337,48 +332,112 @@ const msalConfig = { > [!IMPORTANT] > Please consult the [Troubleshooting Single-Sign On](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/FAQ.md#troubleshooting-single-sign-on) section of the MSAL Browser FAQ if you are having trouble with the `ssoSilent` API. -### hash_empty_error +### `redirect_in_iframe` +- Redirects are not supported for iframed or brokered applications. Please ensure you are using MSAL.js in a top frame of the window if using the redirect APIs, or use the popup APIs. -**Error Messages**: +### `block_iframe_reload` +- Request was blocked inside an iframe because MSAL detected an authentication response. For more visit: https://aka.ms/msaljs/browser-errors#block_iframe_reload -> Hash value cannot be processed because it is empty. Please verify that your redirectUri is not clearing the hash. +This error is thrown when calling `ssoSilent` or `acquireTokenSilent` and the page used as your `redirectUri` is attempting to invoke a login or acquireToken function. +Our recommended mitigation for this is to set your `redirectUri` to a blank page that does not implement MSAL when invoking silent APIs. This will also have the added benefit of improving performance as the hidden iframe doesn't need to render your page. -This error occurs when the page you use as your redirectUri is removing the hash, or auto-redirecting to another page. This most commonly happens when the application implements a router which navigates to another route, dropping the hash. +✔️ You can do this on a per request basis, for example: -To resolve this error we recommend using a dedicated redirectUri page which is not subject to the router. For silent and popup calls it's best to use a blank page. If this is not possible please make sure the router does not navigate while MSAL token acquisition is in progress. You can do this by detecting if your application is loaded in an iframe for silent calls, in a popup for popup calls or by awaiting `handleRedirectPromise` for redirect calls. +```javascript +msalInstance.acquireTokenSilent({ + scopes: ["User.Read"], + redirectUri: "http://localhost:3000/blank.html", +}); +``` -### hash_does_not_contain_known_properties +Remember that you will need to register this new `redirectUri` on your App Registration. -**Error Messages**: +If you do not want to use a dedicated `redirectUri` for this purpose, you should instead ensure that your `redirectUri` is not attempting to call MSAL APIs when rendered inside the hidden iframe used by the silent APIs. -> Hash does not contain known properites. Please verify that your redirectUri is not changing the hash. +### `block_nested_popups` +- Request was blocked inside a popup because MSAL detected it was running in a popup. -Please see explanation for [hash_empty_error](#hash_empty_error) above. The root cause for this error is similar, the difference being the hash has been changed, rather than dropped. +### `iframe_closed_prematurely` +- The iframe being monitored was closed prematurely. -### unable_to_acquire_token_from_native_platform +### `silent_logout_unsupported` +- Silent logout not supported. Please call logoutRedirect or logoutPopup instead. -**Error Messages**: +### `no_account_error` +- No account object provided to acquireTokenSilent and no active account has been set. Please call setActiveAccount or provide an account on the request. -- Unable to acquire token from native platform. +### `silent_prompt_value_error` +- The value given for the prompt value is not valid for silent requests - must be set to 'none' or 'no_session'. + +### `no_token_request_cache_error` +- No token request found in cache. + +### `unable_to_parse_token_request_cache_error` +- The cached token request could not be parsed. + +### `auth_request_not_set_error` +- Auth Request not set. Please ensure initiateAuthRequest was called from the InteractionHandler. + +### `invalid_cache_type` +- Invalid cache type. + +### `non_browser_environment` +- Login and token requests are not supported in non-browser environments. + +### `database_not_open` +- Database is not open. + +### `no_network_connectivity` +- No network connectivity. Check your internet connection. + +### `post_request_failed` +- Network request failed: If the browser threw a CORS error, check that the redirectUri is registered in the Azure App Portal as type 'SPA'. + +### `get_request_failed` +- Network request failed. Please check the network trace to determine root cause. + +### `failed_to_parse_response` +- Failed to parse network response. Check network trace. + +### `unable_to_load_token` +- Error loading token to cache. + +### `crypto_key_not_found` +- Cryptographic Key or Keypair not found in browser storage. + +### `auth_code_required` +- An authorization code must be provided (as the `code` property on the request) to this flow. + +### `auth_code_or_nativeAccountId_required` +- An authorization code or nativeAccountId must be provided to this flow. + +### `spa_code_and_nativeAccountId_present` +- Request cannot contain both spa code and native account id. + +### `database_unavailable` +- IndexedDB, which is required for persistent cryptographic key storage, is unavailable. This may be caused by browser privacy features which block persistent storage in third-party contexts. + +### `unable_to_acquire_token_from_native_platform` +- Unable to acquire token from native platform. This error is thrown when calling the `acquireTokenByCode` API with the `nativeAccountId` instead of `code` and the app is running in an environment which does not acquire tokens from the native broker. For a list of pre-requisites please review the doc on [device bound tokens](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/device-bound-tokens.md). -### native_connection_not_established +### `native_handshake_timeout` +- Timed out while attempting to establish connection to browser extension. -**Error Messages**: +### `native_extension_not_installed` +- Native extension is not installed. If you think this is a mistake call the initialize function. -- Connection to native platform has not been established. Please install a compatible browser extension and run initialize(). +### `native_connection_not_established` +- Connection to native platform has not been established. Please install a compatible browser extension and run initialize(). This error is thrown when the user signed in with the native broker but no connection to the native broker currently exists. This can happen for the following reasons: - The Windows Accounts extension was uninstalled or disabled - The `initialize` API has not been called or was not awaited before invoking another MSAL API -### uninitialized_public_client_application - -**Error Messages**: - -- You must call and await the initialize function before attempting to call any other MSAL API. +### `uninitialized_public_client_application` +- You must call and await the initialize function before attempting to call any other MSAL API. This error is thrown when a `login`, `acquireToken` or `handleRedirectPromise` API is invoked before the `initialize` API has been called. The `initialize` API must be called and awaited before attempting to acquire tokens. @@ -415,27 +474,51 @@ await msalInstance.handleRedirectPromise(); // This will no longer throw this er msalInstance.acquireTokenSilent(); // This will also no longer throw this error ``` -## Other +### `native_prompt_not_supported` +- The provided prompt is not supported by the native platform. This request should be routed to the web based flow. -Errors not thrown by MSAL, such as server or cache errors. +### `invalid_base64_string` +- Invalid base64 encoded string. -### Access to fetch at [url] has been blocked by CORS policy +### `invalid_pop_token_request` +- Invalid PoP token request. The request should not have both a popKid value and signPopToken set to true. -This error occurs with MSAL.js v2.x and is due to improper configuration during **App Registration** on **Azure Portal**. In particular, you should ensure your `redirectUri` is registered as type: `Single-page application` under the **Authentication** blade in your App Registration. If done successfully, you will see a green checkmark that says: +### `failed_to_build_headers` +- Failed to build request headers object. -> Your Redirect URI is eligible for the Authorization Code Flow with PKCE. +### `failed_to_parse_headers` +- Failed to parse response headers. -![image](https://user-images.githubusercontent.com/5307810/110390912-922fa380-801b-11eb-9e2b-d7aa88ca0687.png) +### `failed_to_decrypt_ear_response` +- Failed to decrypt ear response. + +### `storage_not_supported` +- Given storage configuration option was not supported. + +### `stubbed_public_client_application_called` +- Stub instance of Public Client Application was called. If using msal-react, please ensure context is not used without a provider. +- See [msal-react errors](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-react/docs/errors.md). -### cache_quota_exceeded +### `in_mem_redirect_unavailable` +- Redirect cannot be supported. In-memory storage was selected and storeAuthStateInCookie=false, which would cause the library to be unable to handle the incoming hash. If you would like to use the redirect API, please use session/localStorage or set storeAuthStateInCookie=true. -**Error messages**: +### `ContentError` +- Native broker content error. -- Exceeded cache storage capacity +### `user_switch` +- User attempted to switch accounts in the native broker, which is not allowed. All new accounts must sign-in through the standard web flow first, please try again. -This error occurs when MSAL.js surpasses the allotted storage limit when attempting to save token information in the [configured cache storage](./caching.md#cache-storage). See [here](https://developer.mozilla.org/en-US/docs/Web/API/Storage_API/Storage_quotas_and_eviction_criteria#web_storage) for web storage limits. +### `unsupported_method` +- This method is not supported in nested app environment. -**Mitigation**: +### Other -1. Make sure the configured cache storage has enough capacity to allow MSAL.js to persist token payload. The amount of cache storage required depends on the number of [cached artifacts](./caching.md#cached-artifacts). -2. Disable [claimsBasedCachingEnabled](./configuration.md#cache-config-options) cache config option. When enabled, it caches access tokens under a key containing the hash of the requested claims. Depending on the MSAL.js API usage, it may result in the vast number of access tokens persisted in the cache storage. +Errors not thrown by MSAL, such as server or cache errors. + +#### Access to fetch at [url] has been blocked by CORS policy + +This error occurs with MSAL.js v2.x and is due to improper configuration during **App Registration** on **Azure Portal**. In particular, you should ensure your `redirectUri` is registered as type: `Single-page application` under the **Authentication** blade in your App Registration. If done successfully, you will see a green checkmark that says: + +> Your Redirect URI is eligible for the Authorization Code Flow with PKCE. + +![image](https://user-images.githubusercontent.com/5307810/110390912-922fa380-801b-11eb-9e2b-d7aa88ca0687.png) diff --git a/lib/msal-browser/src/error/BrowserAuthError.ts b/lib/msal-browser/src/error/BrowserAuthError.ts index 437efd3674..2b135bec30 100644 --- a/lib/msal-browser/src/error/BrowserAuthError.ts +++ b/lib/msal-browser/src/error/BrowserAuthError.ts @@ -7,107 +7,12 @@ import { AuthError } from "@azure/msal-common/browser"; import * as BrowserAuthErrorCodes from "./BrowserAuthErrorCodes.js"; export { BrowserAuthErrorCodes }; // Allow importing as "BrowserAuthErrorCodes" -const ErrorLink = "For more visit: aka.ms/msaljs/browser-errors"; - -/** - * BrowserAuthErrorMessage class containing string constants used by error codes and messages. - */ -export const BrowserAuthErrorMessages = { - [BrowserAuthErrorCodes.pkceNotCreated]: - "The PKCE code challenge and verifier could not be generated.", - [BrowserAuthErrorCodes.earJwkEmpty]: - "No EAR encryption key provided. This is unexpected.", - [BrowserAuthErrorCodes.earJweEmpty]: - "Server response does not contain ear_jwe property. This is unexpected.", - [BrowserAuthErrorCodes.cryptoNonExistent]: - "The crypto object or function is not available.", - [BrowserAuthErrorCodes.emptyNavigateUri]: - "Navigation URI is empty. Please check stack trace for more info.", - [BrowserAuthErrorCodes.hashEmptyError]: `Hash value cannot be processed because it is empty. Please verify that your redirectUri is not clearing the hash. ${ErrorLink}`, - [BrowserAuthErrorCodes.noStateInHash]: - "Hash does not contain state. Please verify that the request originated from msal.", - [BrowserAuthErrorCodes.hashDoesNotContainKnownProperties]: `Hash does not contain known properites. Please verify that your redirectUri is not changing the hash. ${ErrorLink}`, - [BrowserAuthErrorCodes.unableToParseState]: - "Unable to parse state. Please verify that the request originated from msal.", - [BrowserAuthErrorCodes.stateInteractionTypeMismatch]: - "Hash contains state but the interaction type does not match the caller.", - [BrowserAuthErrorCodes.interactionInProgress]: `Interaction is currently in progress. Please ensure that this interaction has been completed before calling an interactive API. ${ErrorLink}`, - [BrowserAuthErrorCodes.popupWindowError]: - "Error opening popup window. This can happen if you are using IE or if popups are blocked in the browser.", - [BrowserAuthErrorCodes.emptyWindowError]: - "window.open returned null or undefined window object.", - [BrowserAuthErrorCodes.userCancelled]: "User cancelled the flow.", - [BrowserAuthErrorCodes.monitorPopupTimeout]: `Token acquisition in popup failed due to timeout. ${ErrorLink}`, - [BrowserAuthErrorCodes.monitorWindowTimeout]: `Token acquisition in iframe failed due to timeout. ${ErrorLink}`, - [BrowserAuthErrorCodes.redirectInIframe]: - "Redirects are not supported for iframed or brokered applications. Please ensure you are using MSAL.js in a top frame of the window if using the redirect APIs, or use the popup APIs.", - [BrowserAuthErrorCodes.blockIframeReload]: `Request was blocked inside an iframe because MSAL detected an authentication response. ${ErrorLink}`, - [BrowserAuthErrorCodes.blockNestedPopups]: - "Request was blocked inside a popup because MSAL detected it was running in a popup.", - [BrowserAuthErrorCodes.iframeClosedPrematurely]: - "The iframe being monitored was closed prematurely.", - [BrowserAuthErrorCodes.silentLogoutUnsupported]: - "Silent logout not supported. Please call logoutRedirect or logoutPopup instead.", - [BrowserAuthErrorCodes.noAccountError]: - "No account object provided to acquireTokenSilent and no active account has been set. Please call setActiveAccount or provide an account on the request.", - [BrowserAuthErrorCodes.silentPromptValueError]: - "The value given for the prompt value is not valid for silent requests - must be set to 'none' or 'no_session'.", - [BrowserAuthErrorCodes.noTokenRequestCacheError]: - "No token request found in cache.", - [BrowserAuthErrorCodes.unableToParseTokenRequestCacheError]: - "The cached token request could not be parsed.", - [BrowserAuthErrorCodes.authRequestNotSetError]: - "Auth Request not set. Please ensure initiateAuthRequest was called from the InteractionHandler", - [BrowserAuthErrorCodes.invalidCacheType]: "Invalid cache type", - [BrowserAuthErrorCodes.nonBrowserEnvironment]: - "Login and token requests are not supported in non-browser environments.", - [BrowserAuthErrorCodes.databaseNotOpen]: "Database is not open!", - [BrowserAuthErrorCodes.noNetworkConnectivity]: - "No network connectivity. Check your internet connection.", - [BrowserAuthErrorCodes.postRequestFailed]: - "Network request failed: If the browser threw a CORS error, check that the redirectUri is registered in the Azure App Portal as type 'SPA'", - [BrowserAuthErrorCodes.getRequestFailed]: - "Network request failed. Please check the network trace to determine root cause.", - [BrowserAuthErrorCodes.failedToParseResponse]: - "Failed to parse network response. Check network trace.", - [BrowserAuthErrorCodes.unableToLoadToken]: "Error loading token to cache.", - [BrowserAuthErrorCodes.cryptoKeyNotFound]: - "Cryptographic Key or Keypair not found in browser storage.", - [BrowserAuthErrorCodes.authCodeRequired]: - "An authorization code must be provided (as the `code` property on the request) to this flow.", - [BrowserAuthErrorCodes.authCodeOrNativeAccountIdRequired]: - "An authorization code or nativeAccountId must be provided to this flow.", - [BrowserAuthErrorCodes.spaCodeAndNativeAccountIdPresent]: - "Request cannot contain both spa code and native account id.", - [BrowserAuthErrorCodes.databaseUnavailable]: - "IndexedDB, which is required for persistent cryptographic key storage, is unavailable. This may be caused by browser privacy features which block persistent storage in third-party contexts.", - [BrowserAuthErrorCodes.unableToAcquireTokenFromNativePlatform]: `Unable to acquire token from native platform. ${ErrorLink}`, - [BrowserAuthErrorCodes.nativeHandshakeTimeout]: - "Timed out while attempting to establish connection to browser extension", - [BrowserAuthErrorCodes.nativeExtensionNotInstalled]: - "Native extension is not installed. If you think this is a mistake call the initialize function.", - [BrowserAuthErrorCodes.nativeConnectionNotEstablished]: `Connection to native platform has not been established. Please install a compatible browser extension and run initialize(). ${ErrorLink}`, - [BrowserAuthErrorCodes.uninitializedPublicClientApplication]: `You must call and await the initialize function before attempting to call any other MSAL API. ${ErrorLink}`, - [BrowserAuthErrorCodes.nativePromptNotSupported]: - "The provided prompt is not supported by the native platform. This request should be routed to the web based flow.", - [BrowserAuthErrorCodes.invalidBase64String]: - "Invalid base64 encoded string.", - [BrowserAuthErrorCodes.invalidPopTokenRequest]: - "Invalid PoP token request. The request should not have both a popKid value and signPopToken set to true.", - [BrowserAuthErrorCodes.failedToBuildHeaders]: - "Failed to build request headers object.", - [BrowserAuthErrorCodes.failedToParseHeaders]: - "Failed to parse response headers", - [BrowserAuthErrorCodes.failedToDecryptEarResponse]: - "Failed to decrypt ear response", -}; - /** * Browser library error class thrown by the MSAL.js library for SPAs */ export class BrowserAuthError extends AuthError { constructor(errorCode: string, subError?: string) { - super(errorCode, BrowserAuthErrorMessages[errorCode], subError); + super(errorCode, `See https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/errors.md#${errorCode} for details`, subError); Object.setPrototypeOf(this, BrowserAuthError.prototype); this.name = "BrowserAuthError"; diff --git a/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts b/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts index 1550fa0c51..0c58dcdd15 100644 --- a/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts +++ b/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts @@ -6,16 +6,6 @@ import { AuthError } from "@azure/msal-common/browser"; import * as BrowserConfigurationAuthErrorCodes from "./BrowserConfigurationAuthErrorCodes.js"; export { BrowserConfigurationAuthErrorCodes }; - -export const BrowserConfigurationAuthErrorMessages = { - [BrowserConfigurationAuthErrorCodes.storageNotSupported]: - "Given storage configuration option was not supported.", - [BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled]: - "Stub instance of Public Client Application was called. If using msal-react, please ensure context is not used without a provider. For more visit: aka.ms/msaljs/browser-errors", - [BrowserConfigurationAuthErrorCodes.inMemRedirectUnavailable]: - "Redirect cannot be supported. In-memory storage was selected and storeAuthStateInCookie=false, which would cause the library to be unable to handle the incoming hash. If you would like to use the redirect API, please use session/localStorage or set storeAuthStateInCookie=true.", -}; - /** * Browser library error class thrown by the MSAL.js library for SPAs */ @@ -32,7 +22,6 @@ export function createBrowserConfigurationAuthError( errorCode: string ): BrowserConfigurationAuthError { return new BrowserConfigurationAuthError( - errorCode, - BrowserConfigurationAuthErrorMessages[errorCode] + errorCode ); } diff --git a/lib/msal-browser/src/error/NativeAuthError.ts b/lib/msal-browser/src/error/NativeAuthError.ts index c3056ae7e3..78bf2b24ed 100644 --- a/lib/msal-browser/src/error/NativeAuthError.ts +++ b/lib/msal-browser/src/error/NativeAuthError.ts @@ -28,11 +28,6 @@ export type OSError = { const INVALID_METHOD_ERROR = -2147186943; -export const NativeAuthErrorMessages = { - [NativeAuthErrorCodes.userSwitch]: - "User attempted to switch accounts in the native broker, which is not allowed. All new accounts must sign-in through the standard web flow first, please try again.", -}; - export class NativeAuthError extends AuthError { ext: OSError | undefined; @@ -107,7 +102,7 @@ export function createNativeAuthError( return new NativeAuthError( code, - NativeAuthErrorMessages[code] || description, + description, ext ); } diff --git a/lib/msal-browser/src/error/NativeAuthErrorCodes.ts b/lib/msal-browser/src/error/NativeAuthErrorCodes.ts index 85087d00e7..7834f63a26 100644 --- a/lib/msal-browser/src/error/NativeAuthErrorCodes.ts +++ b/lib/msal-browser/src/error/NativeAuthErrorCodes.ts @@ -5,3 +5,4 @@ export const contentError = "ContentError"; export const userSwitch = "user_switch"; +export const unsupportedMethod = "unsupported_method"; diff --git a/lib/msal-browser/src/error/NestedAppAuthError.ts b/lib/msal-browser/src/error/NestedAppAuthError.ts index 7b9ee997b2..628ea92b64 100644 --- a/lib/msal-browser/src/error/NestedAppAuthError.ts +++ b/lib/msal-browser/src/error/NestedAppAuthError.ts @@ -4,16 +4,7 @@ */ import { AuthError } from "@azure/msal-common/browser"; - -/** - * NestedAppAuthErrorMessage class containing string constants used by error codes and messages. - */ -export const NestedAppAuthErrorMessage = { - unsupportedMethod: { - code: "unsupported_method", - desc: "This method is not supported in nested app environment.", - }, -}; +import { unsupportedMethod } from "./NativeAuthErrorCodes.js"; export class NestedAppAuthError extends AuthError { constructor(errorCode: string, errorMessage?: string) { @@ -25,8 +16,7 @@ export class NestedAppAuthError extends AuthError { public static createUnsupportedError(): NestedAppAuthError { return new NestedAppAuthError( - NestedAppAuthErrorMessage.unsupportedMethod.code, - NestedAppAuthErrorMessage.unsupportedMethod.desc + unsupportedMethod ); } } diff --git a/lib/msal-browser/src/index.ts b/lib/msal-browser/src/index.ts index 18a96c2b30..b8491023d3 100644 --- a/lib/msal-browser/src/index.ts +++ b/lib/msal-browser/src/index.ts @@ -110,13 +110,10 @@ export { // Error AuthError, AuthErrorCodes, - AuthErrorMessages, ClientAuthError, ClientAuthErrorCodes, - ClientAuthErrorMessages, ClientConfigurationError, ClientConfigurationErrorCodes, - ClientConfigurationErrorMessages, InteractionRequiredAuthError, InteractionRequiredAuthErrorCodes, ServerError, diff --git a/lib/msal-common/docs/errors.md b/lib/msal-common/docs/errors.md new file mode 100644 index 0000000000..882ef20655 --- /dev/null +++ b/lib/msal-common/docs/errors.md @@ -0,0 +1,221 @@ +# MSAL.js errors + +### `unexpected_error` +- Unexpected error in authentication. + +### `post_request_failed` +- Post request failed from the network, could be a 4xx/5xx or a network unavailability. Please check the exact error code for details. + +### `cache_quota_exceeded` +- Exceeded cache storage capacity. + +This error occurs when MSAL.js surpasses the allotted storage limit when attempting to save token information in the [configured cache storage](./caching.md#cache-storage). See [here](https://developer.mozilla.org/en-US/docs/Web/API/Storage_API/Storage_quotas_and_eviction_criteria#web_storage) for web storage limits. + +**Mitigation**: + +1. Make sure the configured cache storage has enough capacity to allow MSAL.js to persist token payload. The amount of cache storage required depends on the number of [cached artifacts](./caching.md#cached-artifacts). +2. Disable [claimsBasedCachingEnabled](./configuration.md#cache-config-options) cache config option. When enabled, it caches access tokens under a key containing the hash of the requested claims. Depending on the MSAL.js API usage, it may result in the vast number of access tokens persisted in the cache storage. + +### `cache_error_unknown` +- An unknown error occurred while accessing the browser cache. + +### `client_info_decoding_error` +- The client info could not be parsed/decoded correctly. + +### `client_info_empty_error` +- The client info was empty. + +### `token_parsing_error` +- Token cannot be parsed. + +### `null_or_empty_token` +- The token is null or empty. + +### `endpoints_resolution_error` +- Could not resolve endpoints. Please check network and try again. + +### `network_error` +- Network request failed. Please check network and try again. + +### `openid_config_error` +- Could not retrieve endpoints. Check your authority and verify the .well-known/openid-configuration endpoint returns the required endpoints. + +### `hash_not_deserialized` +- The hash parameters could not be deserialized. + +### `invalid_state` +- State was not the expected format. + +### `state_mismatch` +- State mismatch error. + +### `state_not_found` +- State not found. + +### `nonce_mismatch` +- Nonce mismatch error. + +### `auth_time_not_found` +- Max Age was requested and the ID token is missing the auth_time variable auth_time is an optional claim and is not enabled by default - it must be enabled. See https://aka.ms/msaljs/optional-claims for more information. + +### `max_age_transpired` +- Max Age is set to 0, or too much time has elapsed since the last end-user authentication. + +### `multiple_matching_tokens` +- The cache contains multiple tokens satisfying the requirements. Call AcquireToken again providing more requirements such as authority or account. + +### `multiple_matching_appMetadata` +- The cache contains multiple appMetadata satisfying the given parameters. Please pass more info to obtain the correct appMetadata. + +### `request_cannot_be_made` +- Token request cannot be made without authorization code or refresh token. + +### `cannot_remove_empty_scope` +- Cannot remove null or empty scope from ScopeSet. + +### `cannot_append_scopeset` +- Cannot append ScopeSet. + +### `empty_input_scopeset` +- Empty input ScopeSet cannot be processed. + +### `no_account_in_silent_request` +- Please pass an account object, silent flow is not supported without account information. + +### `invalid_cache_record` +- Cache record object was null or undefined. + +### `invalid_cache_environment` +- Invalid environment when attempting to create cache entry. + +### `no_account_found` +- No account found in cache for given key. + +### `no_crypto_object` +- No crypto object detected. + +### `unexpected_credential_type` +- Unexpected credential type. + +### `token_refresh_required` +- Cannot return token from cache because it must be refreshed. This may be due to one of the following reasons: forceRefresh parameter is set to true, claims have been requested, there is no cached access token or it is expired. + +### `token_claims_cnf_required_for_signedjwt` +- Cannot generate a POP jwt if the token_claims are not populated. + +### `authorization_code_missing_from_server_response` +- Server response does not contain an authorization code to proceed. + +### `binding_key_not_removed` +- Could not remove the credential's binding key from storage. + +### `end_session_endpoint_not_supported` +- The provided authority does not support logout. + +### `key_id_missing` +- A keyId value is missing from the requested bound token's cache record and is required to match the token to it's stored binding key. + +### `no_network_connectivity` +- No network connectivity. Check your internet connection. + +### `user_canceled` +- User cancelled the flow. + +### `method_not_implemented` +- This method has not been implemented. + +### `nested_app_auth_bridge_disabled` +- The nested app auth bridge is disabled. + +### `redirect_uri_empty` +- A redirect URI is required for all calls, and none has been set. + +### `claims_request_parsing_error` +- Could not parse the given claims request object. + +### `authority_uri_insecure` +- Authority URIs must use https. Please see here for valid authority configuration options: https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-js-initializing-client-applications#configuration-options. + +### `url_parse_error` +- URL could not be parsed into appropriate segments. + +### `empty_url_error` +- URL was empty or null. + +### `empty_input_scopes_error` +- Scopes cannot be passed as null, undefined or empty array because they are required to obtain an access token. + +### `invalid_prompt_value` +- Invalid prompt value. Please see here for valid configuration options: https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_common.html#commonauthorizationurlrequest + +### `invalid_claims` +- Given claims parameter must be a stringified JSON object. + +### `token_request_empty` +- Token request was empty and not found in cache. + +### `logout_request_empty` +- The logout request was null or undefined. + +### `invalid_code_challenge_method` +- code_challenge_method passed is invalid. Valid values are "plain" and "S256". + +### `pkce_params_missing` +- Both params: code_challenge and code_challenge_method are to be passed if to be sent in the request. + +### `invalid_cloud_discovery_metadata` +- Invalid cloudDiscoveryMetadata provided. Must be a stringified JSON object containing tenant_discovery_endpoint and metadata fields. + +### `invalid_authority_metadata` +- Invalid authorityMetadata provided. Must by a stringified JSON object containing authorization_endpoint, token_endpoint, issuer fields. + +### `untrusted_authority` +- The provided authority is not a trusted authority. Please include this authority in the knownAuthorities config parameter. + +### `missing_ssh_jwk` +- Missing sshJwk in SSH certificate request. A stringified JSON Web Key is required when using the SSH authentication scheme. + +### `missing_ssh_kid` +- Missing sshKid in SSH certificate request. A string that uniquely identifies the public SSH key is required when using the SSH authentication scheme. + +### `missing_nonce_authentication_header` +- Unable to find an authentication header containing server nonce. Either the Authentication-Info or WWW-Authenticate headers must be present in order to obtain a server nonce. + +### `invalid_authentication_header` +- Invalid authentication header provided. + +### `cannot_set_OIDCOptions` +- Cannot set OIDCOptions parameter. Please change the protocol mode to OIDC or use a non-Microsoft authority. + +### `cannot_allow_platform_broker` +- Cannot set allowPlatformBroker parameter to true when not in AAD protocol mode. + +### `authority_mismatch` +- Authority mismatch error. Authority provided in login request or PublicClientApplication config does not match the environment of the provided account. Please use a matching account or make an interactive request to login to this authority. + +### `no_tokens_found` +- No refresh token found in the cache. Please sign-in. + +### `native_account_unavailable` +- The requested account is not available in the native broker. It may have been deleted or logged out. Please sign-in again using an interactive API. + +### `refresh_token_expired` +- Refresh token has expired. + +### `interaction_required` +- User interaction is required. + +### `consent_required` +- User consent is required. + +### `login_required` +- User login is required. + +### `bad_token` +- Identity provider returned bad_token due to an expired or invalid refresh token. Please invoke an interactive API to resolve. + +### `missing_kid_error` +- The JOSE Header for the requested JWT, JWS or JWK object requires a keyId to be configured as the 'kid' header claim. No 'kid' value was provided. + +### `missing_alg_error` +- The JOSE Header for the requested JWT, JWS or JWK object requires an algorithm to be specified as the 'alg' header claim. No 'alg' value was provided. diff --git a/lib/msal-common/src/error/AuthError.ts b/lib/msal-common/src/error/AuthError.ts index b174b36aa9..ec54036361 100644 --- a/lib/msal-common/src/error/AuthError.ts +++ b/lib/msal-common/src/error/AuthError.ts @@ -7,11 +7,9 @@ import { Constants } from "../utils/Constants.js"; import * as AuthErrorCodes from "./AuthErrorCodes.js"; export { AuthErrorCodes }; -export const AuthErrorMessages = { - [AuthErrorCodes.unexpectedError]: "Unexpected error in authentication.", - [AuthErrorCodes.postRequestFailed]: - "Post request failed from the network, could be a 4xx/5xx or a network unavailability. Please check the exact error code for details.", -}; +export function getDefaultErrorMessage(code: string): string { + return `See https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/errors.md#${code} for details`; +} /** * General error class thrown by the MSAL.js library. @@ -61,8 +59,6 @@ export function createAuthError( ): AuthError { return new AuthError( code, - additionalMessage - ? `${AuthErrorMessages[code]} ${additionalMessage}` - : AuthErrorMessages[code] + additionalMessage || getDefaultErrorMessage(code) ); } diff --git a/lib/msal-common/src/error/CacheError.ts b/lib/msal-common/src/error/CacheError.ts index 0ac74e8e37..4e96ead09d 100644 --- a/lib/msal-common/src/error/CacheError.ts +++ b/lib/msal-common/src/error/CacheError.ts @@ -4,15 +4,9 @@ */ import * as CacheErrorCodes from "./CacheErrorCodes.js"; +import { getDefaultErrorMessage } from "./AuthError.js"; export { CacheErrorCodes }; -export const CacheErrorMessages = { - [CacheErrorCodes.cacheQuotaExceededErrorCode]: - "Exceeded cache storage capacity.", - [CacheErrorCodes.cacheUnknownErrorCode]: - "Unexpected error occurred when using cache storage.", -}; - /** * Error thrown when there is an error with the cache */ @@ -28,13 +22,8 @@ export class CacheError extends Error { errorMessage: string; constructor(errorCode: string, errorMessage?: string) { - const message = - errorMessage || - (CacheErrorMessages[errorCode] - ? CacheErrorMessages[errorCode] - : CacheErrorMessages[CacheErrorCodes.cacheUnknownErrorCode]); - - super(`${errorCode}: ${message}`); + const message = errorMessage || getDefaultErrorMessage(errorCode); + super(message); Object.setPrototypeOf(this, CacheError.prototype); this.name = "CacheError"; diff --git a/lib/msal-common/src/error/ClientAuthError.ts b/lib/msal-common/src/error/ClientAuthError.ts index 0a119f65f4..49fc88798d 100644 --- a/lib/msal-common/src/error/ClientAuthError.ts +++ b/lib/msal-common/src/error/ClientAuthError.ts @@ -11,88 +11,6 @@ export { ClientAuthErrorCodes }; // Allow importing as "ClientAuthErrorCodes"; * ClientAuthErrorMessage class containing string constants used by error codes and messages. */ -export const ClientAuthErrorMessages = { - [ClientAuthErrorCodes.clientInfoDecodingError]: - "The client info could not be parsed/decoded correctly", - [ClientAuthErrorCodes.clientInfoEmptyError]: "The client info was empty", - [ClientAuthErrorCodes.tokenParsingError]: "Token cannot be parsed", - [ClientAuthErrorCodes.nullOrEmptyToken]: "The token is null or empty", - [ClientAuthErrorCodes.endpointResolutionError]: - "Endpoints cannot be resolved", - [ClientAuthErrorCodes.networkError]: "Network request failed", - [ClientAuthErrorCodes.openIdConfigError]: - "Could not retrieve endpoints. Check your authority and verify the .well-known/openid-configuration endpoint returns the required endpoints.", - [ClientAuthErrorCodes.hashNotDeserialized]: - "The hash parameters could not be deserialized", - [ClientAuthErrorCodes.invalidState]: "State was not the expected format", - [ClientAuthErrorCodes.stateMismatch]: "State mismatch error", - [ClientAuthErrorCodes.stateNotFound]: "State not found", - [ClientAuthErrorCodes.nonceMismatch]: "Nonce mismatch error", - [ClientAuthErrorCodes.authTimeNotFound]: - "Max Age was requested and the ID token is missing the auth_time variable." + - " auth_time is an optional claim and is not enabled by default - it must be enabled." + - " See https://aka.ms/msaljs/optional-claims for more information.", - [ClientAuthErrorCodes.maxAgeTranspired]: - "Max Age is set to 0, or too much time has elapsed since the last end-user authentication.", - [ClientAuthErrorCodes.multipleMatchingTokens]: - "The cache contains multiple tokens satisfying the requirements. " + - "Call AcquireToken again providing more requirements such as authority or account.", - [ClientAuthErrorCodes.multipleMatchingAccounts]: - "The cache contains multiple accounts satisfying the given parameters. Please pass more info to obtain the correct account", - [ClientAuthErrorCodes.multipleMatchingAppMetadata]: - "The cache contains multiple appMetadata satisfying the given parameters. Please pass more info to obtain the correct appMetadata", - [ClientAuthErrorCodes.requestCannotBeMade]: - "Token request cannot be made without authorization code or refresh token.", - [ClientAuthErrorCodes.cannotRemoveEmptyScope]: - "Cannot remove null or empty scope from ScopeSet", - [ClientAuthErrorCodes.cannotAppendScopeSet]: "Cannot append ScopeSet", - [ClientAuthErrorCodes.emptyInputScopeSet]: - "Empty input ScopeSet cannot be processed", - [ClientAuthErrorCodes.deviceCodePollingCancelled]: - "Caller has cancelled token endpoint polling during device code flow by setting DeviceCodeRequest.cancel = true.", - [ClientAuthErrorCodes.deviceCodeExpired]: "Device code is expired.", - [ClientAuthErrorCodes.deviceCodeUnknownError]: - "Device code stopped polling for unknown reasons.", - [ClientAuthErrorCodes.noAccountInSilentRequest]: - "Please pass an account object, silent flow is not supported without account information", - [ClientAuthErrorCodes.invalidCacheRecord]: - "Cache record object was null or undefined.", - [ClientAuthErrorCodes.invalidCacheEnvironment]: - "Invalid environment when attempting to create cache entry", - [ClientAuthErrorCodes.noAccountFound]: - "No account found in cache for given key.", - [ClientAuthErrorCodes.noCryptoObject]: "No crypto object detected.", - [ClientAuthErrorCodes.unexpectedCredentialType]: - "Unexpected credential type.", - [ClientAuthErrorCodes.invalidAssertion]: - "Client assertion must meet requirements described in https://tools.ietf.org/html/rfc7515", - [ClientAuthErrorCodes.invalidClientCredential]: - "Client credential (secret, certificate, or assertion) must not be empty when creating a confidential client. An application should at most have one credential", - [ClientAuthErrorCodes.tokenRefreshRequired]: - "Cannot return token from cache because it must be refreshed. This may be due to one of the following reasons: forceRefresh parameter is set to true, claims have been requested, there is no cached access token or it is expired.", - [ClientAuthErrorCodes.userTimeoutReached]: - "User defined timeout for device code polling reached", - [ClientAuthErrorCodes.tokenClaimsCnfRequiredForSignedJwt]: - "Cannot generate a POP jwt if the token_claims are not populated", - [ClientAuthErrorCodes.authorizationCodeMissingFromServerResponse]: - "Server response does not contain an authorization code to proceed", - [ClientAuthErrorCodes.bindingKeyNotRemoved]: - "Could not remove the credential's binding key from storage.", - [ClientAuthErrorCodes.endSessionEndpointNotSupported]: - "The provided authority does not support logout", - [ClientAuthErrorCodes.keyIdMissing]: - "A keyId value is missing from the requested bound token's cache record and is required to match the token to it's stored binding key.", - [ClientAuthErrorCodes.noNetworkConnectivity]: - "No network connectivity. Check your internet connection.", - [ClientAuthErrorCodes.userCanceled]: "User cancelled the flow.", - [ClientAuthErrorCodes.missingTenantIdError]: - "A tenant id - not common, organizations, or consumers - must be specified when using the client_credentials flow.", - [ClientAuthErrorCodes.methodNotImplemented]: - "This method has not been implemented", - [ClientAuthErrorCodes.nestedAppAuthBridgeDisabled]: - "The nested app auth bridge is disabled", -}; - /** * Error thrown when there is an error in the client code running on the browser. */ @@ -101,8 +19,6 @@ export class ClientAuthError extends AuthError { super( errorCode, additionalMessage - ? `${ClientAuthErrorMessages[errorCode]}: ${additionalMessage}` - : ClientAuthErrorMessages[errorCode] ); this.name = "ClientAuthError"; diff --git a/lib/msal-common/src/error/ClientConfigurationError.ts b/lib/msal-common/src/error/ClientConfigurationError.ts index a6b6774f3b..a483e68650 100644 --- a/lib/msal-common/src/error/ClientConfigurationError.ts +++ b/lib/msal-common/src/error/ClientConfigurationError.ts @@ -7,58 +7,12 @@ import { AuthError } from "./AuthError.js"; import * as ClientConfigurationErrorCodes from "./ClientConfigurationErrorCodes.js"; export { ClientConfigurationErrorCodes }; -export const ClientConfigurationErrorMessages = { - [ClientConfigurationErrorCodes.redirectUriEmpty]: - "A redirect URI is required for all calls, and none has been set.", - [ClientConfigurationErrorCodes.claimsRequestParsingError]: - "Could not parse the given claims request object.", - [ClientConfigurationErrorCodes.authorityUriInsecure]: - "Authority URIs must use https. Please see here for valid authority configuration options: https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-js-initializing-client-applications#configuration-options", - [ClientConfigurationErrorCodes.urlParseError]: - "URL could not be parsed into appropriate segments.", - [ClientConfigurationErrorCodes.urlEmptyError]: "URL was empty or null.", - [ClientConfigurationErrorCodes.emptyInputScopesError]: - "Scopes cannot be passed as null, undefined or empty array because they are required to obtain an access token.", - [ClientConfigurationErrorCodes.invalidPromptValue]: - "Please see here for valid configuration options: https://azuread.github.io/microsoft-authentication-library-for-js/ref/modules/_azure_msal_common.html#commonauthorizationurlrequest", - [ClientConfigurationErrorCodes.invalidClaims]: - "Given claims parameter must be a stringified JSON object.", - [ClientConfigurationErrorCodes.tokenRequestEmpty]: - "Token request was empty and not found in cache.", - [ClientConfigurationErrorCodes.logoutRequestEmpty]: - "The logout request was null or undefined.", - [ClientConfigurationErrorCodes.invalidCodeChallengeMethod]: - 'code_challenge_method passed is invalid. Valid values are "plain" and "S256".', - [ClientConfigurationErrorCodes.pkceParamsMissing]: - "Both params: code_challenge and code_challenge_method are to be passed if to be sent in the request", - [ClientConfigurationErrorCodes.invalidCloudDiscoveryMetadata]: - "Invalid cloudDiscoveryMetadata provided. Must be a stringified JSON object containing tenant_discovery_endpoint and metadata fields", - [ClientConfigurationErrorCodes.invalidAuthorityMetadata]: - "Invalid authorityMetadata provided. Must by a stringified JSON object containing authorization_endpoint, token_endpoint, issuer fields.", - [ClientConfigurationErrorCodes.untrustedAuthority]: - "The provided authority is not a trusted authority. Please include this authority in the knownAuthorities config parameter.", - [ClientConfigurationErrorCodes.missingSshJwk]: - "Missing sshJwk in SSH certificate request. A stringified JSON Web Key is required when using the SSH authentication scheme.", - [ClientConfigurationErrorCodes.missingSshKid]: - "Missing sshKid in SSH certificate request. A string that uniquely identifies the public SSH key is required when using the SSH authentication scheme.", - [ClientConfigurationErrorCodes.missingNonceAuthenticationHeader]: - "Unable to find an authentication header containing server nonce. Either the Authentication-Info or WWW-Authenticate headers must be present in order to obtain a server nonce.", - [ClientConfigurationErrorCodes.invalidAuthenticationHeader]: - "Invalid authentication header provided", - [ClientConfigurationErrorCodes.cannotSetOIDCOptions]: - "Cannot set OIDCOptions parameter. Please change the protocol mode to OIDC or use a non-Microsoft authority.", - [ClientConfigurationErrorCodes.cannotAllowPlatformBroker]: - "Cannot set allowPlatformBroker parameter to true when not in AAD protocol mode.", - [ClientConfigurationErrorCodes.authorityMismatch]: - "Authority mismatch error. Authority provided in login request or PublicClientApplication config does not match the environment of the provided account. Please use a matching account or make an interactive request to login to this authority.", -}; - /** * Error thrown when there is an error in configuration of the MSAL.js library. */ export class ClientConfigurationError extends AuthError { constructor(errorCode: string) { - super(errorCode, ClientConfigurationErrorMessages[errorCode]); + super(errorCode); this.name = "ClientConfigurationError"; Object.setPrototypeOf(this, ClientConfigurationError.prototype); } diff --git a/lib/msal-common/src/error/InteractionRequiredAuthError.ts b/lib/msal-common/src/error/InteractionRequiredAuthError.ts index 1d7323e627..4438bdf827 100644 --- a/lib/msal-common/src/error/InteractionRequiredAuthError.ts +++ b/lib/msal-common/src/error/InteractionRequiredAuthError.ts @@ -27,17 +27,6 @@ export const InteractionRequiredAuthSubErrorMessage = [ "bad_token", ]; -const InteractionRequiredAuthErrorMessages = { - [InteractionRequiredAuthErrorCodes.noTokensFound]: - "No refresh token found in the cache. Please sign-in.", - [InteractionRequiredAuthErrorCodes.nativeAccountUnavailable]: - "The requested account is not available in the native broker. It may have been deleted or logged out. Please sign-in again using an interactive API.", - [InteractionRequiredAuthErrorCodes.refreshTokenExpired]: - "Refresh token has expired.", - [InteractionRequiredAuthErrorCodes.badToken]: - "Identity provider returned bad_token due to an expired or invalid refresh token. Please invoke an interactive API to resolve.", -}; - /** * Error thrown when user interaction is required. */ @@ -127,7 +116,6 @@ export function createInteractionRequiredAuthError( errorCode: string ): InteractionRequiredAuthError { return new InteractionRequiredAuthError( - errorCode, - InteractionRequiredAuthErrorMessages[errorCode] + errorCode ); } diff --git a/lib/msal-common/src/error/JoseHeaderError.ts b/lib/msal-common/src/error/JoseHeaderError.ts index 6ef5461525..bb6cd1fc26 100644 --- a/lib/msal-common/src/error/JoseHeaderError.ts +++ b/lib/msal-common/src/error/JoseHeaderError.ts @@ -7,13 +7,6 @@ import { AuthError } from "./AuthError.js"; import * as JoseHeaderErrorCodes from "./JoseHeaderErrorCodes.js"; export { JoseHeaderErrorCodes }; -export const JoseHeaderErrorMessages = { - [JoseHeaderErrorCodes.missingKidError]: - "The JOSE Header for the requested JWT, JWS or JWK object requires a keyId to be configured as the 'kid' header claim. No 'kid' value was provided.", - [JoseHeaderErrorCodes.missingAlgError]: - "The JOSE Header for the requested JWT, JWS or JWK object requires an algorithm to be specified as the 'alg' header claim. No 'alg' value was provided.", -}; - /** * Error thrown when there is an error in the client code running on the browser. */ @@ -28,5 +21,5 @@ export class JoseHeaderError extends AuthError { /** Returns JoseHeaderError object */ export function createJoseHeaderError(code: string): JoseHeaderError { - return new JoseHeaderError(code, JoseHeaderErrorMessages[code]); + return new JoseHeaderError(code); } diff --git a/lib/msal-common/src/exports-common.ts b/lib/msal-common/src/exports-common.ts index c70f71e162..944f11875f 100644 --- a/lib/msal-common/src/exports-common.ts +++ b/lib/msal-common/src/exports-common.ts @@ -137,7 +137,6 @@ export { } from "./error/InteractionRequiredAuthError.js"; export { AuthError, - AuthErrorMessages, AuthErrorCodes, createAuthError, } from "./error/AuthError.js"; @@ -146,13 +145,11 @@ export { NetworkError, createNetworkError } from "./error/NetworkError.js"; export { CacheError, CacheErrorCodes } from "./error/CacheError.js"; export { ClientAuthError, - ClientAuthErrorMessages, ClientAuthErrorCodes, createClientAuthError, } from "./error/ClientAuthError.js"; export { ClientConfigurationError, - ClientConfigurationErrorMessages, ClientConfigurationErrorCodes, createClientConfigurationError, } from "./error/ClientConfigurationError.js"; diff --git a/lib/msal-node/src/index.ts b/lib/msal-node/src/index.ts index c80d1c5262..50752bc665 100644 --- a/lib/msal-node/src/index.ts +++ b/lib/msal-node/src/index.ts @@ -93,14 +93,11 @@ export { ValidCacheType, // Error AuthError, - AuthErrorMessages, AuthErrorCodes, ClientAuthError, ClientAuthErrorCodes, - ClientAuthErrorMessages, ClientConfigurationError, ClientConfigurationErrorCodes, - ClientConfigurationErrorMessages, InteractionRequiredAuthError, InteractionRequiredAuthErrorCodes, ServerError, From ec9997aaba76c2bfcf1a2ee375bd28aca56833b8 Mon Sep 17 00:00:00 2001 From: Konstantin Shabelko Date: Mon, 12 May 2025 13:08:04 -0400 Subject: [PATCH 2/5] - Fix formatting. --- lib/msal-browser/src/error/BrowserAuthError.ts | 6 +++++- lib/msal-browser/src/error/BrowserConfigurationAuthError.ts | 4 +--- lib/msal-browser/src/error/NativeAuthError.ts | 6 +----- lib/msal-browser/src/error/NestedAppAuthError.ts | 4 +--- lib/msal-common/src/error/ClientAuthError.ts | 5 +---- lib/msal-common/src/error/InteractionRequiredAuthError.ts | 4 +--- 6 files changed, 10 insertions(+), 19 deletions(-) diff --git a/lib/msal-browser/src/error/BrowserAuthError.ts b/lib/msal-browser/src/error/BrowserAuthError.ts index 2b135bec30..6f3e78c111 100644 --- a/lib/msal-browser/src/error/BrowserAuthError.ts +++ b/lib/msal-browser/src/error/BrowserAuthError.ts @@ -12,7 +12,11 @@ export { BrowserAuthErrorCodes }; // Allow importing as "BrowserAuthErrorCodes" */ export class BrowserAuthError extends AuthError { constructor(errorCode: string, subError?: string) { - super(errorCode, `See https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/errors.md#${errorCode} for details`, subError); + super( + errorCode, + `See https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/errors.md#${errorCode} for details`, + subError + ); Object.setPrototypeOf(this, BrowserAuthError.prototype); this.name = "BrowserAuthError"; diff --git a/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts b/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts index 0c58dcdd15..b5a9131867 100644 --- a/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts +++ b/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts @@ -21,7 +21,5 @@ export class BrowserConfigurationAuthError extends AuthError { export function createBrowserConfigurationAuthError( errorCode: string ): BrowserConfigurationAuthError { - return new BrowserConfigurationAuthError( - errorCode - ); + return new BrowserConfigurationAuthError(errorCode); } diff --git a/lib/msal-browser/src/error/NativeAuthError.ts b/lib/msal-browser/src/error/NativeAuthError.ts index 78bf2b24ed..968c96ae29 100644 --- a/lib/msal-browser/src/error/NativeAuthError.ts +++ b/lib/msal-browser/src/error/NativeAuthError.ts @@ -100,9 +100,5 @@ export function createNativeAuthError( } } - return new NativeAuthError( - code, - description, - ext - ); + return new NativeAuthError(code, description, ext); } diff --git a/lib/msal-browser/src/error/NestedAppAuthError.ts b/lib/msal-browser/src/error/NestedAppAuthError.ts index 628ea92b64..1b4cc3b673 100644 --- a/lib/msal-browser/src/error/NestedAppAuthError.ts +++ b/lib/msal-browser/src/error/NestedAppAuthError.ts @@ -15,8 +15,6 @@ export class NestedAppAuthError extends AuthError { } public static createUnsupportedError(): NestedAppAuthError { - return new NestedAppAuthError( - unsupportedMethod - ); + return new NestedAppAuthError(unsupportedMethod); } } diff --git a/lib/msal-common/src/error/ClientAuthError.ts b/lib/msal-common/src/error/ClientAuthError.ts index 49fc88798d..38c43d43ba 100644 --- a/lib/msal-common/src/error/ClientAuthError.ts +++ b/lib/msal-common/src/error/ClientAuthError.ts @@ -16,10 +16,7 @@ export { ClientAuthErrorCodes }; // Allow importing as "ClientAuthErrorCodes"; */ export class ClientAuthError extends AuthError { constructor(errorCode: string, additionalMessage?: string) { - super( - errorCode, - additionalMessage - ); + super(errorCode, additionalMessage); this.name = "ClientAuthError"; Object.setPrototypeOf(this, ClientAuthError.prototype); diff --git a/lib/msal-common/src/error/InteractionRequiredAuthError.ts b/lib/msal-common/src/error/InteractionRequiredAuthError.ts index 4438bdf827..be92184d39 100644 --- a/lib/msal-common/src/error/InteractionRequiredAuthError.ts +++ b/lib/msal-common/src/error/InteractionRequiredAuthError.ts @@ -115,7 +115,5 @@ export function isInteractionRequiredError( export function createInteractionRequiredAuthError( errorCode: string ): InteractionRequiredAuthError { - return new InteractionRequiredAuthError( - errorCode - ); + return new InteractionRequiredAuthError(errorCode); } From df752fb768038b75b08e3500e08c2792131cef10 Mon Sep 17 00:00:00 2001 From: Konstantin Shabelko Date: Mon, 12 May 2025 13:20:26 -0400 Subject: [PATCH 3/5] Change files --- ...-msal-browser-bde3f512-0d2d-41c3-b6ac-951b5a7948a2.json | 7 +++++++ ...e-msal-common-1d8047ac-0257-4486-bd31-f76b71df1d90.json | 7 +++++++ ...ure-msal-node-a9c0aa9f-2a96-4720-bfaa-4d6d9edf852c.json | 7 +++++++ 3 files changed, 21 insertions(+) create mode 100644 change/@azure-msal-browser-bde3f512-0d2d-41c3-b6ac-951b5a7948a2.json create mode 100644 change/@azure-msal-common-1d8047ac-0257-4486-bd31-f76b71df1d90.json create mode 100644 change/@azure-msal-node-a9c0aa9f-2a96-4720-bfaa-4d6d9edf852c.json diff --git a/change/@azure-msal-browser-bde3f512-0d2d-41c3-b6ac-951b5a7948a2.json b/change/@azure-msal-browser-bde3f512-0d2d-41c3-b6ac-951b5a7948a2.json new file mode 100644 index 0000000000..fa0ee9520a --- /dev/null +++ b/change/@azure-msal-browser-bde3f512-0d2d-41c3-b6ac-951b5a7948a2.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "Move auth error messages out of the bundle #7744", + "packageName": "@azure/msal-browser", + "email": "kshabelko@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@azure-msal-common-1d8047ac-0257-4486-bd31-f76b71df1d90.json b/change/@azure-msal-common-1d8047ac-0257-4486-bd31-f76b71df1d90.json new file mode 100644 index 0000000000..4438cb1f98 --- /dev/null +++ b/change/@azure-msal-common-1d8047ac-0257-4486-bd31-f76b71df1d90.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "Move auth error messages out of the bundle #7744", + "packageName": "@azure/msal-common", + "email": "kshabelko@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@azure-msal-node-a9c0aa9f-2a96-4720-bfaa-4d6d9edf852c.json b/change/@azure-msal-node-a9c0aa9f-2a96-4720-bfaa-4d6d9edf852c.json new file mode 100644 index 0000000000..5be7fc0b86 --- /dev/null +++ b/change/@azure-msal-node-a9c0aa9f-2a96-4720-bfaa-4d6d9edf852c.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "Move auth error messages out of the bundle #7744", + "packageName": "@azure/msal-node", + "email": "kshabelko@microsoft.com", + "dependentChangeType": "patch" +} From e2b4d333f3a82f4e2fb74cdf223784be8464519a Mon Sep 17 00:00:00 2001 From: Konstantin Shabelko Date: Tue, 13 May 2025 11:48:02 -0400 Subject: [PATCH 4/5] - Update tests. --- .../src/error/BrowserAuthError.ts | 10 +-- .../error/BrowserConfigurationAuthError.ts | 6 +- lib/msal-browser/src/error/NativeAuthError.ts | 6 +- .../test/app/IPublicClientApplication.spec.ts | 79 ++++++++----------- .../test/app/PCANonBrowser.spec.ts | 5 +- .../test/app/PublicClientApplication.spec.ts | 17 ++-- .../test/broker/NativeMessageHandler.spec.ts | 15 ++-- .../test/error/BrowserAuthError.spec.ts | 4 +- .../BrowserConfigurationAuthError.spec.ts | 4 +- .../test/error/NativeAuthError.spec.ts | 5 +- .../NativeInteractionClient.spec.ts | 32 +++----- .../interaction_client/PopupClient.spec.ts | 7 +- .../interaction_client/RedirectClient.spec.ts | 6 +- .../SilentIframeClient.spec.ts | 7 +- lib/msal-common/src/error/AuthError.ts | 11 +-- .../src/error/InteractionRequiredAuthError.ts | 5 +- .../test/account/AuthToken.spec.ts | 31 -------- .../test/authority/Authority.spec.ts | 26 +++--- .../test/crypto/JoseHeader.spec.ts | 10 +-- lib/msal-common/test/error/AuthError.spec.ts | 8 +- .../test/error/ClientAuthError.spec.ts | 4 +- .../error/ClientConfigurationError.spec.ts | 4 +- .../test/error/JoseHeaderError.spec.ts | 4 +- .../test/response/ResponseHandler.spec.ts | 15 ++-- 24 files changed, 129 insertions(+), 192 deletions(-) diff --git a/lib/msal-browser/src/error/BrowserAuthError.ts b/lib/msal-browser/src/error/BrowserAuthError.ts index 6f3e78c111..880278031e 100644 --- a/lib/msal-browser/src/error/BrowserAuthError.ts +++ b/lib/msal-browser/src/error/BrowserAuthError.ts @@ -7,16 +7,16 @@ import { AuthError } from "@azure/msal-common/browser"; import * as BrowserAuthErrorCodes from "./BrowserAuthErrorCodes.js"; export { BrowserAuthErrorCodes }; // Allow importing as "BrowserAuthErrorCodes" +export function getDefaultErrorMessage(code: string): string { + return `See https://aka.ms/msaljs/browser/errors#${code} for details`; +} + /** * Browser library error class thrown by the MSAL.js library for SPAs */ export class BrowserAuthError extends AuthError { constructor(errorCode: string, subError?: string) { - super( - errorCode, - `See https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/errors.md#${errorCode} for details`, - subError - ); + super(errorCode, getDefaultErrorMessage(errorCode), subError); Object.setPrototypeOf(this, BrowserAuthError.prototype); this.name = "BrowserAuthError"; diff --git a/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts b/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts index b5a9131867..b3fcc43200 100644 --- a/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts +++ b/lib/msal-browser/src/error/BrowserConfigurationAuthError.ts @@ -5,6 +5,7 @@ import { AuthError } from "@azure/msal-common/browser"; import * as BrowserConfigurationAuthErrorCodes from "./BrowserConfigurationAuthErrorCodes.js"; +import { getDefaultErrorMessage } from "./BrowserAuthError.js"; export { BrowserConfigurationAuthErrorCodes }; /** * Browser library error class thrown by the MSAL.js library for SPAs @@ -21,5 +22,8 @@ export class BrowserConfigurationAuthError extends AuthError { export function createBrowserConfigurationAuthError( errorCode: string ): BrowserConfigurationAuthError { - return new BrowserConfigurationAuthError(errorCode); + return new BrowserConfigurationAuthError( + errorCode, + getDefaultErrorMessage(errorCode) + ); } diff --git a/lib/msal-browser/src/error/NativeAuthError.ts b/lib/msal-browser/src/error/NativeAuthError.ts index 968c96ae29..968367d307 100644 --- a/lib/msal-browser/src/error/NativeAuthError.ts +++ b/lib/msal-browser/src/error/NativeAuthError.ts @@ -12,6 +12,7 @@ import { import { createBrowserAuthError, BrowserAuthErrorCodes, + getDefaultErrorMessage, } from "./BrowserAuthError.js"; import * as NativeAuthErrorCodes from "./NativeAuthErrorCodes.js"; @@ -32,7 +33,7 @@ export class NativeAuthError extends AuthError { ext: OSError | undefined; constructor(errorCode: string, description?: string, ext?: OSError) { - super(errorCode, description); + super(errorCode, description || getDefaultErrorMessage(errorCode)); Object.setPrototypeOf(this, NativeAuthError.prototype); this.name = "NativeAuthError"; @@ -85,7 +86,8 @@ export function createNativeAuthError( switch (ext.status) { case NativeStatusCodes.ACCOUNT_UNAVAILABLE: return createInteractionRequiredAuthError( - InteractionRequiredAuthErrorCodes.nativeAccountUnavailable + InteractionRequiredAuthErrorCodes.nativeAccountUnavailable, + getDefaultErrorMessage(code) ); case NativeStatusCodes.USER_INTERACTION_REQUIRED: return new InteractionRequiredAuthError(code, description); diff --git a/lib/msal-browser/test/app/IPublicClientApplication.spec.ts b/lib/msal-browser/test/app/IPublicClientApplication.spec.ts index 53f6cc44f3..a7787f4261 100644 --- a/lib/msal-browser/test/app/IPublicClientApplication.spec.ts +++ b/lib/msal-browser/test/app/IPublicClientApplication.spec.ts @@ -4,9 +4,9 @@ */ import { stubbedPublicClientApplication } from "../../src/app/IPublicClientApplication"; -import { BrowserConfigurationAuthErrorMessages } from "../../src/error/BrowserConfigurationAuthError"; import { BrowserAuthError } from "../../src/error/BrowserAuthError"; import { BrowserConfigurationAuthErrorCodes } from "../../src/error/BrowserConfigurationAuthError.js"; +import { getDefaultErrorMessage } from "../../src/error/BrowserAuthError.js"; describe("IPublicClientApplication.ts Class Unit Tests", () => { describe("stubbedPublicClientApplication tests", () => { @@ -18,10 +18,9 @@ describe("IPublicClientApplication.ts Class Unit Tests", () => { BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled ); expect(e.errorMessage).toEqual( - BrowserConfigurationAuthErrorMessages[ - BrowserConfigurationAuthErrorCodes - .stubbedPublicClientApplicationCalled - ] + getDefaultErrorMessage( + BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled + ) ); done(); }); @@ -35,10 +34,9 @@ describe("IPublicClientApplication.ts Class Unit Tests", () => { BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled ); expect(e.errorMessage).toEqual( - BrowserConfigurationAuthErrorMessages[ - BrowserConfigurationAuthErrorCodes - .stubbedPublicClientApplicationCalled - ] + getDefaultErrorMessage( + BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled + ) ); done(); }); @@ -52,10 +50,9 @@ describe("IPublicClientApplication.ts Class Unit Tests", () => { BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled ); expect(e.errorMessage).toEqual( - BrowserConfigurationAuthErrorMessages[ - BrowserConfigurationAuthErrorCodes - .stubbedPublicClientApplicationCalled - ] + getDefaultErrorMessage( + BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled + ) ); done(); }); @@ -68,10 +65,9 @@ describe("IPublicClientApplication.ts Class Unit Tests", () => { BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled ); expect(e.errorMessage).toEqual( - BrowserConfigurationAuthErrorMessages[ - BrowserConfigurationAuthErrorCodes - .stubbedPublicClientApplicationCalled - ] + getDefaultErrorMessage( + BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled + ) ); done(); }); @@ -83,10 +79,9 @@ describe("IPublicClientApplication.ts Class Unit Tests", () => { BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled ); expect(e.errorMessage).toEqual( - BrowserConfigurationAuthErrorMessages[ - BrowserConfigurationAuthErrorCodes - .stubbedPublicClientApplicationCalled - ] + getDefaultErrorMessage( + BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled + ) ); done(); }); @@ -98,10 +93,9 @@ describe("IPublicClientApplication.ts Class Unit Tests", () => { BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled ); expect(e.errorMessage).toEqual( - BrowserConfigurationAuthErrorMessages[ - BrowserConfigurationAuthErrorCodes - .stubbedPublicClientApplicationCalled - ] + getDefaultErrorMessage( + BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled + ) ); done(); }); @@ -113,10 +107,9 @@ describe("IPublicClientApplication.ts Class Unit Tests", () => { BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled ); expect(e.errorMessage).toEqual( - BrowserConfigurationAuthErrorMessages[ - BrowserConfigurationAuthErrorCodes - .stubbedPublicClientApplicationCalled - ] + getDefaultErrorMessage( + BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled + ) ); done(); }); @@ -128,10 +121,9 @@ describe("IPublicClientApplication.ts Class Unit Tests", () => { BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled ); expect(e.errorMessage).toEqual( - BrowserConfigurationAuthErrorMessages[ - BrowserConfigurationAuthErrorCodes - .stubbedPublicClientApplicationCalled - ] + getDefaultErrorMessage( + BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled + ) ); done(); }); @@ -143,10 +135,9 @@ describe("IPublicClientApplication.ts Class Unit Tests", () => { BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled ); expect(e.errorMessage).toEqual( - BrowserConfigurationAuthErrorMessages[ - BrowserConfigurationAuthErrorCodes - .stubbedPublicClientApplicationCalled - ] + getDefaultErrorMessage( + BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled + ) ); done(); }); @@ -161,10 +152,9 @@ describe("IPublicClientApplication.ts Class Unit Tests", () => { BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled ); expect(browserAuthError.errorMessage).toEqual( - BrowserConfigurationAuthErrorMessages[ - BrowserConfigurationAuthErrorCodes - .stubbedPublicClientApplicationCalled - ] + getDefaultErrorMessage( + BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled + ) ); } }); @@ -178,10 +168,9 @@ describe("IPublicClientApplication.ts Class Unit Tests", () => { BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled ); expect(browserAuthError.errorMessage).toEqual( - BrowserConfigurationAuthErrorMessages[ - BrowserConfigurationAuthErrorCodes - .stubbedPublicClientApplicationCalled - ] + getDefaultErrorMessage( + BrowserConfigurationAuthErrorCodes.stubbedPublicClientApplicationCalled + ) ); } }); diff --git a/lib/msal-browser/test/app/PCANonBrowser.spec.ts b/lib/msal-browser/test/app/PCANonBrowser.spec.ts index 1efc6bad84..f5d9700151 100644 --- a/lib/msal-browser/test/app/PCANonBrowser.spec.ts +++ b/lib/msal-browser/test/app/PCANonBrowser.spec.ts @@ -18,10 +18,7 @@ import { NavigationClient } from "../../src/navigation/NavigationClient.js"; import { SilentRequest } from "../../src/request/SilentRequest.js"; import { AuthenticationResult } from "../../src/response/AuthenticationResult.js"; import { TestTimeUtils } from "msal-test-utils"; -import { - BrowserAuthErrorCodes, - BrowserAuthErrorMessages, -} from "../../src/error/BrowserAuthError.js"; +import { BrowserAuthErrorCodes } from "../../src/error/BrowserAuthError.js"; /** * Tests for PublicClientApplication.ts when run in a non-browser environment diff --git a/lib/msal-browser/test/app/PublicClientApplication.spec.ts b/lib/msal-browser/test/app/PublicClientApplication.spec.ts index cdc6f94243..76d992a65a 100644 --- a/lib/msal-browser/test/app/PublicClientApplication.spec.ts +++ b/lib/msal-browser/test/app/PublicClientApplication.spec.ts @@ -81,7 +81,6 @@ import { FetchClient } from "../../src/network/FetchClient.js"; import { BrowserAuthError, BrowserAuthErrorCodes, - BrowserAuthErrorMessages, createBrowserAuthError, } from "../../src/error/BrowserAuthError.js"; import * as BrowserUtils from "../../src/utils/BrowserUtils.js"; @@ -116,6 +115,7 @@ import { TestTimeUtils, } from "msal-test-utils"; import { INTERACTION_TYPE } from "../../src/utils/BrowserConstants.js"; +import { getDefaultErrorMessage } from "../../src/error/BrowserAuthError.js"; const cacheConfig = { temporaryCacheLocation: BrowserCacheLocation.SessionStorage, @@ -1892,9 +1892,9 @@ describe("PublicClientApplication.ts Class Unit Tests", () => { BrowserAuthErrorCodes.blockNestedPopups ); expect(e.errorMessage).toEqual( - BrowserAuthErrorMessages[ + getDefaultErrorMessage( BrowserAuthErrorCodes.blockNestedPopups - ] + ) ); done(); }) @@ -3014,9 +3014,9 @@ describe("PublicClientApplication.ts Class Unit Tests", () => { BrowserAuthErrorCodes.blockNestedPopups ); expect(e.errorMessage).toEqual( - BrowserAuthErrorMessages[ + getDefaultErrorMessage( BrowserAuthErrorCodes.blockNestedPopups - ] + ) ); done(); }) @@ -3765,10 +3765,9 @@ describe("PublicClientApplication.ts Class Unit Tests", () => { BrowserAuthErrorCodes.unableToAcquireTokenFromNativePlatform ); expect(e.errorMessage).toEqual( - BrowserAuthErrorMessages[ - BrowserAuthErrorCodes - .unableToAcquireTokenFromNativePlatform - ] + getDefaultErrorMessage( + BrowserAuthErrorCodes.unableToAcquireTokenFromNativePlatform + ) ); }); expect(nativeAcquireTokenSpy).toHaveBeenCalledTimes(0); diff --git a/lib/msal-browser/test/broker/NativeMessageHandler.spec.ts b/lib/msal-browser/test/broker/NativeMessageHandler.spec.ts index 538be2712d..18e82acbb5 100644 --- a/lib/msal-browser/test/broker/NativeMessageHandler.spec.ts +++ b/lib/msal-browser/test/broker/NativeMessageHandler.spec.ts @@ -6,7 +6,6 @@ import { Logger, AuthError, - AuthErrorMessages, AuthErrorCodes, IPerformanceClient, } from "@azure/msal-common"; @@ -16,7 +15,7 @@ import { NativeExtensionMethod } from "../../src/utils/BrowserConstants.js"; import { NativeAuthError } from "../../src/error/NativeAuthError.js"; import { getDefaultPerformanceClient } from "../utils/TelemetryUtils.js"; import { CryptoOps } from "../../src/crypto/CryptoOps.js"; -import { BrowserAuthErrorMessages } from "../../src/error/BrowserAuthError.js"; +import { getDefaultErrorMessage } from "../../src/error/BrowserAuthError.js"; let performanceClient: IPerformanceClient; @@ -170,9 +169,9 @@ describe("NativeMessageHandler Tests", () => { BrowserAuthErrorCodes.nativeExtensionNotInstalled ); expect(e.errorMessage).toBe( - BrowserAuthErrorMessages[ + getDefaultErrorMessage( BrowserAuthErrorCodes.nativeExtensionNotInstalled - ] + ) ); done(); }); @@ -196,9 +195,9 @@ describe("NativeMessageHandler Tests", () => { BrowserAuthErrorCodes.nativeHandshakeTimeout ); expect(e.errorMessage).toBe( - BrowserAuthErrorMessages[ + getDefaultErrorMessage( BrowserAuthErrorCodes.nativeHandshakeTimeout - ] + ) ); done(); }) @@ -482,9 +481,7 @@ describe("NativeMessageHandler Tests", () => { AuthErrorCodes.unexpectedError ); expect(e.errorMessage).toContain( - AuthErrorMessages[ - AuthErrorCodes.unexpectedError - ] + "Event does not contain result" ); done(); }); diff --git a/lib/msal-browser/test/error/BrowserAuthError.spec.ts b/lib/msal-browser/test/error/BrowserAuthError.spec.ts index f7418bebf7..cf7bf461ac 100644 --- a/lib/msal-browser/test/error/BrowserAuthError.spec.ts +++ b/lib/msal-browser/test/error/BrowserAuthError.spec.ts @@ -1,10 +1,10 @@ import { BrowserAuthError, createBrowserAuthError, - BrowserAuthErrorMessages, BrowserAuthErrorCodes, } from "../../src/error/BrowserAuthError"; import { AuthError } from "@azure/msal-common"; +import { getDefaultErrorMessage } from "../../src/error/BrowserAuthError.js"; describe("BrowserAuthError Unit Tests", () => { for (const key in BrowserAuthErrorCodes) { @@ -13,7 +13,7 @@ describe("BrowserAuthError Unit Tests", () => { it(`BrowserAuthError object can be created for code ${code}`, () => { const err: BrowserAuthError = createBrowserAuthError(code); - const message = BrowserAuthErrorMessages[code]; + const message = getDefaultErrorMessage(code); expect(message).toBeTruthy(); expect(err instanceof BrowserAuthError).toBe(true); diff --git a/lib/msal-browser/test/error/BrowserConfigurationAuthError.spec.ts b/lib/msal-browser/test/error/BrowserConfigurationAuthError.spec.ts index 085bc9744f..966d237578 100644 --- a/lib/msal-browser/test/error/BrowserConfigurationAuthError.spec.ts +++ b/lib/msal-browser/test/error/BrowserConfigurationAuthError.spec.ts @@ -2,9 +2,9 @@ import { AuthError } from "@azure/msal-common"; import { BrowserConfigurationAuthError, BrowserConfigurationAuthErrorCodes, - BrowserConfigurationAuthErrorMessages, createBrowserConfigurationAuthError, } from "../../src/error/BrowserConfigurationAuthError"; +import { getDefaultErrorMessage } from "../../src/error/BrowserAuthError.js"; describe("BrowserConfigurationAuthError Unit Tests", () => { for (const key in BrowserConfigurationAuthErrorCodes) { @@ -16,7 +16,7 @@ describe("BrowserConfigurationAuthError Unit Tests", () => { const err: BrowserConfigurationAuthError = createBrowserConfigurationAuthError(code); - const message = BrowserConfigurationAuthErrorMessages[code]; + const message = getDefaultErrorMessage(code); expect(message).toBeTruthy(); expect(err instanceof BrowserConfigurationAuthError).toBe(true); diff --git a/lib/msal-browser/test/error/NativeAuthError.spec.ts b/lib/msal-browser/test/error/NativeAuthError.spec.ts index 47181a55b9..8d8dca1402 100644 --- a/lib/msal-browser/test/error/NativeAuthError.spec.ts +++ b/lib/msal-browser/test/error/NativeAuthError.spec.ts @@ -8,10 +8,7 @@ import { InteractionRequiredAuthError, InteractionRequiredAuthErrorCodes, } from "@azure/msal-common"; -import { - BrowserAuthError, - BrowserAuthErrorMessages, -} from "../../src/error/BrowserAuthError"; +import { BrowserAuthError } from "../../src/error/BrowserAuthError"; import * as NativeStatusCode from "../../src/broker/nativeBroker/NativeStatusCodes"; import { BrowserAuthErrorCodes } from "../../src/error/BrowserAuthError.js"; diff --git a/lib/msal-browser/test/interaction_client/NativeInteractionClient.spec.ts b/lib/msal-browser/test/interaction_client/NativeInteractionClient.spec.ts index bbc6b31aa3..09087d88b9 100644 --- a/lib/msal-browser/test/interaction_client/NativeInteractionClient.spec.ts +++ b/lib/msal-browser/test/interaction_client/NativeInteractionClient.spec.ts @@ -14,12 +14,8 @@ import { CredentialType, TimeUtils, CacheManager, - Logger, - CacheRecord, - AADServerParamKeys, IPerformanceClient, InProgressPerformanceEvent, - PerformanceEvents, AccountEntityUtils, } from "@azure/msal-common"; import { NativeMessageHandler } from "../../src/broker/nativeBroker/NativeMessageHandler.js"; @@ -34,28 +30,20 @@ import { TEST_TOKENS, } from "../utils/StringConstants.js"; import { NavigationClient } from "../../src/navigation/NavigationClient.js"; -import { - BrowserAuthErrorMessages, - BrowserAuthErrorCodes, -} from "../../src/error/BrowserAuthError.js"; +import { BrowserAuthErrorCodes } from "../../src/error/BrowserAuthError.js"; import { NativeAuthError, NativeAuthErrorCodes, - NativeAuthErrorMessages, } from "../../src/error/NativeAuthError.js"; import { NativeExtensionRequestBody } from "../../src/broker/nativeBroker/NativeRequest.js"; import { getDefaultPerformanceClient } from "../utils/TelemetryUtils.js"; import { BrowserCacheManager } from "../../src/cache/BrowserCacheManager.js"; -import { - BrowserPerformanceClient, - IPublicClientApplication, - PopupRequest, - SsoSilentRequest, -} from "../../src/index.js"; +import { BrowserPerformanceClient } from "../../src/index.js"; import { buildAccountFromIdTokenClaims, buildIdToken } from "msal-test-utils"; import { version } from "../../src/packageMetadata.js"; import { BrowserConstants } from "../../src/utils/BrowserConstants.js"; import * as NativeStatusCodes from "../../src/broker/nativeBroker/NativeStatusCodes.js"; +import { getDefaultErrorMessage } from "../../src/error/BrowserAuthError.js"; const MOCK_WAM_RESPONSE = { access_token: TEST_TOKENS.ACCESS_TOKEN, @@ -306,9 +294,9 @@ describe("NativeInteractionClient Tests", () => { BrowserAuthErrorCodes.nativePromptNotSupported ); expect(e.errorMessage).toBe( - BrowserAuthErrorMessages[ + getDefaultErrorMessage( BrowserAuthErrorCodes.nativePromptNotSupported - ] + ) ); done(); }); @@ -325,9 +313,9 @@ describe("NativeInteractionClient Tests", () => { BrowserAuthErrorCodes.nativePromptNotSupported ); expect(e.errorMessage).toBe( - BrowserAuthErrorMessages[ + getDefaultErrorMessage( BrowserAuthErrorCodes.nativePromptNotSupported - ] + ) ); done(); }); @@ -444,7 +432,7 @@ describe("NativeInteractionClient Tests", () => { NativeAuthErrorCodes.userSwitch ); expect(e.errorMessage).not.toBe( - NativeAuthErrorMessages[NativeAuthErrorCodes.userSwitch] + getDefaultErrorMessage(NativeAuthErrorCodes.userSwitch) ); done(); }); @@ -485,7 +473,7 @@ describe("NativeInteractionClient Tests", () => { .catch((e) => { expect(e.errorCode).toBe(NativeAuthErrorCodes.userSwitch); expect(e.errorMessage).toBe( - NativeAuthErrorMessages[NativeAuthErrorCodes.userSwitch] + getDefaultErrorMessage(NativeAuthErrorCodes.userSwitch) ); done(); }); @@ -537,7 +525,7 @@ describe("NativeInteractionClient Tests", () => { NativeAuthErrorCodes.userSwitch ); expect(e.errorMessage).not.toBe( - NativeAuthErrorMessages[NativeAuthErrorCodes.userSwitch] + getDefaultErrorMessage(NativeAuthErrorCodes.userSwitch) ); done(); }); diff --git a/lib/msal-browser/test/interaction_client/PopupClient.spec.ts b/lib/msal-browser/test/interaction_client/PopupClient.spec.ts index 2930772975..5a79b4388d 100644 --- a/lib/msal-browser/test/interaction_client/PopupClient.spec.ts +++ b/lib/msal-browser/test/interaction_client/PopupClient.spec.ts @@ -55,7 +55,6 @@ import { NativeMessageHandler } from "../../src/broker/nativeBroker/NativeMessag import { BrowserAuthError, createBrowserAuthError, - BrowserAuthErrorMessages, BrowserAuthErrorCodes, } from "../../src/error/BrowserAuthError.js"; import { InteractionHandler } from "../../src/interaction_handler/InteractionHandler.js"; @@ -66,7 +65,7 @@ import * as BrowserUtils from "../../src/utils/BrowserUtils.js"; import { FetchClient } from "../../src/network/FetchClient.js"; import { TestTimeUtils } from "msal-test-utils"; import { PopupRequest } from "../../src/request/PopupRequest.js"; -import { emptyNavigateUri } from "../../src/error/BrowserAuthErrorCodes.js"; +import { getDefaultErrorMessage } from "../../src/error/BrowserAuthError.js"; const testPopupWondowDefaults = { height: BrowserConstants.POPUP_HEIGHT, @@ -559,9 +558,9 @@ describe("PopupClient", () => { BrowserAuthErrorCodes.nativeConnectionNotEstablished ); expect(e.errorMessage).toEqual( - BrowserAuthErrorMessages[ + getDefaultErrorMessage( BrowserAuthErrorCodes.nativeConnectionNotEstablished - ] + ) ); }); }); diff --git a/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts b/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts index 0b4bffd3f9..40d14f81b8 100644 --- a/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts +++ b/lib/msal-browser/test/interaction_client/RedirectClient.spec.ts @@ -64,7 +64,6 @@ import { base64Encode } from "../../src/encode/Base64Encode.js"; import { FetchClient } from "../../src/network/FetchClient.js"; import { createBrowserAuthError, - BrowserAuthErrorMessages, BrowserAuthErrorCodes, BrowserAuthError, } from "../../src/error/BrowserAuthError.js"; @@ -89,6 +88,7 @@ import { TestTimeUtils, } from "msal-test-utils"; import { BrowserPerformanceClient } from "../../src/telemetry/BrowserPerformanceClient.js"; +import { getDefaultErrorMessage } from "../../src/error/BrowserAuthError.js"; const cacheConfig = { cacheLocation: BrowserCacheLocation.SessionStorage, @@ -702,9 +702,9 @@ describe("RedirectClient", () => { BrowserAuthErrorCodes.nativeConnectionNotEstablished ); expect(e.errorMessage).toEqual( - BrowserAuthErrorMessages[ + getDefaultErrorMessage( BrowserAuthErrorCodes.nativeConnectionNotEstablished - ] + ) ); done(); }); diff --git a/lib/msal-browser/test/interaction_client/SilentIframeClient.spec.ts b/lib/msal-browser/test/interaction_client/SilentIframeClient.spec.ts index d67697f5fd..b88741d769 100644 --- a/lib/msal-browser/test/interaction_client/SilentIframeClient.spec.ts +++ b/lib/msal-browser/test/interaction_client/SilentIframeClient.spec.ts @@ -33,7 +33,6 @@ import { } from "@azure/msal-common/browser"; import { createBrowserAuthError, - BrowserAuthErrorMessages, BrowserAuthErrorCodes, } from "../../src/error/BrowserAuthError.js"; import * as SilentHandler from "../../src/interaction_handler/SilentHandler.js"; @@ -54,8 +53,8 @@ import { import { FetchClient } from "../../src/network/FetchClient.js"; import { TestTimeUtils } from "msal-test-utils"; import { AuthenticationResult } from "../../src/response/AuthenticationResult.js"; -import { SilentRequest } from "../../src/request/SilentRequest.js"; import { SsoSilentRequest } from "../../src/index.js"; +import { getDefaultErrorMessage } from "../../src/error/BrowserAuthError.js"; describe("SilentIframeClient", () => { let silentIframeClient: SilentIframeClient; @@ -612,9 +611,9 @@ describe("SilentIframeClient", () => { BrowserAuthErrorCodes.nativeConnectionNotEstablished ); expect(e.errorMessage).toEqual( - BrowserAuthErrorMessages[ + getDefaultErrorMessage( BrowserAuthErrorCodes.nativeConnectionNotEstablished - ] + ) ); done(); }); diff --git a/lib/msal-common/src/error/AuthError.ts b/lib/msal-common/src/error/AuthError.ts index ec54036361..f961a3cdc9 100644 --- a/lib/msal-common/src/error/AuthError.ts +++ b/lib/msal-common/src/error/AuthError.ts @@ -8,7 +8,7 @@ import * as AuthErrorCodes from "./AuthErrorCodes.js"; export { AuthErrorCodes }; export function getDefaultErrorMessage(code: string): string { - return `See https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/errors.md#${code} for details`; + return `See https://aka.ms/msaljs/common/errors#${code} for details`; } /** @@ -36,14 +36,15 @@ export class AuthError extends Error { correlationId: string; constructor(errorCode?: string, errorMessage?: string, suberror?: string) { - const errorString = errorMessage - ? `${errorCode}: ${errorMessage}` - : errorCode; + const message = + errorMessage || + (errorCode ? getDefaultErrorMessage(errorCode) : ""); + const errorString = message ? `${errorCode}: ${message}` : errorCode; super(errorString); Object.setPrototypeOf(this, AuthError.prototype); this.errorCode = errorCode || Constants.EMPTY_STRING; - this.errorMessage = errorMessage || Constants.EMPTY_STRING; + this.errorMessage = message || Constants.EMPTY_STRING; this.subError = suberror || Constants.EMPTY_STRING; this.name = "AuthError"; } diff --git a/lib/msal-common/src/error/InteractionRequiredAuthError.ts b/lib/msal-common/src/error/InteractionRequiredAuthError.ts index be92184d39..8100146e13 100644 --- a/lib/msal-common/src/error/InteractionRequiredAuthError.ts +++ b/lib/msal-common/src/error/InteractionRequiredAuthError.ts @@ -113,7 +113,8 @@ export function isInteractionRequiredError( * Creates an InteractionRequiredAuthError */ export function createInteractionRequiredAuthError( - errorCode: string + errorCode: string, + errorMessage?: string ): InteractionRequiredAuthError { - return new InteractionRequiredAuthError(errorCode); + return new InteractionRequiredAuthError(errorCode, errorMessage); } diff --git a/lib/msal-common/test/account/AuthToken.spec.ts b/lib/msal-common/test/account/AuthToken.spec.ts index 147370bbd5..0b0f3265b7 100644 --- a/lib/msal-common/test/account/AuthToken.spec.ts +++ b/lib/msal-common/test/account/AuthToken.spec.ts @@ -9,7 +9,6 @@ import { } from "../test_kit/StringConstants"; import { ICrypto } from "../../src/crypto/ICrypto"; import { - ClientAuthErrorMessages, ClientAuthErrorCodes, ClientAuthError, } from "../../src/error/ClientAuthError"; @@ -106,16 +105,6 @@ describe("AuthToken.ts Class Unit Tests", () => { expect(parsedErr.errorCode).toBe( ClientAuthErrorCodes.nullOrEmptyToken ); - expect(parsedErr.errorMessage).toContain( - ClientAuthErrorMessages[ - ClientAuthErrorCodes.nullOrEmptyToken - ] - ); - expect(parsedErr.message).toContain( - ClientAuthErrorMessages[ - ClientAuthErrorCodes.nullOrEmptyToken - ] - ); expect(parsedErr.name).toBe("ClientAuthError"); expect(parsedErr.stack).toContain("AuthToken.spec.ts"); done(); @@ -133,16 +122,6 @@ describe("AuthToken.ts Class Unit Tests", () => { expect(parsedErr.errorCode).toBe( ClientAuthErrorCodes.nullOrEmptyToken ); - expect(parsedErr.errorMessage).toContain( - ClientAuthErrorMessages[ - ClientAuthErrorCodes.nullOrEmptyToken - ] - ); - expect(parsedErr.message).toContain( - ClientAuthErrorMessages[ - ClientAuthErrorCodes.nullOrEmptyToken - ] - ); expect(parsedErr.name).toBe("ClientAuthError"); expect(parsedErr.stack).toContain("AuthToken.spec.ts"); done(); @@ -160,16 +139,6 @@ describe("AuthToken.ts Class Unit Tests", () => { expect(parsedErr.errorCode).toBe( ClientAuthErrorCodes.tokenParsingError ); - expect(parsedErr.errorMessage).toContain( - ClientAuthErrorMessages[ - ClientAuthErrorCodes.tokenParsingError - ] - ); - expect(parsedErr.message).toContain( - ClientAuthErrorMessages[ - ClientAuthErrorCodes.tokenParsingError - ] - ); expect(parsedErr.name).toBe("ClientAuthError"); expect(parsedErr.stack).toContain("AuthToken.spec.ts"); done(); diff --git a/lib/msal-common/test/authority/Authority.spec.ts b/lib/msal-common/test/authority/Authority.spec.ts index c5b8f69d93..633fc8ec5c 100644 --- a/lib/msal-common/test/authority/Authority.spec.ts +++ b/lib/msal-common/test/authority/Authority.spec.ts @@ -18,7 +18,6 @@ import { B2C_OPENID_CONFIG_RESPONSE, } from "../test_kit/StringConstants"; import { - ClientConfigurationErrorMessages, ClientConfigurationError, createClientConfigurationError, ClientConfigurationErrorCodes, @@ -46,6 +45,7 @@ import { import { RegionDiscovery } from "../../src/authority/RegionDiscovery"; import { InstanceDiscoveryMetadata } from "../../src/authority/AuthorityMetadata"; import * as authorityMetadata from "../../src/authority/AuthorityMetadata"; +import { getDefaultErrorMessage } from "../../src/error/AuthError.js"; let mockStorage: MockStorageClass; @@ -1099,10 +1099,9 @@ describe("Authority.ts Class Unit Tests", () => { authority.resolveEndpointsAsync().catch((e) => { expect(e).toBeInstanceOf(ClientConfigurationError); expect(e.errorMessage).toBe( - ClientConfigurationErrorMessages[ - ClientConfigurationErrorCodes - .invalidAuthorityMetadata - ] + getDefaultErrorMessage( + ClientConfigurationErrorCodes.invalidAuthorityMetadata + ) ); done(); }); @@ -2315,11 +2314,8 @@ describe("Authority.ts Class Unit Tests", () => { ); authority.resolveEndpointsAsync().catch((e) => { expect(e).toBeInstanceOf(ClientConfigurationError); - expect(e.errorMessage).toBe( - ClientConfigurationErrorMessages[ - ClientConfigurationErrorCodes - .invalidCloudDiscoveryMetadata - ] + getDefaultErrorMessage( + ClientConfigurationErrorCodes.invalidCloudDiscoveryMetadata ); done(); }); @@ -2360,9 +2356,9 @@ describe("Authority.ts Class Unit Tests", () => { authority.resolveEndpointsAsync().catch((e) => { expect(e).toBeInstanceOf(ClientConfigurationError); expect(e.errorMessage).toBe( - ClientConfigurationErrorMessages[ + getDefaultErrorMessage( ClientConfigurationErrorCodes.untrustedAuthority - ] + ) ); expect(e.errorCode).toBe( ClientConfigurationErrorCodes.untrustedAuthority @@ -2410,10 +2406,10 @@ describe("Authority.ts Class Unit Tests", () => { authority.resolveEndpointsAsync().catch((e) => { expect(e).toBeInstanceOf(ClientConfigurationError); - expect(e.errorMessage).toEqual( - ClientConfigurationErrorMessages[ + expect(e.errorMessage).toBe( + getDefaultErrorMessage( ClientConfigurationErrorCodes.untrustedAuthority - ] + ) ); expect(e.errorCode).toEqual( ClientConfigurationErrorCodes.untrustedAuthority diff --git a/lib/msal-common/test/crypto/JoseHeader.spec.ts b/lib/msal-common/test/crypto/JoseHeader.spec.ts index 06dbeabe7f..f4cce7e287 100644 --- a/lib/msal-common/test/crypto/JoseHeader.spec.ts +++ b/lib/msal-common/test/crypto/JoseHeader.spec.ts @@ -1,13 +1,11 @@ import { JoseHeader } from "../../src/crypto/JoseHeader"; -import { - JoseHeaderErrorCodes, - JoseHeaderErrorMessages, -} from "../../src/error/JoseHeaderError"; +import { JoseHeaderErrorCodes } from "../../src/error/JoseHeaderError"; import { JsonWebTokenTypes } from "../../src/utils/Constants"; import { TEST_CRYPTO_ALGORITHMS, TEST_POP_VALUES, } from "../test_kit/StringConstants"; +import { getDefaultErrorMessage } from "../../src/error/AuthError.js"; describe("JoseHeader.ts Unit Tests", () => { describe("getShrHeaderString", () => { @@ -42,7 +40,7 @@ describe("JoseHeader.ts Unit Tests", () => { typ: JsonWebTokenTypes.Pop, }) ).toThrowError( - JoseHeaderErrorMessages[JoseHeaderErrorCodes.missingKidError] + getDefaultErrorMessage(JoseHeaderErrorCodes.missingKidError) ); }); @@ -53,7 +51,7 @@ describe("JoseHeader.ts Unit Tests", () => { typ: JsonWebTokenTypes.Pop, }) ).toThrowError( - JoseHeaderErrorMessages[JoseHeaderErrorCodes.missingAlgError] + getDefaultErrorMessage(JoseHeaderErrorCodes.missingAlgError) ); }); }); diff --git a/lib/msal-common/test/error/AuthError.spec.ts b/lib/msal-common/test/error/AuthError.spec.ts index 2daad43ea5..6974e6b0c1 100644 --- a/lib/msal-common/test/error/AuthError.spec.ts +++ b/lib/msal-common/test/error/AuthError.spec.ts @@ -1,10 +1,10 @@ import { AuthError, AuthErrorCodes, - AuthErrorMessages, createAuthError, } from "../../src/error/AuthError"; import { TEST_CONFIG } from "../test_kit/StringConstants"; +import { getDefaultErrorMessage } from "../../src/error/AuthError.js"; describe("AuthError.ts Class", () => { for (const key in AuthErrorCodes) { @@ -12,14 +12,16 @@ describe("AuthError.ts Class", () => { it(`AuthError object can be created for code ${code}`, () => { const err: AuthError = createAuthError(code); - const message = AuthErrorMessages[code]; + const message = getDefaultErrorMessage(code); expect(message).toBeTruthy(); - expect(err instanceof AuthError).toBe(true); expect(err instanceof AuthError).toBe(true); expect(err instanceof Error).toBe(true); expect(err.errorCode).toBe(code); expect(err.errorMessage).toBe(message); + expect(err.errorMessage).toBe( + `See https://aka.ms/msaljs/common/errors#${code} for details` + ); expect(err.message).toBe(`${code}: ${message}`); expect(err.name).toBe("AuthError"); expect(err.stack?.includes("AuthError.spec.ts")).toBe(true); diff --git a/lib/msal-common/test/error/ClientAuthError.spec.ts b/lib/msal-common/test/error/ClientAuthError.spec.ts index 84df6f18ea..3ca52504fa 100644 --- a/lib/msal-common/test/error/ClientAuthError.spec.ts +++ b/lib/msal-common/test/error/ClientAuthError.spec.ts @@ -1,10 +1,10 @@ import { ClientAuthError, ClientAuthErrorCodes, - ClientAuthErrorMessages, createClientAuthError, } from "../../src/error/ClientAuthError"; import { AuthError } from "../../src/error/AuthError"; +import { getDefaultErrorMessage } from "../../src/error/AuthError.js"; describe("ClientAuthError.ts Class Unit Tests", () => { for (const key in ClientAuthErrorCodes) { @@ -13,7 +13,7 @@ describe("ClientAuthError.ts Class Unit Tests", () => { it(`ClientAuthError object can be created for code ${code}`, () => { const err: ClientAuthError = createClientAuthError(code); - const message = ClientAuthErrorMessages[code]; + const message = getDefaultErrorMessage(code); expect(message).toBeTruthy(); expect(err instanceof ClientAuthError).toBe(true); diff --git a/lib/msal-common/test/error/ClientConfigurationError.spec.ts b/lib/msal-common/test/error/ClientConfigurationError.spec.ts index 4544f24f42..addcb73eec 100644 --- a/lib/msal-common/test/error/ClientConfigurationError.spec.ts +++ b/lib/msal-common/test/error/ClientConfigurationError.spec.ts @@ -2,9 +2,9 @@ import { AuthError } from "../../src/error/AuthError"; import { ClientConfigurationError, ClientConfigurationErrorCodes, - ClientConfigurationErrorMessages, createClientConfigurationError, } from "../../src/error/ClientConfigurationError"; +import { getDefaultErrorMessage } from "../../src/error/AuthError.js"; describe("ClientConfigurationError.ts Class Unit Tests", () => { for (const key in ClientConfigurationErrorCodes) { @@ -16,7 +16,7 @@ describe("ClientConfigurationError.ts Class Unit Tests", () => { const err: ClientConfigurationError = createClientConfigurationError(code); - const message = ClientConfigurationErrorMessages[code]; + const message = getDefaultErrorMessage(code); expect(message).toBeTruthy(); expect(err instanceof ClientConfigurationError).toBe(true); diff --git a/lib/msal-common/test/error/JoseHeaderError.spec.ts b/lib/msal-common/test/error/JoseHeaderError.spec.ts index 0fbe90e6f6..3f5cfbce31 100644 --- a/lib/msal-common/test/error/JoseHeaderError.spec.ts +++ b/lib/msal-common/test/error/JoseHeaderError.spec.ts @@ -1,10 +1,10 @@ import { JoseHeaderError, JoseHeaderErrorCodes, - JoseHeaderErrorMessages, createJoseHeaderError, } from "../../src/error/JoseHeaderError"; import { AuthError } from "../../src/error/AuthError"; +import { getDefaultErrorMessage } from "../../src/error/AuthError.js"; describe("JoseHeaderError.ts Class Unit Tests", () => { for (const key in JoseHeaderErrorCodes) { @@ -13,7 +13,7 @@ describe("JoseHeaderError.ts Class Unit Tests", () => { it(`JoseHeaderError object can be created for code ${code}`, () => { const err: JoseHeaderError = createJoseHeaderError(code); - const message = JoseHeaderErrorMessages[code]; + const message = getDefaultErrorMessage(code); expect(message).toBeTruthy(); expect(err instanceof JoseHeaderError).toBe(true); diff --git a/lib/msal-common/test/response/ResponseHandler.spec.ts b/lib/msal-common/test/response/ResponseHandler.spec.ts index a6a26a3990..04545180b0 100644 --- a/lib/msal-common/test/response/ResponseHandler.spec.ts +++ b/lib/msal-common/test/response/ResponseHandler.spec.ts @@ -37,15 +37,12 @@ import { } from "../../src/error/ClientAuthError.js"; import { InteractionRequiredAuthError } from "../../src/error/InteractionRequiredAuthError.js"; import { ServerError } from "../../src/error/ServerError.js"; -import { - CacheError, - CacheErrorCodes, - CacheErrorMessages, -} from "../../src/error/CacheError.js"; +import { CacheError, CacheErrorCodes } from "../../src/error/CacheError.js"; import { CacheManager } from "../../src/cache/CacheManager.js"; import { cacheQuotaExceededErrorCode } from "../../src/error/CacheErrorCodes.js"; import { TestTimeUtils } from "msal-test-utils"; import * as AccountEntityUtils from "../../src/cache/utils/AccountEntityUtils.js"; +import { getDefaultErrorMessage } from "../../src/error/AuthError.js"; const networkInterface: INetworkModule = { sendGetRequestAsync(url: string, options?: NetworkRequestOptions): T { @@ -893,7 +890,7 @@ describe("ResponseHandler.ts", () => { const cacheError: CacheError = e as CacheError; expect(cacheError.errorCode).toEqual("cache_quota_exceeded"); expect(cacheError.errorMessage).toEqual( - CacheErrorMessages[cacheQuotaExceededErrorCode] + getDefaultErrorMessage(cacheQuotaExceededErrorCode) ); } }); @@ -939,7 +936,7 @@ describe("ResponseHandler.ts", () => { const cacheError: CacheError = e as CacheError; expect(cacheError.errorCode).toEqual("cache_quota_exceeded"); expect(cacheError.errorMessage).toEqual( - CacheErrorMessages[cacheQuotaExceededErrorCode] + getDefaultErrorMessage(cacheQuotaExceededErrorCode) ); } }); @@ -1030,7 +1027,9 @@ describe("ResponseHandler.ts", () => { CacheErrorCodes.cacheUnknownErrorCode ); expect(cacheError.errorMessage).toEqual( - CacheErrorMessages[CacheErrorCodes.cacheUnknownErrorCode] + getDefaultErrorMessage( + CacheErrorCodes.cacheUnknownErrorCode + ) ); } }); From 1e6185a821edc0cb49213276dd436d8eddc9bb62 Mon Sep 17 00:00:00 2001 From: Konstantin Shabelko Date: Tue, 13 May 2025 11:49:58 -0400 Subject: [PATCH 5/5] - Update API docs --- .../apiReview/msal-browser.api.md | 11 +-- lib/msal-common/apiReview/msal-common.api.md | 88 +------------------ 2 files changed, 2 insertions(+), 97 deletions(-) diff --git a/lib/msal-browser/apiReview/msal-browser.api.md b/lib/msal-browser/apiReview/msal-browser.api.md index 355eecb7d8..93a95845b7 100644 --- a/lib/msal-browser/apiReview/msal-browser.api.md +++ b/lib/msal-browser/apiReview/msal-browser.api.md @@ -14,15 +14,12 @@ import { AuthenticationResult as AuthenticationResult_2 } from '@azure/msal-comm import { AuthenticationScheme } from '@azure/msal-common/browser'; import { AuthError } from '@azure/msal-common/browser'; import { AuthErrorCodes } from '@azure/msal-common/browser'; -import { AuthErrorMessages } from '@azure/msal-common/browser'; import { AzureCloudInstance } from '@azure/msal-common/browser'; import { AzureCloudOptions } from '@azure/msal-common/browser'; import { ClientAuthError } from '@azure/msal-common/browser'; import { ClientAuthErrorCodes } from '@azure/msal-common/browser'; -import { ClientAuthErrorMessages } from '@azure/msal-common/browser'; import { ClientConfigurationError } from '@azure/msal-common/browser'; import { ClientConfigurationErrorCodes } from '@azure/msal-common/browser'; -import { ClientConfigurationErrorMessages } from '@azure/msal-common/browser'; import { CommonAuthorizationCodeRequest } from '@azure/msal-common/browser'; import { CommonAuthorizationUrlRequest } from '@azure/msal-common/browser'; import { CommonEndSessionRequest } from '@azure/msal-common/browser'; @@ -113,8 +110,6 @@ export { AuthError } export { AuthErrorCodes } -export { AuthErrorMessages } - // Warning: (ae-missing-release-tag) "AuthorizationCodeRequest" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -431,14 +426,10 @@ export { ClientAuthError } export { ClientAuthErrorCodes } -export { ClientAuthErrorMessages } - export { ClientConfigurationError } export { ClientConfigurationErrorCodes } -export { ClientConfigurationErrorMessages } - // Warning: (ae-missing-release-tag) "Configuration" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @@ -1491,7 +1482,7 @@ export type WrapperSKU = (typeof WrapperSKU)[keyof typeof WrapperSKU]; // src/cache/LocalStorage.ts:296:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/cache/LocalStorage.ts:354:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/cache/LocalStorage.ts:385:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen -// src/config/Configuration.ts:256:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts +// src/config/Configuration.ts:231:5 - (ae-forgotten-export) The symbol "InternalAuthOptions" needs to be exported by the entry point index.d.ts // src/event/EventHandler.ts:113:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/event/EventHandler.ts:139:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen // src/index.ts:8:12 - (tsdoc-characters-after-block-tag) The token "@azure" looks like a TSDoc tag but contains an invalid character "/"; if it is not a tag, use a backslash to escape the "@" diff --git a/lib/msal-common/apiReview/msal-common.api.md b/lib/msal-common/apiReview/msal-common.api.md index cca1651662..4d41a43f80 100644 --- a/lib/msal-common/apiReview/msal-common.api.md +++ b/lib/msal-common/apiReview/msal-common.api.md @@ -577,14 +577,6 @@ declare namespace AuthErrorCodes { } export { AuthErrorCodes } -// Warning: (ae-missing-release-tag) "AuthErrorMessages" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const AuthErrorMessages: { - unexpected_error: string; - post_request_failed: string; -}; - // Warning: (ae-internal-missing-underscore) The name "AuthOptions" should be prefixed with an underscore because the declaration is marked as @internal // // @internal @@ -1409,56 +1401,6 @@ declare namespace ClientAuthErrorCodes { } export { ClientAuthErrorCodes } -// Warning: (ae-missing-release-tag) "ClientAuthErrorMessages" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public -export const ClientAuthErrorMessages: { - client_info_decoding_error: string; - client_info_empty_error: string; - token_parsing_error: string; - null_or_empty_token: string; - endpoints_resolution_error: string; - network_error: string; - openid_config_error: string; - hash_not_deserialized: string; - invalid_state: string; - state_mismatch: string; - state_not_found: string; - nonce_mismatch: string; - auth_time_not_found: string; - max_age_transpired: string; - multiple_matching_tokens: string; - multiple_matching_accounts: string; - multiple_matching_appMetadata: string; - request_cannot_be_made: string; - cannot_remove_empty_scope: string; - cannot_append_scopeset: string; - empty_input_scopeset: string; - device_code_polling_cancelled: string; - device_code_expired: string; - device_code_unknown_error: string; - no_account_in_silent_request: string; - invalid_cache_record: string; - invalid_cache_environment: string; - no_account_found: string; - no_crypto_object: string; - unexpected_credential_type: string; - invalid_assertion: string; - invalid_client_credential: string; - token_refresh_required: string; - user_timeout_reached: string; - token_claims_cnf_required_for_signedjwt: string; - authorization_code_missing_from_server_response: string; - binding_key_not_removed: string; - end_session_endpoint_not_supported: string; - key_id_missing: string; - no_network_connectivity: string; - user_canceled: string; - missing_tenant_id_error: string; - method_not_implemented: string; - nested_app_auth_bridge_disabled: string; -}; - // Warning: (ae-internal-missing-underscore) The name "ClientConfiguration" should be prefixed with an underscore because the declaration is marked as @internal // // @internal @@ -1513,34 +1455,6 @@ declare namespace ClientConfigurationErrorCodes { } export { ClientConfigurationErrorCodes } -// Warning: (ae-missing-release-tag) "ClientConfigurationErrorMessages" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const ClientConfigurationErrorMessages: { - redirect_uri_empty: string; - claims_request_parsing_error: string; - authority_uri_insecure: string; - url_parse_error: string; - empty_url_error: string; - empty_input_scopes_error: string; - invalid_prompt_value: string; - invalid_claims: string; - token_request_empty: string; - logout_request_empty: string; - invalid_code_challenge_method: string; - pkce_params_missing: string; - invalid_cloud_discovery_metadata: string; - invalid_authority_metadata: string; - untrusted_authority: string; - missing_ssh_jwk: string; - missing_ssh_kid: string; - missing_nonce_authentication_header: string; - invalid_authentication_header: string; - cannot_set_OIDCOptions: string; - cannot_allow_platform_broker: string; - authority_mismatch: string; -}; - // Warning: (ae-missing-release-tag) "ClientInfo" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @@ -1812,7 +1726,7 @@ function createIdTokenEntity(homeAccountId: string, environment: string, idToken // Warning: (ae-missing-release-tag) "createInteractionRequiredAuthError" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public -export function createInteractionRequiredAuthError(errorCode: string): InteractionRequiredAuthError; +export function createInteractionRequiredAuthError(errorCode: string, errorMessage?: string): InteractionRequiredAuthError; // Warning: (ae-missing-release-tag) "createNetworkError" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) //