Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a10f01f
windows support added
NandanPrabhu Aug 17, 2025
ce3967c
windows support added
NandanPrabhu Aug 17, 2025
50ebfae
windows support added
NandanPrabhu Aug 17, 2025
f2d0866
windows support fixes build issue due to dependencies
NandanPrabhu Aug 21, 2025
c4c896d
fixes redirection issues
NandanPrabhu Sep 7, 2025
9b6d647
.env.example added
NandanPrabhu Sep 8, 2025
1213893
Merge branch 'main' into SDK-6071
NandanPrabhu Dec 7, 2025
c3f7dbb
Adds PKCE flow
NandanPrabhu Dec 17, 2025
1380f56
PKCE bug fixes
NandanPrabhu Dec 19, 2025
e6e936e
code refactoring
NandanPrabhu Dec 19, 2025
ccf541b
fixes build issues
NandanPrabhu Dec 21, 2025
46f28b5
Fixes issue due to expires in
NandanPrabhu Dec 21, 2025
95310b6
Fixes PKCE issues
NandanPrabhu Jan 3, 2026
d199d28
adds logout code
NandanPrabhu Jan 5, 2026
8699d4e
adds login to bring app window to the front on redirection
NandanPrabhu Jan 8, 2026
f870e5e
deleted few unused files
NandanPrabhu Jan 8, 2026
6fa485f
Add unit test and CI setup
NandanPrabhu Jan 20, 2026
052648a
Resolves PR comments - adds uniform naming convention to files - perc…
NandanPrabhu Jan 20, 2026
408b69a
- Added Id token signature validator fixes - Default redirect_uri sam…
NandanPrabhu Feb 21, 2026
40cc44a
uses pplx::task + tokeninstead of detach() for thread safety and back…
NandanPrabhu Feb 26, 2026
b914557
id token validation azp validation added
NandanPrabhu Mar 6, 2026
1f318f7
Merge branch 'main' into SDK-6071
NandanPrabhu Mar 7, 2026
6749217
scope calculation logicrefactored to support default scopes
NandanPrabhu Mar 9, 2026
c1c816f
fixes tests
NandanPrabhu Mar 9, 2026
3dbafa2
adds flutter_encodable_value stub
NandanPrabhu Mar 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 83 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,74 @@ jobs:
name: Test results
path: 'auth0_flutter/example/build/app/reports/androidTests/*.xml'

test-windows-unit:
name: Run native Windows unit tests
runs-on: windows-latest
environment: ${{ github.event.pull_request.head.repo.fork && 'external' || 'internal' }}

steps:
- name: Checkout
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3

- name: Install Flutter
uses: subosito/flutter-action@fd55f4c5af5b953cc57a2be44cb082c8f6635e8e # pin@v2.21.0
with:
flutter-version: ${{ env.flutter }}
channel: stable
cache: true

- name: Add example/.env
working-directory: auth0_flutter
run: Copy-Item example/.env.example example/.env
shell: powershell

- name: Set up vcpkg
uses: lukka/run-vcpkg@5e0cab206a5ea620130caf672fce3e4a6b5666a1 # pin@v11.5
with:
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
vcpkgGitCommitId: '66c0373dc7fca549e5803087b9487edfe3aca0a1'

- name: Install vcpkg dependencies
run: |
${{ github.workspace }}\vcpkg\vcpkg install cpprestsdk:x64-windows openssl:x64-windows boost-system:x64-windows boost-date-time:x64-windows boost-regex:x64-windows
shell: cmd

