├── ios ├── Assets │ └── .gitkeep ├── .gitignore ├── flutter_web_auth.podspec └── Classes │ └── FlutterWebAuthPlugin.swift ├── android ├── settings.gradle ├── gradle.properties ├── .settings │ └── org.eclipse.buildship.core.prefs ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── .gitignore ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ └── com │ │ └── linusu │ │ └── flutter_web_auth │ │ ├── KeepAliveService.kt │ │ ├── CallbackActivity.kt │ │ └── FlutterWebAuthPlugin.kt ├── .classpath ├── .project ├── build.gradle ├── gradlew.bat └── gradlew ├── example ├── ios │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── xcshareddata │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ └── project.pbxproj │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── .gitignore │ ├── Podfile.lock │ ├── RunnerTests │ │ └── RunnerTests.swift │ └── Podfile ├── web │ ├── favicon.png │ ├── icons │ │ ├── Icon-192.png │ │ ├── Icon-512.png │ │ ├── Icon-maskable-192.png │ │ └── Icon-maskable-512.png │ ├── manifest.json │ └── index.html ├── macos │ ├── Runner │ │ ├── Configs │ │ │ ├── Debug.xcconfig │ │ │ ├── Release.xcconfig │ │ │ ├── Warnings.xcconfig │ │ │ └── AppInfo.xcconfig │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ ├── app_icon_128.png │ │ │ │ ├── app_icon_16.png │ │ │ │ ├── app_icon_256.png │ │ │ │ ├── app_icon_32.png │ │ │ │ ├── app_icon_512.png │ │ │ │ ├── app_icon_64.png │ │ │ │ ├── app_icon_1024.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Release.entitlements │ │ ├── DebugProfile.entitlements │ │ ├── MainFlutterWindow.swift │ │ ├── Info.plist │ │ └── Base.lproj │ │ │ └── MainMenu.xib │ ├── .gitignore │ ├── Flutter │ │ ├── Flutter-Debug.xcconfig │ │ ├── Flutter-Release.xcconfig │ │ └── GeneratedPluginRegistrant.swift │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Podfile.lock │ ├── RunnerTests │ │ └── RunnerTests.swift │ └── Podfile ├── android │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ └── flutter_web_auth_example │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── build.gradle │ └── settings.gradle ├── README.md ├── .gitignore ├── test │ └── widget_test.dart ├── integration_test │ └── plugin_integration_test.dart ├── analysis_options.yaml ├── pubspec.yaml ├── lib │ └── main.dart └── pubspec.lock ├── screen-ios.gif ├── screen-macos.gif ├── screen-android.gif ├── .metadata ├── .gitignore ├── macos ├── flutter_web_auth.podspec └── Classes │ └── FlutterWebAuthPlugin.swift ├── LICENSE ├── test └── flutter_web_auth_test.dart ├── lib ├── flutter_web_auth_web.dart └── flutter_web_auth.dart ├── pubspec.yaml ├── CHANGELOG.md └── README.md /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'flutter_web_auth' 2 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /screen-ios.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/screen-ios.gif -------------------------------------------------------------------------------- /screen-macos.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/screen-macos.gif -------------------------------------------------------------------------------- /screen-android.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/screen-android.gif -------------------------------------------------------------------------------- /example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/web/favicon.png -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /android/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir=../example/android 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .cxx 10 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LinusU/flutter_web_auth/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/example/flutter_web_auth_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.linusu.flutter_web_auth_example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() 6 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip 6 | -------------------------------------------------------------------------------- /example/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @main 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/to/reference-keystore 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 8661d8aecd626f7f57ccbcb735553edc05a2e713 8 | channel: stable 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /example/macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import flutter_web_auth 9 | 10 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 11 | FlutterWebAuthPlugin.register(with: registry.registrar(forPlugin: "FlutterWebAuthPlugin")) 12 | } 13 | -------------------------------------------------------------------------------- /android/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | rootProject.buildDir = "../build" 9 | subprojects { 10 | project.buildDir = "${rootProject.buildDir}/${project.name}" 11 | } 12 | subprojects { 13 | project.evaluationDependsOn(":app") 14 | } 15 | 16 | tasks.register("clean", Delete) { 17 | delete rootProject.buildDir 18 | } 19 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/linusu/flutter_web_auth/KeepAliveService.kt: -------------------------------------------------------------------------------- 1 | package com.linusu.flutter_web_auth 2 | 3 | import android.app.Service 4 | import android.content.Intent 5 | import android.os.Binder 6 | import android.os.IBinder 7 | 8 | class KeepAliveService: Service() { 9 | companion object { 10 | val binder = Binder() 11 | } 12 | 13 | override fun onBind(intent: Intent): IBinder { 14 | return binder 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | @main 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/linusu/flutter_web_auth/CallbackActivity.kt: -------------------------------------------------------------------------------- 1 | package com.linusu.flutter_web_auth 2 | 3 | import android.app.Activity 4 | import android.net.Uri 5 | import android.os.Bundle 6 | 7 | class CallbackActivity: Activity() { 8 | override fun onCreate(savedInstanceState: Bundle?) { 9 | super.onCreate(savedInstanceState) 10 | 11 | val url = intent?.data 12 | val scheme = url?.scheme 13 | 14 | if (scheme != null) { 15 | FlutterWebAuthPlugin.callbacks.remove(scheme)?.success(url.toString()) 16 | } 17 | 18 | finish() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/ephemeral/ 38 | /Flutter/flutter_export_environment.sh 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | build/ 30 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # flutter_web_auth_example 2 | 3 | Demonstrates how to use the flutter_web_auth plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) 13 | 14 | For help getting started with Flutter development, view the 15 | [online documentation](https://docs.flutter.dev/), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/macos/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - flutter_web_auth (0.6.0): 3 | - FlutterMacOS 4 | - FlutterMacOS (1.0.0) 5 | 6 | DEPENDENCIES: 7 | - flutter_web_auth (from `Flutter/ephemeral/.symlinks/plugins/flutter_web_auth/macos`) 8 | - FlutterMacOS (from `Flutter/ephemeral`) 9 | 10 | EXTERNAL SOURCES: 11 | flutter_web_auth: 12 | :path: Flutter/ephemeral/.symlinks/plugins/flutter_web_auth/macos 13 | FlutterMacOS: 14 | :path: Flutter/ephemeral 15 | 16 | SPEC CHECKSUMS: 17 | flutter_web_auth: 1966f190ad0051456e12d9f2db506a4df81e7434 18 | FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 19 | 20 | PODFILE CHECKSUM: 9ebaf0ce3d369aaa26a9ea0e159195ed94724cf3 21 | 22 | COCOAPODS: 1.15.2 23 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = flutter_web_auth_example 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWebAuthExample 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2024 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | flutter_web_auth 4 | Project flutter_web_auth created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.buildship.core.gradleprojectnature 22 | 23 | 24 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 21 | id "com.android.application" version "8.1.0" apply false 22 | id "org.jetbrains.kotlin.android" version "1.8.22" apply false 23 | } 24 | 25 | include ":app" 26 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Symbolication related 35 | app.*.symbols 36 | 37 | # Obfuscation related 38 | app.*.map.json 39 | 40 | # Android Studio will place build artifacts here 41 | /android/app/debug 42 | /android/app/profile 43 | /android/app/release 44 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - flutter_web_auth (0.6.0): 4 | - Flutter 5 | - integration_test (0.0.1): 6 | - Flutter 7 | 8 | DEPENDENCIES: 9 | - Flutter (from `Flutter`) 10 | - flutter_web_auth (from `.symlinks/plugins/flutter_web_auth/ios`) 11 | - integration_test (from `.symlinks/plugins/integration_test/ios`) 12 | 13 | EXTERNAL SOURCES: 14 | Flutter: 15 | :path: Flutter 16 | flutter_web_auth: 17 | :path: ".symlinks/plugins/flutter_web_auth/ios" 18 | integration_test: 19 | :path: ".symlinks/plugins/integration_test/ios" 20 | 21 | SPEC CHECKSUMS: 22 | Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 23 | flutter_web_auth: acc15a8fd7bba796a933c724a6dffc3d00f07c27 24 | integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 25 | 26 | PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796 27 | 28 | COCOAPODS: 1.15.2 29 | -------------------------------------------------------------------------------- /example/ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | 6 | @testable import flutter_web_auth 7 | 8 | // This demonstrates a simple unit test of the Swift portion of this plugin's implementation. 9 | // 10 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 11 | 12 | class RunnerTests: XCTestCase { 13 | 14 | func testGetPlatformVersion() { 15 | let plugin = FlutterWebAuthPlugin() 16 | 17 | let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: []) 18 | 19 | let resultExpectation = expectation(description: "result block must be called.") 20 | plugin.handle(call) { result in 21 | XCTAssertEqual(result as! String, "iOS " + UIDevice.current.systemVersion) 22 | resultExpectation.fulfill() 23 | } 24 | waitForExpectations(timeout: 1) 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /macos/flutter_web_auth.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint flutter_web_auth.podspec` to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'flutter_web_auth' 7 | s.version = '0.6.0' 8 | s.summary = 'A new flutter plugin project.' 9 | s.description = <<-DESC 10 | A new flutter plugin project. 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | 16 | s.source = { :path => '.' } 17 | s.source_files = 'Classes/**/*' 18 | s.dependency 'FlutterMacOS' 19 | 20 | s.platform = :osx, '10.15' 21 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } 22 | s.swift_version = '5.0' 23 | end 24 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/macos/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | import XCTest 4 | 5 | 6 | @testable import flutter_web_auth 7 | 8 | // This demonstrates a simple unit test of the Swift portion of this plugin's implementation. 9 | // 10 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 11 | 12 | class RunnerTests: XCTestCase { 13 | 14 | func testGetPlatformVersion() { 15 | let plugin = FlutterWebAuthPlugin() 16 | 17 | let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: []) 18 | 19 | let resultExpectation = expectation(description: "result block must be called.") 20 | plugin.handle(call) { result in 21 | XCTAssertEqual(result as! String, 22 | "macOS " + ProcessInfo.processInfo.operatingSystemVersionString) 23 | resultExpectation.fulfill() 24 | } 25 | waitForExpectations(timeout: 1) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility in the flutter_test package. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:flutter_web_auth_example/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Verify Platform version', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(const MyApp()); 17 | 18 | // Verify that platform version is retrieved. 19 | expect( 20 | find.byWidgetPredicate( 21 | (Widget widget) => widget is Text && 22 | widget.data!.startsWith('Running on:'), 23 | ), 24 | findsOneWidget, 25 | ); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /example/integration_test/plugin_integration_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter integration test. 2 | // 3 | // Since integration tests run in a full Flutter application, they can interact 4 | // with the host side of a plugin implementation, unlike Dart unit tests. 5 | // 6 | // For more information about Flutter integration tests, please see 7 | // https://flutter.dev/to/integration-testing 8 | 9 | 10 | import 'package:flutter_test/flutter_test.dart'; 11 | import 'package:integration_test/integration_test.dart'; 12 | 13 | import 'package:flutter_web_auth/flutter_web_auth.dart'; 14 | 15 | void main() { 16 | IntegrationTestWidgetsFlutterBinding.ensureInitialized(); 17 | 18 | testWidgets('getPlatformVersion test', (WidgetTester tester) async { 19 | final FlutterWebAuth plugin = FlutterWebAuth(); 20 | final String? version = await plugin.getPlatformVersion(); 21 | // The version string depends on the host platform running the test, so 22 | // just assert that some non-empty string is returned. 23 | expect(version?.isNotEmpty, true); 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Linus Unnebäck 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flutter_web_auth_example", 3 | "short_name": "flutter_web_auth_example", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "Demonstrates how to use the flutter_web_auth plugin.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /example/macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /test/flutter_web_auth_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:flutter_web_auth/flutter_web_auth.dart'; 4 | 5 | void main() { 6 | const MethodChannel channel = MethodChannel('flutter_web_auth'); 7 | 8 | TestWidgetsFlutterBinding.ensureInitialized(); 9 | 10 | setUp(() { 11 | channel.setMockMethodCallHandler((MethodCall methodCall) async { 12 | expect(methodCall.method, 'authenticate'); 13 | 14 | expect(methodCall.arguments['url'] as String, 'https://example.com/login'); 15 | expect(methodCall.arguments['callbackUrlScheme'] as String, 'foobar'); 16 | 17 | return 'https://example.com/success'; 18 | }); 19 | }); 20 | 21 | tearDown(() { 22 | channel.setMockMethodCallHandler(null); 23 | }); 24 | 25 | test('authenticate', () async { 26 | expect( 27 | await FlutterWebAuth.authenticate(url: 'https://example.com/login', callbackUrlScheme: 'foobar'), 28 | 'https://example.com/success', 29 | ); 30 | }); 31 | 32 | test('invalid scheme', () async { 33 | await expectLater( 34 | FlutterWebAuth.authenticate(url: 'https://example.com/login', callbackUrlScheme: 'foobar://test'), 35 | throwsA(isA()), 36 | ); 37 | }); 38 | } 39 | -------------------------------------------------------------------------------- /ios/flutter_web_auth.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint flutter_web_auth.podspec` to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'flutter_web_auth' 7 | s.version = '0.6.0' 8 | s.summary = 'A new flutter plugin project.' 9 | s.description = <<-DESC 10 | A new flutter plugin project. 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.dependency 'Flutter' 18 | s.platform = :ios, '12.0' 19 | 20 | # Flutter.framework does not contain a i386 slice. 21 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } 22 | s.swift_version = '5.0' 23 | 24 | # If your plugin requires a privacy manifest, for example if it uses any 25 | # required reason APIs, update the PrivacyInfo.xcprivacy file to describe your 26 | # plugin's privacy impact, and then uncomment this line. For more information, 27 | # see https://developer.apple.com/documentation/bundleresources/privacy_manifest_files 28 | # s.resource_bundles = {'flutter_web_auth_privacy' => ['Resources/PrivacyInfo.xcprivacy']} 29 | end 30 | -------------------------------------------------------------------------------- /example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | flutter_web_auth_example 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at https://dart.dev/lints. 17 | # 18 | # Instead of disabling a lint rule for the entire project in the 19 | # section below, it can also be suppressed for a single line of code 20 | # or a specific dart file by using the `// ignore: name_of_lint` and 21 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 22 | # producing the lint. 23 | rules: 24 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 25 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 26 | 27 | # Additional information about this file can be found at 28 | # https://dart.dev/guides/language/analysis-options 29 | -------------------------------------------------------------------------------- /example/macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.15' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | target 'RunnerTests' do 35 | inherit! :search_paths 36 | end 37 | end 38 | 39 | post_install do |installer| 40 | installer.pods_project.targets.each do |target| 41 | flutter_additional_macos_build_settings(target) 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. 5 | id "dev.flutter.flutter-gradle-plugin" 6 | } 7 | 8 | android { 9 | namespace = "com.linusu.flutter_web_auth_example" 10 | compileSdk = flutter.compileSdkVersion 11 | ndkVersion = flutter.ndkVersion 12 | 13 | compileOptions { 14 | sourceCompatibility = JavaVersion.VERSION_1_8 15 | targetCompatibility = JavaVersion.VERSION_1_8 16 | } 17 | 18 | kotlinOptions { 19 | jvmTarget = JavaVersion.VERSION_1_8 20 | } 21 | 22 | defaultConfig { 23 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 24 | applicationId = "com.linusu.flutter_web_auth_example" 25 | // You can update the following values to match your application needs. 26 | // For more information, see: https://flutter.dev/to/review-gradle-config. 27 | minSdk = flutter.minSdkVersion 28 | targetSdk = flutter.targetSdkVersion 29 | versionCode = flutter.versionCode 30 | versionName = flutter.versionName 31 | } 32 | 33 | buildTypes { 34 | release { 35 | // TODO: Add your own signing config for the release build. 36 | // Signing with the debug keys for now, so `flutter run --release` works. 37 | signingConfig = signingConfigs.debug 38 | } 39 | } 40 | } 41 | 42 | flutter { 43 | source = "../.." 44 | } 45 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '12.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | target 'RunnerTests' do 36 | inherit! :search_paths 37 | end 38 | end 39 | 40 | post_install do |installer| 41 | installer.pods_project.targets.each do |target| 42 | flutter_additional_ios_build_settings(target) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group = "com.linusu.flutter_web_auth" 2 | version = "1.0-SNAPSHOT" 3 | 4 | buildscript { 5 | ext.kotlin_version = "1.8.22" 6 | repositories { 7 | google() 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | classpath("com.android.tools.build:gradle:8.1.0") 13 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") 14 | } 15 | } 16 | 17 | allprojects { 18 | repositories { 19 | google() 20 | mavenCentral() 21 | } 22 | } 23 | 24 | apply plugin: "com.android.library" 25 | apply plugin: "kotlin-android" 26 | 27 | android { 28 | if (project.android.hasProperty("namespace")) { 29 | namespace = "com.linusu.flutter_web_auth" 30 | } 31 | 32 | compileSdk = 34 33 | 34 | compileOptions { 35 | sourceCompatibility = JavaVersion.VERSION_1_8 36 | targetCompatibility = JavaVersion.VERSION_1_8 37 | } 38 | 39 | kotlinOptions { 40 | jvmTarget = JavaVersion.VERSION_1_8 41 | } 42 | 43 | sourceSets { 44 | main.java.srcDirs += "src/main/kotlin" 45 | test.java.srcDirs += "src/test/kotlin" 46 | } 47 | 48 | defaultConfig { 49 | minSdk = 21 50 | } 51 | 52 | dependencies { 53 | implementation("androidx.browser:browser:1.8.0") 54 | testImplementation("org.jetbrains.kotlin:kotlin-test") 55 | testImplementation("org.mockito:mockito-core:5.0.0") 56 | } 57 | 58 | testOptions { 59 | unitTests.all { 60 | useJUnitPlatform() 61 | 62 | testLogging { 63 | events "passed", "skipped", "failed", "standardOut", "standardError" 64 | outputs.upToDateWhen {false} 65 | showStandardStreams = true 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Flutter Web Auth 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | flutter_web_auth_example 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | CADisableMinimumFrameDurationOnPhone 45 | 46 | UIApplicationSupportsIndirectInputEvents 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /lib/flutter_web_auth_web.dart: -------------------------------------------------------------------------------- 1 | // ignore: avoid_web_libraries_in_flutter 2 | 3 | import 'dart:async'; 4 | import 'dart:convert'; 5 | import 'dart:html'; 6 | import 'dart:js'; 7 | 8 | import 'package:flutter/services.dart'; 9 | import 'package:flutter_web_plugins/flutter_web_plugins.dart'; 10 | 11 | class FlutterWebAuthWeb { 12 | static void registerWith(Registrar registrar) { 13 | final MethodChannel channel = MethodChannel( 14 | 'flutter_web_auth', const StandardMethodCodec(), registrar.messenger); 15 | final FlutterWebAuthWeb instance = FlutterWebAuthWeb(); 16 | channel.setMethodCallHandler(instance.handleMethodCall); 17 | } 18 | 19 | Future handleMethodCall(MethodCall call) async { 20 | switch (call.method) { 21 | case 'authenticate': 22 | final String url = call.arguments['url']; 23 | return _authenticate(url); 24 | default: 25 | throw PlatformException( 26 | code: 'Unimplemented', 27 | details: "The flutter_web_auth plugin for web doesn't implement " 28 | "the method '${call.method}'"); 29 | } 30 | } 31 | 32 | static Future _authenticate(String url) async { 33 | context.callMethod('open', [url]); 34 | await for (MessageEvent messageEvent in window.onMessage) { 35 | if (messageEvent.origin == Uri.base.origin) { 36 | final flutterWebAuthMessage = messageEvent.data['flutter-web-auth']; 37 | if (flutterWebAuthMessage is String) { 38 | return flutterWebAuthMessage; 39 | } 40 | } 41 | var appleOrigin = Uri(scheme: 'https', host: 'appleid.apple.com'); 42 | if (messageEvent.origin == appleOrigin.toString()) { 43 | try { 44 | Map data = jsonDecode(messageEvent.data); 45 | if (data['method'] == 'oauthDone') { 46 | final appleAuth = data['data']['authorization']; 47 | if (appleAuth != null) { 48 | final appleAuthQuery = Uri(queryParameters: appleAuth).query; 49 | return appleOrigin.replace(fragment: appleAuthQuery).toString(); 50 | } 51 | } 52 | } on FormatException {} 53 | } 54 | } 55 | throw new PlatformException( 56 | code: 'error', message: 'Iterable window.onMessage is empty'); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_web_auth 2 | description: Flutter plugin for authenticating a user with a web service. 3 | version: 0.6.0 4 | homepage: https://github.com/LinusU/flutter_web_auth 5 | 6 | environment: 7 | sdk: ^3.5.3 8 | flutter: '>=3.3.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | flutter_web_plugins: 14 | sdk: flutter 15 | 16 | dev_dependencies: 17 | flutter_test: 18 | sdk: flutter 19 | 20 | # For information on the generic Dart part of this file, see the 21 | # following page: https://www.dartlang.org/tools/pub/pubspec 22 | 23 | # The following section is specific to Flutter. 24 | flutter: 25 | # This section identifies this Flutter project as a plugin project. 26 | # The androidPackage and pluginClass identifiers should not ordinarily 27 | # be modified. They are used by the tooling to maintain consistency when 28 | # adding or updating assets for this project. 29 | plugin: 30 | platforms: 31 | android: 32 | package: com.linusu.flutter_web_auth 33 | pluginClass: FlutterWebAuthPlugin 34 | ios: 35 | pluginClass: FlutterWebAuthPlugin 36 | macos: 37 | pluginClass: FlutterWebAuthPlugin 38 | web: 39 | pluginClass: FlutterWebAuthWeb 40 | fileName: flutter_web_auth_web.dart 41 | 42 | # To add assets to your plugin package, add an assets section, like this: 43 | # assets: 44 | # - images/a_dot_burr.jpeg 45 | # - images/a_dot_ham.jpeg 46 | # 47 | # For details regarding assets in packages, see 48 | # https://flutter.io/assets-and-images/#from-packages 49 | # 50 | # An image asset can refer to one or more resolution-specific "variants", see 51 | # https://flutter.io/assets-and-images/#resolution-aware. 52 | 53 | # To add custom fonts to your plugin package, add a fonts section here, 54 | # in this "flutter" section. Each entry in this list should have a 55 | # "family" key with the font family name, and a "fonts" key with a 56 | # list giving the asset and other descriptors for the font. For 57 | # example: 58 | # fonts: 59 | # - family: Schyler 60 | # fonts: 61 | # - asset: fonts/Schyler-Regular.ttf 62 | # - asset: fonts/Schyler-Italic.ttf 63 | # style: italic 64 | # - family: Trajan Pro 65 | # fonts: 66 | # - asset: fonts/TrajanPro.ttf 67 | # - asset: fonts/TrajanPro_Bold.ttf 68 | # weight: 700 69 | # 70 | # For details regarding fonts in packages, see 71 | # https://flutter.io/custom-fonts/#from-packages 72 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/flutter_web_auth.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/services.dart' show MethodChannel; 5 | 6 | class _OnAppLifecycleResumeObserver extends WidgetsBindingObserver { 7 | final Function onResumed; 8 | 9 | _OnAppLifecycleResumeObserver(this.onResumed); 10 | 11 | @override 12 | void didChangeAppLifecycleState(AppLifecycleState state) { 13 | if (state == AppLifecycleState.resumed) { 14 | onResumed(); 15 | } 16 | } 17 | } 18 | 19 | class FlutterWebAuth { 20 | static const MethodChannel _channel = const MethodChannel('flutter_web_auth'); 21 | static RegExp _schemeRegExp = new RegExp(r"^[a-z][a-z0-9+.-]*$"); 22 | 23 | static final _OnAppLifecycleResumeObserver _resumedObserver = _OnAppLifecycleResumeObserver(() { 24 | _cleanUpDanglingCalls(); // unawaited 25 | }); 26 | 27 | /// Ask the user to authenticate to the specified web service. 28 | /// 29 | /// The page pointed to by [url] will be loaded and displayed to the user. From the page, the user can authenticate herself and grant access to the app. On completion, the service will send a callback URL with an authentication token, and this URL will be result of the returned [Future]. 30 | /// 31 | /// [callbackUrlScheme] should be a string specifying the scheme of the url that the page will redirect to upon successful authentication. 32 | /// [preferEphemeral] if this is specified as `true`, an ephemeral web browser session will be used where possible (`FLAG_ACTIVITY_NO_HISTORY` on Android, `prefersEphemeralWebBrowserSession` on iOS/macOS) 33 | static Future authenticate({required String url, required String callbackUrlScheme, bool? preferEphemeral}) async { 34 | if (!_schemeRegExp.hasMatch(callbackUrlScheme)) { 35 | throw ArgumentError.value(callbackUrlScheme, 'callbackUrlScheme', 'must be a valid URL scheme'); 36 | } 37 | 38 | WidgetsBinding.instance.removeObserver(_resumedObserver); // safety measure so we never add this observer twice 39 | WidgetsBinding.instance.addObserver(_resumedObserver); 40 | return await _channel.invokeMethod('authenticate', { 41 | 'url': url, 42 | 'callbackUrlScheme': callbackUrlScheme, 43 | 'preferEphemeral': preferEphemeral ?? false, 44 | }) as String; 45 | } 46 | 47 | /// On Android, the plugin has to store the Result callbacks in order to pass the result back to the caller of 48 | /// `authenticate`. But if that result never comes the callback will dangle around forever. This can be called to 49 | /// terminate all `authenticate` calls with an error. 50 | static Future _cleanUpDanglingCalls() async { 51 | await _channel.invokeMethod('cleanUpDanglingCalls'); 52 | WidgetsBinding.instance.removeObserver(_resumedObserver); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /macos/Classes/FlutterWebAuthPlugin.swift: -------------------------------------------------------------------------------- 1 | import AuthenticationServices 2 | import SafariServices 3 | import FlutterMacOS 4 | 5 | @available(OSX 10.15, *) 6 | public class FlutterWebAuthPlugin: NSObject, FlutterPlugin { 7 | public static func register(with registrar: FlutterPluginRegistrar) { 8 | let channel = FlutterMethodChannel(name: "flutter_web_auth", binaryMessenger: registrar.messenger) 9 | let instance = FlutterWebAuthPlugin() 10 | registrar.addMethodCallDelegate(instance, channel: channel) 11 | } 12 | 13 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { 14 | if call.method == "authenticate" { 15 | let url = URL(string: (call.arguments as! Dictionary)["url"] as! String)! 16 | let callbackURLScheme = (call.arguments as! Dictionary)["callbackUrlScheme"] as! String 17 | let preferEphemeral = (call.arguments as! Dictionary)["preferEphemeral"] as! Bool 18 | 19 | var keepMe: Any? = nil 20 | let completionHandler = { (url: URL?, err: Error?) in 21 | keepMe = nil 22 | 23 | if let err = err { 24 | if case ASWebAuthenticationSessionError.canceledLogin = err { 25 | result(FlutterError(code: "CANCELED", message: "User canceled login", details: nil)) 26 | return 27 | } 28 | 29 | result(FlutterError(code: "EUNKNOWN", message: err.localizedDescription, details: nil)) 30 | return 31 | } 32 | 33 | result(url!.absoluteString) 34 | } 35 | 36 | let session = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURLScheme, completionHandler: completionHandler) 37 | 38 | guard let provider = NSApplication.shared.keyWindow!.contentViewController as? FlutterViewController else { 39 | result(FlutterError(code: "FAILED", message: "Failed to aquire root FlutterViewController" , details: nil)) 40 | return 41 | } 42 | 43 | session.presentationContextProvider = provider 44 | session.prefersEphemeralWebBrowserSession = preferEphemeral 45 | 46 | session.start() 47 | keepMe = session 48 | } else if (call.method == "cleanUpDanglingCalls") { 49 | // we do not keep track of old callbacks on macOS, so nothing to do here 50 | result(nil) 51 | } else { 52 | result(FlutterMethodNotImplemented) 53 | } 54 | } 55 | } 56 | 57 | @available(OSX 10.15, *) 58 | extension FlutterViewController: ASWebAuthenticationPresentationContextProviding { 59 | public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { 60 | return self.view.window! 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 42 | 45 | 46 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.6.0 2 | 3 | - 💥 Upgrade to Flutter version 3.23 4 | 5 | Migration guide: 6 | 7 | The source have been updated to work with the latest version of Flutter, including upgrading from Gradle v7 to v8. Make sure that you are on the latest version on Flutter before upgrading to this version. 8 | 9 | ## 0.5.0 10 | 11 | - 💥 Upgrade to Flutter version 3 12 | 13 | Migration guide: 14 | 15 | This release drops support for Flutter v2, and adds support for Flutter v3. Make sure to upgrade to Flutter v3 when upgrading to this version. 16 | 17 | ## 0.4.3 18 | 19 | - 🐛 Revert accidental breaking change (#142) 20 | 21 | ## 0.4.2 22 | 23 | - 🎉 Add `preferEphemeral` support on macOS 24 | - 🐛 Remove null aware operators from not null widgets (#132) 25 | - 🐛 Throw a proper error on invalid callback scheme 26 | - 🌹 Add troubleshooting documentation 27 | 28 | ## 0.4.1 29 | 30 | - 🎉 Add support for Flutter "add to app" (#106) 31 | 32 | ## 0.4.0 33 | 34 | - 💥 Upgrade to Android V2 embedding (#87) 35 | 36 | Migration guide: 37 | 38 | Make sure that you are running a recent version of Flutter before upgrading. 39 | 40 | ## 0.3.2 41 | 42 | - 🎉 Add Web support (#77) 43 | 44 | ## 0.3.1 45 | 46 | - 🎉 Add support for Android Plugin API v2 (#67) 47 | - 🎉 Add support for ephemeral sessions (#64) 48 | - 🌹 Avoid deprecated RaisedButton in example (#75) 49 | - 🌹 Cleanup metadata 50 | 51 | ## 0.3.0 52 | 53 | - 💥 Add null safety support (#60) 54 | 55 | Migration guide: 56 | 57 | This version drops support for Flutter 1.x, please upgrade to Flutter 2 for continued support. 58 | 59 | ## 0.2.4 60 | 61 | - 🐛 Fix building on iOS ([#36](https://github.com/LinusU/flutter_web_auth/pull/36)) 62 | 63 | ## 0.2.3 64 | 65 | - 🐛 Remove NoHistory flag ([#33](https://github.com/LinusU/flutter_web_auth/pull/33)) 66 | - 🐛 Fix building on iOS 8, 9, and 10 ([#29](https://github.com/LinusU/flutter_web_auth/pull/29)) 67 | - 🐛 Always terminate 'authenticate' callbacks on Android ([#28](https://github.com/LinusU/flutter_web_auth/pull/28)) 68 | 69 | ## 0.2.2 70 | 71 | - 🐛 Fix propagation of "CANCELED" error on iOS ([#31](https://github.com/LinusU/flutter_web_auth/pull/31)) 72 | 73 | ## 0.2.1 74 | 75 | - 🐛 Fix AndroidX build issues ([#27](https://github.com/LinusU/flutter_web_auth/pull/27)) 76 | 77 | ## 0.2.0 78 | 79 | - 💥 Add macOS support ([#20](https://github.com/LinusU/flutter_web_auth/pull/20)) 80 | 81 | Migration guide: 82 | 83 | This version drops support for Flutter 1.9 and older, please upgrade to Flutter 1.12 for continued support. 84 | 85 | ## 0.1.3 86 | 87 | - 🎉 Update the kotlin plugin version to 1.3.61 88 | 89 | ## 0.1.2 90 | 91 | - 🎉 Add support for iOS 13 92 | 93 | ## 0.1.1 94 | 95 | - 🐛 Add swift_version to the Podspec 96 | - 🐛 Update Gradle and Kotlin versions 97 | - 🐛 Add missing link in readme 98 | 99 | ## 0.1.0 100 | 101 | - 🎉 Add initial implementation 102 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/linusu/flutter_web_auth/FlutterWebAuthPlugin.kt: -------------------------------------------------------------------------------- 1 | package com.linusu.flutter_web_auth 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.net.Uri 6 | 7 | import androidx.browser.customtabs.CustomTabsIntent 8 | 9 | import io.flutter.embedding.engine.plugins.FlutterPlugin 10 | import io.flutter.plugin.common.BinaryMessenger 11 | import io.flutter.plugin.common.MethodCall 12 | import io.flutter.plugin.common.MethodChannel 13 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler 14 | import io.flutter.plugin.common.MethodChannel.Result 15 | import io.flutter.plugin.common.PluginRegistry.Registrar 16 | 17 | class FlutterWebAuthPlugin(private var context: Context? = null, private var channel: MethodChannel? = null): MethodCallHandler, FlutterPlugin { 18 | companion object { 19 | val callbacks = mutableMapOf() 20 | 21 | @JvmStatic 22 | fun registerWith(registrar: Registrar) { 23 | val plugin = FlutterWebAuthPlugin() 24 | plugin.initInstance(registrar.messenger(), registrar.context()) 25 | } 26 | 27 | } 28 | 29 | fun initInstance(messenger: BinaryMessenger, context: Context) { 30 | this.context = context 31 | channel = MethodChannel(messenger, "flutter_web_auth") 32 | channel?.setMethodCallHandler(this) 33 | } 34 | 35 | override public fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { 36 | initInstance(binding.getBinaryMessenger(), binding.getApplicationContext()) 37 | } 38 | 39 | override public fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { 40 | context = null 41 | channel = null 42 | } 43 | 44 | override fun onMethodCall(call: MethodCall, resultCallback: Result) { 45 | when (call.method) { 46 | "authenticate" -> { 47 | val url = Uri.parse(call.argument("url")) 48 | val callbackUrlScheme = call.argument("callbackUrlScheme")!! 49 | val preferEphemeral = call.argument("preferEphemeral")!! 50 | 51 | callbacks[callbackUrlScheme] = resultCallback 52 | 53 | val intent = CustomTabsIntent.Builder().build() 54 | val keepAliveIntent = Intent(context, KeepAliveService::class.java) 55 | 56 | intent.intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) 57 | if (preferEphemeral) { 58 | intent.intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY) 59 | } 60 | intent.intent.putExtra("android.support.customtabs.extra.KEEP_ALIVE", keepAliveIntent) 61 | 62 | intent.launchUrl(context!!, url) 63 | } 64 | "cleanUpDanglingCalls" -> { 65 | callbacks.forEach{ (_, danglingResultCallback) -> 66 | danglingResultCallback.error("CANCELED", "User canceled login", null) 67 | } 68 | callbacks.clear() 69 | resultCallback.success(null) 70 | } 71 | else -> resultCallback.notImplemented() 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto init 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto init 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :init 68 | @rem Get command-line arguments, handling Windows variants 69 | 70 | if not "%OS%" == "Windows_NT" goto win9xME_args 71 | 72 | :win9xME_args 73 | @rem Slurp the command line arguments. 74 | set CMD_LINE_ARGS= 75 | set _SKIP=2 76 | 77 | :win9xME_args_slurp 78 | if "x%~1" == "x" goto execute 79 | 80 | set CMD_LINE_ARGS=%* 81 | 82 | :execute 83 | @rem Setup the command line 84 | 85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 86 | 87 | @rem Execute Gradle 88 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 89 | 90 | :end 91 | @rem End local scope for the variables with windows NT shell 92 | if "%ERRORLEVEL%"=="0" goto mainEnd 93 | 94 | :fail 95 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 96 | rem the _cmd.exe /c_ return code! 97 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 98 | exit /b 1 99 | 100 | :mainEnd 101 | if "%OS%"=="Windows_NT" endlocal 102 | 103 | :omega 104 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_web_auth_example 2 | description: "Demonstrates how to use the flutter_web_auth plugin." 3 | # The following line prevents the package from being accidentally published to 4 | # pub.dev using `flutter pub publish`. This is preferred for private packages. 5 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 6 | 7 | environment: 8 | sdk: ^3.5.3 9 | 10 | # Dependencies specify other packages that your package needs in order to work. 11 | # To automatically upgrade your package dependencies to the latest versions 12 | # consider running `flutter pub upgrade --major-versions`. Alternatively, 13 | # dependencies can be manually updated by changing the version numbers below to 14 | # the latest version available on pub.dev. To see which dependencies have newer 15 | # versions available, run `flutter pub outdated`. 16 | dependencies: 17 | flutter: 18 | sdk: flutter 19 | 20 | flutter_web_auth: 21 | # When depending on this package from a real application you should use: 22 | # flutter_web_auth: ^x.y.z 23 | # See https://dart.dev/tools/pub/dependencies#version-constraints 24 | # The example app is bundled with the plugin so we use a path dependency on 25 | # the parent directory to use the current plugin's version. 26 | path: ../ 27 | 28 | # The following adds the Cupertino Icons font to your application. 29 | # Use with the CupertinoIcons class for iOS style icons. 30 | cupertino_icons: ^1.0.8 31 | 32 | dev_dependencies: 33 | integration_test: 34 | sdk: flutter 35 | flutter_test: 36 | sdk: flutter 37 | 38 | # The "flutter_lints" package below contains a set of recommended lints to 39 | # encourage good coding practices. The lint set provided by the package is 40 | # activated in the `analysis_options.yaml` file located at the root of your 41 | # package. See that file for information about deactivating specific lint 42 | # rules and activating additional ones. 43 | flutter_lints: ^4.0.0 44 | 45 | # For information on the generic Dart part of this file, see the 46 | # following page: https://dart.dev/tools/pub/pubspec 47 | 48 | # The following section is specific to Flutter packages. 49 | flutter: 50 | 51 | # The following line ensures that the Material Icons font is 52 | # included with your application, so that you can use the icons in 53 | # the material Icons class. 54 | uses-material-design: true 55 | 56 | # To add assets to your application, add an assets section, like this: 57 | # assets: 58 | # - images/a_dot_burr.jpeg 59 | # - images/a_dot_ham.jpeg 60 | 61 | # An image asset can refer to one or more resolution-specific "variants", see 62 | # https://flutter.dev/to/resolution-aware-images 63 | 64 | # For details regarding adding assets from package dependencies, see 65 | # https://flutter.dev/to/asset-from-package 66 | 67 | # To add custom fonts to your application, add a fonts section here, 68 | # in this "flutter" section. Each entry in this list should have a 69 | # "family" key with the font family name, and a "fonts" key with a 70 | # list giving the asset and other descriptors for the font. For 71 | # example: 72 | # fonts: 73 | # - family: Schyler 74 | # fonts: 75 | # - asset: fonts/Schyler-Regular.ttf 76 | # - asset: fonts/Schyler-Italic.ttf 77 | # style: italic 78 | # - family: Trajan Pro 79 | # fonts: 80 | # - asset: fonts/TrajanPro.ttf 81 | # - asset: fonts/TrajanPro_Bold.ttf 82 | # weight: 700 83 | # 84 | # For details regarding fonts from package dependencies, 85 | # see https://flutter.dev/to/font-from-package 86 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | import 'dart:async'; 4 | import 'dart:io' show HttpServer; 5 | 6 | import 'package:flutter_web_auth/flutter_web_auth.dart'; 7 | 8 | const html = """ 9 | 10 | 11 | 12 | 13 | Grant Access to Flutter 14 | 15 | 54 | 55 | 56 |
57 |
🏇
58 |
Press the button below to sign in using your Localtest.me account.
59 | 60 |
61 | 62 | 63 | """; 64 | 65 | void main() => runApp(MyApp()); 66 | 67 | class MyApp extends StatefulWidget { 68 | @override 69 | _MyAppState createState() => _MyAppState(); 70 | } 71 | 72 | class _MyAppState extends State { 73 | String _status = ''; 74 | 75 | @override 76 | void initState() { 77 | super.initState(); 78 | startServer(); 79 | } 80 | 81 | Future startServer() async { 82 | final server = await HttpServer.bind('127.0.0.1', 43823); 83 | 84 | server.listen((req) async { 85 | setState(() { _status = 'Received request!'; }); 86 | 87 | req.response.headers.add('Content-Type', 'text/html'); 88 | req.response.write(html); 89 | req.response.close(); 90 | }); 91 | } 92 | 93 | void authenticate() async { 94 | final url = 'http://localtest.me:43823/'; 95 | final callbackUrlScheme = 'foobar'; 96 | 97 | try { 98 | final result = await FlutterWebAuth.authenticate(url: url, callbackUrlScheme: callbackUrlScheme); 99 | setState(() { _status = 'Got result: $result'; }); 100 | } on PlatformException catch (e) { 101 | setState(() { _status = 'Got error: $e'; }); 102 | } 103 | } 104 | 105 | @override 106 | Widget build(BuildContext context) { 107 | return MaterialApp( 108 | home: Scaffold( 109 | appBar: AppBar( 110 | title: const Text('Web Auth example'), 111 | ), 112 | body: Center( 113 | child: Column( 114 | mainAxisAlignment: MainAxisAlignment.center, 115 | children: [ 116 | Text('Status: $_status\n'), 117 | const SizedBox(height: 80), 118 | ElevatedButton( 119 | child: Text('Authenticate'), 120 | onPressed: () { this.authenticate(); }, 121 | ), 122 | ], 123 | ), 124 | ), 125 | ), 126 | ); 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /ios/Classes/FlutterWebAuthPlugin.swift: -------------------------------------------------------------------------------- 1 | import AuthenticationServices 2 | import SafariServices 3 | import Flutter 4 | import UIKit 5 | 6 | public class FlutterWebAuthPlugin: NSObject, FlutterPlugin { 7 | public static func register(with registrar: FlutterPluginRegistrar) { 8 | let channel = FlutterMethodChannel(name: "flutter_web_auth", binaryMessenger: registrar.messenger()) 9 | let instance = FlutterWebAuthPlugin() 10 | registrar.addMethodCallDelegate(instance, channel: channel) 11 | } 12 | 13 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { 14 | if call.method == "authenticate", 15 | let arguments = call.arguments as? Dictionary, 16 | let urlString = arguments["url"] as? String, 17 | let url = URL(string: urlString), 18 | let callbackURLScheme = arguments["callbackUrlScheme"] as? String, 19 | let preferEphemeral = arguments["preferEphemeral"] as? Bool 20 | { 21 | 22 | var sessionToKeepAlive: Any? = nil // if we do not keep the session alive, it will get closed immediately while showing the dialog 23 | let completionHandler = { (url: URL?, err: Error?) in 24 | sessionToKeepAlive = nil 25 | 26 | if let err = err { 27 | if #available(iOS 12, *) { 28 | if case ASWebAuthenticationSessionError.canceledLogin = err { 29 | result(FlutterError(code: "CANCELED", message: "User canceled login", details: nil)) 30 | return 31 | } 32 | } 33 | 34 | if #available(iOS 11, *) { 35 | if case SFAuthenticationError.canceledLogin = err { 36 | result(FlutterError(code: "CANCELED", message: "User canceled login", details: nil)) 37 | return 38 | } 39 | } 40 | 41 | result(FlutterError(code: "EUNKNOWN", message: err.localizedDescription, details: nil)) 42 | return 43 | } 44 | 45 | guard let url = url else { 46 | result(FlutterError(code: "EUNKNOWN", message: "URL was null, but no error provided.", details: nil)) 47 | return 48 | } 49 | 50 | result(url.absoluteString) 51 | } 52 | 53 | if #available(iOS 12, *) { 54 | let session = ASWebAuthenticationSession(url: url, callbackURLScheme: callbackURLScheme, completionHandler: completionHandler) 55 | 56 | if #available(iOS 13, *) { 57 | guard var topController = UIApplication.shared.keyWindow?.rootViewController else { 58 | result(FlutterError.aquireRootViewControllerFailed) 59 | return 60 | } 61 | 62 | while let presentedViewController = topController.presentedViewController { 63 | topController = presentedViewController 64 | } 65 | if let nav = topController as? UINavigationController { 66 | topController = nav.visibleViewController ?? topController 67 | } 68 | 69 | guard let contextProvider = topController as? ASWebAuthenticationPresentationContextProviding else { 70 | result(FlutterError.aquireRootViewControllerFailed) 71 | return 72 | } 73 | session.presentationContextProvider = contextProvider 74 | session.prefersEphemeralWebBrowserSession = preferEphemeral 75 | } 76 | 77 | session.start() 78 | sessionToKeepAlive = session 79 | } else if #available(iOS 11, *) { 80 | let session = SFAuthenticationSession(url: url, callbackURLScheme: callbackURLScheme, completionHandler: completionHandler) 81 | session.start() 82 | sessionToKeepAlive = session 83 | } else { 84 | result(FlutterError(code: "FAILED", message: "This plugin does currently not support iOS lower than iOS 11" , details: nil)) 85 | } 86 | } else if (call.method == "cleanUpDanglingCalls") { 87 | // we do not keep track of old callbacks on iOS, so nothing to do here 88 | result(nil) 89 | } else { 90 | result(FlutterMethodNotImplemented) 91 | } 92 | } 93 | } 94 | 95 | @available(iOS 13, *) 96 | extension FlutterViewController: ASWebAuthenticationPresentationContextProviding { 97 | public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { 98 | return self.view.window! 99 | } 100 | } 101 | 102 | fileprivate extension FlutterError { 103 | static var aquireRootViewControllerFailed: FlutterError { 104 | return FlutterError(code: "AQUIRE_ROOT_VIEW_CONTROLLER_FAILED", message: "Failed to aquire root view controller" , details: nil) 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=`expr $i + 1` 158 | done 159 | case $i in 160 | 0) set -- ;; 161 | 1) set -- "$args0" ;; 162 | 2) set -- "$args0" "$args1" ;; 163 | 3) set -- "$args0" "$args1" "$args2" ;; 164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=`save "$@"` 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | exec "$JAVACMD" "$@" 184 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "1.3.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "1.18.0" 44 | cupertino_icons: 45 | dependency: "direct main" 46 | description: 47 | name: cupertino_icons 48 | sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "1.0.8" 52 | fake_async: 53 | dependency: transitive 54 | description: 55 | name: fake_async 56 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "1.3.1" 60 | file: 61 | dependency: transitive 62 | description: 63 | name: file 64 | sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "7.0.0" 68 | flutter: 69 | dependency: "direct main" 70 | description: flutter 71 | source: sdk 72 | version: "0.0.0" 73 | flutter_driver: 74 | dependency: transitive 75 | description: flutter 76 | source: sdk 77 | version: "0.0.0" 78 | flutter_lints: 79 | dependency: "direct dev" 80 | description: 81 | name: flutter_lints 82 | sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" 83 | url: "https://pub.dev" 84 | source: hosted 85 | version: "4.0.0" 86 | flutter_test: 87 | dependency: "direct dev" 88 | description: flutter 89 | source: sdk 90 | version: "0.0.0" 91 | flutter_web_auth: 92 | dependency: "direct main" 93 | description: 94 | path: ".." 95 | relative: true 96 | source: path 97 | version: "0.6.0" 98 | flutter_web_plugins: 99 | dependency: transitive 100 | description: flutter 101 | source: sdk 102 | version: "0.0.0" 103 | fuchsia_remote_debug_protocol: 104 | dependency: transitive 105 | description: flutter 106 | source: sdk 107 | version: "0.0.0" 108 | integration_test: 109 | dependency: "direct dev" 110 | description: flutter 111 | source: sdk 112 | version: "0.0.0" 113 | leak_tracker: 114 | dependency: transitive 115 | description: 116 | name: leak_tracker 117 | sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" 118 | url: "https://pub.dev" 119 | source: hosted 120 | version: "10.0.5" 121 | leak_tracker_flutter_testing: 122 | dependency: transitive 123 | description: 124 | name: leak_tracker_flutter_testing 125 | sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" 126 | url: "https://pub.dev" 127 | source: hosted 128 | version: "3.0.5" 129 | leak_tracker_testing: 130 | dependency: transitive 131 | description: 132 | name: leak_tracker_testing 133 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" 134 | url: "https://pub.dev" 135 | source: hosted 136 | version: "3.0.1" 137 | lints: 138 | dependency: transitive 139 | description: 140 | name: lints 141 | sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" 142 | url: "https://pub.dev" 143 | source: hosted 144 | version: "4.0.0" 145 | matcher: 146 | dependency: transitive 147 | description: 148 | name: matcher 149 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 150 | url: "https://pub.dev" 151 | source: hosted 152 | version: "0.12.16+1" 153 | material_color_utilities: 154 | dependency: transitive 155 | description: 156 | name: material_color_utilities 157 | sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec 158 | url: "https://pub.dev" 159 | source: hosted 160 | version: "0.11.1" 161 | meta: 162 | dependency: transitive 163 | description: 164 | name: meta 165 | sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 166 | url: "https://pub.dev" 167 | source: hosted 168 | version: "1.15.0" 169 | path: 170 | dependency: transitive 171 | description: 172 | name: path 173 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 174 | url: "https://pub.dev" 175 | source: hosted 176 | version: "1.9.0" 177 | platform: 178 | dependency: transitive 179 | description: 180 | name: platform 181 | sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" 182 | url: "https://pub.dev" 183 | source: hosted 184 | version: "3.1.5" 185 | process: 186 | dependency: transitive 187 | description: 188 | name: process 189 | sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" 190 | url: "https://pub.dev" 191 | source: hosted 192 | version: "5.0.2" 193 | sky_engine: 194 | dependency: transitive 195 | description: flutter 196 | source: sdk 197 | version: "0.0.99" 198 | source_span: 199 | dependency: transitive 200 | description: 201 | name: source_span 202 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 203 | url: "https://pub.dev" 204 | source: hosted 205 | version: "1.10.0" 206 | stack_trace: 207 | dependency: transitive 208 | description: 209 | name: stack_trace 210 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 211 | url: "https://pub.dev" 212 | source: hosted 213 | version: "1.11.1" 214 | stream_channel: 215 | dependency: transitive 216 | description: 217 | name: stream_channel 218 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 219 | url: "https://pub.dev" 220 | source: hosted 221 | version: "2.1.2" 222 | string_scanner: 223 | dependency: transitive 224 | description: 225 | name: string_scanner 226 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 227 | url: "https://pub.dev" 228 | source: hosted 229 | version: "1.2.0" 230 | sync_http: 231 | dependency: transitive 232 | description: 233 | name: sync_http 234 | sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" 235 | url: "https://pub.dev" 236 | source: hosted 237 | version: "0.3.1" 238 | term_glyph: 239 | dependency: transitive 240 | description: 241 | name: term_glyph 242 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 243 | url: "https://pub.dev" 244 | source: hosted 245 | version: "1.2.1" 246 | test_api: 247 | dependency: transitive 248 | description: 249 | name: test_api 250 | sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" 251 | url: "https://pub.dev" 252 | source: hosted 253 | version: "0.7.2" 254 | vector_math: 255 | dependency: transitive 256 | description: 257 | name: vector_math 258 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 259 | url: "https://pub.dev" 260 | source: hosted 261 | version: "2.1.4" 262 | vm_service: 263 | dependency: transitive 264 | description: 265 | name: vm_service 266 | sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" 267 | url: "https://pub.dev" 268 | source: hosted 269 | version: "14.2.5" 270 | webdriver: 271 | dependency: transitive 272 | description: 273 | name: webdriver 274 | sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" 275 | url: "https://pub.dev" 276 | source: hosted 277 | version: "3.0.3" 278 | sdks: 279 | dart: ">=3.5.3 <4.0.0" 280 | flutter: ">=3.18.0-18.0.pre.54" 281 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Web Auth for Flutter 2 | 3 | A Flutter plugin for authenticating a user with a web service, even if the web service is run by a third party. Most commonly used with OAuth2, but can be used with any web flow that can redirect to a custom scheme. 4 | 5 | In the background, this plugin uses [`ASWebAuthenticationSession`][ASWebAuthenticationSession] on iOS 12+ and macOS 10.15+, [`SFAuthenticationSession`][SFAuthenticationSession] on iOS 11, [Chrome Custom Tabs][Chrome Custom Tabs] on Android and opens a new window on Web. You can build it with iOS 8+, but it is currently only supported by iOS 11 or higher. 6 | 7 | [ASWebAuthenticationSession]: https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession 8 | [SFAuthenticationSession]: https://developer.apple.com/documentation/safariservices/sfauthenticationsession 9 | [Chrome Custom Tabs]: https://developer.chrome.com/multidevice/android/customtabs 10 | 11 | | **iOS** | **Android** | 12 | | ---------------------- | ------------------------------ | 13 | | ![iOS](screen-ios.gif) | ![Android](screen-android.gif) | 14 | 15 | | **macOS** | 16 | | -------------------------- | 17 | | ![macOS](screen-macos.gif) | 18 | 19 | ## Usage 20 | 21 | To authenticate against your own custom site: 22 | 23 | ```dart 24 | import 'package:flutter_web_auth/flutter_web_auth.dart'; 25 | 26 | // Present the dialog to the user 27 | final result = await FlutterWebAuth.authenticate(url: "https://my-custom-app.com/connect", callbackUrlScheme: "my-custom-app"); 28 | 29 | // Extract token from resulting url 30 | final token = Uri.parse(result).queryParameters['token'] 31 | ``` 32 | 33 | To authenticate the user using Google's OAuth2: 34 | 35 | ```dart 36 | import 'package:flutter_web_auth/flutter_web_auth.dart'; 37 | 38 | import 'dart:convert' show jsonDecode; 39 | import 'package:http/http.dart' as http; 40 | 41 | // App specific variables 42 | final googleClientId = 'XXXXXXXXXXXX-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com'; 43 | final callbackUrlScheme = 'com.googleusercontent.apps.XXXXXXXXXXXX-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; 44 | 45 | // Construct the url 46 | final url = Uri.https('accounts.google.com', '/o/oauth2/v2/auth', { 47 | 'response_type': 'code', 48 | 'client_id': googleClientId, 49 | 'redirect_uri': '$callbackUrlScheme:/', 50 | 'scope': 'email', 51 | }); 52 | 53 | // Present the dialog to the user 54 | final result = await FlutterWebAuth.authenticate(url: url.toString(), callbackUrlScheme: callbackUrlScheme); 55 | 56 | // Extract code from resulting url 57 | final code = Uri.parse(result).queryParameters['code']; 58 | 59 | // Construct an Uri to Google's oauth2 endpoint 60 | final url = Uri.https('www.googleapis.com', 'oauth2/v4/token'); 61 | 62 | // Use this code to get an access token 63 | final response = await http.post(url, body: { 64 | 'client_id': googleClientId, 65 | 'redirect_uri': '$callbackUrlScheme:/', 66 | 'grant_type': 'authorization_code', 67 | 'code': code, 68 | }); 69 | 70 | // Get the access token from the response 71 | final accessToken = jsonDecode(response.body)['access_token'] as String; 72 | ``` 73 | 74 | **Note:** To use multiple scopes with Google, you need to encode them as a single string, separated by spaces. For example, `scope: 'email https://www.googleapis.com/auth/userinfo.profile'`. Here is [a list of all supported scopes](https://developers.google.com/identity/protocols/oauth2/scopes). 75 | 76 | ## Setup 77 | 78 | Setup works as for any Flutter plugin, expect the Android and Web caveats outlined below: 79 | 80 | ### Android 81 | 82 | In order to capture the callback url, the following `activity` needs to be added to your `AndroidManifest.xml`. Be sure to relpace `YOUR_CALLBACK_URL_SCHEME_HERE` with your actual callback url scheme. 83 | 84 | ```xml 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | ``` 100 | 101 | ### Web 102 | 103 | On the Web platform an endpoint needs to be created that captures the callback URL and sends it to the application using the JavaScript `postMessage()` method. In the `./web` folder of the project, create an HTML file with the name e.g. `auth.html` with content: 104 | 105 | ```html 106 | 107 | Authentication complete 108 |

Authentication is complete. If this does not happen automatically, please 109 | close the window. 110 | 116 | ``` 117 | 118 | Redirection URL passed to the authentication service must be the same as the URL on which the application is running (schema, host, port if necessary) and the path must point to created HTML file, `/auth.html` in this case. The `callbackUrlScheme` parameter of the `authenticate()` method does not take into account, so it is possible to use a schema for native platforms in the code. 119 | 120 | For the Sign in with Apple in web_message response mode, postMessage from https://appleid.apple.com is also captured, and the authorization object is returned as a URL fragment encoded as a query string (for compatibility with other providers). 121 | 122 | ## Troubleshooting 123 | 124 | When you use this package for the first time, there are some problems you may have. These are some of the common solutions 125 | 126 | ### Troubleshooting `callbackUrlScheme` 127 | 128 | - `callbackUrlScheme` must be a valid schema string or else this wont work. 129 | - A valid RFC 3986 URL scheme must consist of "a letter and followed by any combination of letters, digits, plus ("+"), period ("."), or hyphen ("-")." 130 | - scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) 131 | - This means you can not use underscore "_", space " " or uppercase "ABCDEF...". You can not also start with a number. See [RFC3986#page-17](https://www.rfc-editor.org/rfc/rfc3986#page-17) 132 | - examples of VALID `callbackUrlScheme` are `callback-scheme`, `another.scheme`, `examplescheme` 133 | - examples of INVALID `callbackUrlScheme` are `callback_scheme`,`1another.scheme`, `exampleScheme` 134 | 135 | ### Troubleshooting Flutter App 136 | 137 | - You have to tell the `FlutterWebAuth.authenticate` function what your `callbackUrlScheme` is. 138 | - Example if your `callbackUrlScheme` is `valid-callback-scheme`, your dart code will look like 139 | 140 | ```dart 141 | import 'package:flutter_web_auth/flutter_web_auth.dart'; 142 | 143 | // Present the dialog to the user 144 | final result = await FlutterWebAuth.authenticate(url: "https://my-custom-app.com/connect", callbackUrlScheme: "valid-callback-scheme"); 145 | ``` 146 | 147 | ### Troubleshooting Android 148 | 149 | - You are required to update your `AndroidManifest.xml` to include the `com.linusu.flutter_web_auth.CallbackActivity` activity something like 150 | 151 | ```xml 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | ``` 168 | 169 | - Example of valid `AndroidManifest.xml` with VALID `callbackUrlScheme`. in the example below `valid-callback-scheme` is our `callbackUrlScheme` 170 | 171 | ```xml 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | ``` 187 | 188 | - If you are targeting S+ (version 31 and above) you need to provide an explicit value for `android:exported`. If you followed earlier installation instructions this was not included. Make sure that you add `android:exported="true"` to the `com.linusu.flutter_web_auth.CallbackActivity` activity in your `AndroidManifest.xml` file. 189 | 190 | ```diff 191 | - 192 | + 193 | ``` 194 | 195 | ### Troubleshooting OAuth redirects 196 | 197 | - Your OAuth Provider must redirect to the valid `callbackUrlScheme` + `://`. This mean if your `callbackUrlScheme` is `validscheme`, your OAuth Provider must redirect to `validscheme://` 198 | - Example with `php` 199 | ```php 200 | Go Back to App 212 | ``` 213 | 214 | ### Troubleshooting passing data to app 215 | 216 | - You can pass data back to your app by adding GET query parameters. This means by adding name=value type of data after your `callbackUrlScheme` + `://` + `?` 217 | - example to pass `access-token` to your app a valid url for that could be 218 | 219 | ```text 220 | my-callback-schema://?access-token=jdu9292s 221 | ``` 222 | 223 | - You can pass multipe data by concatenating with `&` 224 | 225 | ```text 226 | my-callback-schema://?data1=value1&data2=value2 227 | ``` 228 | 229 | - example to pass `access-token` and `user_id` to your app a valid url for that could be 230 | 231 | ```text 232 | my-callback-schema://?access-token=jdu9292s&user_id=23 233 | ``` 234 | 235 | - You can get the data in your app by using `Uri.parse(result).queryParameters` 236 | 237 | ```dart 238 | // Present the dialog to the user 239 | final result = await FlutterWebAuth.authenticate(url: "https://my-custom-app.com/connect", callbackUrlScheme: "valid-callback-scheme"); 240 | // Extract token from resulting url 241 | String accessToken = Uri.parse(result).queryParameters['access-token']; 242 | String userId = Uri.parse(result).queryParameters['user_id']; 243 | ``` 244 | 245 | ### Cannot open keyboard on iOS 246 | 247 | This seems to be a bug in `ASWebAuthenticationSession`, and no work around have been found. Please see [issue #120](https://github.com/LinusU/flutter_web_auth/issues/120) for more info. 248 | 249 | ### Error on macOS if Chrome is default browser 250 | 251 | This seems to be a bug in `ASWebAuthenticationSession`, and no work around have been found. Please see [issue #136](https://github.com/LinusU/flutter_web_auth/issues/136) for more info. 252 | -------------------------------------------------------------------------------- /example/macos/Runner/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |

24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | A3143F062D0495028253E2F1 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B8E2FE615F702B8C539DF7F /* Pods_Runner.framework */; }; 18 | A7A9D35890057D806AACAE05 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECA7C49ED332AB6540F2FFBE /* Pods_RunnerTests.framework */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 97C146E61CF9000F007C117D /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = 97C146ED1CF9000F007C117D; 27 | remoteInfo = Runner; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXCopyFilesBuildPhase section */ 32 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 33 | isa = PBXCopyFilesBuildPhase; 34 | buildActionMask = 2147483647; 35 | dstPath = ""; 36 | dstSubfolderSpec = 10; 37 | files = ( 38 | ); 39 | name = "Embed Frameworks"; 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXCopyFilesBuildPhase section */ 43 | 44 | /* Begin PBXFileReference section */ 45 | 0E026D3883213B0E1D243BE3 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 46 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 47 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 48 | 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 49 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 51 | 6B8E2FE615F702B8C539DF7F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 53 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 54 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 55 | 884805677B771AC65FBEC69C /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 56 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 57 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 58 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 60 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 61 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 62 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 63 | A8DEF5409B07AC609F30F05E /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 64 | BB0862EB4003D6C6163E9725 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 65 | DC6DF15CF2F84F3224C59BA6 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 66 | ECA7C49ED332AB6540F2FFBE /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | F1A746F38A623793558F9DA3 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 68 | /* End PBXFileReference section */ 69 | 70 | /* Begin PBXFrameworksBuildPhase section */ 71 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | A3143F062D0495028253E2F1 /* Pods_Runner.framework in Frameworks */, 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | B9ED3590DFDC6A6586B8E77D /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | A7A9D35890057D806AACAE05 /* Pods_RunnerTests.framework in Frameworks */, 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | /* End PBXFrameworksBuildPhase section */ 88 | 89 | /* Begin PBXGroup section */ 90 | 21BB9C9D6170E03B053D9C76 /* Pods */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | DC6DF15CF2F84F3224C59BA6 /* Pods-Runner.debug.xcconfig */, 94 | BB0862EB4003D6C6163E9725 /* Pods-Runner.release.xcconfig */, 95 | 0E026D3883213B0E1D243BE3 /* Pods-Runner.profile.xcconfig */, 96 | A8DEF5409B07AC609F30F05E /* Pods-RunnerTests.debug.xcconfig */, 97 | F1A746F38A623793558F9DA3 /* Pods-RunnerTests.release.xcconfig */, 98 | 884805677B771AC65FBEC69C /* Pods-RunnerTests.profile.xcconfig */, 99 | ); 100 | name = Pods; 101 | path = Pods; 102 | sourceTree = ""; 103 | }; 104 | 2662D64544CA3970C2FC3142 /* Frameworks */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 6B8E2FE615F702B8C539DF7F /* Pods_Runner.framework */, 108 | ECA7C49ED332AB6540F2FFBE /* Pods_RunnerTests.framework */, 109 | ); 110 | name = Frameworks; 111 | sourceTree = ""; 112 | }; 113 | 331C8082294A63A400263BE5 /* RunnerTests */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 331C807B294A618700263BE5 /* RunnerTests.swift */, 117 | ); 118 | path = RunnerTests; 119 | sourceTree = ""; 120 | }; 121 | 9740EEB11CF90186004384FC /* Flutter */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 125 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 126 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 127 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 128 | ); 129 | name = Flutter; 130 | sourceTree = ""; 131 | }; 132 | 97C146E51CF9000F007C117D = { 133 | isa = PBXGroup; 134 | children = ( 135 | 9740EEB11CF90186004384FC /* Flutter */, 136 | 97C146F01CF9000F007C117D /* Runner */, 137 | 97C146EF1CF9000F007C117D /* Products */, 138 | 331C8082294A63A400263BE5 /* RunnerTests */, 139 | 21BB9C9D6170E03B053D9C76 /* Pods */, 140 | 2662D64544CA3970C2FC3142 /* Frameworks */, 141 | ); 142 | sourceTree = ""; 143 | }; 144 | 97C146EF1CF9000F007C117D /* Products */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | 97C146EE1CF9000F007C117D /* Runner.app */, 148 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */, 149 | ); 150 | name = Products; 151 | sourceTree = ""; 152 | }; 153 | 97C146F01CF9000F007C117D /* Runner */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 157 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 158 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 159 | 97C147021CF9000F007C117D /* Info.plist */, 160 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 161 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 162 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 163 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 164 | ); 165 | path = Runner; 166 | sourceTree = ""; 167 | }; 168 | /* End PBXGroup section */ 169 | 170 | /* Begin PBXNativeTarget section */ 171 | 331C8080294A63A400263BE5 /* RunnerTests */ = { 172 | isa = PBXNativeTarget; 173 | buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; 174 | buildPhases = ( 175 | 1FE375C65236475469EA4B9B /* [CP] Check Pods Manifest.lock */, 176 | 331C807D294A63A400263BE5 /* Sources */, 177 | 331C807F294A63A400263BE5 /* Resources */, 178 | B9ED3590DFDC6A6586B8E77D /* Frameworks */, 179 | ); 180 | buildRules = ( 181 | ); 182 | dependencies = ( 183 | 331C8086294A63A400263BE5 /* PBXTargetDependency */, 184 | ); 185 | name = RunnerTests; 186 | productName = RunnerTests; 187 | productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; 188 | productType = "com.apple.product-type.bundle.unit-test"; 189 | }; 190 | 97C146ED1CF9000F007C117D /* Runner */ = { 191 | isa = PBXNativeTarget; 192 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 193 | buildPhases = ( 194 | B9216A486AD22F945C3018D4 /* [CP] Check Pods Manifest.lock */, 195 | 9740EEB61CF901F6004384FC /* Run Script */, 196 | 97C146EA1CF9000F007C117D /* Sources */, 197 | 97C146EB1CF9000F007C117D /* Frameworks */, 198 | 97C146EC1CF9000F007C117D /* Resources */, 199 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 200 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 201 | C16CEE4270A639EDEB2E24F8 /* [CP] Embed Pods Frameworks */, 202 | ); 203 | buildRules = ( 204 | ); 205 | dependencies = ( 206 | ); 207 | name = Runner; 208 | productName = Runner; 209 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 210 | productType = "com.apple.product-type.application"; 211 | }; 212 | /* End PBXNativeTarget section */ 213 | 214 | /* Begin PBXProject section */ 215 | 97C146E61CF9000F007C117D /* Project object */ = { 216 | isa = PBXProject; 217 | attributes = { 218 | BuildIndependentTargetsInParallel = YES; 219 | LastUpgradeCheck = 1510; 220 | ORGANIZATIONNAME = ""; 221 | TargetAttributes = { 222 | 331C8080294A63A400263BE5 = { 223 | CreatedOnToolsVersion = 14.0; 224 | TestTargetID = 97C146ED1CF9000F007C117D; 225 | }; 226 | 97C146ED1CF9000F007C117D = { 227 | CreatedOnToolsVersion = 7.3.1; 228 | LastSwiftMigration = 1100; 229 | }; 230 | }; 231 | }; 232 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 233 | compatibilityVersion = "Xcode 9.3"; 234 | developmentRegion = en; 235 | hasScannedForEncodings = 0; 236 | knownRegions = ( 237 | en, 238 | Base, 239 | ); 240 | mainGroup = 97C146E51CF9000F007C117D; 241 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 242 | projectDirPath = ""; 243 | projectRoot = ""; 244 | targets = ( 245 | 97C146ED1CF9000F007C117D /* Runner */, 246 | 331C8080294A63A400263BE5 /* RunnerTests */, 247 | ); 248 | }; 249 | /* End PBXProject section */ 250 | 251 | /* Begin PBXResourcesBuildPhase section */ 252 | 331C807F294A63A400263BE5 /* Resources */ = { 253 | isa = PBXResourcesBuildPhase; 254 | buildActionMask = 2147483647; 255 | files = ( 256 | ); 257 | runOnlyForDeploymentPostprocessing = 0; 258 | }; 259 | 97C146EC1CF9000F007C117D /* Resources */ = { 260 | isa = PBXResourcesBuildPhase; 261 | buildActionMask = 2147483647; 262 | files = ( 263 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 264 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 265 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 266 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 267 | ); 268 | runOnlyForDeploymentPostprocessing = 0; 269 | }; 270 | /* End PBXResourcesBuildPhase section */ 271 | 272 | /* Begin PBXShellScriptBuildPhase section */ 273 | 1FE375C65236475469EA4B9B /* [CP] Check Pods Manifest.lock */ = { 274 | isa = PBXShellScriptBuildPhase; 275 | buildActionMask = 2147483647; 276 | files = ( 277 | ); 278 | inputFileListPaths = ( 279 | ); 280 | inputPaths = ( 281 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 282 | "${PODS_ROOT}/Manifest.lock", 283 | ); 284 | name = "[CP] Check Pods Manifest.lock"; 285 | outputFileListPaths = ( 286 | ); 287 | outputPaths = ( 288 | "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", 289 | ); 290 | runOnlyForDeploymentPostprocessing = 0; 291 | shellPath = /bin/sh; 292 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 293 | showEnvVarsInLog = 0; 294 | }; 295 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 296 | isa = PBXShellScriptBuildPhase; 297 | alwaysOutOfDate = 1; 298 | buildActionMask = 2147483647; 299 | files = ( 300 | ); 301 | inputPaths = ( 302 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 303 | ); 304 | name = "Thin Binary"; 305 | outputPaths = ( 306 | ); 307 | runOnlyForDeploymentPostprocessing = 0; 308 | shellPath = /bin/sh; 309 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 310 | }; 311 | 9740EEB61CF901F6004384FC /* Run Script */ = { 312 | isa = PBXShellScriptBuildPhase; 313 | alwaysOutOfDate = 1; 314 | buildActionMask = 2147483647; 315 | files = ( 316 | ); 317 | inputPaths = ( 318 | ); 319 | name = "Run Script"; 320 | outputPaths = ( 321 | ); 322 | runOnlyForDeploymentPostprocessing = 0; 323 | shellPath = /bin/sh; 324 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 325 | }; 326 | B9216A486AD22F945C3018D4 /* [CP] Check Pods Manifest.lock */ = { 327 | isa = PBXShellScriptBuildPhase; 328 | buildActionMask = 2147483647; 329 | files = ( 330 | ); 331 | inputFileListPaths = ( 332 | ); 333 | inputPaths = ( 334 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 335 | "${PODS_ROOT}/Manifest.lock", 336 | ); 337 | name = "[CP] Check Pods Manifest.lock"; 338 | outputFileListPaths = ( 339 | ); 340 | outputPaths = ( 341 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 342 | ); 343 | runOnlyForDeploymentPostprocessing = 0; 344 | shellPath = /bin/sh; 345 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 346 | showEnvVarsInLog = 0; 347 | }; 348 | C16CEE4270A639EDEB2E24F8 /* [CP] Embed Pods Frameworks */ = { 349 | isa = PBXShellScriptBuildPhase; 350 | buildActionMask = 2147483647; 351 | files = ( 352 | ); 353 | inputFileListPaths = ( 354 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 355 | ); 356 | name = "[CP] Embed Pods Frameworks"; 357 | outputFileListPaths = ( 358 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 359 | ); 360 | runOnlyForDeploymentPostprocessing = 0; 361 | shellPath = /bin/sh; 362 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 363 | showEnvVarsInLog = 0; 364 | }; 365 | /* End PBXShellScriptBuildPhase section */ 366 | 367 | /* Begin PBXSourcesBuildPhase section */ 368 | 331C807D294A63A400263BE5 /* Sources */ = { 369 | isa = PBXSourcesBuildPhase; 370 | buildActionMask = 2147483647; 371 | files = ( 372 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | }; 376 | 97C146EA1CF9000F007C117D /* Sources */ = { 377 | isa = PBXSourcesBuildPhase; 378 | buildActionMask = 2147483647; 379 | files = ( 380 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 381 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 382 | ); 383 | runOnlyForDeploymentPostprocessing = 0; 384 | }; 385 | /* End PBXSourcesBuildPhase section */ 386 | 387 | /* Begin PBXTargetDependency section */ 388 | 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { 389 | isa = PBXTargetDependency; 390 | target = 97C146ED1CF9000F007C117D /* Runner */; 391 | targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; 392 | }; 393 | /* End PBXTargetDependency section */ 394 | 395 | /* Begin PBXVariantGroup section */ 396 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 397 | isa = PBXVariantGroup; 398 | children = ( 399 | 97C146FB1CF9000F007C117D /* Base */, 400 | ); 401 | name = Main.storyboard; 402 | sourceTree = ""; 403 | }; 404 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 405 | isa = PBXVariantGroup; 406 | children = ( 407 | 97C147001CF9000F007C117D /* Base */, 408 | ); 409 | name = LaunchScreen.storyboard; 410 | sourceTree = ""; 411 | }; 412 | /* End PBXVariantGroup section */ 413 | 414 | /* Begin XCBuildConfiguration section */ 415 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 416 | isa = XCBuildConfiguration; 417 | buildSettings = { 418 | ALWAYS_SEARCH_USER_PATHS = NO; 419 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 420 | CLANG_ANALYZER_NONNULL = YES; 421 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 422 | CLANG_CXX_LIBRARY = "libc++"; 423 | CLANG_ENABLE_MODULES = YES; 424 | CLANG_ENABLE_OBJC_ARC = YES; 425 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 426 | CLANG_WARN_BOOL_CONVERSION = YES; 427 | CLANG_WARN_COMMA = YES; 428 | CLANG_WARN_CONSTANT_CONVERSION = YES; 429 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 430 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 431 | CLANG_WARN_EMPTY_BODY = YES; 432 | CLANG_WARN_ENUM_CONVERSION = YES; 433 | CLANG_WARN_INFINITE_RECURSION = YES; 434 | CLANG_WARN_INT_CONVERSION = YES; 435 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 436 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 437 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 438 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 439 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 440 | CLANG_WARN_STRICT_PROTOTYPES = YES; 441 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 442 | CLANG_WARN_UNREACHABLE_CODE = YES; 443 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 444 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 445 | COPY_PHASE_STRIP = NO; 446 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 447 | ENABLE_NS_ASSERTIONS = NO; 448 | ENABLE_STRICT_OBJC_MSGSEND = YES; 449 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 450 | GCC_C_LANGUAGE_STANDARD = gnu99; 451 | GCC_NO_COMMON_BLOCKS = YES; 452 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 453 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 454 | GCC_WARN_UNDECLARED_SELECTOR = YES; 455 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 456 | GCC_WARN_UNUSED_FUNCTION = YES; 457 | GCC_WARN_UNUSED_VARIABLE = YES; 458 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 459 | MTL_ENABLE_DEBUG_INFO = NO; 460 | SDKROOT = iphoneos; 461 | SUPPORTED_PLATFORMS = iphoneos; 462 | TARGETED_DEVICE_FAMILY = "1,2"; 463 | VALIDATE_PRODUCT = YES; 464 | }; 465 | name = Profile; 466 | }; 467 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 468 | isa = XCBuildConfiguration; 469 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 470 | buildSettings = { 471 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 472 | CLANG_ENABLE_MODULES = YES; 473 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 474 | DEVELOPMENT_TEAM = TUYUZ63ZY8; 475 | ENABLE_BITCODE = NO; 476 | INFOPLIST_FILE = Runner/Info.plist; 477 | LD_RUNPATH_SEARCH_PATHS = ( 478 | "$(inherited)", 479 | "@executable_path/Frameworks", 480 | ); 481 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWebAuthExample; 482 | PRODUCT_NAME = "$(TARGET_NAME)"; 483 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 484 | SWIFT_VERSION = 5.0; 485 | VERSIONING_SYSTEM = "apple-generic"; 486 | }; 487 | name = Profile; 488 | }; 489 | 331C8088294A63A400263BE5 /* Debug */ = { 490 | isa = XCBuildConfiguration; 491 | baseConfigurationReference = A8DEF5409B07AC609F30F05E /* Pods-RunnerTests.debug.xcconfig */; 492 | buildSettings = { 493 | BUNDLE_LOADER = "$(TEST_HOST)"; 494 | CODE_SIGN_STYLE = Automatic; 495 | CURRENT_PROJECT_VERSION = 1; 496 | GENERATE_INFOPLIST_FILE = YES; 497 | MARKETING_VERSION = 1.0; 498 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWebAuthExample.RunnerTests; 499 | PRODUCT_NAME = "$(TARGET_NAME)"; 500 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 501 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 502 | SWIFT_VERSION = 5.0; 503 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 504 | }; 505 | name = Debug; 506 | }; 507 | 331C8089294A63A400263BE5 /* Release */ = { 508 | isa = XCBuildConfiguration; 509 | baseConfigurationReference = F1A746F38A623793558F9DA3 /* Pods-RunnerTests.release.xcconfig */; 510 | buildSettings = { 511 | BUNDLE_LOADER = "$(TEST_HOST)"; 512 | CODE_SIGN_STYLE = Automatic; 513 | CURRENT_PROJECT_VERSION = 1; 514 | GENERATE_INFOPLIST_FILE = YES; 515 | MARKETING_VERSION = 1.0; 516 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWebAuthExample.RunnerTests; 517 | PRODUCT_NAME = "$(TARGET_NAME)"; 518 | SWIFT_VERSION = 5.0; 519 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 520 | }; 521 | name = Release; 522 | }; 523 | 331C808A294A63A400263BE5 /* Profile */ = { 524 | isa = XCBuildConfiguration; 525 | baseConfigurationReference = 884805677B771AC65FBEC69C /* Pods-RunnerTests.profile.xcconfig */; 526 | buildSettings = { 527 | BUNDLE_LOADER = "$(TEST_HOST)"; 528 | CODE_SIGN_STYLE = Automatic; 529 | CURRENT_PROJECT_VERSION = 1; 530 | GENERATE_INFOPLIST_FILE = YES; 531 | MARKETING_VERSION = 1.0; 532 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWebAuthExample.RunnerTests; 533 | PRODUCT_NAME = "$(TARGET_NAME)"; 534 | SWIFT_VERSION = 5.0; 535 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 536 | }; 537 | name = Profile; 538 | }; 539 | 97C147031CF9000F007C117D /* Debug */ = { 540 | isa = XCBuildConfiguration; 541 | buildSettings = { 542 | ALWAYS_SEARCH_USER_PATHS = NO; 543 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 544 | CLANG_ANALYZER_NONNULL = YES; 545 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 546 | CLANG_CXX_LIBRARY = "libc++"; 547 | CLANG_ENABLE_MODULES = YES; 548 | CLANG_ENABLE_OBJC_ARC = YES; 549 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 550 | CLANG_WARN_BOOL_CONVERSION = YES; 551 | CLANG_WARN_COMMA = YES; 552 | CLANG_WARN_CONSTANT_CONVERSION = YES; 553 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 554 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 555 | CLANG_WARN_EMPTY_BODY = YES; 556 | CLANG_WARN_ENUM_CONVERSION = YES; 557 | CLANG_WARN_INFINITE_RECURSION = YES; 558 | CLANG_WARN_INT_CONVERSION = YES; 559 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 560 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 561 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 562 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 563 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 564 | CLANG_WARN_STRICT_PROTOTYPES = YES; 565 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 566 | CLANG_WARN_UNREACHABLE_CODE = YES; 567 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 568 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 569 | COPY_PHASE_STRIP = NO; 570 | DEBUG_INFORMATION_FORMAT = dwarf; 571 | ENABLE_STRICT_OBJC_MSGSEND = YES; 572 | ENABLE_TESTABILITY = YES; 573 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 574 | GCC_C_LANGUAGE_STANDARD = gnu99; 575 | GCC_DYNAMIC_NO_PIC = NO; 576 | GCC_NO_COMMON_BLOCKS = YES; 577 | GCC_OPTIMIZATION_LEVEL = 0; 578 | GCC_PREPROCESSOR_DEFINITIONS = ( 579 | "DEBUG=1", 580 | "$(inherited)", 581 | ); 582 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 583 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 584 | GCC_WARN_UNDECLARED_SELECTOR = YES; 585 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 586 | GCC_WARN_UNUSED_FUNCTION = YES; 587 | GCC_WARN_UNUSED_VARIABLE = YES; 588 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 589 | MTL_ENABLE_DEBUG_INFO = YES; 590 | ONLY_ACTIVE_ARCH = YES; 591 | SDKROOT = iphoneos; 592 | TARGETED_DEVICE_FAMILY = "1,2"; 593 | }; 594 | name = Debug; 595 | }; 596 | 97C147041CF9000F007C117D /* Release */ = { 597 | isa = XCBuildConfiguration; 598 | buildSettings = { 599 | ALWAYS_SEARCH_USER_PATHS = NO; 600 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 601 | CLANG_ANALYZER_NONNULL = YES; 602 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 603 | CLANG_CXX_LIBRARY = "libc++"; 604 | CLANG_ENABLE_MODULES = YES; 605 | CLANG_ENABLE_OBJC_ARC = YES; 606 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 607 | CLANG_WARN_BOOL_CONVERSION = YES; 608 | CLANG_WARN_COMMA = YES; 609 | CLANG_WARN_CONSTANT_CONVERSION = YES; 610 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 611 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 612 | CLANG_WARN_EMPTY_BODY = YES; 613 | CLANG_WARN_ENUM_CONVERSION = YES; 614 | CLANG_WARN_INFINITE_RECURSION = YES; 615 | CLANG_WARN_INT_CONVERSION = YES; 616 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 617 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 618 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 619 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 620 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 621 | CLANG_WARN_STRICT_PROTOTYPES = YES; 622 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 623 | CLANG_WARN_UNREACHABLE_CODE = YES; 624 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 625 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 626 | COPY_PHASE_STRIP = NO; 627 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 628 | ENABLE_NS_ASSERTIONS = NO; 629 | ENABLE_STRICT_OBJC_MSGSEND = YES; 630 | ENABLE_USER_SCRIPT_SANDBOXING = NO; 631 | GCC_C_LANGUAGE_STANDARD = gnu99; 632 | GCC_NO_COMMON_BLOCKS = YES; 633 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 634 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 635 | GCC_WARN_UNDECLARED_SELECTOR = YES; 636 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 637 | GCC_WARN_UNUSED_FUNCTION = YES; 638 | GCC_WARN_UNUSED_VARIABLE = YES; 639 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 640 | MTL_ENABLE_DEBUG_INFO = NO; 641 | SDKROOT = iphoneos; 642 | SUPPORTED_PLATFORMS = iphoneos; 643 | SWIFT_COMPILATION_MODE = wholemodule; 644 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 645 | TARGETED_DEVICE_FAMILY = "1,2"; 646 | VALIDATE_PRODUCT = YES; 647 | }; 648 | name = Release; 649 | }; 650 | 97C147061CF9000F007C117D /* Debug */ = { 651 | isa = XCBuildConfiguration; 652 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 653 | buildSettings = { 654 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 655 | CLANG_ENABLE_MODULES = YES; 656 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 657 | DEVELOPMENT_TEAM = TUYUZ63ZY8; 658 | ENABLE_BITCODE = NO; 659 | INFOPLIST_FILE = Runner/Info.plist; 660 | LD_RUNPATH_SEARCH_PATHS = ( 661 | "$(inherited)", 662 | "@executable_path/Frameworks", 663 | ); 664 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWebAuthExample; 665 | PRODUCT_NAME = "$(TARGET_NAME)"; 666 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 667 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 668 | SWIFT_VERSION = 5.0; 669 | VERSIONING_SYSTEM = "apple-generic"; 670 | }; 671 | name = Debug; 672 | }; 673 | 97C147071CF9000F007C117D /* Release */ = { 674 | isa = XCBuildConfiguration; 675 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 676 | buildSettings = { 677 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 678 | CLANG_ENABLE_MODULES = YES; 679 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 680 | DEVELOPMENT_TEAM = TUYUZ63ZY8; 681 | ENABLE_BITCODE = NO; 682 | INFOPLIST_FILE = Runner/Info.plist; 683 | LD_RUNPATH_SEARCH_PATHS = ( 684 | "$(inherited)", 685 | "@executable_path/Frameworks", 686 | ); 687 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterWebAuthExample; 688 | PRODUCT_NAME = "$(TARGET_NAME)"; 689 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 690 | SWIFT_VERSION = 5.0; 691 | VERSIONING_SYSTEM = "apple-generic"; 692 | }; 693 | name = Release; 694 | }; 695 | /* End XCBuildConfiguration section */ 696 | 697 | /* Begin XCConfigurationList section */ 698 | 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { 699 | isa = XCConfigurationList; 700 | buildConfigurations = ( 701 | 331C8088294A63A400263BE5 /* Debug */, 702 | 331C8089294A63A400263BE5 /* Release */, 703 | 331C808A294A63A400263BE5 /* Profile */, 704 | ); 705 | defaultConfigurationIsVisible = 0; 706 | defaultConfigurationName = Release; 707 | }; 708 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 709 | isa = XCConfigurationList; 710 | buildConfigurations = ( 711 | 97C147031CF9000F007C117D /* Debug */, 712 | 97C147041CF9000F007C117D /* Release */, 713 | 249021D3217E4FDB00AE95B9 /* Profile */, 714 | ); 715 | defaultConfigurationIsVisible = 0; 716 | defaultConfigurationName = Release; 717 | }; 718 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 719 | isa = XCConfigurationList; 720 | buildConfigurations = ( 721 | 97C147061CF9000F007C117D /* Debug */, 722 | 97C147071CF9000F007C117D /* Release */, 723 | 249021D4217E4FDB00AE95B9 /* Profile */, 724 | ); 725 | defaultConfigurationIsVisible = 0; 726 | defaultConfigurationName = Release; 727 | }; 728 | /* End XCConfigurationList section */ 729 | }; 730 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 731 | } 732 | --------------------------------------------------------------------------------