Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
82 changes: 81 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,72 @@ 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@v11 # pin@v11
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
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@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 +485,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 +517,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 +550,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

96 changes: 88 additions & 8 deletions auth0_flutter/README.md
Original file line number Diff line number Diff line change
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: `https://YOUR_HOSTED_DOMAIN/callback` (or your custom callback URL on your intermediary server)
Copy link
Contributor

@pmathew92 pmathew92 Feb 12, 2026

Choose a reason for hiding this comment

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

Should we mention the callback url here as this is a workaround we suggest for users. This should be mentioned in the example code . For windows by default we have the flutterapp://calback uri defined


<details>
<summary>Example</summary>
Expand All @@ -86,11 +87,37 @@ 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: `https://your-app.example.com/callback` (your intermediary server endpoint)

</details>

> πŸ’‘ **Windows**: The Windows implementation uses a custom scheme callback architecture (`auth0flutter://callback`). This requires an intermediary server to receive the Auth0 callback and forward it to your Windows app via the custom protocol. The intermediary server URL (e.g., `https://your-app.example.com/callback`) should be configured as the callback URL in your Auth0 dashboard. The server should handle the Auth0 redirect and trigger the `auth0flutter://` protocol to activate your app with the authorization code and state parameters.

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:** Custom schemes are currently required due to platform limitations. Ensure your intermediary server validates requests and uses secure communication
>
> πŸ“– 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 +154,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 +274,46 @@ 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 and intermediary server

Windows authentication requires two components:

1. **Custom Protocol Handler**: Your Windows app needs to register the `auth0flutter://` protocol handler
2. **Intermediary Server**: A hosted server that receives the Auth0 callback and forwards it to your app

**Step 1: Register the custom protocol handler**

The `auth0flutter://` protocol should be automatically registered when your app is installed. The Flutter Windows plugin handles protocol activation through the `PLUGIN_STARTUP_URL` environment variable.

**Step 2: Set up your intermediary server**

Create a web endpoint (e.g., `https://your-app.example.com/callback`) that:
1. Receives the Auth0 callback with `code` and `state` parameters
2. Redirects to `auth0flutter://callback?code=...&state=...`

Example server implementation:

```javascript
// Node.js/Express example
app.get('/callback', (req, res) => {
const { code, state, error, error_description } = req.query;

if (error) {
res.redirect(`auth0flutter://callback?error=${error}&error_description=${error_description}`);
} else {
res.redirect(`auth0flutter://callback?code=${code}&state=${state}`);
}
});
```

**Step 3: Configure Auth0 callback URLs**

In your Auth0 application settings, add your intermediary server URL:
- **Allowed Callback URLs**: `https://your-app.example.com/callback`
- **Allowed Logout URLs**: `https://your-app.example.com/logout`

The SDK will automatically use the `auth0flutter://callback` custom scheme internally to receive the forwarded callback from your server.

#### 🌐 Web

Start by importing `auth0_flutter/auth0_flutter_web.dart`.
Expand All @@ -271,24 +338,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 @@ -407,19 +476,28 @@ Check the [FAQ](FAQ.md) for more information about the alert box that pops up **
- [Retrieve stored credentials](EXAMPLES.md#retrieve-stored-credentials) - fetch the user's credentials from the storage, automatically renewing them if they have expired.
- [Retrieve user information](EXAMPLES.md#retrieve-user-information) - fetch the latest user information from the `/userinfo` endpoint.

### πŸͺŸ Windows

- **Custom Protocol Handler**: Windows uses `auth0flutter://` custom scheme for OAuth callbacks, requiring an intermediary server (see setup guide 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 a custom scheme callback (`auth0flutter://`) that requires an intermediary server to forward the Auth0 callback to your app. See the [Windows configuration section](#windows-configure-protocol-handler-and-intermediary-server) above for setup details.

#### API

- [login](https://pub.dev/documentation/auth0_flutter/latest/auth0_flutter/AuthenticationApi/login.html)
Expand All @@ -432,6 +510,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
2 changes: 1 addition & 1 deletion auth0_flutter/example/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ AUTH0_CLIENT_ID=YOUR_AUTH0_CLIENT_ID
# settings page of your Auth0 application with the custom scheme value.
# 2. Update the scheme value in android/app/src/main/res/values/strings.xml
#
AUTH0_CUSTOM_SCHEME=YOUR_AUTH0_CUSTOM_SCHEME
AUTH0_CUSTOM_SCHEME=YOUR_AUTH0_CUSTOM_SCHEME
Loading
Loading