Skip to content

Add Capacitor support with native redirect handling and Angular integration - #180

Open
topdev-spetermann wants to merge 10 commits into
keycloakify:mainfrom
topdev-spetermann:feature/capacitor
Open

Add Capacitor support with native redirect handling and Angular integration#180
topdev-spetermann wants to merge 10 commits into
keycloakify:mainfrom
topdev-spetermann:feature/capacitor

Conversation

@topdev-spetermann

@topdev-spetermann topdev-spetermann commented May 13, 2026

Copy link
Copy Markdown

Fixes #37

Summary

This PR adds Capacitor support to oidc-spa while aiming to preserve the existing behavior for current browser users who do not opt into the new parameters.

The implementation keeps the existing web flow intact and adds a native-specific path for Capacitor apps, including redirect handling, storage integration, and an Angular-friendly setup.

Main changes

  • Add a new oidc-spa/capacitor entrypoint
  • Add CapacitorNavigator for native login/logout redirects through Capacitor
  • Add CapacitorPreferencesStorageAdapter for Capacitor-backed persistence
  • Add oidc-spa/capacitor/angular with a native-oriented Angular integration
  • Add support for optional storageAdapter, tokenStorageAdapter, navigator, isNativeApp, and nativeSessionRestoreMode parameters
  • Add native redirect buffering and replay via externalRedirectUrl
  • Add shared parsing logic for OIDC redirect responses
  • Refactor persisted auth state and lazy session storage to support async storage adapters
  • Extract refresh token expiration handling into a dedicated helper
  • Add a complete examples/capacitor-angular example project for Android and iOS

Design notes

  • Existing browser behavior remains unchanged unless the new Capacitor-related parameters are explicitly used
  • In web mode, the redirect/callback stateStore intentionally remains on localStorage for compatibility with synchronous early-init and iframe-based flows
  • Native flows use a dedicated callback URL and external deep-link handling instead of relying on window.location.href
  • Local token restore is only enabled where it is explicitly intended by the native flow configuration

Compatibility

  • No intended breaking changes for existing users of the browser flow
  • Existing redirect, silent signin, and callback logic remain unchanged for non-native usage
  • The new storage and navigator options are additive and optional

Validation

  • Native example flow manually tested on iOS
  • Native example flow manually tested on Android
  • Existing Angular example re-tested as a regression check

Review notes

I am happy to adapt the public API, naming, internal structure, or integration shape if that makes upstreaming easier, as long as the Capacitor integration requirements remain covered.

If you prefer a different surface for the Angular integration or a different split between internal helpers and public API, I can adjust the PR accordingly.

Review focus

The most important areas to review are:

  • Native redirect lifecycle and callback replay
  • Storage behavior split between browser and native environments
  • Preservation of existing browser behavior
  • The Angular Capacitor integration surface
  • The example app and expected developer workflow

Summary by CodeRabbit

  • New Features

    • Native Capacitor mobile support (iOS/Android) with a complete example app, launcher assets, and build/run scripts
    • Native-friendly auth flows: Capacitor navigator, deep-link callback handling, and a Preferences-backed storage adapter
    • Angular example with guarded protected routes and token-aware HTTP integration
  • Documentation

    • Comprehensive Capacitor+Angular authentication guide covering deep links, storage options, callbacks, and session restore
  • Refactor

    • Async, pluggable auth/session persistence and external redirect handling for native/web consistency

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Capacitor native-mobile support and Angular integration: navigator and storage abstractions/adapters, async session/storage plumbing, external redirect persistence and parsing, refresh-token helpers, Angular DI/provider extensions, and a full Capacitor+Angular example (Android/iOS projects and docs).

Changes

Core library: native & async storage integration

