Skip to content

Conversation

@NandanPrabhu
Copy link
Contributor

@NandanPrabhu NandanPrabhu commented Sep 8, 2025

Changes

This PR consists of changes with respect to adding flutter windows desktop support.

Feature implemented PKCE flow end to end
Right now the flutter channels supported are webauthlogin and webauthlogout
CredentialsManager would be supported in another PR
Dependency management for windows is done via CMakeLists.txt file. Under the hood flutter provides C++ application as wrapper over windows

@NandanPrabhu NandanPrabhu marked this pull request as ready for review January 8, 2026 07:37
@NandanPrabhu NandanPrabhu requested a review from a team as a code owner January 8, 2026 07:37
@NandanPrabhu NandanPrabhu changed the title Windows desktop support Flutter windows desktop support Jan 8, 2026
NandanPrabhu and others added 4 commits January 8, 2026 22:39
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds Windows desktop support to the Auth0 Flutter SDK and introduces a cross‑platform custom token exchange flow, along with logout enhancements and CI/test updates.

Changes:

  • Implement custom token exchange (auth#customTokenExchange) across platform interface, Android, iOS/macOS, and Web, with new request option types and extensive tests.
  • Add allowedBrowsers support to the Web Auth logout API on mobile and platform interface, plus corresponding tests and documentation.
  • Introduce a full Windows desktop plugin (C++), including PKCE-based WebAuth login/logout flows, supporting utilities, unit tests, and a new GitHub Actions job to run Windows tests with coverage.

Reviewed changes

Copilot reviewed 101 out of 115 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
auth0_flutter_platform_interface/test/method_channel_auth0_flutter_web_auth_test.dart Extends WebAuth logout method-channel tests to assert allowedBrowsers mapping and defaults.
auth0_flutter_platform_interface/test/method_channel_auth0_flutter_auth_test.dart Adds method-channel tests covering customTokenExchange mapping, defaults, organization, and error handling.
auth0_flutter_platform_interface/test/auth_custom_token_exchange_options_test.dart New tests for AuthCustomTokenExchangeOptions construction and toMap behavior.
auth0_flutter_platform_interface/pubspec.yaml Bumps platform interface version to 2.0.0-beta.2.
auth0_flutter_platform_interface/lib/src/web/exchange_token_options.dart Introduces ExchangeTokenOptions model for web token exchange (subject token, audience, scopes, organization).
auth0_flutter_platform_interface/lib/src/web-auth/web_auth_logout_options.dart Adds allowedBrowsers list to logout options and includes it in toMap.
auth0_flutter_platform_interface/lib/src/method_channel_auth0_flutter_auth.dart Wires auth#customTokenExchange constant and implements method-channel call returning Credentials.
auth0_flutter_platform_interface/lib/src/auth0_flutter_web_platform.dart Extends web platform interface with customTokenExchange(ExchangeTokenOptions).
auth0_flutter_platform_interface/lib/src/auth0_flutter_auth_platform.dart Extends auth platform interface with customTokenExchange(ApiRequest<AuthCustomTokenExchangeOptions>).
auth0_flutter_platform_interface/lib/src/auth/auth_custom_token_exchange_options.dart Adds AuthCustomTokenExchangeOptions (subject token/type, optional audience, scopes, organization) with toMap for method channel.
auth0_flutter_platform_interface/lib/auth0_flutter_platform_interface.dart Exports the new auth and web option types so they are part of the public platform interface.
auth0_flutter_platform_interface/CHANGELOG.md Documents afpi-v2.0.0-beta.2 with custom token exchange and logout allowedBrowsers.
auth0_flutter/windows/windows_utils.h Declares Windows helpers for wide-string to UTF‑8, window focus, and debug logging.
auth0_flutter/windows/windows_utils.cpp Implements wide→UTF‑8 conversion, window foreground activation, and debug printing for Windows.
auth0_flutter/windows/vcpkg.json Declares vcpkg dependencies (cpprestsdk, OpenSSL, Boost) for the Windows plugin.
auth0_flutter/windows/user_profile.h Defines a UserProfile model with identities, metadata maps, and serialization helpers.
auth0_flutter/windows/user_profile.cpp Implements UserProfile deserialization from EncodableMap, custom-claims extraction, and ID resolution.
auth0_flutter/windows/user_identity.h Declares UserIdentity model with JSON/encodable conversions.
auth0_flutter/windows/user_identity.cpp Implements JSON and Flutter-encodable conversions for user identity, including profile data.
auth0_flutter/windows/url_utils.h Declares URL decoding utilities and safe query parsing for Windows.
auth0_flutter/windows/url_utils.cpp Implements URL percent-decoding and query-string parsing into key/value maps.
auth0_flutter/windows/token_decoder.h Declares DecodeTokenResponse to convert token JSON into Credentials.
auth0_flutter/windows/token_decoder.cpp Implements parsing of OAuth token JSON into Credentials, including expiry and scope parsing.
auth0_flutter/windows/time_util.h Declares ISO‑8601 parse/format helpers for system_clock::time_point.
auth0_flutter/windows/time_util.cpp Implements ISO‑8601 parsing/formatting (UTC) for token expiry handling.
auth0_flutter/windows/test/windows_utils_test.cpp Adds GTest coverage for WideToUtf8, BringFlutterWindowToFront, and DebugPrint.
auth0_flutter/windows/test/user_profile_test.cpp Adds tests for UserProfile deserialization, mapping, custom claims, and ID resolution.
auth0_flutter/windows/test/user_identity_test.cpp Tests UserIdentity JSON/encodable conversions and round‑trip behavior.
auth0_flutter/windows/test/url_utils_test.cpp Tests UrlDecode and SafeParseQuery over multiple edge cases.
auth0_flutter/windows/test/token_decoder_test.cpp Tests DecodeTokenResponse parsing, expiry logic, scope handling, and error conditions.
auth0_flutter/windows/test/time_util_test.cpp Tests ISO‑8601 time parsing/formatting and round‑trip consistency.
auth0_flutter/windows/test/oauth_helpers_test.cpp Covers PKCE helpers and basic behavior of auth-code wait functions.
auth0_flutter/windows/test/jwt_util_test.cpp Tests JWT splitting, payload decoding, JSON→Encodable conversions.
auth0_flutter/windows/request_handlers/web_auth/WebAuthRequestHandler.h Defines abstract base for Windows WebAuth request handlers (login/logout).
auth0_flutter/windows/request_handlers/web_auth/LogoutWebAuthRequestHandler.h Declares Windows logout handler for webAuth#logout.
auth0_flutter/windows/request_handlers/web_auth/LogoutWebAuthRequestHandler.cpp Implements Windows logout flow (builds logout URL, opens browser) for webAuth#logout.
auth0_flutter/windows/request_handlers/web_auth/LoginWebAuthRequestHandler.h Declares Windows login handler for webAuth#login using PKCE.
auth0_flutter/windows/request_handlers/web_auth/LoginWebAuthRequestHandler.cpp Implements full Windows PKCE login flow (build auth URL, open browser, wait for code, exchange tokens, return credentials).
auth0_flutter/windows/oauth_helpers.h Declares PKCE helpers, base64url encoding, and auth-code wait utilities.
auth0_flutter/windows/oauth_helpers.cpp Implements PKCE code verifier/challenge, URL parsing, and callback wait logic for Windows.
auth0_flutter/windows/jwt_util.h Declares JWT splitting/payload decode and JSON→Encodable utilities.
auth0_flutter/windows/jwt_util.cpp Implements base64url decoding, JWT payload parsing, and JSON→Encodable conversion.
auth0_flutter/windows/include/auth0_flutter/auth0_flutter_plugin_c_api.h Declares the C API entrypoint to register the Windows plugin with Flutter.
auth0_flutter/windows/credentials.h Defines a simple Credentials struct used on the Windows side.
auth0_flutter/windows/auth0_flutter_plugin_c_api.cpp Bridges Flutter’s C registrar API to the C++ Auth0FlutterPlugin.
auth0_flutter/windows/auth0_flutter_plugin.h Declares main Windows plugin class and method-call handling.
auth0_flutter/windows/auth0_flutter_plugin.cpp Implements Windows plugin registration and WebAuth method routing via handler objects.
auth0_flutter/windows/auth0_client.h Declares Auth0Client for token exchange HTTP calls.
auth0_flutter/windows/auth0_client.cpp Implements Auth0Client::ExchangeCodeForTokens using cpprestsdk and DecodeTokenResponse.
auth0_flutter/windows/CMakeLists.txt Adds Windows plugin build, links vcpkg deps, and defines a GTest-based unit-test binary with coverage targets.
auth0_flutter/windows/Auth0FlutterWebAuthMethodCallHandler.h Declares router that dispatches WebAuth method calls to specific handlers.
auth0_flutter/windows/Auth0FlutterWebAuthMethodCallHandler.cpp Implements method-name based dispatch for Windows WebAuth handlers.
auth0_flutter/windows/.vs/windows/v17/DocumentLayout.json Adds Visual Studio workspace layout metadata (IDE state) under the Windows plugin.
auth0_flutter/windows/.vs/VSWorkspaceState.json Adds VS workspace state metadata file for the Windows plugin.
auth0_flutter/windows/.vs/ProjectSettings.json Adds VS project settings metadata for the Windows plugin.
auth0_flutter/windows/.gitignore Adds a Windows-local .gitignore for build outputs and VS cache files.
auth0_flutter/test/web/extensions/exchange_token_options_extension_test.dart Tests web ExchangeTokenOptions → JS interop conversion, including scopes and organization.
auth0_flutter/test/web/auth0_flutter_web_test.mocks.dart Extends web client mock to support exchangeToken(ExchangeTokenOptions).
auth0_flutter/test/web/auth0_flutter_web_test.dart Adds customTokenExchange tests for web: parameter mapping, error handling, and credentials conversion.
auth0_flutter/test/mobile/web_authentication_test.dart Adds mobile tests ensuring allowedBrowsers is passed or defaulted correctly on logout.
auth0_flutter/pubspec.yaml Bumps main package version to 2.0.0-beta.2, updates platform-interface dependency, and declares Windows plugin entry.
auth0_flutter/macos/auth0_flutter.podspec Bumps macOS pod version to 2.0.0-beta.2 and updates Auth0 native SDK to 2.16.2.
auth0_flutter/macos/Classes/AuthAPI/AuthAPICustomTokenExchangeMethodHandler.swift Forwards to shared darwin implementation for custom token exchange.
auth0_flutter/lib/src/web/js_interop.dart Adds JS interop type for token exchange options and Auth0Client.exchangeToken.
auth0_flutter/lib/src/web/extensions/exchange_token_options_extension.dart Maps platform ExchangeTokenOptions to JS interop type, handling optional audience/scopes/organization.
auth0_flutter/lib/src/web/auth0_flutter_web_platform_proxy.dart Extends web client proxy with exchangeToken wrapper.
auth0_flutter/lib/src/web/auth0_flutter_plugin_real.dart Implements web customTokenExchange using interop client and maps errors to WebException.
auth0_flutter/lib/src/version.dart Updates SDK version constant to 2.0.0-beta.2.
auth0_flutter/lib/src/mobile/web_authentication.dart Refactors formatting and adds allowedBrowsers parameter to mobile logout, threading through to platform.
auth0_flutter/lib/src/mobile/authentication_api.dart Adds customTokenExchange API on mobile, constructing AuthCustomTokenExchangeOptions and invoking platform.
auth0_flutter/lib/auth0_flutter_web.dart Adds high-level web customTokenExchange API with detailed documentation.
auth0_flutter/ios/auth0_flutter.podspec Bumps iOS pod version to 2.0.0-beta.2 and updates Auth0 native SDK to 2.16.2.
auth0_flutter/ios/Classes/AuthAPI/AuthAPICustomTokenExchangeMethodHandler.swift Forwards to shared darwin implementation for custom token exchange.
auth0_flutter/example/windows/runner/main.cpp Adds single-instance/deep-link handling via mutex and named pipe for Windows example, wiring PLUGIN_STARTUP_URL.
auth0_flutter/example/windows/runner/flutter_window.cpp Forces a redraw after plugin initialization to ensure window shows first Flutter frame.
auth0_flutter/example/windows/runner/.vs/runner/v17/DocumentLayout.json Adds VS runner workspace layout metadata (IDE state).
auth0_flutter/example/windows/runner/.vs/runner/v17/.wsuo Adds VS runner binary workspace settings.
auth0_flutter/example/windows/runner/.vs/VSWorkspaceState.json Adds VS workspace state metadata for runner.
auth0_flutter/example/windows/runner/.vs/ProjectSettings.json Adds VS project settings metadata for runner.
auth0_flutter/example/windows/flutter/generated_plugins.cmake Registers auth0_flutter as a plugin for the Windows example build.
auth0_flutter/example/windows/flutter/generated_plugin_registrant.cc Registers the Auth0 Windows plugin C API with the example app.
auth0_flutter/example/windows/flutter/CMakeLists.txt Adds FLUTTER_TARGET_PLATFORM fallback and uses it when invoking the Flutter tool backend.
auth0_flutter/example/ios/Tests/AuthAPI/AuthAPIHandlerTests.swift Extends handler-dispatch tests to include customTokenExchange method handler.
auth0_flutter/example/ios/Tests/AuthAPI/AuthAPICustomTokenExchangeMethodHandlerTests.swift New iOS unit tests for Auth API custom token exchange handler (arguments, success, options, errors).
auth0_flutter/example/android/app/src/main/res/values/strings.xml.example Switches Android example to use {DOMAIN}/{SCHEME} placeholders for Auth0 config.
auth0_flutter/example/android/app/build.gradle Uses string resources for manifest placeholders (auth0Domain/auth0Scheme) in Android example.
auth0_flutter/example/.env.example Keeps example .env template aligned (minor formatting tweak).
auth0_flutter/darwin/auth0_flutter.podspec Bumps shared darwin pod to 2.0.0-beta.2 and Auth0 native SDK to 2.16.2.
auth0_flutter/darwin/Classes/AuthAPI/AuthAPIHandler.swift Wires auth#customTokenExchange to new darwin method handler.
auth0_flutter/darwin/Classes/AuthAPI/AuthAPICustomTokenExchangeMethodHandler.swift Implements darwin custom token exchange handler, mapping arguments to Auth0 SDK and returning credentials.
auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/request_handlers/api/CustomTokenExchangeApiRequestHandlerTest.kt Adds Android unit tests for custom token exchange handler (args, audience, scopes, org, errors, method name).
auth0_flutter/android/src/test/kotlin/com/auth0/auth0_flutter/LogoutWebAuthRequestHandlerTest.kt Extends logout handler tests to cover allowedBrowsers mapping into CustomTabsOptions.
auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/web_auth/LogoutWebAuthRequestHandler.kt Adds allowedBrowsers handling via CustomTabsOptions/BrowserPicker for Android logout.
auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/request_handlers/api/CustomTokenExchangeApiRequestHandler.kt Implements Android custom token exchange handler, mapping options and returning credential map.
auth0_flutter/android/src/main/kotlin/com/auth0/auth0_flutter/Auth0FlutterPlugin.kt Registers CustomTokenExchangeApiRequestHandler in the Android plugin.
auth0_flutter/android/build.gradle Bumps Auth0 Android SDK dependency to 3.12.0.
auth0_flutter/EXAMPLES.md Adds documentation and sample code for custom token exchange usage on mobile and web.
auth0_flutter/CHANGELOG.md Adds af-v2.0.0-beta.2 entry highlighting custom token exchange and allowedBrowsers support.
auth0_flutter/.metadata Updates Flutter metadata (revision/channel and migration entries, including Windows platform).
appium-test/package-lock.json Updates lodash dev dependency from 4.17.21 to 4.17.23.
.vscode/settings.json Adds VS Code C++ file association settings for standard headers.
.github/workflows/main.yml Adds test-windows-unit job and integrates Windows coverage into the CI matrix.
.github/actions/setup-darwin/action.yml Updates ruby/setup-ruby action version pin.
.claude/settings.local.json Adds local settings file for a tooling integration (bash permission for grep).
Files not reviewed (1)
  • appium-test/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +159 to +167
func customTokenExchange(subjectToken: String,
subjectTokenType: String,
audience: String?,
scope: String?,
organization: String?) -> Request<Credentials, AuthenticationError> {
return onCustomTokenExchange?(subjectToken, subjectTokenType, audience, scope, organization) ?? request()
}
} }
}
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

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