- name: Build Windows example app
working-directory: auth0_flutter/example
run: flutter build windows --debug
env:
CMAKE_TOOLCHAIN_FILE: ${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake

- name: Install OpenCppCoverage
run: |
choco install opencppcoverage
echo "C:\Program Files\OpenCppCoverage" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
shell: powershell

- name: Build Windows unit tests
working-directory: auth0_flutter/windows
run: |
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake -DAUTH0_FLUTTER_ENABLE_TESTS=ON -DCMAKE_BUILD_TYPE=Debug
cmake --build build --config Debug
shell: cmd

- name: Run Windows unit tests with coverage
working-directory: auth0_flutter/windows
run: |
& "C:\Program Files\OpenCppCoverage\OpenCppCoverage.exe" `
--sources ${{ github.workspace }}\auth0_flutter\windows `
--excluded_sources ${{ github.workspace }}\auth0_flutter\windows\test `
--export_type cobertura:coverage.xml `
--export_type html:coverage_html `
-- .\build\Debug\auth0_flutter_tests.exe
shell: powershell

- name: Upload coverage report
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # pin@v6
with:
name: Windows coverage
path: auth0_flutter/windows/coverage.xml

# test-android-smoke:
# name: Run native Android smoke tests using API-level ${{ matrix.android-api }}
# runs-on: macos-latest-xl
Expand Down Expand Up @@ -419,7 +487,8 @@ jobs:
test-auth0_flutter,
test-auth0_flutter_platform_interface,
test-ios-unit,
test-android-unit
test-android-unit,
test-windows-unit
]

steps:
Expand Down Expand Up @@ -450,6 +519,12 @@ jobs:
name: Android coverage
path: coverage/android

- name: Download coverage report for Windows
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
with:
name: Windows coverage
path: coverage/windows

- name: Upload coverage report for auth0_flutter
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de
with:
Expand Down Expand Up @@ -477,3 +552,10 @@ jobs:
name: Auth0 Flutter
flags: auth0_flutter_android
directory: coverage/android

- name: Upload coverage report for Windows
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de
with:
name: Auth0 Flutter
flags: auth0_flutter_windows
directory: coverage/windows
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# Global coverage
coverage/
**/.vs/

appium-test/node_modules/*

Expand Down
3 changes: 0 additions & 3 deletions .idea/.gitignore

This file was deleted.

32 changes: 0 additions & 32 deletions .idea/auth0-flutter.iml

This file was deleted.

8 changes: 0 additions & 8 deletions .idea/modules.xml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/vcs.xml

This file was deleted.

1 change: 1 addition & 0 deletions auth0_flutter/.metadata
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ version:
channel: stable

project_type: plugin

134 changes: 121 additions & 13 deletions auth0_flutter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ We're excited to announce the release of auth0_flutter v2.0.0!

### Requirements

| Flutter | Android | iOS | macOS |
| :---------- | :-------------- | :---------------- | :---------------- |
| SDK 3.24.0+ | Android API 21+ | iOS 14+ | macOS 11+ |
| Dart 3.5.0+ | Java 8+ | Swift 5.9+ | Swift 5.9+ |
| | | Xcode 15.x / 16.x | Xcode 15.x / 16.x |
| Flutter | Android | iOS | macOS | Windows |
| :---------- | :-------------- | :---------------- | :---------------- | :------------------------------- |
| SDK 3.24.0+ | Android API 21+ | iOS 14+ | macOS 11+ | Windows 10+ |
| Dart 3.5.0+ | Java 8+ | Swift 5.9+ | Swift 5.9+ | C++ 17, Visual Studio 2022 |
| | | Xcode 15.x / 16.x | Xcode 15.x / 16.x | vcpkg (for dependencies) |

### Installation

Expand Down Expand Up @@ -77,6 +77,7 @@ Under the **Application URIs** section of the **Settings** page, configure the f
- Android: `SCHEME://YOUR_DOMAIN/android/YOUR_PACKAGE_NAME/callback`
- iOS: `https://YOUR_DOMAIN/ios/YOUR_BUNDLE_ID/callback,YOUR_BUNDLE_ID://YOUR_DOMAIN/ios/YOUR_BUNDLE_ID/callback`
- macOS: `https://YOUR_DOMAIN/macos/YOUR_BUNDLE_ID/callback,YOUR_BUNDLE_ID://YOUR_DOMAIN/macos/YOUR_BUNDLE_ID/callback`
- Windows: `auth0flutter://callback` (direct, no server) **or** `https://YOUR_HOSTED_DOMAIN/callback` (intermediary server β€” see below)

<details>
<summary>Example</summary>
Expand All @@ -86,11 +87,42 @@ If your Auth0 domain was `company.us.auth0.com` and your package name (Android)
- Android: `https://company.us.auth0.com/android/com.company.myapp/callback`
- iOS: `https://company.us.auth0.com/ios/com.company.myapp/callback,com.company.myapp://company.us.auth0.com/ios/com.company.myapp/callback`
- macOS: `https://company.us.auth0.com/macos/com.company.myapp/callback,com.company.myapp://company.us.auth0.com/macos/com.company.myapp/callback`
- Windows (direct): `auth0flutter://callback`
- Windows (intermediary server): `https://your-app.example.com/callback`

</details>

> πŸ’‘ **Windows**: The Windows plugin always listens for the callback on the `auth0flutter://callback` custom scheme. You have two options for the **Allowed Callback URL** you register in the Auth0 dashboard:
>
> - **Direct (recommended for most apps):** Register `auth0flutter://callback` directly. Auth0 redirects straight to the custom scheme and the plugin picks it up immediately. The browser may leave a blank or protocol-handler tab open after the redirect, but authentication completes successfully.
>
> - **Intermediary server (better browser UX):** Register an HTTPS URL on a server you control (e.g. `https://your-app.example.com/callback`). Auth0 redirects to that server, which in turn redirects to `auth0flutter://callback`. This lets the server show a "Returning you to the app…" page and close cleanly, avoiding any hanging browser tab. The trade-off is that you must host and maintain the server endpoint.

Take note of the **client ID** and **domain** values under the **Basic Information** section. You'll need these values in the next step.

##### Security Considerations for Custom URL Schemes

> ⚠️ **Important Security Information**
>
> Custom URL schemes (nonverifiable callback URIs) can be vulnerable to **app impersonation attacks**, where malicious apps could potentially intercept OAuth authorization codes by registering the same custom scheme on a device.
>
> **Recommended Best Practices:**
>
> - **Use HTTPS-based schemes whenever possible:**
> - iOS 17.4+ / macOS 14.4+: Use Universal Links
> - Android: Use Android App Links with HTTPS schemes
> - These verifiable schemes cryptographically bind your app to your domain, preventing impersonation
>
> - **If you must use custom URL schemes:**
> - Implement additional security measures such as PKCE (Proof Key for Code Exchange), which is automatically enabled in this SDK
> - Consider using short-lived authorization codes
> - Implement additional client-side validation
> - Be aware that custom schemes offer no protection against malicious apps on the same device
>
> - **For Windows applications:** The `auth0flutter://` custom scheme is required. When using the direct pattern, PKCE (automatically enabled) is your primary protection. When using the intermediary server pattern, also ensure the server endpoint validates the `state` parameter and uses HTTPS
>
> πŸ“– For more details about app impersonation risks and mitigation strategies, see [Auth0's Security Guidance: Measures Against App Impersonation](https://auth0.com/docs/secure/security-guidance/measures-against-app-impersonation)

#### 🌐 Web

Head to the [Auth0 Dashboard](https://manage.auth0.com/#/applications/) and create a new **Single Page** application.
Expand Down Expand Up @@ -127,7 +159,7 @@ Take note of the **client ID** and **domain** values under the **Basic Informati

### Configure the SDK

#### πŸ“± Mobile/macOS
#### πŸ“± Mobile/macOS/Windows

Start by importing `auth0_flutter/auth0_flutter.dart`.

Expand Down Expand Up @@ -247,6 +279,69 @@ If you have aΒ [custom domain](https://auth0.com/docs/customize/custom-domains),

> ⚠️ For the associated domain to work, your app must be signed with your team certificate **even when building for the iOS simulator**. Make sure you are using the Apple Team whose Team ID is configured in the **Settings** page of your application.

##### Windows: Configure protocol handler

The `auth0flutter://` protocol is automatically registered when your app is installed. The Flutter Windows plugin receives the callback by listening for `auth0flutter://callback` activations via the `PLUGIN_STARTUP_URL` environment variable β€” no extra app-side code is required.

You have two options for how Auth0 delivers the callback to your app:

---

###### Option A β€” Direct custom-scheme redirect (recommended)

Register `auth0flutter://callback` directly as the callback URL in your Auth0 dashboard:

- **Allowed Callback URLs**: `auth0flutter://callback`
- **Allowed Logout URLs**: `auth0flutter://callback`

Then call `login` with the same URL:

```dart
final credentials = await auth0.windowsWebAuthentication().login(
redirectUrl: 'auth0flutter://callback',
);
```

Auth0 redirects straight to the custom scheme. The Windows OS hands the URL to your app and authentication completes immediately. The browser may leave a blank or protocol-handler tab open afterwards β€” this is a browser behaviour, not an error, and does not affect the login result.

---

###### Option B β€” Intermediary server redirect (better browser UX)

If leaving a blank tab open is unacceptable for your users, you can route the callback through a lightweight HTTPS server you control. The server receives the Auth0 redirect and immediately redirects onward to `auth0flutter://callback`, giving it the opportunity to show a clean "Returning you to the app…" page before the tab closes.

Register your server endpoint in the Auth0 dashboard:

- **Allowed Callback URLs**: `https://your-app.example.com/callback`
- **Allowed Logout URLs**: `https://your-app.example.com/logout`

Pass the server URL to `login`:

```dart
final credentials = await auth0.windowsWebAuthentication().login(
redirectUrl: 'https://your-app.example.com/callback',
);
```

Minimal server implementation (Node.js/Express):

```javascript
app.get('/callback', (req, res) => {
const { code, state, error, error_description } = req.query;
if (error) {
res.redirect(`auth0flutter://callback?error=${error}&error_description=${encodeURIComponent(error_description)}`);
} else {
res.redirect(`auth0flutter://callback?code=${code}&state=${state}`);
}
});
```

> ⚠️ Validate the `state` parameter on your server before forwarding to `auth0flutter://callback` to prevent open-redirect abuse. The SDK also validates `state` client-side as part of PKCE, but defence-in-depth is recommended.

---

Both options use PKCE automatically β€” no additional configuration is required for security.

#### 🌐 Web

Start by importing `auth0_flutter/auth0_flutter_web.dart`.
Expand All @@ -271,24 +366,26 @@ Finally, in your `index.html` add the following `<script>` tag:

### Logging in

#### πŸ“± Mobile/macOS
#### πŸ“± Mobile/macOS/Windows

Present the [Universal Login](https://auth0.com/docs/authenticate/login/auth0-universal-login) page in the `onPressed` callback of your **Login** button.

```dart
// Use a Universal Link callback URL on iOS 17.4+ / macOS 14.4+
// useHTTPS is ignored on Android
// useHTTPS is ignored on Android and Windows
final credentials = await auth0.webAuthentication().login(useHTTPS: true);

// Access token -> credentials.accessToken
// User profile -> credentials.user
```

auth0_flutter automatically stores the user's credentials using the built-in [Credentials Manager](#credentials-manager) instance. You can access this instance through the `credentialsManager` property.
**Credential Storage:**
- **Mobile/macOS**: auth0_flutter automatically stores the user's credentials using the built-in [Credentials Manager](#credentials-manager) instance. You can access this instance through the `credentialsManager` property:
```dart
final credentials = await auth0.credentialsManager.credentials();
```

```dart
final credentials = await auth0.credentialsManager.credentials();
```
- **Windows**: Credentials are **not** automatically stored. You must manually store and manage the `credentials` object returned from `login()` in your app (e.g., using `shared_preferences` or secure storage)

For other comprehensive examples, see the [EXAMPLES.md](EXAMPLES.md) document.

Expand Down Expand Up @@ -408,19 +505,28 @@ Check the [FAQ](FAQ.md) for more information about the alert box that pops up **
- [Retrieve user information](EXAMPLES.md#retrieve-user-information) - fetch the latest user information from the `/userinfo` endpoint.
- [Native to Web SSO](EXAMPLES.md#native-to-web-sso) - obtain a session transfer token to authenticate a WebView without re-prompting the user.

### πŸͺŸ Windows

- **Custom Protocol Handler**: Windows uses the `auth0flutter://` custom scheme. Auth0 can redirect to it directly (no server needed) or via an intermediary HTTPS server for a cleaner browser UX β€” see the [Windows configuration section](#windows-configure-protocol-handler) above
- **No Credentials Manager**: Credential storage is not currently supported on Windows. Credentials must be managed manually in your app
- **C++ SDK**: The Windows implementation is built with native C++ using PKCE for secure authentication
- **Unit Tests**: Comprehensive unit tests for Windows OAuth helpers are available in `windows/test/`

### 🌐 Web

- [Handling credentials on the web](EXAMPLES.md#handling-credentials-on-the-web) - how to check and retrieve credentials on the web platform.

## API reference

### πŸ“± Mobile/macOS
### πŸ“± Mobile/macOS/Windows

#### Web Authentication

- [login](https://pub.dev/documentation/auth0_flutter/latest/auth0_flutter/WebAuthentication/login.html)
- [logout](https://pub.dev/documentation/auth0_flutter/latest/auth0_flutter/WebAuthentication/logout.html)

> πŸ’‘ **Windows**: Web Authentication on Windows uses the `auth0flutter://` custom scheme. Auth0 can redirect to it directly (simplest setup) or via an intermediary HTTPS server (avoids a hanging browser tab). See the [Windows configuration section](#windows-configure-protocol-handler) above for both options.

#### API

- [login](https://pub.dev/documentation/auth0_flutter/latest/auth0_flutter/AuthenticationApi/login.html)
Expand All @@ -433,6 +539,8 @@ Check the [FAQ](FAQ.md) for more information about the alert box that pops up **

#### Credentials Manager

> ⚠️ **Note**: Credentials Manager is available on Mobile (Android/iOS) and macOS platforms only. Windows does not currently support credential storage. On Windows, you must manually manage credentials returned from `login()`.

- [credentials](https://pub.dev/documentation/auth0_flutter/latest/auth0_flutter/DefaultCredentialsManager/credentials.html)
- [hasValidCredentials](https://pub.dev/documentation/auth0_flutter/latest/auth0_flutter/DefaultCredentialsManager/hasValidCredentials.html)
- [storeCredentials](https://pub.dev/documentation/auth0_flutter/latest/auth0_flutter/DefaultCredentialsManager/storeCredentials.html)
Expand Down
Loading
Loading