Layer / File(s) Summary
Navigator abstraction & core types
src/core/BaseNavigator.ts, src/vendor/frontend/oidc-client-ts.ts
Adds BaseNavigator and BaseNavigatorWarning plus re-exports INavigator, IWindow, AsyncStorage types for implementations.
Capacitor navigator implementation
src/capacitor/CapacitorNavigator.ts
Implements CapacitorNavigator with callback URL policy, browser-finished grace period, App.getLaunchUrl/appUrlOpen handling, initialize/prepare/callback contracts, and warning emission.
Capacitor storage adapter
src/capacitor/CapacitorStorage.ts, src/capacitor/index.ts
Adds CapacitorPreferencesStorageAdapter (namespaced keys over Capacitor Preferences) and re-exports it from src/capacitor/index.ts.
Async storage adapters
src/tools/localStorageAdapter.ts, src/tools/sessionStorageAdapter.ts
Adds localStorageAdapter and sessionStorageAdapter implementing AsyncStorage wrappers around browser storage APIs.
Lazy async session storage
src/tools/lazyAsyncSessionStorage.ts (removed: src/tools/lazySessionStorage.ts)
Adds async lazy session storage factory backed by a persistence adapter; removes old sync lazySessionStorage.
External redirect persistence
src/core/externalRedirectUrl.ts
New per-config external-redirect persistence: initialize, wait-for-init, set/peek/clear, with storage + in-memory caching and expiry.
OIDC redirect parsing helpers
src/core/parseOidcRedirectUrl.ts
New helpers hasOidcRedirectResponse() and extractOidcRedirectResponse() for fragment/query detection and extraction.
Persisted auth state async layer
src/core/persistedAuthState.ts
persistAuthState / getPersistedAuthState now use AsyncStorage adapters (default localStorageAdapter) and perform async validation/expiry cleanup.
Refresh token helpers & numeric utils
src/core/getRefreshTokenExpirationTime.ts, src/tools/toNumber.ts
Extracts refresh-token expiration computation and adds toNumber utility.
Token conversion update
src/core/oidcClientTsUserToTokens.ts
Uses shared getRefreshTokenExpirationTime and toNumber instead of inline parsing.
Early init & login flow wiring
src/core/earlyInit.ts, src/core/loginOrGoToAuthServer.ts
Delegates URL auth response detection to parsing helpers, makes preRedirectHook async-capable, and ensures redirect_uri uses computed oidcCallbackUrl.
OIDC creation & lifecycle changes
src/core/createOidc.ts
Large refactor: adds storageAdapter/tokenStorageAdapter, navigator/onNavigatorWarning, isNativeApp, nativeSessionRestoreMode; disables iframes in native mode; wires async lazy session storage and external-redirect flow; per-config logout tracking; routes persisted state through adapters; updates restoration/renewal/persistence paths.

Angular integration: types, providers, guard behavior

Layer / File(s) Summary
Angular public API updates
src/angular.ts
Extends ParamsOfProvide (storageAdapter, tokenStorageAdapter, navigator, onNavigatorWarning, isNativeApp, nativeSessionRestoreMode); AbstractOidcService.provide accepts additionalProviders; enforceLoginGuard refactored to a typed CanActivateFn with native-specific async login behavior.
Capacitor Angular service & tokens
src/capacitor/angular.ts
Adds CapacitorOidcService and DI tokens (CAPACITOR_NAVIGATOR_WARNING_HANDLER, CAPACITOR_CALLBACK_URL_POLICY, CAPACITOR_BROWSER_FINISHED_GRACE_PERIOD_MS, CAPACITOR_IS_NATIVE_APP); wires native detection and navigator/storage adapters into provide() and overrides guard behavior for native flows.

Example application: Capacitor + Angular sample and platform projects