There are extra closing braces at the end of this file (} } followed by another }), which makes the extension and/or file syntactically invalid and will cause the tests not to compile. Please fix the brace structure so the SpyAuthentication extension and enclosing scopes are closed exactly once.

Suggested change
func customTokenExchange(subjectToken: String,
subjectTokenType: String,
audience: String?,
scope: String?,
organization: String?) -> Request<Credentials, AuthenticationError> {
return onCustomTokenExchange?(subjectToken, subjectTokenType, audience, scope, organization) ?? request()
}
} }
}
func customTokenExchange(subjectToken: String,
subjectTokenType: String,
audience: String?,
scope: String?,
organization: String?) -> Request<Credentials, AuthenticationError> {
return onCustomTokenExchange?(subjectToken, subjectTokenType, audience, scope, organization) ?? request()
}
}

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

@NandanPrabhu could you please pull the latest main changes into this PR

Comment on lines +1 to +8
{
"Version": 1,
"WorkspaceRootPath": "C:\\Users\\Administrator\\Documents\\auth0-flutter\\auth0_flutter\\windows\\",
"Documents": [],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

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

This Visual Studio workspace file contains user- and machine-specific IDE state (including absolute local paths) and should not be committed to source control. Please remove it from the repo and add the .vs/ directory under auth0_flutter/windows to .gitignore to avoid re-introducing it.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +3
{
"CurrentProjectSetting": "x64-Debug"
} No newline at end of file
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

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

ProjectSettings.json under .vs is a Visual Studio user configuration file and should not be versioned with the plugin sources. Please remove it and ensure the .vs/ directory is ignored by Git for this Windows project.

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +31
guard let scopes = arguments[Argument.scopes] as? [String], !scopes.isEmpty else {
return callback(FlutterError(from: .requiredArgumentMissing(Argument.scopes.rawValue)))
}

let scope = scopes.asSpaceSeparatedString
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

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

AuthAPICustomTokenExchangeMethodHandler requires scopes to be present and non-empty, which makes scopes effectively mandatory on iOS/macOS while Android and Web treat it as optional (empty list just omits the scope parameter). This cross-platform inconsistency can cause identical Dart calls (especially if a caller intentionally passes an empty set) to succeed on some platforms and fail with requiredArgumentMissing on others. To align behaviour, consider treating scopes as optional here (accepting a missing or empty list and only building a scope string when non-empty), matching the Android handler and web implementation.

Suggested change
guard let scopes = arguments[Argument.scopes] as? [String], !scopes.isEmpty else {
return callback(FlutterError(from: .requiredArgumentMissing(Argument.scopes.rawValue)))
}
let scope = scopes.asSpaceSeparatedString
let scopes = arguments[Argument.scopes] as? [String]
let scope = (scopes?.isEmpty == false) ? scopes!.asSpaceSeparatedString : nil

Copilot uses AI. Check for mistakes.
let authError = AuthenticationError(
info: ["error": "invalid_grant", "error_description": "Invalid token"]
)
spy.onCustomTokenExchange = { _, _, _, _ in
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

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

The closure assigned to spy.onCustomTokenExchange here takes four parameters, but the onCustomTokenExchange function type is defined with five parameters. This will not compile and should be updated so the closure’s parameter list matches the onCustomTokenExchange signature.

Suggested change
spy.onCustomTokenExchange = { _, _, _, _ in
spy.onCustomTokenExchange = { _, _, _, _, _ in

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +11
{
"OutputFoldersPerTargetSystem": {
"Local Machine": [
"out\\build\\x64-Debug",
"out\\install\\x64-Debug"
]
},
"ExpandedNodes": [
""
],
"PreviewInSolutionExplorer": false
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

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

This VS workspace state file is environment-specific metadata and doesn’t belong in the tracked source. Consider deleting it and adding the containing .vs/ directory to .gitignore so these files are not checked in.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +11
{
"Version": 1,
"WorkspaceRootPath": "C:\\Users\\Administrator\\Documents\\auth0-flutter\\auth0_flutter\\example\\windows\\runner\\",
"Documents": [],
"DocumentGroupContainers": [
{
"Orientation": 0,
"VerticalTabListWidth": 256,
"DocumentGroups": []
}
]
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

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

This Visual Studio runner workspace layout file is user- and machine-specific and should not be part of the example app’s committed sources. Please delete it and add the example/windows/runner/.vs/ directory to .gitignore to prevent future commits of these artifacts.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +12
{
"OutputFoldersPerTargetSystem": {
"Local Machine": [
"out\\build\\x64-Debug",
"out\\install\\x64-Debug"
]
},
"ExpandedNodes": [
""
],
"PreviewInSolutionExplorer": false
} No newline at end of file
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

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

This example runner VSWorkspaceState.json contains local IDE state (output folders, expanded nodes, etc.) and should not live in the repository. Please drop this file and add the surrounding .vs/ directory to .gitignore to keep Visual Studio metadata out of source control.

Suggested change
{
"OutputFoldersPerTargetSystem": {
"Local Machine": [
"out\\build\\x64-Debug",
"out\\install\\x64-Debug"
]
},
"ExpandedNodes": [
""
],
"PreviewInSolutionExplorer": false
}
{}

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,3 @@
{
"CurrentProjectSetting": "x64-Debug"
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

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

ProjectSettings.json under the example runner’s .vs folder is a per-developer Visual Studio configuration file and should not be checked in. Consider removing it and ignoring example/windows/runner/.vs/ so these settings aren’t versioned.

Suggested change
"CurrentProjectSetting": "x64-Debug"

Copilot uses AI. Check for mistakes.
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.

5 participants