From 7442bba22f6e4f764f321e6a14bccb37b0d099f9 Mon Sep 17 00:00:00 2001
From: Michael Bui <25263378+MaikuB@users.noreply.github.com>
Date: Sat, 15 Feb 2020 20:10:36 +1100
Subject: [PATCH] [flutter_appauth_platform_interface] create platform
interface library (#82)
* move plugin to allow for adding platform interface later
* create platform interface package with default method channel implementation
* throw ArgumentError when grant type cannot be inferred
* update platform interface pubspec and changelog
* add execution of platform interface tests to cirrus script
* fix path in cirrus script
---
.cirrus.yml | 13 +-
.idea/libraries/Dart_SDK.xml | 19 --
.idea/libraries/Flutter_for_Android.xml | 9 -
.idea/modules.xml | 10 --
.../example_lib_main_dart.xml | 6 -
.idea/workspace.xml | 45 -----
.vscode/launch.json | 13 --
README.md | 125 +------------
CHANGELOG.md => flutter_appauth/CHANGELOG.md | 0
LICENSE => flutter_appauth/LICENSE | 0
flutter_appauth/README.md | 122 +++++++++++++
.../analysis_options.yaml | 0
.../android}/.gitignore | 0
.../android}/build.gradle | 0
.../android}/gradle.properties | 0
.../android}/settings.gradle | 0
.../android}/src/main/AndroidManifest.xml | 0
.../flutterappauth/FlutterAppauthPlugin.java | 0
.../InsecureConnectionBuilder.java | 0
.../example}/.gitignore | 0
.../example}/.metadata | 0
.../example}/README.md | 0
.../example}/analysis_options.yaml | 0
.../example}/android/.gitignore | 0
.../example}/android/app/build.gradle | 0
.../android/app/src/main/AndroidManifest.xml | 0
.../flutterappauthexample/MainActivity.java | 0
.../main/res/drawable/launch_background.xml | 0
.../src/main/res/mipmap-hdpi/ic_launcher.png | Bin
.../src/main/res/mipmap-mdpi/ic_launcher.png | Bin
.../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin
.../main/res/mipmap-xxhdpi/ic_launcher.png | Bin
.../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin
.../app/src/main/res/values/styles.xml | 0
.../example}/android/build.gradle | 0
.../example}/android/gradle.properties | 0
.../gradle/wrapper/gradle-wrapper.properties | 0
.../example}/android/settings.gradle | 0
.../example}/ios/.gitignore | 0
.../ios/Flutter/AppFrameworkInfo.plist | 0
.../example}/ios/Flutter/Debug.xcconfig | 0
.../example}/ios/Flutter/Release.xcconfig | 0
.../ios/Runner.xcodeproj/project.pbxproj | 0
.../contents.xcworkspacedata | 0
.../xcshareddata/xcschemes/Runner.xcscheme | 0
.../contents.xcworkspacedata | 0
.../xcshareddata/IDEWorkspaceChecks.plist | 0
.../xcshareddata/WorkspaceSettings.xcsettings | 0
.../example}/ios/Runner/AppDelegate.h | 0
.../example}/ios/Runner/AppDelegate.m | 0
.../AppIcon.appiconset/Contents.json | 0
.../Icon-App-1024x1024@1x.png | Bin
.../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin
.../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin
.../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin
.../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin
.../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin
.../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin
.../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin
.../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin
.../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin
.../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin
.../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin
.../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin
.../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin
.../Icon-App-83.5x83.5@2x.png | Bin
.../LaunchImage.imageset/Contents.json | 0
.../LaunchImage.imageset/LaunchImage.png | Bin
.../LaunchImage.imageset/LaunchImage@2x.png | Bin
.../LaunchImage.imageset/LaunchImage@3x.png | Bin
.../LaunchImage.imageset/README.md | 0
.../Runner/Base.lproj/LaunchScreen.storyboard | 0
.../ios/Runner/Base.lproj/Main.storyboard | 0
.../example}/ios/Runner/Info.plist | 0
.../example}/ios/Runner/main.m | 0
.../example}/lib/main.dart | 0
.../example}/pubspec.yaml | 0
.../flutter_appauth.iml | 0
{ios => flutter_appauth/ios}/.gitignore | 0
{ios => flutter_appauth/ios}/Assets/.gitkeep | 0
.../ios}/Classes/FlutterAppauthPlugin.h | 0
.../ios}/Classes/FlutterAppauthPlugin.m | 0
.../ios}/flutter_appauth.podspec | 0
.../lib}/flutter_appauth.dart | 0
.../lib}/src/authorization_parameters.dart | 0
.../lib}/src/authorization_request.dart | 0
.../lib}/src/authorization_response.dart | 0
.../authorization_service_configuration.dart | 0
.../lib}/src/authorization_token_request.dart | 0
.../src/authorization_token_response.dart | 0
.../lib}/src/common_request_details.dart | 0
.../lib}/src/flutter_appauth.dart | 0
.../lib}/src/grant_types.dart | 0
.../lib}/src/mappable.dart | 0
.../lib}/src/token_request.dart | 0
.../lib}/src/token_response.dart | 0
pubspec.yaml => flutter_appauth/pubspec.yaml | 0
flutter_appauth_platform_interface/.gitignore | 75 ++++++++
.../.metadata | 4 +-
.../CHANGELOG.md | 3 +
flutter_appauth_platform_interface/LICENSE | 29 +++
flutter_appauth_platform_interface/README.md | 3 +
.../flutter_appauth_platform_interface.dart | 9 +
.../lib/src/authorization_parameters.dart | 17 ++
.../lib/src/authorization_request.dart | 28 +++
.../lib/src/authorization_response.dart | 13 ++
.../authorization_service_configuration.dart | 17 ++
.../lib/src/authorization_token_request.dart | 31 ++++
.../lib/src/authorization_token_response.dart | 17 ++
.../lib/src/common_request_details.dart | 42 +++++
.../lib/src/flutter_appauth_platform.dart | 47 +++++
.../lib/src/grant_types.dart | 5 +
.../lib/src/mappable.dart | 3 +
.../src/method_channel_flutter_appauth.dart | 67 +++++++
.../lib/src/token_request.dart | 76 ++++++++
.../lib/src/token_response.dart | 22 +++
.../pubspec.yaml | 18 ++
.../method_channel_flutter_appauth_test.dart | 167 ++++++++++++++++++
118 files changed, 828 insertions(+), 227 deletions(-)
delete mode 100644 .idea/libraries/Dart_SDK.xml
delete mode 100644 .idea/libraries/Flutter_for_Android.xml
delete mode 100644 .idea/modules.xml
delete mode 100644 .idea/runConfigurations/example_lib_main_dart.xml
delete mode 100644 .idea/workspace.xml
delete mode 100644 .vscode/launch.json
rename CHANGELOG.md => flutter_appauth/CHANGELOG.md (100%)
rename LICENSE => flutter_appauth/LICENSE (100%)
create mode 100644 flutter_appauth/README.md
rename analysis_options.yaml => flutter_appauth/analysis_options.yaml (100%)
rename {android => flutter_appauth/android}/.gitignore (100%)
rename {android => flutter_appauth/android}/build.gradle (100%)
rename {android => flutter_appauth/android}/gradle.properties (100%)
rename {android => flutter_appauth/android}/settings.gradle (100%)
rename {android => flutter_appauth/android}/src/main/AndroidManifest.xml (100%)
rename {android => flutter_appauth/android}/src/main/java/io/crossingthestreams/flutterappauth/FlutterAppauthPlugin.java (100%)
rename {android => flutter_appauth/android}/src/main/java/io/crossingthestreams/flutterappauth/InsecureConnectionBuilder.java (100%)
rename {example => flutter_appauth/example}/.gitignore (100%)
rename {example => flutter_appauth/example}/.metadata (100%)
rename {example => flutter_appauth/example}/README.md (100%)
rename {example => flutter_appauth/example}/analysis_options.yaml (100%)
rename {example => flutter_appauth/example}/android/.gitignore (100%)
rename {example => flutter_appauth/example}/android/app/build.gradle (100%)
rename {example => flutter_appauth/example}/android/app/src/main/AndroidManifest.xml (100%)
rename {example => flutter_appauth/example}/android/app/src/main/java/io/crossingthestreams/flutterappauthexample/MainActivity.java (100%)
rename {example => flutter_appauth/example}/android/app/src/main/res/drawable/launch_background.xml (100%)
rename {example => flutter_appauth/example}/android/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%)
rename {example => flutter_appauth/example}/android/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%)
rename {example => flutter_appauth/example}/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%)
rename {example => flutter_appauth/example}/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%)
rename {example => flutter_appauth/example}/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%)
rename {example => flutter_appauth/example}/android/app/src/main/res/values/styles.xml (100%)
rename {example => flutter_appauth/example}/android/build.gradle (100%)
rename {example => flutter_appauth/example}/android/gradle.properties (100%)
rename {example => flutter_appauth/example}/android/gradle/wrapper/gradle-wrapper.properties (100%)
rename {example => flutter_appauth/example}/android/settings.gradle (100%)
rename {example => flutter_appauth/example}/ios/.gitignore (100%)
rename {example => flutter_appauth/example}/ios/Flutter/AppFrameworkInfo.plist (100%)
rename {example => flutter_appauth/example}/ios/Flutter/Debug.xcconfig (100%)
rename {example => flutter_appauth/example}/ios/Flutter/Release.xcconfig (100%)
rename {example => flutter_appauth/example}/ios/Runner.xcodeproj/project.pbxproj (100%)
rename {example => flutter_appauth/example}/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%)
rename {example => flutter_appauth/example}/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (100%)
rename {example => flutter_appauth/example}/ios/Runner.xcworkspace/contents.xcworkspacedata (100%)
rename {example => flutter_appauth/example}/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%)
rename {example => flutter_appauth/example}/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings (100%)
rename {example => flutter_appauth/example}/ios/Runner/AppDelegate.h (100%)
rename {example => flutter_appauth/example}/ios/Runner/AppDelegate.m (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png (100%)
rename {example => flutter_appauth/example}/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md (100%)
rename {example => flutter_appauth/example}/ios/Runner/Base.lproj/LaunchScreen.storyboard (100%)
rename {example => flutter_appauth/example}/ios/Runner/Base.lproj/Main.storyboard (100%)
rename {example => flutter_appauth/example}/ios/Runner/Info.plist (100%)
rename {example => flutter_appauth/example}/ios/Runner/main.m (100%)
rename {example => flutter_appauth/example}/lib/main.dart (100%)
rename {example => flutter_appauth/example}/pubspec.yaml (100%)
rename flutter_appauth.iml => flutter_appauth/flutter_appauth.iml (100%)
rename {ios => flutter_appauth/ios}/.gitignore (100%)
rename {ios => flutter_appauth/ios}/Assets/.gitkeep (100%)
rename {ios => flutter_appauth/ios}/Classes/FlutterAppauthPlugin.h (100%)
rename {ios => flutter_appauth/ios}/Classes/FlutterAppauthPlugin.m (100%)
rename {ios => flutter_appauth/ios}/flutter_appauth.podspec (100%)
rename {lib => flutter_appauth/lib}/flutter_appauth.dart (100%)
rename {lib => flutter_appauth/lib}/src/authorization_parameters.dart (100%)
rename {lib => flutter_appauth/lib}/src/authorization_request.dart (100%)
rename {lib => flutter_appauth/lib}/src/authorization_response.dart (100%)
rename {lib => flutter_appauth/lib}/src/authorization_service_configuration.dart (100%)
rename {lib => flutter_appauth/lib}/src/authorization_token_request.dart (100%)
rename {lib => flutter_appauth/lib}/src/authorization_token_response.dart (100%)
rename {lib => flutter_appauth/lib}/src/common_request_details.dart (100%)
rename {lib => flutter_appauth/lib}/src/flutter_appauth.dart (100%)
rename {lib => flutter_appauth/lib}/src/grant_types.dart (100%)
rename {lib => flutter_appauth/lib}/src/mappable.dart (100%)
rename {lib => flutter_appauth/lib}/src/token_request.dart (100%)
rename {lib => flutter_appauth/lib}/src/token_response.dart (100%)
rename pubspec.yaml => flutter_appauth/pubspec.yaml (100%)
create mode 100644 flutter_appauth_platform_interface/.gitignore
rename .metadata => flutter_appauth_platform_interface/.metadata (75%)
create mode 100644 flutter_appauth_platform_interface/CHANGELOG.md
create mode 100644 flutter_appauth_platform_interface/LICENSE
create mode 100644 flutter_appauth_platform_interface/README.md
create mode 100644 flutter_appauth_platform_interface/lib/flutter_appauth_platform_interface.dart
create mode 100644 flutter_appauth_platform_interface/lib/src/authorization_parameters.dart
create mode 100644 flutter_appauth_platform_interface/lib/src/authorization_request.dart
create mode 100644 flutter_appauth_platform_interface/lib/src/authorization_response.dart
create mode 100644 flutter_appauth_platform_interface/lib/src/authorization_service_configuration.dart
create mode 100644 flutter_appauth_platform_interface/lib/src/authorization_token_request.dart
create mode 100644 flutter_appauth_platform_interface/lib/src/authorization_token_response.dart
create mode 100644 flutter_appauth_platform_interface/lib/src/common_request_details.dart
create mode 100644 flutter_appauth_platform_interface/lib/src/flutter_appauth_platform.dart
create mode 100644 flutter_appauth_platform_interface/lib/src/grant_types.dart
create mode 100644 flutter_appauth_platform_interface/lib/src/mappable.dart
create mode 100644 flutter_appauth_platform_interface/lib/src/method_channel_flutter_appauth.dart
create mode 100644 flutter_appauth_platform_interface/lib/src/token_request.dart
create mode 100644 flutter_appauth_platform_interface/lib/src/token_response.dart
create mode 100644 flutter_appauth_platform_interface/pubspec.yaml
create mode 100644 flutter_appauth_platform_interface/test/method_channel_flutter_appauth_test.dart
diff --git a/.cirrus.yml b/.cirrus.yml
index dec18122..a540a259 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -1,3 +1,12 @@
+task:
+ name: Run platform interface tests
+ container:
+ image: cirrusci/flutter:stable
+ pub_cache:
+ folder: ~/.pub-cache
+ build_script:
+ - cd flutter_appauth_platform_interface
+ - flutter test
task:
name: Build Android example
container:
@@ -5,7 +14,7 @@ task:
pub_cache:
folder: ~/.pub-cache
build_script:
- - cd example
+ - cd flutter_appauth/example
- flutter build appbundle
task:
@@ -15,5 +24,5 @@ task:
pub_cache:
folder: ~/.pub-cache
build_script:
- - cd example
+ - cd flutter_appauth/example
- flutter build ios --no-codesign
diff --git a/.idea/libraries/Dart_SDK.xml b/.idea/libraries/Dart_SDK.xml
deleted file mode 100644
index 000218f8..00000000
--- a/.idea/libraries/Dart_SDK.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/libraries/Flutter_for_Android.xml b/.idea/libraries/Flutter_for_Android.xml
deleted file mode 100644
index 8f1af711..00000000
--- a/.idea/libraries/Flutter_for_Android.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 8152fccf..00000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/.idea/runConfigurations/example_lib_main_dart.xml b/.idea/runConfigurations/example_lib_main_dart.xml
deleted file mode 100644
index 5fd9159d..00000000
--- a/.idea/runConfigurations/example_lib_main_dart.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
deleted file mode 100644
index f82f7bb7..00000000
--- a/.idea/workspace.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.vscode/launch.json b/.vscode/launch.json
deleted file mode 100644
index 3287bb67..00000000
--- a/.vscode/launch.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- // Use IntelliSense to learn about possible attributes.
- // Hover to view descriptions of existing attributes.
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
- "version": "0.2.0",
- "configurations": [
- {
- "name": "Flutter",
- "request": "launch",
- "type": "dart"
- }
- ]
-}
\ No newline at end of file
diff --git a/README.md b/README.md
index 6256f438..793eb79f 100644
--- a/README.md
+++ b/README.md
@@ -1,122 +1,5 @@
-# Flutter AppAuth Plugin
+# flutter_appauth
+A Flutter plugin that provides a wrapper for native AppAuth SDKs (https://appauth.io) used authenticating and authorizing users. The repository consists of the following folders
-[![pub package](https://img.shields.io/pub/v/flutter_appauth.svg)](https://pub.dartlang.org/packages/flutter_appauth)
-[![Build Status](https://api.cirrus-ci.com/github/MaikuB/flutter_appauth.svg)](https://cirrus-ci.com/github/MaikuB/flutter_appauth/)
-
-A Flutter bridge for AppAuth (https://appauth.io) used authenticating and authorizing users. Note that AppAuth also supports the PKCE extension that is required some providers so this plugin should work with them.
-
-**IMPORTANT NOTES**:
-- This plugin requires apps to be using AndroidX. The Flutter tooling supports creating apps with AndroidX support but requires passing the `androidx` flag. Details on AndroidX compatibility and migration can be found [here](https://flutter.dev/docs/development/packages-and-plugins/androidx-compatibility)
-- If Chrome Custom Tabs are not working in your Android app, check to make sure that you have the latest version of this plugin, Android Studio, Gradle distribution and Android Gradle plugin for your app. There was previously a known [issue](https://issuetracker.google.com/issues/119183822) with the Android tooling with AndroidX that should now be resolved since Android Studio 3.4 has been released
-
-
-## Getting Started
-
-Please see the example that demonstrates how to sign into the IdentityServer4 demo site (https://demo.identityserver.io). It has also been tested with Azure B2C and Google Sign-in. It is suggested that developers check the documentation of the identity provider they are using to see what capabilities it supports e.g. how to logout, what values of the `prompt` parameter it supports etc. API docs can be found [here](https://pub.dartlang.org/documentation/flutter_appauth/latest/)
-
-
-The first step is to create an instance of the plugin
-
-```
-FlutterAppAuth appAuth = FlutterAppAuth();
-```
-
-Afterwards, you'll reach a point where end-users need to be authorized and authenticated. A convenience method is provided that will perform an authorization request and automatically exchange the authorization code. This can be done in a few different ways, one of which is to use the OpenID Connect Discovery
-
-```dart
-final AuthorizationTokenResponse result = await appAuth.authorizeAndExchangeCode(
- AuthorizationTokenRequest(
- '',
- '',
- discoveryUrl: '',
- scopes: ['openid','profile', 'email', 'offline_access', 'api'],
- ),
- );
-```
-
-Here the `` and `` should be replaced by the values registered with your identity provider. The `` would be the URL for the discovery endpoint exposed by your provider that will return a document containing information about the OAuth 2.0 endpoints among other things. This URL is obtained by concatenating the issuer with the path `/.well-known/openid-configuration`. For example, the full URL for the IdentityServer4 demo site is `https://demo.identityserver.io/.well-known/openid-configuration`. As demonstrated in the above sample code, it's also possible specify the `scopes` being requested.
-
-Rather than using the full discovery URL, the issuer could be used instead so that the process retrieving the discovery document is skipped
-
-```dart
-final AuthorizationTokenResponse result = await appAuth.authorizeAndExchangeCode(
- AuthorizationTokenRequest(
- '',
- '',
- issuer: '',
- scopes: ['openid','profile', 'email', 'offline_access', 'api'],
- ),
- );
-```
-
-If you already know the authorization and token endpoints, which may be because discovery isn't supported, then these could be explicitly specified
-
-```dart
-final AuthorizationTokenResponse result = await appAuth.authorizeAndExchangeCode(
- AuthorizationTokenRequest(
- '',
- '',
- serviceConfiguration: AuthorizationServiceConfiguration('', ''),
- scopes: ['openid','profile', 'email', 'offline_access', 'api']
- ),
- );
-```
-
-Upon completing the request successfully, the method should return an object (the `result` variable in the above sample code is an instance of the `AuthorizationTokenResponse` class) that contain details that should be stored for future use e.g. access token, refresh token etc.
-
-If you would prefer to not have the automatic code exchange to happen then can call the `authorize` method instead of the `authorizeAndExchangeCode` method. This will return an instance of the `AuthorizationResponse` class that will contain the code verifier that AppAuth generated (as part of implementing PKCE) when issuing the authorization request, the authorization code and additional parameters should they exist. Both of the code verifier and authorization code would need to be stored so they can then be reused to exchange the code later on e.g.
-
-```dart
-final TokenResponse result = await appAuth.token(TokenRequest('', '',
- authorizationCode: '',
- discoveryUrl: '',
- codeVerifier: '',
- scopes: ['openid','profile', 'email', 'offline_access', 'api']));
-```
-
-### Refreshing tokens
-
-Some providers may return a refresh token that could be used to refresh short-lived access tokens. A request to get a new access token before it expires could be made that would like similar to the following code
-
-```dart
-final TokenResponse result = await appAuth.token(TokenRequest('', '',
- discoveryUrl: '',
- refreshToken: '',
- scopes: ['openid','profile', 'email', 'offline_access', 'api']));
-```
-
-## Android setup
-
-Go to the `build.gradle` file for your Android app to specify the custom scheme so that there should be a section in it that look similar to the following but replace `` with the desired value
-
-```
-...
-android {
- ...
- defaultConfig {
- ...
- manifestPlaceholders = [
- 'appAuthRedirectScheme': ''
- ]
- }
-}
-```
-
-## iOS setup
-
-Go to the `Info.plist` for your iOS app to specify the custom scheme so that there should be a section in it that look similar to the following but replace `` with the desired value
-
-
-```xml
-CFBundleURLTypes
-
-
- CFBundleTypeRole
- Editor
- CFBundleURLSchemes
-
-
-
-
-
-```
+- flutter_appauth: code for the plugin
+- flutter_appauth_platform_interface: the code for common platform interface
\ No newline at end of file
diff --git a/CHANGELOG.md b/flutter_appauth/CHANGELOG.md
similarity index 100%
rename from CHANGELOG.md
rename to flutter_appauth/CHANGELOG.md
diff --git a/LICENSE b/flutter_appauth/LICENSE
similarity index 100%
rename from LICENSE
rename to flutter_appauth/LICENSE
diff --git a/flutter_appauth/README.md b/flutter_appauth/README.md
new file mode 100644
index 00000000..6256f438
--- /dev/null
+++ b/flutter_appauth/README.md
@@ -0,0 +1,122 @@
+# Flutter AppAuth Plugin
+
+[![pub package](https://img.shields.io/pub/v/flutter_appauth.svg)](https://pub.dartlang.org/packages/flutter_appauth)
+[![Build Status](https://api.cirrus-ci.com/github/MaikuB/flutter_appauth.svg)](https://cirrus-ci.com/github/MaikuB/flutter_appauth/)
+
+A Flutter bridge for AppAuth (https://appauth.io) used authenticating and authorizing users. Note that AppAuth also supports the PKCE extension that is required some providers so this plugin should work with them.
+
+**IMPORTANT NOTES**:
+- This plugin requires apps to be using AndroidX. The Flutter tooling supports creating apps with AndroidX support but requires passing the `androidx` flag. Details on AndroidX compatibility and migration can be found [here](https://flutter.dev/docs/development/packages-and-plugins/androidx-compatibility)
+- If Chrome Custom Tabs are not working in your Android app, check to make sure that you have the latest version of this plugin, Android Studio, Gradle distribution and Android Gradle plugin for your app. There was previously a known [issue](https://issuetracker.google.com/issues/119183822) with the Android tooling with AndroidX that should now be resolved since Android Studio 3.4 has been released
+
+
+## Getting Started
+
+Please see the example that demonstrates how to sign into the IdentityServer4 demo site (https://demo.identityserver.io). It has also been tested with Azure B2C and Google Sign-in. It is suggested that developers check the documentation of the identity provider they are using to see what capabilities it supports e.g. how to logout, what values of the `prompt` parameter it supports etc. API docs can be found [here](https://pub.dartlang.org/documentation/flutter_appauth/latest/)
+
+
+The first step is to create an instance of the plugin
+
+```
+FlutterAppAuth appAuth = FlutterAppAuth();
+```
+
+Afterwards, you'll reach a point where end-users need to be authorized and authenticated. A convenience method is provided that will perform an authorization request and automatically exchange the authorization code. This can be done in a few different ways, one of which is to use the OpenID Connect Discovery
+
+```dart
+final AuthorizationTokenResponse result = await appAuth.authorizeAndExchangeCode(
+ AuthorizationTokenRequest(
+ '',
+ '',
+ discoveryUrl: '',
+ scopes: ['openid','profile', 'email', 'offline_access', 'api'],
+ ),
+ );
+```
+
+Here the `` and `` should be replaced by the values registered with your identity provider. The `` would be the URL for the discovery endpoint exposed by your provider that will return a document containing information about the OAuth 2.0 endpoints among other things. This URL is obtained by concatenating the issuer with the path `/.well-known/openid-configuration`. For example, the full URL for the IdentityServer4 demo site is `https://demo.identityserver.io/.well-known/openid-configuration`. As demonstrated in the above sample code, it's also possible specify the `scopes` being requested.
+
+Rather than using the full discovery URL, the issuer could be used instead so that the process retrieving the discovery document is skipped
+
+```dart
+final AuthorizationTokenResponse result = await appAuth.authorizeAndExchangeCode(
+ AuthorizationTokenRequest(
+ '',
+ '',
+ issuer: '',
+ scopes: ['openid','profile', 'email', 'offline_access', 'api'],
+ ),
+ );
+```
+
+If you already know the authorization and token endpoints, which may be because discovery isn't supported, then these could be explicitly specified
+
+```dart
+final AuthorizationTokenResponse result = await appAuth.authorizeAndExchangeCode(
+ AuthorizationTokenRequest(
+ '',
+ '',
+ serviceConfiguration: AuthorizationServiceConfiguration('', ''),
+ scopes: ['openid','profile', 'email', 'offline_access', 'api']
+ ),
+ );
+```
+
+Upon completing the request successfully, the method should return an object (the `result` variable in the above sample code is an instance of the `AuthorizationTokenResponse` class) that contain details that should be stored for future use e.g. access token, refresh token etc.
+
+If you would prefer to not have the automatic code exchange to happen then can call the `authorize` method instead of the `authorizeAndExchangeCode` method. This will return an instance of the `AuthorizationResponse` class that will contain the code verifier that AppAuth generated (as part of implementing PKCE) when issuing the authorization request, the authorization code and additional parameters should they exist. Both of the code verifier and authorization code would need to be stored so they can then be reused to exchange the code later on e.g.
+
+```dart
+final TokenResponse result = await appAuth.token(TokenRequest('', '',
+ authorizationCode: '',
+ discoveryUrl: '',
+ codeVerifier: '',
+ scopes: ['openid','profile', 'email', 'offline_access', 'api']));
+```
+
+### Refreshing tokens
+
+Some providers may return a refresh token that could be used to refresh short-lived access tokens. A request to get a new access token before it expires could be made that would like similar to the following code
+
+```dart
+final TokenResponse result = await appAuth.token(TokenRequest('', '',
+ discoveryUrl: '',
+ refreshToken: '',
+ scopes: ['openid','profile', 'email', 'offline_access', 'api']));
+```
+
+## Android setup
+
+Go to the `build.gradle` file for your Android app to specify the custom scheme so that there should be a section in it that look similar to the following but replace `` with the desired value
+
+```
+...
+android {
+ ...
+ defaultConfig {
+ ...
+ manifestPlaceholders = [
+ 'appAuthRedirectScheme': ''
+ ]
+ }
+}
+```
+
+## iOS setup
+
+Go to the `Info.plist` for your iOS app to specify the custom scheme so that there should be a section in it that look similar to the following but replace `` with the desired value
+
+
+```xml
+CFBundleURLTypes
+
+
+ CFBundleTypeRole
+ Editor
+ CFBundleURLSchemes
+
+
+
+
+
+```
diff --git a/analysis_options.yaml b/flutter_appauth/analysis_options.yaml
similarity index 100%
rename from analysis_options.yaml
rename to flutter_appauth/analysis_options.yaml
diff --git a/android/.gitignore b/flutter_appauth/android/.gitignore
similarity index 100%
rename from android/.gitignore
rename to flutter_appauth/android/.gitignore
diff --git a/android/build.gradle b/flutter_appauth/android/build.gradle
similarity index 100%
rename from android/build.gradle
rename to flutter_appauth/android/build.gradle
diff --git a/android/gradle.properties b/flutter_appauth/android/gradle.properties
similarity index 100%
rename from android/gradle.properties
rename to flutter_appauth/android/gradle.properties
diff --git a/android/settings.gradle b/flutter_appauth/android/settings.gradle
similarity index 100%
rename from android/settings.gradle
rename to flutter_appauth/android/settings.gradle
diff --git a/android/src/main/AndroidManifest.xml b/flutter_appauth/android/src/main/AndroidManifest.xml
similarity index 100%
rename from android/src/main/AndroidManifest.xml
rename to flutter_appauth/android/src/main/AndroidManifest.xml
diff --git a/android/src/main/java/io/crossingthestreams/flutterappauth/FlutterAppauthPlugin.java b/flutter_appauth/android/src/main/java/io/crossingthestreams/flutterappauth/FlutterAppauthPlugin.java
similarity index 100%
rename from android/src/main/java/io/crossingthestreams/flutterappauth/FlutterAppauthPlugin.java
rename to flutter_appauth/android/src/main/java/io/crossingthestreams/flutterappauth/FlutterAppauthPlugin.java
diff --git a/android/src/main/java/io/crossingthestreams/flutterappauth/InsecureConnectionBuilder.java b/flutter_appauth/android/src/main/java/io/crossingthestreams/flutterappauth/InsecureConnectionBuilder.java
similarity index 100%
rename from android/src/main/java/io/crossingthestreams/flutterappauth/InsecureConnectionBuilder.java
rename to flutter_appauth/android/src/main/java/io/crossingthestreams/flutterappauth/InsecureConnectionBuilder.java
diff --git a/example/.gitignore b/flutter_appauth/example/.gitignore
similarity index 100%
rename from example/.gitignore
rename to flutter_appauth/example/.gitignore
diff --git a/example/.metadata b/flutter_appauth/example/.metadata
similarity index 100%
rename from example/.metadata
rename to flutter_appauth/example/.metadata
diff --git a/example/README.md b/flutter_appauth/example/README.md
similarity index 100%
rename from example/README.md
rename to flutter_appauth/example/README.md
diff --git a/example/analysis_options.yaml b/flutter_appauth/example/analysis_options.yaml
similarity index 100%
rename from example/analysis_options.yaml
rename to flutter_appauth/example/analysis_options.yaml
diff --git a/example/android/.gitignore b/flutter_appauth/example/android/.gitignore
similarity index 100%
rename from example/android/.gitignore
rename to flutter_appauth/example/android/.gitignore
diff --git a/example/android/app/build.gradle b/flutter_appauth/example/android/app/build.gradle
similarity index 100%
rename from example/android/app/build.gradle
rename to flutter_appauth/example/android/app/build.gradle
diff --git a/example/android/app/src/main/AndroidManifest.xml b/flutter_appauth/example/android/app/src/main/AndroidManifest.xml
similarity index 100%
rename from example/android/app/src/main/AndroidManifest.xml
rename to flutter_appauth/example/android/app/src/main/AndroidManifest.xml
diff --git a/example/android/app/src/main/java/io/crossingthestreams/flutterappauthexample/MainActivity.java b/flutter_appauth/example/android/app/src/main/java/io/crossingthestreams/flutterappauthexample/MainActivity.java
similarity index 100%
rename from example/android/app/src/main/java/io/crossingthestreams/flutterappauthexample/MainActivity.java
rename to flutter_appauth/example/android/app/src/main/java/io/crossingthestreams/flutterappauthexample/MainActivity.java
diff --git a/example/android/app/src/main/res/drawable/launch_background.xml b/flutter_appauth/example/android/app/src/main/res/drawable/launch_background.xml
similarity index 100%
rename from example/android/app/src/main/res/drawable/launch_background.xml
rename to flutter_appauth/example/android/app/src/main/res/drawable/launch_background.xml
diff --git a/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/flutter_appauth/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
similarity index 100%
rename from example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
rename to flutter_appauth/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
diff --git a/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/flutter_appauth/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
similarity index 100%
rename from example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
rename to flutter_appauth/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
diff --git a/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/flutter_appauth/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
similarity index 100%
rename from example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
rename to flutter_appauth/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
diff --git a/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/flutter_appauth/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
similarity index 100%
rename from example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
rename to flutter_appauth/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
diff --git a/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/flutter_appauth/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
similarity index 100%
rename from example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
rename to flutter_appauth/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
diff --git a/example/android/app/src/main/res/values/styles.xml b/flutter_appauth/example/android/app/src/main/res/values/styles.xml
similarity index 100%
rename from example/android/app/src/main/res/values/styles.xml
rename to flutter_appauth/example/android/app/src/main/res/values/styles.xml
diff --git a/example/android/build.gradle b/flutter_appauth/example/android/build.gradle
similarity index 100%
rename from example/android/build.gradle
rename to flutter_appauth/example/android/build.gradle
diff --git a/example/android/gradle.properties b/flutter_appauth/example/android/gradle.properties
similarity index 100%
rename from example/android/gradle.properties
rename to flutter_appauth/example/android/gradle.properties
diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/flutter_appauth/example/android/gradle/wrapper/gradle-wrapper.properties
similarity index 100%
rename from example/android/gradle/wrapper/gradle-wrapper.properties
rename to flutter_appauth/example/android/gradle/wrapper/gradle-wrapper.properties
diff --git a/example/android/settings.gradle b/flutter_appauth/example/android/settings.gradle
similarity index 100%
rename from example/android/settings.gradle
rename to flutter_appauth/example/android/settings.gradle
diff --git a/example/ios/.gitignore b/flutter_appauth/example/ios/.gitignore
similarity index 100%
rename from example/ios/.gitignore
rename to flutter_appauth/example/ios/.gitignore
diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/flutter_appauth/example/ios/Flutter/AppFrameworkInfo.plist
similarity index 100%
rename from example/ios/Flutter/AppFrameworkInfo.plist
rename to flutter_appauth/example/ios/Flutter/AppFrameworkInfo.plist
diff --git a/example/ios/Flutter/Debug.xcconfig b/flutter_appauth/example/ios/Flutter/Debug.xcconfig
similarity index 100%
rename from example/ios/Flutter/Debug.xcconfig
rename to flutter_appauth/example/ios/Flutter/Debug.xcconfig
diff --git a/example/ios/Flutter/Release.xcconfig b/flutter_appauth/example/ios/Flutter/Release.xcconfig
similarity index 100%
rename from example/ios/Flutter/Release.xcconfig
rename to flutter_appauth/example/ios/Flutter/Release.xcconfig
diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/flutter_appauth/example/ios/Runner.xcodeproj/project.pbxproj
similarity index 100%
rename from example/ios/Runner.xcodeproj/project.pbxproj
rename to flutter_appauth/example/ios/Runner.xcodeproj/project.pbxproj
diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/flutter_appauth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
similarity index 100%
rename from example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
rename to flutter_appauth/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/flutter_appauth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
similarity index 100%
rename from example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
rename to flutter_appauth/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
diff --git a/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/flutter_appauth/example/ios/Runner.xcworkspace/contents.xcworkspacedata
similarity index 100%
rename from example/ios/Runner.xcworkspace/contents.xcworkspacedata
rename to flutter_appauth/example/ios/Runner.xcworkspace/contents.xcworkspacedata
diff --git a/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_appauth/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
similarity index 100%
rename from example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
rename to flutter_appauth/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
diff --git a/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/flutter_appauth/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
similarity index 100%
rename from example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
rename to flutter_appauth/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
diff --git a/example/ios/Runner/AppDelegate.h b/flutter_appauth/example/ios/Runner/AppDelegate.h
similarity index 100%
rename from example/ios/Runner/AppDelegate.h
rename to flutter_appauth/example/ios/Runner/AppDelegate.h
diff --git a/example/ios/Runner/AppDelegate.m b/flutter_appauth/example/ios/Runner/AppDelegate.m
similarity index 100%
rename from example/ios/Runner/AppDelegate.m
rename to flutter_appauth/example/ios/Runner/AppDelegate.m
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/flutter_appauth/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/flutter_appauth/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/flutter_appauth/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
similarity index 100%
rename from example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
rename to flutter_appauth/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
diff --git a/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/flutter_appauth/example/ios/Runner/Base.lproj/LaunchScreen.storyboard
similarity index 100%
rename from example/ios/Runner/Base.lproj/LaunchScreen.storyboard
rename to flutter_appauth/example/ios/Runner/Base.lproj/LaunchScreen.storyboard
diff --git a/example/ios/Runner/Base.lproj/Main.storyboard b/flutter_appauth/example/ios/Runner/Base.lproj/Main.storyboard
similarity index 100%
rename from example/ios/Runner/Base.lproj/Main.storyboard
rename to flutter_appauth/example/ios/Runner/Base.lproj/Main.storyboard
diff --git a/example/ios/Runner/Info.plist b/flutter_appauth/example/ios/Runner/Info.plist
similarity index 100%
rename from example/ios/Runner/Info.plist
rename to flutter_appauth/example/ios/Runner/Info.plist
diff --git a/example/ios/Runner/main.m b/flutter_appauth/example/ios/Runner/main.m
similarity index 100%
rename from example/ios/Runner/main.m
rename to flutter_appauth/example/ios/Runner/main.m
diff --git a/example/lib/main.dart b/flutter_appauth/example/lib/main.dart
similarity index 100%
rename from example/lib/main.dart
rename to flutter_appauth/example/lib/main.dart
diff --git a/example/pubspec.yaml b/flutter_appauth/example/pubspec.yaml
similarity index 100%
rename from example/pubspec.yaml
rename to flutter_appauth/example/pubspec.yaml
diff --git a/flutter_appauth.iml b/flutter_appauth/flutter_appauth.iml
similarity index 100%
rename from flutter_appauth.iml
rename to flutter_appauth/flutter_appauth.iml
diff --git a/ios/.gitignore b/flutter_appauth/ios/.gitignore
similarity index 100%
rename from ios/.gitignore
rename to flutter_appauth/ios/.gitignore
diff --git a/ios/Assets/.gitkeep b/flutter_appauth/ios/Assets/.gitkeep
similarity index 100%
rename from ios/Assets/.gitkeep
rename to flutter_appauth/ios/Assets/.gitkeep
diff --git a/ios/Classes/FlutterAppauthPlugin.h b/flutter_appauth/ios/Classes/FlutterAppauthPlugin.h
similarity index 100%
rename from ios/Classes/FlutterAppauthPlugin.h
rename to flutter_appauth/ios/Classes/FlutterAppauthPlugin.h
diff --git a/ios/Classes/FlutterAppauthPlugin.m b/flutter_appauth/ios/Classes/FlutterAppauthPlugin.m
similarity index 100%
rename from ios/Classes/FlutterAppauthPlugin.m
rename to flutter_appauth/ios/Classes/FlutterAppauthPlugin.m
diff --git a/ios/flutter_appauth.podspec b/flutter_appauth/ios/flutter_appauth.podspec
similarity index 100%
rename from ios/flutter_appauth.podspec
rename to flutter_appauth/ios/flutter_appauth.podspec
diff --git a/lib/flutter_appauth.dart b/flutter_appauth/lib/flutter_appauth.dart
similarity index 100%
rename from lib/flutter_appauth.dart
rename to flutter_appauth/lib/flutter_appauth.dart
diff --git a/lib/src/authorization_parameters.dart b/flutter_appauth/lib/src/authorization_parameters.dart
similarity index 100%
rename from lib/src/authorization_parameters.dart
rename to flutter_appauth/lib/src/authorization_parameters.dart
diff --git a/lib/src/authorization_request.dart b/flutter_appauth/lib/src/authorization_request.dart
similarity index 100%
rename from lib/src/authorization_request.dart
rename to flutter_appauth/lib/src/authorization_request.dart
diff --git a/lib/src/authorization_response.dart b/flutter_appauth/lib/src/authorization_response.dart
similarity index 100%
rename from lib/src/authorization_response.dart
rename to flutter_appauth/lib/src/authorization_response.dart
diff --git a/lib/src/authorization_service_configuration.dart b/flutter_appauth/lib/src/authorization_service_configuration.dart
similarity index 100%
rename from lib/src/authorization_service_configuration.dart
rename to flutter_appauth/lib/src/authorization_service_configuration.dart
diff --git a/lib/src/authorization_token_request.dart b/flutter_appauth/lib/src/authorization_token_request.dart
similarity index 100%
rename from lib/src/authorization_token_request.dart
rename to flutter_appauth/lib/src/authorization_token_request.dart
diff --git a/lib/src/authorization_token_response.dart b/flutter_appauth/lib/src/authorization_token_response.dart
similarity index 100%
rename from lib/src/authorization_token_response.dart
rename to flutter_appauth/lib/src/authorization_token_response.dart
diff --git a/lib/src/common_request_details.dart b/flutter_appauth/lib/src/common_request_details.dart
similarity index 100%
rename from lib/src/common_request_details.dart
rename to flutter_appauth/lib/src/common_request_details.dart
diff --git a/lib/src/flutter_appauth.dart b/flutter_appauth/lib/src/flutter_appauth.dart
similarity index 100%
rename from lib/src/flutter_appauth.dart
rename to flutter_appauth/lib/src/flutter_appauth.dart
diff --git a/lib/src/grant_types.dart b/flutter_appauth/lib/src/grant_types.dart
similarity index 100%
rename from lib/src/grant_types.dart
rename to flutter_appauth/lib/src/grant_types.dart
diff --git a/lib/src/mappable.dart b/flutter_appauth/lib/src/mappable.dart
similarity index 100%
rename from lib/src/mappable.dart
rename to flutter_appauth/lib/src/mappable.dart
diff --git a/lib/src/token_request.dart b/flutter_appauth/lib/src/token_request.dart
similarity index 100%
rename from lib/src/token_request.dart
rename to flutter_appauth/lib/src/token_request.dart
diff --git a/lib/src/token_response.dart b/flutter_appauth/lib/src/token_response.dart
similarity index 100%
rename from lib/src/token_response.dart
rename to flutter_appauth/lib/src/token_response.dart
diff --git a/pubspec.yaml b/flutter_appauth/pubspec.yaml
similarity index 100%
rename from pubspec.yaml
rename to flutter_appauth/pubspec.yaml
diff --git a/flutter_appauth_platform_interface/.gitignore b/flutter_appauth_platform_interface/.gitignore
new file mode 100644
index 00000000..bb431f0d
--- /dev/null
+++ b/flutter_appauth_platform_interface/.gitignore
@@ -0,0 +1,75 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+build/
+
+# Android related
+**/android/**/gradle-wrapper.jar
+**/android/.gradle
+**/android/captures/
+**/android/gradlew
+**/android/gradlew.bat
+**/android/local.properties
+**/android/**/GeneratedPluginRegistrant.java
+
+# iOS/XCode related
+**/ios/**/*.mode1v3
+**/ios/**/*.mode2v3
+**/ios/**/*.moved-aside
+**/ios/**/*.pbxuser
+**/ios/**/*.perspectivev3
+**/ios/**/*sync/
+**/ios/**/.sconsign.dblite
+**/ios/**/.tags*
+**/ios/**/.vagrant/
+**/ios/**/DerivedData/
+**/ios/**/Icon?
+**/ios/**/Pods/
+**/ios/**/.symlinks/
+**/ios/**/profile
+**/ios/**/xcuserdata
+**/ios/.generated/
+**/ios/Flutter/App.framework
+**/ios/Flutter/Flutter.framework
+**/ios/Flutter/Flutter.podspec
+**/ios/Flutter/Generated.xcconfig
+**/ios/Flutter/app.flx
+**/ios/Flutter/app.zip
+**/ios/Flutter/flutter_assets/
+**/ios/Flutter/flutter_export_environment.sh
+**/ios/ServiceDefinitions.json
+**/ios/Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!**/ios/**/default.mode1v3
+!**/ios/**/default.mode2v3
+!**/ios/**/default.pbxuser
+!**/ios/**/default.perspectivev3
+!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
diff --git a/.metadata b/flutter_appauth_platform_interface/.metadata
similarity index 75%
rename from .metadata
rename to flutter_appauth_platform_interface/.metadata
index 2517d637..34217a6a 100644
--- a/.metadata
+++ b/flutter_appauth_platform_interface/.metadata
@@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited.
version:
- revision: 5391447fae6209bb21a89e6a5a6583cac1af9b4b
+ revision: 9f5ff2306bb3e30b2b98eee79cd231b1336f41f4
channel: stable
-project_type: plugin
+project_type: package
diff --git a/flutter_appauth_platform_interface/CHANGELOG.md b/flutter_appauth_platform_interface/CHANGELOG.md
new file mode 100644
index 00000000..4c45f55e
--- /dev/null
+++ b/flutter_appauth_platform_interface/CHANGELOG.md
@@ -0,0 +1,3 @@
+## [1.0.0]
+
+* Initial release of platform interface
\ No newline at end of file
diff --git a/flutter_appauth_platform_interface/LICENSE b/flutter_appauth_platform_interface/LICENSE
new file mode 100644
index 00000000..cd01e3fe
--- /dev/null
+++ b/flutter_appauth_platform_interface/LICENSE
@@ -0,0 +1,29 @@
+BSD 3-Clause License
+
+Copyright (c) 2020, Michael Bui
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/flutter_appauth_platform_interface/README.md b/flutter_appauth_platform_interface/README.md
new file mode 100644
index 00000000..dd0d45d0
--- /dev/null
+++ b/flutter_appauth_platform_interface/README.md
@@ -0,0 +1,3 @@
+# flutter_appauth_platform_interface
+
+A common platform interface for the [`flutter_appauth`](https://pub.dev/packages/flutter_appauth) plugin.
\ No newline at end of file
diff --git a/flutter_appauth_platform_interface/lib/flutter_appauth_platform_interface.dart b/flutter_appauth_platform_interface/lib/flutter_appauth_platform_interface.dart
new file mode 100644
index 00000000..3697e181
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/flutter_appauth_platform_interface.dart
@@ -0,0 +1,9 @@
+export 'src/authorization_request.dart';
+export 'src/authorization_response.dart';
+export 'src/authorization_service_configuration.dart';
+export 'src/authorization_token_request.dart';
+export 'src/authorization_token_response.dart';
+export 'src/grant_types.dart';
+export 'src/token_request.dart';
+export 'src/token_response.dart';
+export 'src/flutter_appauth_platform.dart';
diff --git a/flutter_appauth_platform_interface/lib/src/authorization_parameters.dart b/flutter_appauth_platform_interface/lib/src/authorization_parameters.dart
new file mode 100644
index 00000000..c4cd2f57
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/src/authorization_parameters.dart
@@ -0,0 +1,17 @@
+import 'mappable.dart';
+
+mixin AuthorizationParameters on Mappable {
+ /// Hint to the Authorization Server about the login identifier the End-User might use to log in
+ String loginHint;
+
+ /// list of ASCII string values that specifies whether the Authorization Server prompts the End-User for reauthentication and consent
+ List promptValues;
+
+ @override
+ Map toMap() {
+ final Map map = super.toMap();
+ map['loginHint'] = loginHint;
+ map['promptValues'] = promptValues;
+ return map;
+ }
+}
diff --git a/flutter_appauth_platform_interface/lib/src/authorization_request.dart b/flutter_appauth_platform_interface/lib/src/authorization_request.dart
new file mode 100644
index 00000000..835ca0a6
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/src/authorization_request.dart
@@ -0,0 +1,28 @@
+import 'authorization_parameters.dart';
+import 'authorization_service_configuration.dart';
+import 'common_request_details.dart';
+
+/// The details of an authorization request to get an authorization code
+class AuthorizationRequest extends CommonRequestDetails
+ with AuthorizationParameters {
+ AuthorizationRequest(String clientId, String redirectUrl,
+ {String loginHint,
+ List scopes,
+ AuthorizationServiceConfiguration serviceConfiguration,
+ Map additionalParameters,
+ String issuer,
+ String discoveryUrl,
+ List promptValues,
+ bool allowInsecureConnections = false}) {
+ this.clientId = clientId;
+ this.redirectUrl = redirectUrl;
+ this.scopes = scopes;
+ this.serviceConfiguration = serviceConfiguration;
+ this.additionalParameters = additionalParameters;
+ this.issuer = issuer;
+ this.discoveryUrl = discoveryUrl;
+ this.loginHint = loginHint;
+ this.promptValues = promptValues;
+ this.allowInsecureConnections = allowInsecureConnections;
+ }
+}
diff --git a/flutter_appauth_platform_interface/lib/src/authorization_response.dart b/flutter_appauth_platform_interface/lib/src/authorization_response.dart
new file mode 100644
index 00000000..58dd27b2
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/src/authorization_response.dart
@@ -0,0 +1,13 @@
+class AuthorizationResponse {
+ AuthorizationResponse(this.authorizationCode, this.codeVerifier,
+ this.authorizationAdditionalParameters);
+
+ /// The authorization code
+ final String authorizationCode;
+
+ /// The code verifier generated by AppAuth when issue the authorization request. Use this when exchanging the [authorizationCode] for a token
+ final String codeVerifier;
+
+ /// Additional parameters included in the response
+ final Map authorizationAdditionalParameters;
+}
diff --git a/flutter_appauth_platform_interface/lib/src/authorization_service_configuration.dart b/flutter_appauth_platform_interface/lib/src/authorization_service_configuration.dart
new file mode 100644
index 00000000..57e0f394
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/src/authorization_service_configuration.dart
@@ -0,0 +1,17 @@
+class AuthorizationServiceConfiguration {
+ AuthorizationServiceConfiguration(
+ this.authorizationEndpoint, this.tokenEndpoint)
+ : assert(tokenEndpoint != null && authorizationEndpoint != null,
+ 'Must specify both the authorization and token endpoints');
+
+ final String authorizationEndpoint;
+
+ final String tokenEndpoint;
+
+ Map toMap() {
+ return {
+ 'tokenEndpoint': tokenEndpoint,
+ 'authorizationEndpoint': authorizationEndpoint
+ };
+ }
+}
diff --git a/flutter_appauth_platform_interface/lib/src/authorization_token_request.dart b/flutter_appauth_platform_interface/lib/src/authorization_token_request.dart
new file mode 100644
index 00000000..44cbec51
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/src/authorization_token_request.dart
@@ -0,0 +1,31 @@
+import 'authorization_parameters.dart';
+import 'authorization_service_configuration.dart';
+import 'grant_types.dart';
+import 'token_request.dart';
+
+/// Details required for a combined authorization and code exchange request
+class AuthorizationTokenRequest extends TokenRequest
+ with AuthorizationParameters {
+ AuthorizationTokenRequest(String clientId, String redirectUrl,
+ {String loginHint,
+ String clientSecret,
+ List scopes,
+ AuthorizationServiceConfiguration serviceConfiguration,
+ Map additionalParameters,
+ String issuer,
+ String discoveryUrl,
+ List promptValues,
+ bool allowInsecureConnections = false})
+ : super(clientId, redirectUrl,
+ clientSecret: clientSecret,
+ discoveryUrl: discoveryUrl,
+ issuer: issuer,
+ scopes: scopes,
+ grantType: GrantType.authorizationCode,
+ serviceConfiguration: serviceConfiguration,
+ additionalParameters: additionalParameters,
+ allowInsecureConnections: allowInsecureConnections) {
+ this.loginHint = loginHint;
+ this.promptValues = promptValues;
+ }
+}
diff --git a/flutter_appauth_platform_interface/lib/src/authorization_token_response.dart b/flutter_appauth_platform_interface/lib/src/authorization_token_response.dart
new file mode 100644
index 00000000..83aff80d
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/src/authorization_token_response.dart
@@ -0,0 +1,17 @@
+import 'token_response.dart';
+
+/// The details from making a successful combined authorization and token exchange request
+class AuthorizationTokenResponse extends TokenResponse {
+ AuthorizationTokenResponse(
+ String accessToken,
+ String refreshToken,
+ DateTime accessTokenExpirationDateTime,
+ String idToken,
+ String tokenType,
+ this.authorizationAdditionalParameters,
+ Map tokenAdditionalParameters)
+ : super(accessToken, refreshToken, accessTokenExpirationDateTime, idToken,
+ tokenType, tokenAdditionalParameters);
+
+ final Map authorizationAdditionalParameters;
+}
diff --git a/flutter_appauth_platform_interface/lib/src/common_request_details.dart b/flutter_appauth_platform_interface/lib/src/common_request_details.dart
new file mode 100644
index 00000000..da259122
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/src/common_request_details.dart
@@ -0,0 +1,42 @@
+import 'authorization_service_configuration.dart';
+import 'mappable.dart';
+
+class CommonRequestDetails implements Mappable {
+ /// The client id
+ String clientId;
+
+ /// The issuer
+ String issuer;
+
+ /// The URL of where the discovery document can be found
+ String discoveryUrl;
+
+ /// The redirect URL
+ String redirectUrl;
+
+ /// The request scopes
+ List scopes;
+
+ /// The details of the OAuth 2.0 endpoints that can be explicitly when discovery isn't used or not possible
+ AuthorizationServiceConfiguration serviceConfiguration;
+
+ /// Additional parameters to include in the request
+ Map additionalParameters;
+
+ /// Whether to allow non-HTTPS endpoints (only applicable on Android)
+ bool allowInsecureConnections;
+
+ @override
+ Map toMap() {
+ return {
+ 'clientId': clientId,
+ 'issuer': issuer,
+ 'discoveryUrl': discoveryUrl,
+ 'redirectUrl': redirectUrl,
+ 'scopes': scopes,
+ 'serviceConfiguration': serviceConfiguration?.toMap(),
+ 'additionalParameters': additionalParameters,
+ 'allowInsecureConnections': allowInsecureConnections
+ };
+ }
+}
diff --git a/flutter_appauth_platform_interface/lib/src/flutter_appauth_platform.dart b/flutter_appauth_platform_interface/lib/src/flutter_appauth_platform.dart
new file mode 100644
index 00000000..38c0d10b
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/src/flutter_appauth_platform.dart
@@ -0,0 +1,47 @@
+import 'package:flutter_appauth_platform_interface/src/method_channel_flutter_appauth.dart';
+import 'package:plugin_platform_interface/plugin_platform_interface.dart';
+
+import 'authorization_request.dart';
+import 'authorization_response.dart';
+import 'authorization_token_request.dart';
+import 'authorization_token_response.dart';
+import 'token_request.dart';
+import 'token_response.dart';
+
+/// The platform interface that all implementations of flutter_appauth must implement.
+abstract class FlutterAppAuthPlatform extends PlatformInterface {
+ FlutterAppAuthPlatform() : super(token: _token);
+
+ /// The default instance of [FlutterAppAuthPlatform] to use.
+ ///
+ /// Defaults to [MethodChannelFlutterAppAuth].
+ static get instance => _instance;
+
+ static FlutterAppAuthPlatform _instance = MethodChannelFlutterAppAuth();
+
+ static final Object _token = Object();
+
+ /// Platform-specific plugins should set this with their own platform-specific
+ /// class that extends [FlutterAppAuthPlatform] when they register themselves.
+ static set instance(FlutterAppAuthPlatform instance) {
+ PlatformInterface.verifyToken(instance, _token);
+ _instance = instance;
+ }
+
+ /// Convenience method for authorizing and then exchanges the authorization grant code
+ Future authorizeAndExchangeCode(
+ AuthorizationTokenRequest request) {
+ throw UnimplementedError(
+ 'authorizeAndExchangeCode() has not been implemented');
+ }
+
+ /// Sends an authorization request
+ Future authorize(AuthorizationRequest request) {
+ throw UnimplementedError('authorize() has not been implemented');
+ }
+
+ /// For exchanging tokens
+ Future token(TokenRequest request) {
+ throw UnimplementedError('token() has not been implemented');
+ }
+}
diff --git a/flutter_appauth_platform_interface/lib/src/grant_types.dart b/flutter_appauth_platform_interface/lib/src/grant_types.dart
new file mode 100644
index 00000000..e32217a2
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/src/grant_types.dart
@@ -0,0 +1,5 @@
+class GrantType {
+ static const String authorizationCode = 'authorization_code';
+ static const String refreshToken = 'refresh_token';
+ static const String implicit = 'implicit';
+}
diff --git a/flutter_appauth_platform_interface/lib/src/mappable.dart b/flutter_appauth_platform_interface/lib/src/mappable.dart
new file mode 100644
index 00000000..67a193fb
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/src/mappable.dart
@@ -0,0 +1,3 @@
+abstract class Mappable {
+ Map toMap();
+}
diff --git a/flutter_appauth_platform_interface/lib/src/method_channel_flutter_appauth.dart b/flutter_appauth_platform_interface/lib/src/method_channel_flutter_appauth.dart
new file mode 100644
index 00000000..8280398f
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/src/method_channel_flutter_appauth.dart
@@ -0,0 +1,67 @@
+import 'package:flutter/services.dart';
+
+import 'authorization_request.dart';
+import 'authorization_response.dart';
+import 'authorization_token_request.dart';
+import 'authorization_token_response.dart';
+import 'flutter_appauth_platform.dart';
+import 'token_request.dart';
+import 'token_response.dart';
+
+const MethodChannel _channel =
+ MethodChannel('crossingthestreams.io/flutter_appauth');
+
+class MethodChannelFlutterAppAuth extends FlutterAppAuthPlatform {
+ @override
+ Future authorize(AuthorizationRequest request) async {
+ final Map result =
+ await _channel.invokeMethod('authorize', request.toMap());
+ if (result == null) {
+ return null;
+ }
+ return AuthorizationResponse(
+ result['authorizationCode'],
+ result['codeVerifier'],
+ result['authorizationAdditionalParameters']?.cast());
+ }
+
+ @override
+ Future authorizeAndExchangeCode(
+ AuthorizationTokenRequest request) async {
+ final Map result = await _channel.invokeMethod(
+ 'authorizeAndExchangeCode', request.toMap());
+ if (result == null) {
+ return null;
+ }
+ return AuthorizationTokenResponse(
+ result['accessToken'],
+ result['refreshToken'],
+ result['accessTokenExpirationTime'] == null
+ ? null
+ : DateTime.fromMillisecondsSinceEpoch(
+ result['accessTokenExpirationTime'].toInt()),
+ result['idToken'],
+ result['tokenType'],
+ result['authorizationAdditionalParameters']?.cast(),
+ result['tokenAdditionalParameters']?.cast());
+ }
+
+ @override
+ Future token(TokenRequest request) async {
+ final Map result =
+ await _channel.invokeMethod('token', request.toMap());
+ if (result == null) {
+ return null;
+ }
+ return TokenResponse(
+ result['accessToken'],
+ result['refreshToken'],
+ result['accessTokenExpirationTime'] == null
+ ? null
+ : DateTime.fromMillisecondsSinceEpoch(
+ result['accessTokenExpirationTime'].toInt()),
+ result['idToken'],
+ result['tokenType'],
+ result['tokenAdditionalParameters']?.cast());
+ }
+}
diff --git a/flutter_appauth_platform_interface/lib/src/token_request.dart b/flutter_appauth_platform_interface/lib/src/token_request.dart
new file mode 100644
index 00000000..9bf723a7
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/src/token_request.dart
@@ -0,0 +1,76 @@
+import 'authorization_service_configuration.dart';
+import 'common_request_details.dart';
+import 'grant_types.dart';
+
+/// Details for a token exchange request
+class TokenRequest with CommonRequestDetails {
+ TokenRequest(String clientId, String redirectUrl,
+ {this.clientSecret,
+ List scopes,
+ AuthorizationServiceConfiguration serviceConfiguration,
+ Map additionalParameters,
+ this.refreshToken,
+ this.grantType,
+ String issuer,
+ String discoveryUrl,
+ this.authorizationCode,
+ this.codeVerifier,
+ bool allowInsecureConnections = false})
+ : assert(
+ issuer != null ||
+ discoveryUrl != null ||
+ (serviceConfiguration?.authorizationEndpoint != null &&
+ serviceConfiguration?.tokenEndpoint != null),
+ 'Either the issuer, discovery URL or service configuration must be provided') {
+ this.clientId = clientId;
+ this.redirectUrl = redirectUrl;
+ this.scopes = scopes;
+ this.serviceConfiguration = serviceConfiguration;
+ this.additionalParameters = additionalParameters;
+ this.issuer = issuer;
+ this.discoveryUrl = discoveryUrl;
+ this.allowInsecureConnections = allowInsecureConnections;
+ }
+
+ /// The client secret
+ final String clientSecret;
+
+ /// The refresh token
+ final String refreshToken;
+
+ /// The grant type. This would be inferred if it hasn't been set based on if a refresh token or authorization code has been specified
+ final String grantType;
+
+ /// The authorization code
+ final String authorizationCode;
+
+ /// The code verifier to be sent with the authorization code. This should match the code verifier used when performing the authorization request
+ final String codeVerifier;
+
+ @override
+ Map toMap() {
+ final Map map = super.toMap();
+ final String inferredGrantType = _inferGrantType();
+ map['clientSecret'] = clientSecret;
+ map['refreshToken'] = refreshToken;
+ map['authorizationCode'] = authorizationCode;
+ map['grantType'] = inferredGrantType;
+ map['codeVerifier'] = codeVerifier;
+ return map;
+ }
+
+ String _inferGrantType() {
+ if (grantType != null) {
+ return grantType;
+ }
+ if (refreshToken != null) {
+ return GrantType.refreshToken;
+ }
+ if (authorizationCode != null) {
+ return GrantType.authorizationCode;
+ }
+
+ throw ArgumentError.value(
+ null, 'grantType', 'Grant type not specified and cannot be inferred');
+ }
+}
diff --git a/flutter_appauth_platform_interface/lib/src/token_response.dart b/flutter_appauth_platform_interface/lib/src/token_response.dart
new file mode 100644
index 00000000..13e8b5f0
--- /dev/null
+++ b/flutter_appauth_platform_interface/lib/src/token_response.dart
@@ -0,0 +1,22 @@
+/// Details from making a successful token exchange
+class TokenResponse {
+ TokenResponse(
+ this.accessToken,
+ this.refreshToken,
+ this.accessTokenExpirationDateTime,
+ this.idToken,
+ this.tokenType,
+ this.tokenAdditionalParameters);
+
+ final String accessToken;
+
+ final String refreshToken;
+
+ final DateTime accessTokenExpirationDateTime;
+
+ final String idToken;
+
+ final String tokenType;
+
+ final Map tokenAdditionalParameters;
+}
diff --git a/flutter_appauth_platform_interface/pubspec.yaml b/flutter_appauth_platform_interface/pubspec.yaml
new file mode 100644
index 00000000..6aff27cf
--- /dev/null
+++ b/flutter_appauth_platform_interface/pubspec.yaml
@@ -0,0 +1,18 @@
+name: flutter_appauth_platform_interface
+description: A common platform interface for the flutter_appauth plugin.
+version: 1.0.0
+homepage: https://github.com/MaikuB/flutter_appauth/tree/master/flutter_appauth_platform_interface
+
+environment:
+ sdk: ">=2.1.0 <3.0.0"
+ flutter: ">=1.10.0"
+
+dependencies:
+ flutter:
+ sdk: flutter
+ plugin_platform_interface: ^1.0.1
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+ mockito: ^4.1.1
\ No newline at end of file
diff --git a/flutter_appauth_platform_interface/test/method_channel_flutter_appauth_test.dart b/flutter_appauth_platform_interface/test/method_channel_flutter_appauth_test.dart
new file mode 100644
index 00000000..edeeb81e
--- /dev/null
+++ b/flutter_appauth_platform_interface/test/method_channel_flutter_appauth_test.dart
@@ -0,0 +1,167 @@
+import 'package:flutter/services.dart';
+import 'package:flutter_appauth_platform_interface/src/method_channel_flutter_appauth.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import 'package:flutter_appauth_platform_interface/flutter_appauth_platform_interface.dart';
+import 'package:mockito/mockito.dart';
+import 'package:plugin_platform_interface/plugin_platform_interface.dart';
+
+void main() {
+ TestWidgetsFlutterBinding.ensureInitialized();
+ const MethodChannel channel =
+ MethodChannel('crossingthestreams.io/flutter_appauth');
+ final List log = [];
+ channel.setMockMethodCallHandler((MethodCall methodCall) async {
+ log.add(methodCall);
+ });
+
+ tearDown(() {
+ log.clear();
+ });
+
+ MethodChannelFlutterAppAuth flutterAppAuth = MethodChannelFlutterAppAuth();
+ test('authorize', () async {
+ await flutterAppAuth.authorize(AuthorizationRequest(
+ 'someClientId', 'someRedirectUrl',
+ discoveryUrl: 'someDiscoveryUrl', loginHint: 'someLoginHint'));
+ expect(
+ log,
+ [
+ isMethodCall('authorize', arguments: {
+ 'clientId': 'someClientId',
+ 'issuer': null,
+ 'redirectUrl': 'someRedirectUrl',
+ 'discoveryUrl': 'someDiscoveryUrl',
+ 'loginHint': 'someLoginHint',
+ 'scopes': null,
+ 'serviceConfiguration': null,
+ 'additionalParameters': null,
+ 'allowInsecureConnections': false,
+ 'promptValues': null,
+ })
+ ],
+ );
+ });
+
+ test('authorizeAndExchangeCode', () async {
+ await flutterAppAuth.authorizeAndExchangeCode(AuthorizationTokenRequest(
+ 'someClientId', 'someRedirectUrl',
+ discoveryUrl: 'someDiscoveryUrl', loginHint: 'someLoginHint'));
+ expect(
+ log,
+ [
+ isMethodCall('authorizeAndExchangeCode', arguments: {
+ 'clientId': 'someClientId',
+ 'issuer': null,
+ 'redirectUrl': 'someRedirectUrl',
+ 'discoveryUrl': 'someDiscoveryUrl',
+ 'loginHint': 'someLoginHint',
+ 'scopes': null,
+ 'serviceConfiguration': null,
+ 'additionalParameters': null,
+ 'allowInsecureConnections': false,
+ 'promptValues': null,
+ 'clientSecret': null,
+ 'refreshToken': null,
+ 'authorizationCode': null,
+ 'grantType': 'authorization_code',
+ 'codeVerifier': null
+ })
+ ],
+ );
+ });
+
+ group('token', () {
+ test('cannot infer grant type', () async {
+ expect(
+ () async => await flutterAppAuth.token(TokenRequest(
+ 'someClientId', 'someRedirectUrl',
+ discoveryUrl: 'someDiscoveryUrl')),
+ throwsArgumentError);
+ });
+ test('infers refresh token grant type', () async {
+ await flutterAppAuth.token(TokenRequest('someClientId', 'someRedirectUrl',
+ discoveryUrl: 'someDiscoveryUrl', refreshToken: 'someRefreshToken'));
+ expect(
+ log,
+ [
+ isMethodCall('token', arguments: {
+ 'clientId': 'someClientId',
+ 'issuer': null,
+ 'redirectUrl': 'someRedirectUrl',
+ 'discoveryUrl': 'someDiscoveryUrl',
+ 'scopes': null,
+ 'serviceConfiguration': null,
+ 'additionalParameters': null,
+ 'allowInsecureConnections': false,
+ 'clientSecret': null,
+ 'refreshToken': 'someRefreshToken',
+ 'authorizationCode': null,
+ 'grantType': 'refresh_token',
+ 'codeVerifier': null
+ })
+ ],
+ );
+ });
+
+ test('infers authorization code grant type', () async {
+ await flutterAppAuth.token(TokenRequest('someClientId', 'someRedirectUrl',
+ discoveryUrl: 'someDiscoveryUrl',
+ authorizationCode: 'someAuthorizationCode'));
+ expect(
+ log,
+ [
+ isMethodCall('token', arguments: {
+ 'clientId': 'someClientId',
+ 'issuer': null,
+ 'redirectUrl': 'someRedirectUrl',
+ 'discoveryUrl': 'someDiscoveryUrl',
+ 'scopes': null,
+ 'serviceConfiguration': null,
+ 'additionalParameters': null,
+ 'allowInsecureConnections': false,
+ 'clientSecret': null,
+ 'refreshToken': null,
+ 'authorizationCode': 'someAuthorizationCode',
+ 'grantType': 'authorization_code',
+ 'codeVerifier': null
+ })
+ ],
+ );
+ });
+
+ test('sends specified grant type', () async {
+ await flutterAppAuth.token(TokenRequest('someClientId', 'someRedirectUrl',
+ discoveryUrl: 'someDiscoveryUrl', grantType: 'someGrantType'));
+ expect(
+ log,
+ [
+ isMethodCall('token', arguments: {
+ 'clientId': 'someClientId',
+ 'issuer': null,
+ 'redirectUrl': 'someRedirectUrl',
+ 'discoveryUrl': 'someDiscoveryUrl',
+ 'scopes': null,
+ 'serviceConfiguration': null,
+ 'additionalParameters': null,
+ 'allowInsecureConnections': false,
+ 'clientSecret': null,
+ 'refreshToken': null,
+ 'authorizationCode': null,
+ 'grantType': 'someGrantType',
+ 'codeVerifier': null
+ })
+ ],
+ );
+ });
+ });
+}
+
+class FlutterAppAuthPlatformMock extends Mock
+ with MockPlatformInterfaceMixin
+ implements FlutterAppAuthPlatform {}
+
+class ImplementsFlutterAppAuthPlatform extends Mock
+ implements FlutterAppAuthPlatform {}
+
+class ExtendsFlutterAppAuthPlatform extends FlutterAppAuthPlatform {}