Layer / File(s) Summary
Example app code & DI wiring
examples/capacitor-angular/src/app/*, examples/capacitor-angular/src/main.ts, examples/capacitor-angular/src/main.lazy.ts, examples/capacitor-angular/src/index.html, examples/capacitor-angular/src/styles.scss
New Angular example wiring platform detection, selecting Capacitor adapters, early OIDC init, lazy bootstrap, routes (protected guarded by Oidc.enforceLoginGuard), root component, public/protected pages, injectable Oidc service, styles and HTML shell.
Example build & TS configs
examples/capacitor-angular/angular.json, tsconfig*.json, examples/capacitor-angular/package.json, examples/capacitor-angular/capacitor.config.ts
Adds Angular CLI config, strict TypeScript configs, example package.json (deps/devDeps/scripts), and typed Capacitor config. Also adds new package exports and peer/dev dependency adjustments in root package.json.
Android native project
examples/capacitor-angular/android/**
Adds Android Gradle scripts, manifest with OAuth2 redirect intent-filter, MainActivity (BridgeActivity), resources (icons, drawables), file_paths.xml, tests, ProGuard placeholder, Gradle wrapper and settings, and .gitignore entries.
iOS native project
examples/capacitor-angular/ios/**
Adds Xcode project, AppDelegate forwarding URLs/universal links to Capacitor, storyboards with CAPBridgeViewController, Info.plist with URL scheme, asset catalogs, and Podfile.
Docs & gitignore
examples/capacitor-angular/README.md, examples/capacitor-angular/.gitignore, platform .gitignore files
Comprehensive README explaining setup, deep-linking, callback URI requirements, native vs web behavior, optional biometric adapter pattern, and example .gitignore files.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

"I hopped into code with ears held high,
Deep links and prefs beneath the sky,
Browser opens, apps reply,
Tokens tucked where carrots lie,
Native auth now leaps — oh my!"

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

🧹 Nitpick comments (1)
examples/capacitor-angular/android/app/build.gradle (1)

47-54: 💤 Low value

Consider a cleaner file existence check.

The current pattern works but relies on exception handling for flow control. Checking file existence explicitly before accessing .text would be more idiomatic.

♻️ Proposed cleaner approach
 try {
     def servicesJSON = file('google-services.json')
-    if (servicesJSON.text) {
+    if (servicesJSON.exists()) {
         apply plugin: 'com.google.gms.google-services'
     }
 } catch(Exception e) {
     logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/capacitor-angular/android/app/build.gradle` around lines 47 - 54,
Replace the try/catch flow-control with an explicit file-existence check: test
for the presence of 'google-services.json' using the file(...) object's exists()
(or .isFile()) before reading servicesJSON.text and before calling apply plugin:
'com.google.gms.google-services'; remove the try/catch and log the same info
message if the file does not exist, referencing the servicesJSON variable and
the apply plugin: 'com.google.gms.google-services' line when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/capacitor-angular/android/.gitignore`:
- Around line 55-58: Un-ignore Android keystore patterns in the .gitignore by
enabling the entries for "*.jks" and "*.keystore" so signing keys are excluded
from commits; locate the commented patterns "#*.jks" and "#*..keystore" and
remove the leading "#" to ensure the glob patterns (*.jks, *.keystore) are
active in the .gitignore.

In `@examples/capacitor-angular/android/app/src/main/AndroidManifest.xml`:
- Line 5: The AndroidManifest currently has android:allowBackup="true" on the
Application declaration which allows system backups of app data; change this
attribute to android:allowBackup="false" in the <application> element to disable
backups for auth/session artifacts, and verify there are no backup-related
entries (e.g., android:backupAgent or android:fullBackupContent) that re-enable
backups; rebuild and test to confirm sensitive state is no longer included in
device backups.

In
`@examples/capacitor-angular/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml`:
- Line 4: The adaptive icon XML is referencing the foreground as a mipmap but
the resource is in drawable; update the foreground attribute in the adaptive
icon files (ic_launcher.xml and ic_launcher_round.xml) to use
`@drawable/ic_launcher_foreground` instead of `@mipmap/ic_launcher_foreground` so
the resource type matches the actual drawable-v24/ic_launcher_foreground.xml
resource and fixes Android resource linking.

In `@examples/capacitor-angular/android/app/src/main/res/xml/file_paths.xml`:
- Around line 3-4: The <external-path name="my_images" path="." /> and
<cache-path name="my_cache_images" path="." /> entries in file_paths.xml are too
broad; replace the path="." values with restrictive subdirectories your app
actually uses (for example path="images/" or path="shared/" for external media
and path="cache/images/" for cached files) so FileProvider only exposes those
specific folders; update any code that constructs URIs or expects file locations
(where you reference these providers) to match the new subdirectory names and
verify Intent grants still work with the narrowed paths.

In `@examples/capacitor-angular/android/build.gradle`:
- Around line 10-11: The specified plugin coordinates
"com.android.tools.build:gradle" and "com.google.gms:google-services" use
versions that cannot be resolved; update the classpath declarations to use
versions that exist in your configured Maven repositories (for example replace
the version numbers after com.android.tools.build:gradle and
com.google.gms:google-services with verified, resolvable versions) or add the
repository that hosts those versions to your buildscript repositories; verify
resolution by running a dependency sync/gradle build to ensure the new versions
for the Android Gradle plugin and Google Services plugin resolve correctly.

In `@examples/capacitor-angular/README.md`:
- Line 116: The fenced architecture code block in README.md is missing a
language identifier (MD040); update the opening triple-backtick for the ASCII
diagram to include a language tag (for example change ``` to ```text) so the
block is properly identified and passes markdown linting—locate the diagram
block (the ASCII "Angular Application" architecture fence) and add the language
identifier to the opening fence.

In `@examples/capacitor-angular/src/app/app.config.ts`:
- Line 33: The config currently always sets postLoginRedirectUrl to a native
deep-link which breaks web login; update the config so postLoginRedirectUrl is
only assigned when isNativeApp is true (e.g., set it to the deep-link when
isNativeApp === true and leave it undefined/omit it for web). Apply the same
conditional treatment to the related postLogoutRedirectUrl entry as noted (both
symbols: postLoginRedirectUrl and postLogoutRedirectUrl) so web mode uses the
browser's current URL while native uses the deep-link.

In `@examples/capacitor-angular/src/app/pages/protected.ts`:
- Around line 48-50: The renewTokens method currently awaits
this.oidc.renewTokens() with no error handling; wrap the call in a try/catch (or
handle the returned promise) inside renewTokens to catch renewal failures, log
the error (include error details) and surface user feedback (e.g., call a
notification method or redirect to login) so the app doesn't leave an unhandled
rejection or silent failure; update the renewTokens function and any UI helper
used for notifications accordingly.

In `@src/capacitor/CapacitorNavigator.ts`:
- Around line 245-269: Wrap the native redirect flow async calls in try-catch
blocks: in the appUrlOpen handler around setExternalRedirectUrl(...) and
`#closeBrowserIfNotAndroid`(), catch errors, call this.#emitWarning(...) with the
caught error and context ("appUrlOpen"), and return (do not rethrow); in the
navigate method wrap Browser.open(...) and setExternalRedirectUrl(...) so after
running cleanup methods (`#clearBrowserFinishedTimeout`,
`#cleanupBrowserFinishedListenerRemove`, `#cleanupListener`) you emit a warning via
this.#emitWarning(...) and then rethrow the error to propagate failure; in the
callback and close handlers wrap setExternalRedirectUrl(...) and
Browser.close(...) respectively, emit warnings with this.#emitWarning(...) on
error and do not rethrow; ensure you still call `#getRequiredInitialization`() and
other cleanup before/after the try-catch as needed so listeners/timeouts are not
left attached.

In `@src/core/createOidc.ts`:
- Around line 643-658: The code currently computes oidcCallbackUrl for native
apps but continues to use homeUrlAndRedirectUri/validRedirectUri in subsequent
reporting/logging; change the logic so that wherever validRedirectUri or any
troubleshooting/log messages reference the registered redirect URI they use
oidcCallbackUrl when isNativeApp is true (i.e., prefer oidcCallbackUrl over
homeUrlAndRedirectUri/postLoginRedirectUrl_default for native flows); update the
construction/assignment of validRedirectUri (and any logs that print
homeUrlAndRedirectUri) to resolve to oidcCallbackUrl when isNativeApp is true so
native integrators see the actual callback URI to register.
- Around line 1096-1101: When restoring from session storage (inside the
restore_from_session_storage block) we must not return a cached getUser() when
there is a pending native callback; update the conditional that checks
shouldPreferLocalRestoreInNative and
evtIsThereMoreThanOneInstanceThatCantUserIframes.current to also ensure no
pending native callback/external redirect is present (e.g. check
externalRedirectUrl or the auth callback flag) before breaking out and returning
getUser(); in other words, defer preferring local restore until any pending
native callback has been consumed. Apply the same guard to the analogous code
region around lines 1162-1191 so both restore paths wait for callback handling
before short-circuiting with a persisted user.

In `@src/core/externalRedirectUrl.ts`:
- Line 13: The in-memory cache externalRedirectUrlByConfigId_memory currently
stores only the URL so reads bypass MAX_AGE_MS; change the map to store an
object with timestamp (e.g., { url: string, ts: number }) and update all
read/write sites (the code paths around the current checks at the regions you
flagged - ~112-116 and ~151-153) so writers set ts = Date.now() and readers
validate Date.now() - ts <= MAX_AGE_MS before returning the cached URL
(otherwise fall through to refresh and update the map). Ensure references to
externalRedirectUrlByConfigId_memory are adjusted to use the new shape and that
MAX_AGE_MS is used for invalidation.

In `@src/core/loginOrGoToAuthServer.ts`:
- Around line 329-331: The preRedirectHook await (rest.preRedirectHook) can
reject and leave the login latch stuck; wrap the await in a try/catch (or
try/finally) so that on rejection you reset the login latch/lock before
rethrowing the error, and apply the same change to the other occurrence around
signinRedirect handling (the block near lines 366-368) so both
rest.preRedirectHook and signinRedirect failure paths always clear the login
latch.

---

Nitpick comments:
In `@examples/capacitor-angular/android/app/build.gradle`:
- Around line 47-54: Replace the try/catch flow-control with an explicit
file-existence check: test for the presence of 'google-services.json' using the
file(...) object's exists() (or .isFile()) before reading servicesJSON.text and
before calling apply plugin: 'com.google.gms.google-services'; remove the
try/catch and log the same info message if the file does not exist, referencing
the servicesJSON variable and the apply plugin: 'com.google.gms.google-services'
line when making the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ad836b70-6519-4bdd-8761-3229b6ad3451

📥 Commits

Reviewing files that changed from the base of the PR and between d7f880f and be0bcd3.

⛔ Files ignored due to path filters (32)
  • examples/capacitor-angular/android/app/src/main/res/drawable-land-hdpi/splash.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/drawable-land-mdpi/splash.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/drawable-land-xhdpi/splash.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/drawable-land-xxhdpi/splash.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/drawable-land-xxxhdpi/splash.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/drawable-port-hdpi/splash.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/drawable-port-mdpi/splash.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/drawable-port-xhdpi/splash.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/drawable-port-xxhdpi/splash.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/drawable-port-xxxhdpi/splash.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/drawable/splash.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-hdpi/ic_launcher.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-mdpi/ic_launcher.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png is excluded by !**/*.png
  • examples/capacitor-angular/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png is excluded by !**/*.png
  • examples/capacitor-angular/android/gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
  • examples/capacitor-angular/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png is excluded by !**/*.png
  • examples/capacitor-angular/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png is excluded by !**/*.png
  • examples/capacitor-angular/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png is excluded by !**/*.png
  • examples/capacitor-angular/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png is excluded by !**/*.png
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (76)
  • examples/capacitor-angular/.gitignore
  • examples/capacitor-angular/README.md
  • examples/capacitor-angular/android/.gitignore
  • examples/capacitor-angular/android/app/.gitignore
  • examples/capacitor-angular/android/app/build.gradle
  • examples/capacitor-angular/android/app/capacitor.build.gradle
  • examples/capacitor-angular/android/app/proguard-rules.pro
  • examples/capacitor-angular/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java
  • examples/capacitor-angular/android/app/src/main/AndroidManifest.xml
  • examples/capacitor-angular/android/app/src/main/java/com/oidcspa/capacitor/MainActivity.java
  • examples/capacitor-angular/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
  • examples/capacitor-angular/android/app/src/main/res/drawable/ic_launcher_background.xml
  • examples/capacitor-angular/android/app/src/main/res/layout/activity_main.xml
  • examples/capacitor-angular/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  • examples/capacitor-angular/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  • examples/capacitor-angular/android/app/src/main/res/values/ic_launcher_background.xml
  • examples/capacitor-angular/android/app/src/main/res/values/strings.xml
  • examples/capacitor-angular/android/app/src/main/res/values/styles.xml
  • examples/capacitor-angular/android/app/src/main/res/xml/file_paths.xml
  • examples/capacitor-angular/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java
  • examples/capacitor-angular/android/build.gradle
  • examples/capacitor-angular/android/capacitor.settings.gradle
  • examples/capacitor-angular/android/gradle.properties
  • examples/capacitor-angular/android/gradle/wrapper/gradle-wrapper.properties
  • examples/capacitor-angular/android/gradlew
  • examples/capacitor-angular/android/gradlew.bat
  • examples/capacitor-angular/android/settings.gradle
  • examples/capacitor-angular/android/variables.gradle
  • examples/capacitor-angular/angular.json
  • examples/capacitor-angular/capacitor.config.ts
  • examples/capacitor-angular/ios/.gitignore
  • examples/capacitor-angular/ios/App/App.xcodeproj/project.pbxproj
  • examples/capacitor-angular/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  • examples/capacitor-angular/ios/App/App/AppDelegate.swift
  • examples/capacitor-angular/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json
  • examples/capacitor-angular/ios/App/App/Assets.xcassets/Contents.json
  • examples/capacitor-angular/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json
  • examples/capacitor-angular/ios/App/App/Base.lproj/LaunchScreen.storyboard
  • examples/capacitor-angular/ios/App/App/Base.lproj/Main.storyboard
  • examples/capacitor-angular/ios/App/App/Info.plist
  • examples/capacitor-angular/ios/App/Podfile
  • examples/capacitor-angular/package.json
  • examples/capacitor-angular/src/app/app.config.ts
  • examples/capacitor-angular/src/app/app.routes.ts
  • examples/capacitor-angular/src/app/app.ts
  • examples/capacitor-angular/src/app/pages/protected.ts
  • examples/capacitor-angular/src/app/pages/public.ts
  • examples/capacitor-angular/src/app/services/oidc.service.ts
  • examples/capacitor-angular/src/index.html
  • examples/capacitor-angular/src/main.lazy.ts
  • examples/capacitor-angular/src/main.ts
  • examples/capacitor-angular/src/styles.scss
  • examples/capacitor-angular/tsconfig.app.json
  • examples/capacitor-angular/tsconfig.json
  • examples/capacitor-angular/tsconfig.spec.json
  • package.json
  • src/angular.ts
  • src/capacitor/CapacitorNavigator.ts
  • src/capacitor/CapacitorStorage.ts
  • src/capacitor/angular.ts
  • src/capacitor/index.ts
  • src/core/BaseNavigator.ts
  • src/core/createOidc.ts
  • src/core/earlyInit.ts
  • src/core/externalRedirectUrl.ts
  • src/core/getRefreshTokenExpirationTime.ts
  • src/core/loginOrGoToAuthServer.ts
  • src/core/oidcClientTsUserToTokens.ts
  • src/core/parseOidcRedirectUrl.ts
  • src/core/persistedAuthState.ts
  • src/tools/lazyAsyncSessionStorage.ts
  • src/tools/lazySessionStorage.ts
  • src/tools/localStorageAdapter.ts
  • src/tools/sessionStorageAdapter.ts
  • src/tools/toNumber.ts
  • src/vendor/frontend/oidc-client-ts.ts
💤 Files with no reviewable changes (1)
  • src/tools/lazySessionStorage.ts

Comment thread examples/capacitor-angular/android/.gitignore Outdated
Comment thread examples/capacitor-angular/android/app/src/main/AndroidManifest.xml Outdated
Comment thread examples/capacitor-angular/android/app/src/main/res/xml/file_paths.xml Outdated
Comment thread examples/capacitor-angular/android/build.gradle
Comment thread src/capacitor/CapacitorNavigator.ts
Comment thread src/core/createOidc.ts
Comment thread src/core/createOidc.ts
Comment thread src/core/externalRedirectUrl.ts Outdated
Comment thread src/core/loginOrGoToAuthServer.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/capacitor/angular.ts`:
- Around line 17-19: The InjectionToken CAPACITOR_NAVIGATOR is declared as
InjectionToken<CapacitorNavigator> but the factory (effectiveNavigator) can
return undefined in web mode, so change the token's type to allow undefined
(InjectionToken<CapacitorNavigator | undefined>) or adjust the provider to
always return a non-undefined object; update the declaration of
CAPACITOR_NAVIGATOR and any related provider/factory that references
effectiveNavigator so callers get a correct compile-time type (or a stable
fallback) and handle the undefined case safely.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ac150d57-13d6-43bf-a6e0-44275eb5752a

📥 Commits

Reviewing files that changed from the base of the PR and between 7a8d6f6 and 6557b91.

📒 Files selected for processing (3)
  • examples/capacitor-angular/README.md
  • src/capacitor/CapacitorNavigator.ts
  • src/capacitor/angular.ts
✅ Files skipped from review due to trivial changes (1)
  • examples/capacitor-angular/README.md

Comment thread src/capacitor/angular.ts
@garronej

Copy link
Copy Markdown
Collaborator

Sorry I didn't get a chance to review it yet but I will.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mobile usage - Ionic / Capacitor

2 participants