Deprecate built-in Cordova adapters (#297)

Add a deprecation utility (`logDeprecation`) that emits each warning
at most once per page load, keyed by a unique code (KC-DEP-###).

Use it to deprecate the built-in 'cordova' and 'cordova-native'
adapters at runtime, and mark them as deprecated in the type
definitions and documentation ahead of removal in the next major.

Closes #271

Signed-off-by: Jon Koops <jonkoops@gmail.com>
This commit is contained in:
Jon Koops
2026-04-23 12:43:34 +02:00
committed by GitHub
parent 7abc00c8db
commit 46ad3374fc
5 changed files with 49 additions and 5 deletions
@@ -188,6 +188,8 @@ await keycloak.init({
[#hybrid-apps-with-cordova]
== Hybrid Apps with Cordova
WARNING: The built-in `cordova` and `cordova-native` adapters are deprecated and will be removed in a future major version. Use a <<custom-adapters,custom adapter>> instead.
{project_name} supports hybrid mobile apps developed with https://cordova.apache.org/[Apache Cordova]. The adapter has two modes for this: `cordova` and `cordova-native`:
The default is `cordova`, which the adapter automatically selects if no adapter type has been explicitly configured and `window.cordova` is present. When logging in, it opens an https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/[InApp Browser] that lets the user interact with {project_name} and afterwards returns to the app by redirecting to `http://localhost`. Because of this behavior, you whitelist this URL as a valid redirect-uri in the client configuration section of the Admin Console.
@@ -384,8 +386,8 @@ adapter::
Allows you to override the way that redirects and other browser-related functions will be handled by the library.
Available options:
* "default" - the library uses the browser api for redirects (this is the default)
* "cordova" - the library will try to use the InAppBrowser cordova plugin to load keycloak login/registration pages (this is used automatically when the library is working in a cordova ecosystem)
* "cordova-native" - the library tries to open the login and registration page using the phone's system browser using the BrowserTabs cordova plugin. This requires extra setup for redirecting back to the app (see <<hybrid-apps-with-cordova>>).
* "cordova" - *Deprecated.* the library will try to use the InAppBrowser cordova plugin to load keycloak login/registration pages (this is used automatically when the library is working in a cordova ecosystem)
* "cordova-native" - *Deprecated.* the library tries to open the login and registration page using the phone's system browser using the BrowserTabs cordova plugin. This requires extra setup for redirecting back to the app (see <<hybrid-apps-with-cordova>>).
* "custom" - allows you to implement a custom adapter (only for advanced use cases)
responseType::
@@ -449,7 +451,7 @@ and link:{adminguide_link}#_step-up-flow[Step-up authentication documentation] f
If the value is `UPDATE_PASSWORD` or another supported required action, the user will be redirected to the reset password page or the other required action page. However, if the user is not authenticated, the user will be sent to the login page and redirected after authentication.
See link:{adminguide_link}#con-aia_server_administration_guide[Application Initiated Action section] for more details.
* locale - Sets the 'ui_locales' query param in compliance with https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest[section 3.1.2.1 of the OIDC 1.0 specification].
* cordovaOptions - Specifies the arguments that are passed to the Cordova in-app-browser (if applicable). Options `hidden` and `location` are not affected by these arguments. All available options are defined at https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/. Example of use: `{ zoom: "no", hardwareback: "yes" }`;
* cordovaOptions - *Deprecated.* Specifies the arguments that are passed to the Cordova in-app-browser (if applicable). Options `hidden` and `location` are not affected by these arguments. All available options are defined at https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/. Example of use: `{ zoom: "no", hardwareback: "yes" }`;
*createLoginUrl(options)*
+21
View File
@@ -0,0 +1,21 @@
This release of Keycloak JS deprecates the built-in Cordova adapters ahead of their removal in the next major version.
== Deprecations
=== Cordova adapters are deprecated
The built-in `cordova` and `cordova-native` adapters are now deprecated and will be removed in a future major version. Passing `'cordova'` or `'cordova-native'` to the `adapter` init option, or relying on the automatic detection of the `window.cordova` global, will now emit a runtime deprecation warning in the browser console. The `cordovaOptions` property on `KeycloakLoginOptions` is also deprecated.
This decision was made after extensive discussion with the community (https://github.com/keycloak/keycloak-js/issues/271[keycloak/keycloak-js#271], https://github.com/keycloak/keycloak-js/issues/272[keycloak/keycloak-js#272]) and is motivated by the following:
* *Abandoned plugin ecosystem* — The `cordova-native` adapter depends on https://github.com/google/cordova-plugin-browsertab[`cordova-plugin-browsertab`] and https://github.com/e-imaxina/cordova-plugin-deeplinks[`cordova-plugin-deeplinks`], both of which are no longer maintained and are incompatible with recent Android SDK versions, requiring manual patching to function.
* *Security concerns* — The `cordova` adapter uses an embedded WebView (InAppBrowser) for authentication, which gives the host application full control over the browser rendering the login page. This approach is https://www.rfc-editor.org/rfc/rfc8252.txt[discouraged by RFC 8252] (OAuth 2.0 for Native Apps), which recommends using the system browser instead.
* *Lack of testing infrastructure* — The Cordova adapters have no automated test coverage and no clear code ownership, making it difficult to verify fixes or prevent regressions.
* *Declining adoption* — The https://npmtrends.com/cordova[Cordova ecosystem has been on a downward trend since 2019], largely displaced by Capacitor, React Native and Flutter. Maintaining the built-in adapters imposes a disproportionate maintenance burden relative to actual usage.
==== Migration
If you are using Cordova or a similar hybrid app framework, use a <<custom-adapters,custom adapter>> to provide your own implementation. For users migrating to Capacitor, see https://github.com/keycloak/keycloak-js/issues/27[keycloak/keycloak-js#27] for an ongoing discussion on improving the custom adapter interface to better support this use case.
+16
View File
@@ -0,0 +1,16 @@
/** @type {Set<string>} */
const emitted = new Set()
/**
* Emit a deprecation warning. Each code is only warned once per page load.
* @param {string} code Unique deprecation identifier (e.g. "KC-DEP-001").
* @param {string} message Human-readable deprecation message.
*/
export function logDeprecation (code, message) {
if (emitted.has(code)) {
return
}
emitted.add(code)
console.warn(`[KEYCLOAK] ${code}: ${message}`)
}
+3 -2
View File
@@ -93,8 +93,8 @@ export interface KeycloakInitOptions {
*
* The following options are supported:
* - `default` - Use default APIs that are available in browsers.
* - `cordova` - Use a WebView in Cordova.
* - `cordova-native` - Use Cordova native APIs, this is recommended over `cordova`.
* - `cordova` - **Deprecated.** Use a WebView in Cordova. Use a custom adapter instead.
* - `cordova-native` - **Deprecated.** Use Cordova native APIs. Use a custom adapter instead.
*
* It's also possible to pass in a custom adapter for the environment you are running Keycloak in. In order to do so extend the `KeycloakAdapter` interface and implement the methods that are defined there.
*
@@ -300,6 +300,7 @@ export interface KeycloakLoginOptions {
* Options 'hidden' and 'location' are not affected by these arguments.
* All available options are defined at https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-inappbrowser/.
* Example of use: { zoom: "no", hardwareback: "yes" }
* @deprecated The built-in Cordova adapters are deprecated and will be removed in a future version. Use a custom adapter instead.
*/
cordovaOptions?: { [optionName: string]: string }
}
+4
View File
@@ -19,6 +19,8 @@
* limitations under the License.
*/
import { logDeprecation } from './deprecations.js'
const CONTENT_TYPE_JSON = 'application/json'
/**
@@ -292,11 +294,13 @@ export default class Keycloak {
}
if (type === 'cordova') {
logDeprecation('KC-DEP-001', "The 'cordova' adapter is deprecated and will be removed in a future version. Use a custom adapter instead.")
this.#loginIframe.enable = false
return this.#loadCordovaAdapter()
}
if (type === 'cordova-native') {
logDeprecation('KC-DEP-002', "The 'cordova-native' adapter is deprecated and will be removed in a future version. Use a custom adapter instead.")
this.#loginIframe.enable = false
return this.#loadCordovaNativeAdapter()
}