├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── android ├── .classpath ├── .gradle │ └── vcs-1 │ │ └── gc.properties ├── .project ├── .settings │ ├── org.eclipse.buildship.core.prefs │ └── org.eclipse.jdt.core.prefs ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── io │ └── flutter │ └── plugins │ └── flutterauth0 │ ├── AuthenticationReceiver.java │ ├── FlutterAuth0Plugin.java │ └── common │ └── AuthenticationFactory.java ├── example ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .project │ ├── .settings │ │ └── org.eclipse.buildship.core.prefs │ ├── app │ │ ├── .classpath │ │ ├── .project │ │ ├── .settings │ │ │ ├── org.eclipse.buildship.core.prefs │ │ │ └── org.eclipse.jdt.core.prefs │ │ ├── build.gradle │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ ├── com │ │ │ │ └── example │ │ │ │ │ └── flutterauth0 │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── RedirectUriReceiver.java │ │ │ └── io │ │ │ │ └── flutter │ │ │ │ └── plugins │ │ │ │ └── GeneratedPluginRegistrant.java │ │ │ └── res │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── 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 │ │ │ └── values │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── flutter_auth0.iml ├── flutter_auth0_android.iml ├── ios │ ├── .symlinks │ │ ├── flutter │ │ └── plugins │ │ │ └── flutter_auth0 │ ├── Flutter │ │ ├── App.framework │ │ │ ├── App │ │ │ └── Info.plist │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ ├── Flutter.framework │ │ │ ├── Flutter │ │ │ ├── Headers │ │ │ │ ├── Flutter.h │ │ │ │ ├── FlutterAppDelegate.h │ │ │ │ ├── FlutterBinaryMessenger.h │ │ │ │ ├── FlutterCallbackCache.h │ │ │ │ ├── FlutterChannels.h │ │ │ │ ├── FlutterCodecs.h │ │ │ │ ├── FlutterDartProject.h │ │ │ │ ├── FlutterEngine.h │ │ │ │ ├── FlutterHeadlessDartRunner.h │ │ │ │ ├── FlutterMacros.h │ │ │ │ ├── FlutterPlatformViews.h │ │ │ │ ├── FlutterPlugin.h │ │ │ │ ├── FlutterPluginAppLifeCycleDelegate.h │ │ │ │ ├── FlutterTexture.h │ │ │ │ └── FlutterViewController.h │ │ │ ├── Info.plist │ │ │ ├── Modules │ │ │ │ └── module.modulemap │ │ │ └── icudtl.dat │ │ ├── Generated.xcconfig │ │ ├── Release.xcconfig │ │ ├── flutter_assets │ │ │ ├── AssetManifest.json │ │ │ ├── FontManifest.json │ │ │ ├── LICENSE │ │ │ ├── fonts │ │ │ │ └── MaterialIcons-Regular.ttf │ │ │ ├── isolate_snapshot_data │ │ │ ├── kernel_blob.bin │ │ │ ├── packages │ │ │ │ └── cupertino_icons │ │ │ │ │ └── assets │ │ │ │ │ └── CupertinoIcons.ttf │ │ │ └── vm_snapshot_data │ │ └── flutter_export_environment.sh │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcuserdata │ │ │ └── tangdev.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ ├── Runner │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── 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-83.5x83.5@2x.png │ │ │ └── LaunchImage.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ └── README.md │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── GeneratedPluginRegistrant.h │ │ ├── GeneratedPluginRegistrant.m │ │ ├── Info.plist │ │ └── main.m │ └── ServiceDefinitions.json ├── lib │ ├── demo.dart │ ├── main.dart │ ├── pkce.dart │ └── standard.dart ├── pubspec.lock └── pubspec.yaml ├── flutter_auth0.iml ├── ios ├── .gitignore ├── Assets │ └── .gitkeep ├── Classes │ ├── FlutterAuth0Plugin.h │ └── FlutterAuth0Plugin.m └── flutter_auth0.podspec ├── lib ├── flutter_auth0.dart └── src │ ├── auth │ └── index.dart │ ├── auth0_error.dart │ ├── auth_exeption.dart │ ├── management │ └── users.dart │ ├── networking │ ├── client.dart │ └── telemetry.dart │ ├── user_info.dart │ └── webauth │ └── index.dart ├── pubspec.lock ├── pubspec.yaml └── test └── flutter_auth0_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | # File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig 2 | 3 | # Created by https://www.gitignore.io/api/android,dart,flutter,macos,visualstudiocode,xcode,jetbrains,swift,swiftpackagemanager 4 | # Edit at https://www.gitignore.io/?templates=android,dart,flutter,macos,visualstudiocode,xcode,jetbrains,swift,swiftpackagemanager 5 | 6 | ### Android ### 7 | # Built application files 8 | *.apk 9 | *.ap_ 10 | *.aab 11 | 12 | # Files for the ART/Dalvik VM 13 | *.dex 14 | 15 | # Java class files 16 | *.class 17 | 18 | # Generated files 19 | bin/ 20 | gen/ 21 | out/ 22 | release/ 23 | 24 | # Gradle files 25 | .gradle/ 26 | build/ 27 | 28 | # Local configuration file (sdk path, etc) 29 | local.properties 30 | 31 | # Proguard folder generated by Eclipse 32 | proguard/ 33 | 34 | # Log Files 35 | *.log 36 | 37 | # Android Studio Navigation editor temp files 38 | .navigation/ 39 | 40 | # Android Studio captures folder 41 | captures/ 42 | 43 | # IntelliJ 44 | *.iml 45 | .idea/workspace.xml 46 | .idea/tasks.xml 47 | .idea/gradle.xml 48 | .idea/assetWizardSettings.xml 49 | .idea/dictionaries 50 | .idea/libraries 51 | # Android Studio 3 in .gitignore file. 52 | .idea/caches 53 | .idea/modules.xml 54 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 55 | .idea/navEditor.xml 56 | 57 | # Keystore files 58 | # Uncomment the following lines if you do not want to check your keystore files in. 59 | #*.jks 60 | #*.keystore 61 | 62 | # External native build folder generated in Android Studio 2.2 and later 63 | .externalNativeBuild 64 | 65 | # Google Services (e.g. APIs or Firebase) 66 | # google-services.json 67 | 68 | # Freeline 69 | freeline.py 70 | freeline/ 71 | freeline_project_description.json 72 | 73 | # fastlane 74 | fastlane/report.xml 75 | fastlane/Preview.html 76 | fastlane/screenshots 77 | fastlane/test_output 78 | fastlane/readme.md 79 | 80 | # Version control 81 | vcs.xml 82 | 83 | # lint 84 | lint/intermediates/ 85 | lint/generated/ 86 | lint/outputs/ 87 | lint/tmp/ 88 | # lint/reports/ 89 | 90 | ### Android Patch ### 91 | gen-external-apklibs 92 | output.json 93 | 94 | ### Dart ### 95 | # See https://www.dartlang.org/guides/libraries/private-files 96 | 97 | # Files and directories created by pub 98 | .dart_tool/ 99 | .packages 100 | # If you're building an application, you may want to check-in your pubspec.lock 101 | pubspec.lock 102 | 103 | # Directory created by dartdoc 104 | # If you don't generate documentation locally you can remove this line. 105 | doc/api/ 106 | 107 | # Avoid committing generated Javascript files: 108 | *.dart.js 109 | *.info.json # Produced by the --dump-info flag. 110 | *.js # When generated by dart2js. Don't specify *.js if your 111 | # project includes source files written in JavaScript. 112 | *.js_ 113 | *.js.deps 114 | *.js.map 115 | 116 | ### Flutter ### 117 | # Flutter/Dart/Pub related 118 | **/doc/api/ 119 | .flutter-plugins 120 | .pub-cache/ 121 | .pub/ 122 | 123 | # Android related 124 | **/android/**/gradle-wrapper.jar 125 | **/android/.gradle 126 | **/android/captures/ 127 | **/android/gradlew 128 | **/android/gradlew.bat 129 | **/android/local.properties 130 | **/android/**/GeneratedPluginRegistrant.java 131 | 132 | # iOS/XCode related 133 | **/ios/**/*.mode1v3 134 | **/ios/**/*.mode2v3 135 | **/ios/**/*.moved-aside 136 | **/ios/**/*.pbxuser 137 | **/ios/**/*.perspectivev3 138 | **/ios/**/*sync/ 139 | **/ios/**/.sconsign.dblite 140 | **/ios/**/.tags* 141 | **/ios/**/.vagrant/ 142 | **/ios/**/DerivedData/ 143 | **/ios/**/Icon? 144 | **/ios/**/Pods/ 145 | **/ios/**/.symlinks/ 146 | **/ios/**/profile 147 | **/ios/**/xcuserdata 148 | **/ios/.generated/ 149 | **/ios/Flutter/App.framework 150 | **/ios/Flutter/Flutter.framework 151 | **/ios/Flutter/Generated.xcconfig 152 | **/ios/Flutter/app.flx 153 | **/ios/Flutter/app.zip 154 | **/ios/Flutter/flutter_assets/ 155 | **/ios/ServiceDefinitions.json 156 | **/ios/Runner/GeneratedPluginRegistrant.* 157 | 158 | # Exceptions to above rules. 159 | !**/ios/**/default.mode1v3 160 | !**/ios/**/default.mode2v3 161 | !**/ios/**/default.pbxuser 162 | !**/ios/**/default.perspectivev3 163 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 164 | 165 | ### JetBrains ### 166 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 167 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 168 | 169 | # User-specific stuff 170 | .idea/**/workspace.xml 171 | .idea/**/tasks.xml 172 | .idea/**/usage.statistics.xml 173 | .idea/**/dictionaries 174 | .idea/**/shelf 175 | 176 | # Generated files 177 | .idea/**/contentModel.xml 178 | 179 | # Sensitive or high-churn files 180 | .idea/**/dataSources/ 181 | .idea/**/dataSources.ids 182 | .idea/**/dataSources.local.xml 183 | .idea/**/sqlDataSources.xml 184 | .idea/**/dynamic.xml 185 | .idea/**/uiDesigner.xml 186 | .idea/**/dbnavigator.xml 187 | 188 | # Gradle 189 | .idea/**/gradle.xml 190 | .idea/**/libraries 191 | 192 | # Gradle and Maven with auto-import 193 | # When using Gradle or Maven with auto-import, you should exclude module files, 194 | # since they will be recreated, and may cause churn. Uncomment if using 195 | # auto-import. 196 | # .idea/modules.xml 197 | # .idea/*.iml 198 | # .idea/modules 199 | # *.iml 200 | # *.ipr 201 | 202 | # CMake 203 | cmake-build-*/ 204 | 205 | # Mongo Explorer plugin 206 | .idea/**/mongoSettings.xml 207 | 208 | # File-based project format 209 | *.iws 210 | 211 | # IntelliJ 212 | 213 | # mpeltonen/sbt-idea plugin 214 | .idea_modules/ 215 | 216 | # JIRA plugin 217 | atlassian-ide-plugin.xml 218 | 219 | # Cursive Clojure plugin 220 | .idea/replstate.xml 221 | 222 | # Crashlytics plugin (for Android Studio and IntelliJ) 223 | com_crashlytics_export_strings.xml 224 | crashlytics.properties 225 | crashlytics-build.properties 226 | fabric.properties 227 | 228 | # Editor-based Rest Client 229 | .idea/httpRequests 230 | 231 | # Android studio 3.1+ serialized cache file 232 | .idea/caches/build_file_checksums.ser 233 | 234 | ### JetBrains Patch ### 235 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 236 | 237 | # *.iml 238 | # modules.xml 239 | # .idea/misc.xml 240 | # *.ipr 241 | 242 | # Sonarlint plugin 243 | .idea/sonarlint 244 | 245 | ### macOS ### 246 | # General 247 | .DS_Store 248 | .AppleDouble 249 | .LSOverride 250 | 251 | # Icon must end with two \r 252 | Icon 253 | 254 | # Thumbnails 255 | ._* 256 | 257 | # Files that might appear in the root of a volume 258 | .DocumentRevisions-V100 259 | .fseventsd 260 | .Spotlight-V100 261 | .TemporaryItems 262 | .Trashes 263 | .VolumeIcon.icns 264 | .com.apple.timemachine.donotpresent 265 | 266 | # Directories potentially created on remote AFP share 267 | .AppleDB 268 | .AppleDesktop 269 | Network Trash Folder 270 | Temporary Items 271 | .apdisk 272 | 273 | ### Swift ### 274 | # Xcode 275 | # 276 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 277 | 278 | ## Build generated 279 | DerivedData/ 280 | 281 | ## Various settings 282 | *.pbxuser 283 | !default.pbxuser 284 | *.mode1v3 285 | !default.mode1v3 286 | *.mode2v3 287 | !default.mode2v3 288 | *.perspectivev3 289 | !default.perspectivev3 290 | xcuserdata/ 291 | 292 | ## Other 293 | *.moved-aside 294 | *.xccheckout 295 | *.xcscmblueprint 296 | 297 | ## Obj-C/Swift specific 298 | *.hmap 299 | *.ipa 300 | *.dSYM.zip 301 | *.dSYM 302 | 303 | ## Playgrounds 304 | timeline.xctimeline 305 | playground.xcworkspace 306 | 307 | # Swift Package Manager 308 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 309 | # Packages/ 310 | # Package.pins 311 | # Package.resolved 312 | .build/ 313 | 314 | # CocoaPods 315 | # We recommend against adding the Pods directory to your .gitignore. However 316 | # you should judge for yourself, the pros and cons are mentioned at: 317 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 318 | # Pods/ 319 | # Add this line if you want to avoid checking in source code from the Xcode workspace 320 | # *.xcworkspace 321 | 322 | # Carthage 323 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 324 | # Carthage/Checkouts 325 | 326 | Carthage/Build 327 | 328 | # Accio dependency management 329 | Dependencies/ 330 | .accio/ 331 | 332 | # fastlane 333 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 334 | # screenshots whenever they are needed. 335 | # For more information about the recommended setup visit: 336 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 337 | 338 | fastlane/screenshots/**/*.png 339 | 340 | # Code Injection 341 | # After new code Injection tools there's a generated folder /iOSInjectionProject 342 | # https://github.com/johnno1962/injectionforxcode 343 | 344 | iOSInjectionProject/ 345 | 346 | ### SwiftPackageManager ### 347 | Packages 348 | xcuserdata 349 | *.xcodeproj 350 | 351 | 352 | ### VisualStudioCode ### 353 | .vscode/* 354 | !.vscode/settings.json 355 | !.vscode/tasks.json 356 | !.vscode/launch.json 357 | !.vscode/extensions.json 358 | 359 | ### VisualStudioCode Patch ### 360 | # Ignore all local history of files 361 | .history 362 | 363 | ### Xcode ### 364 | # Xcode 365 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 366 | 367 | ## User settings 368 | 369 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 370 | 371 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 372 | 373 | ## Xcode Patch 374 | *.xcodeproj/* 375 | !*.xcodeproj/project.pbxproj 376 | !*.xcodeproj/xcshareddata/ 377 | !*.xcworkspace/contents.xcworkspacedata 378 | /*.gcno 379 | 380 | ### Xcode Patch ### 381 | **/xcshareddata/WorkspaceSettings.xcsettings 382 | 383 | # End of https://www.gitignore.io/api/android,dart,flutter,macos,visualstudiocode,xcode,jetbrains,swift,swiftpackagemanager 384 | 385 | # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) 386 | .vscode/launch.json 387 | 388 | scripts/pub_publish.sh 389 | .idea/ 390 | .flutter-plugins-dependencies 391 | .gradle/ 392 | local.properties 393 | .flutter-plugins 394 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## v0.5.0 (2019-08-09) 2 | 3 | breaking changes: 4 | 5 | - parameter to use auth0 authentication 6 | 7 | features: 8 | 9 | - users handler 10 | - get user info 11 | - update user info 12 | 13 | ## v0.3.1 (2019-08-09) 14 | 15 | fixes: 16 | 17 | - pub.dev fixes 18 | 19 | ## v0.3.0 (2019-08-09) 20 | 21 | fixes: 22 | 23 | - blank login page 24 | 25 | ## v0.2.2 (2019-08-08) 26 | 27 | fixes: 28 | 29 | - minor fixes 30 | 31 | ## v0.2.1 (2019-01-31) 32 | 33 | fixes: 34 | 35 | - Expiration token in seconds. 36 | 37 | ## v0.2.0 (2019-01-30) 38 | 39 | enhances: 40 | 41 | - Error handler when sign-in/sign-up. 42 | 43 | ## v0.1.0 (2019-01-10) 44 | 45 | features: 46 | 47 | - Refresh token integrated. 48 | 49 | enhances: 50 | 51 | - directory layout was change. 52 | 53 | ## v0.0.2 (2018-12-03) 54 | 55 | ### Using Authorization Code flow with PKCE 56 | 57 | ![alt](screenshots/web-login.png) 58 | 59 | ### Callback URL(s) 60 | 61 | Callback URLs are the URLs that Auth0 invokes after the authentication process. Auth0 routes your application back to this URL and appends additional parameters to it, including a token. Since callback URLs can be manipulated, you will need to add this URL to your Application's Allowed Callback URLs for security. This will enable Auth0 to recognize these URLs as valid. If omitted, authentication will not be successful. 62 | 63 | Go to the [Auth0 Dashboard](https://manage.auth0.com/#/applications), select your application and make sure that **Allowed Callback URLs** contains the following: 64 | 65 | #### iOS 66 | 67 | ```text 68 | {YOUR_BUNDLE_IDENTIFIER}://${YOUR_AUTH0_DOMAIN}/ios/{YOUR_BUNDLE_IDENTIFIER}/callback 69 | ``` 70 | 71 | #### Android 72 | 73 | ```text 74 | {YOUR_APP_PACKAGE_NAME}://{YOUR_AUTH0_DOMAIN}/android/{YOUR_APP_PACKAGE_NAME}/callback 75 | ``` 76 | 77 | ### To use 78 | 79 | #### Android 80 | 81 | In the file `android/app/src/main/AndroidManifest.xml` you must make sure the **MainActivity** of the app has a **launchMode** value of `singleTask` and add the following activity: 82 | 83 | So if you have `samples.auth0.com` as your Auth0 domain you would have the following **MainActivity** configuration: 84 | 85 | ![manifes-activity](screenshots/new-activity.png) 86 | 87 | Create the file **RedirectUriReceiver.java** 88 | 89 | ![RedirectUriReceiver.java](screenshots/receiver.png) 90 | 91 | #### iOS 92 | 93 | Inside the ios folder find the file AppDelegate.[swift|m] add the following to it 94 | 95 | ![RedirectUriReceiver.java](screenshots/AppDelegate.png) 96 | 97 | Inside the `ios` folder open the `Info.plist` and locate the value for `CFBundleIdentifier`, e.g. 98 | 99 | ```xml 100 | CFBundleIdentifier 101 | $(PRODUCT_BUNDLE_IDENTIFIER) 102 | ``` 103 | 104 | and then register a URL type entry using the value of `CFBundleIdentifier` as the value of `CFBundleURLSchemes` 105 | 106 | ```xml 107 | CFBundleURLTypes 108 | 109 | 110 | CFBundleTypeRole 111 | None 112 | CFBundleURLName 113 | auth0 114 | CFBundleURLSchemes 115 | 116 | $(PRODUCT_BUNDLE_IDENTIFIER) 117 | 118 | 119 | 120 | ``` 121 | 122 | ## v0.0.1 (2018-10-31) 123 | 124 | A Flutter plugin to use the [Auth0 API](https://auth0.com/docs/api/authentication). 125 | 126 | Note: This plugin is still under development, and some APIs might not be available yet. Feedback and Pull Requests are most welcome! 127 | 128 | ## Usage 129 | 130 | To use this plugin, add `flutter_auth0` as a [dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/). 131 | 132 | ## SignIn with email and password 133 | 134 | To signin instance auth0 using `auth0-client-id` and `auth0-domain` and call signInWithEmailAndPassword function with email and password as params 135 | 136 | ```dart 137 | 138 | final auth = new Auth0(clientId: 'your-client-id', domain: 'your-domain'); 139 | 140 | Auth0User user = await auth.passwordRealm( 141 | username: 'username/email', 142 | password: 'password', 143 | realm: 'Username-Password-Authentication'); 144 | ``` 145 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_auth0 plugin 2 | 3 | A Flutter plugin to use the [Auth0 API & Auth0 PKCE flow](https://auth0.com/docs/api/authentication). 4 | 5 | Note: This plugin is still under development, and some APIs might not be available yet. Feedback and Pull Requests are most welcome! 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | ## Example 16 | 17 | See the [example application](https://github.com/devdennysegura/flutter-auth0/tree/master/example) source 18 | for a complete sample app using the auth0 authentication. 19 | 20 | ## What is Auth0? 21 | 22 | Auth0 helps you to: 23 | 24 | - Add authentication with [multiple authentication sources](https://docs.auth0.com/identityproviders), either social like **Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, amont others**, or enterprise identity systems like **Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider**. 25 | - Add authentication through more traditional **[username/password databases](https://docs.auth0.com/mysql-connection-tutorial)**. 26 | - Add support for **[linking different user accounts](https://docs.auth0.com/link-accounts)** with the same user. 27 | - Support for generating signed [Json Web Tokens](https://docs.auth0.com/jwt) to call your APIs and **flow the user identity** securely. 28 | - Analytics of how, when and where users are logging in. 29 | - Pull data from other sources and add it to the user profile, through [JavaScript rules](https://docs.auth0.com/rules). 30 | 31 | ## Create a free Auth0 Account 32 | 33 | 1. Go to [Auth0](https://auth0.com) and click Sign Up. 34 | 2. Use Google, GitHub or Microsoft Account to login. 35 | 36 | ## Author 37 | 38 | Denny Segura 39 | 40 | This readme based on [react-native-auth0](https://github.com/auth0/react-native-auth0) 41 | 42 | ## License 43 | 44 | This project is licensed under the MIT license. See the [LICENSE](LICENSE.txt) file for more info. 45 | -------------------------------------------------------------------------------- /android/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /android/.gradle/vcs-1/gc.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/android/.gradle/vcs-1/gc.properties -------------------------------------------------------------------------------- /android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | flutter_auth0 4 | Project flutter_auth0 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 | -------------------------------------------------------------------------------- /android/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | arguments= 2 | auto.sync=false 3 | build.scans.enabled=false 4 | connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(5.4)) 5 | connection.project.dir=../example/android 6 | eclipse.preferences.version=1 7 | gradle.user.home= 8 | java.home= 9 | jvm.arguments= 10 | offline.mode=false 11 | override.workspace.settings=true 12 | show.console.view=true 13 | show.executions.view=true 14 | -------------------------------------------------------------------------------- /android/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=12 3 | org.eclipse.jdt.core.compiler.compliance=12 4 | org.eclipse.jdt.core.compiler.source=12 5 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'io.flutter.plugins.flutterauth0' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:3.4.1' 12 | } 13 | } 14 | 15 | rootProject.allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | 24 | android { 25 | compileSdkVersion 28 26 | 27 | defaultConfig { 28 | minSdkVersion 16 29 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 30 | } 31 | lintOptions { 32 | disable 'InvalidPackage' 33 | } 34 | dependencies{ 35 | implementation 'androidx.legacy:legacy-support-core-utils:1.0.0' 36 | implementation 'androidx.browser:browser:1.0.0' } 37 | } -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | -------------------------------------------------------------------------------- /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-5.1.1-all.zip -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'flutter_auth0' -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /android/src/main/java/io/flutter/plugins/flutterauth0/AuthenticationReceiver.java: -------------------------------------------------------------------------------- 1 | package io.flutter.plugins.flutterauth0; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.content.Intent; 6 | import android.net.Uri; 7 | import android.os.Bundle; 8 | import android.util.Log; 9 | import io.flutter.plugins.flutterauth0.FlutterAuth0Plugin; 10 | 11 | public class AuthenticationReceiver extends Activity { 12 | private static final String TAG = AuthenticationReceiver.class.getName(); 13 | 14 | public static final String EXTRA_CODE = "Auth0Code"; 15 | public static final String EXTRA_ERROR = "Auth0Error"; 16 | 17 | public void onCreate(Bundle savedInstanceBundle) { 18 | super.onCreate(savedInstanceBundle); 19 | Intent intent = this.getIntent(); 20 | Uri uri = intent.getData(); 21 | String access_token = uri.getQueryParameter("code"); 22 | String error = uri.getQueryParameter("error"); 23 | closeView(access_token, error); 24 | } 25 | 26 | private void closeView(String token, String errorMessage) { 27 | Intent intent = new Intent(AuthenticationReceiver.this, FlutterAuth0Plugin.getActivity().getClass()); 28 | intent.putExtra(EXTRA_CODE, token); 29 | intent.putExtra(EXTRA_ERROR, errorMessage); 30 | if (errorMessage != null) 31 | setResult(Activity.RESULT_CANCELED, intent); 32 | else 33 | setResult(Activity.RESULT_OK, intent); 34 | intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); 35 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 36 | FlutterAuth0Plugin.resolve(token, errorMessage); 37 | startActivityIfNeeded(intent, 0); 38 | finish(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /android/src/main/java/io/flutter/plugins/flutterauth0/FlutterAuth0Plugin.java: -------------------------------------------------------------------------------- 1 | package io.flutter.plugins.flutterauth0; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.os.Bundle; 7 | import android.util.Log; 8 | // import android.os.Handler; 9 | import androidx.browser.customtabs.CustomTabsIntent; 10 | import io.flutter.plugin.common.MethodCall; 11 | import io.flutter.plugin.common.MethodChannel; 12 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 13 | import io.flutter.plugin.common.MethodChannel.Result; 14 | import io.flutter.plugin.common.PluginRegistry.Registrar; 15 | import io.flutter.plugin.common.PluginRegistry.ActivityResultListener; 16 | import java.util.Map; 17 | 18 | import io.flutter.plugins.flutterauth0.common.AuthenticationFactory; 19 | 20 | /** Flutter plugin for Auth0. */ 21 | public class FlutterAuth0Plugin implements MethodCallHandler { 22 | private static final String TAG = FlutterAuth0Plugin.class.getName(); 23 | private static Registrar registrar; 24 | private static final String CHANNEL = "io.flutter.plugins/auth0"; 25 | private static final int REQUEST = 1; 26 | private static Result response; 27 | 28 | public static void registerWith(Registrar registrar) { 29 | final MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL); 30 | FlutterAuth0Plugin instance = new FlutterAuth0Plugin(registrar); 31 | channel.setMethodCallHandler(instance); 32 | } 33 | 34 | private FlutterAuth0Plugin(Registrar pluginRegister) { 35 | super(); 36 | registrar = pluginRegister; 37 | } 38 | 39 | @Override 40 | public void onMethodCall(MethodCall call, Result result) { 41 | response = result; 42 | if (call.method.equals("authorize")) { 43 | authorize(call); 44 | } else if (call.method.equals("parameters")) { 45 | getOauthParameters(result); 46 | } else if (call.method.equals("bundleIdentifier")) { 47 | getBundleIdentifier(result); 48 | } else { 49 | result.notImplemented(); 50 | } 51 | } 52 | 53 | @SuppressWarnings("unchecked") 54 | public void getBundleIdentifier(Result result) { 55 | String packageName = AuthenticationFactory.getIdentifier(registrar.context()); 56 | result.success(packageName); 57 | } 58 | 59 | private void getOauthParameters(Result result) { 60 | Map params = AuthenticationFactory.getAuthParameters(); 61 | result.success(params); 62 | } 63 | 64 | private void authorize(MethodCall call) { 65 | final String url = (String) call.arguments; 66 | final Activity activity = registrar.activity(); 67 | CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); 68 | CustomTabsIntent customTabsIntent = builder.build(); 69 | customTabsIntent.launchUrl(activity, Uri.parse(url)); 70 | } 71 | 72 | public static Activity getActivity() { 73 | return registrar.activity(); 74 | } 75 | 76 | public static void resolve(String code, String error) { 77 | if (error != null) 78 | response.error("ACTIVITY_FAILURE", error, null); 79 | response.success(code); 80 | } 81 | 82 | } -------------------------------------------------------------------------------- /android/src/main/java/io/flutter/plugins/flutterauth0/common/AuthenticationFactory.java: -------------------------------------------------------------------------------- 1 | package io.flutter.plugins.flutterauth0.common; 2 | 3 | import android.content.Context; 4 | import android.util.Base64; 5 | import androidx.annotation.NonNull; 6 | 7 | import java.io.UnsupportedEncodingException; 8 | import java.security.MessageDigest; 9 | import java.security.NoSuchAlgorithmException; 10 | import java.security.SecureRandom; 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | 14 | public class AuthenticationFactory { 15 | 16 | private static final String TAG = AuthenticationFactory.class.getName(); 17 | private static final String US_ASCII = "US-ASCII"; 18 | private static final String SHA_256 = "SHA-256"; 19 | private static final int CANCEL_EVENT_DELAY = 100; 20 | 21 | public AuthenticationFactory() { 22 | super(); 23 | } 24 | 25 | public static String getIdentifier(Context context) { 26 | return context.getPackageName(); 27 | } 28 | 29 | public static Map getAuthParameters() { 30 | final String verifier = generateRandomValue(); 31 | Map parameters = new HashMap<>(); 32 | parameters.put("verifier", verifier); 33 | parameters.put("code_challenge", generateCodeChallenge(verifier)); 34 | parameters.put("code_challenge_method", "S256"); 35 | parameters.put("state", generateRandomValue()); 36 | return parameters; 37 | } 38 | 39 | private static String getBase64String(byte[] source) { 40 | return Base64.encodeToString(source, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING); 41 | } 42 | 43 | private static byte[] getASCIIBytes(String value) { 44 | byte[] input; 45 | try { 46 | input = value.getBytes(US_ASCII); 47 | } catch (UnsupportedEncodingException e) { 48 | throw new IllegalStateException("Could not convert string to an ASCII byte array", e); 49 | } 50 | return input; 51 | } 52 | 53 | private static byte[] getSHA256(byte[] input) { 54 | byte[] signature; 55 | try { 56 | MessageDigest md = MessageDigest.getInstance(SHA_256); 57 | md.update(input, 0, input.length); 58 | signature = md.digest(); 59 | } catch (NoSuchAlgorithmException e) { 60 | throw new IllegalStateException("Failed to get SHA-256 signature", e); 61 | } 62 | return signature; 63 | } 64 | 65 | private static String generateRandomValue() { 66 | SecureRandom sr = new SecureRandom(); 67 | byte[] code = new byte[32]; 68 | sr.nextBytes(code); 69 | return getBase64String(code); 70 | } 71 | 72 | private static String generateCodeChallenge(@NonNull String codeVerifier) { 73 | byte[] input = getASCIIBytes(codeVerifier); 74 | byte[] signature = getSHA256(input); 75 | return getBase64String(signature); 76 | } 77 | } -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | ios/Pods/ 2 | ios/Podfile.lock 3 | build/ 4 | ios/.symlinks -------------------------------------------------------------------------------- /example/.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: 6a3ff018b199a7febbe2b5adbb564081d8f49e2f 8 | channel: dev 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | 3 | add `flutter_auth0: x.x.x.` to pubspec.yml file 4 | 5 | ```bash 6 | flutter pub get 7 | ``` 8 | 9 | ### Configuration 10 | 11 | > This section is for those that want to use [Web Authentication](#web-authentication), if you dont need it just ignore this section. 12 | 13 | #### Android 14 | 15 | In the file `android/app/src/main/AndroidManifest.xml` you must make sure the **MainActivity** of the app has a **launchMode** value of `singleTask` and add the following activity: 16 | 17 | ```xml 18 | 20 | 21 | 22 | 23 | 24 | 28 | 29 | 30 | ``` 31 | 32 | So if you have `dennysegura.auth0.com` as your Auth0 domain you would have the following **MainActivity** configuration: 33 | 34 | ```xml 35 | 37 | 38 | 39 | 40 | 41 | 45 | 46 | 47 | ``` 48 | 49 | #### iOS 50 | 51 | Inside the `ios` folder find the file `AppDelegate.[swift|m]` add the following to it 52 | 53 | ```objc 54 | #import 55 | 56 | - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { 57 | return [FlutterAuth0Plugin application:app openURL:url options:options]; 58 | } 59 | ``` 60 | 61 | Inside the `ios` folder open the `Info.plist` and locate the values for `CFBundleIdentifier`, `CFBundleURLSchemes` and then register a URL type entry using the value of `CFBundleIdentifier` as the value of `CFBundleURLSchemes` 62 | 63 | ```xml 64 | CFBundleURLTypes 65 | 66 | 67 | CFBundleTypeRole 68 | None 69 | CFBundleURLName 70 | auth0 71 | CFBundleURLSchemes 72 | 73 | $(PRODUCT_BUNDLE_IDENTIFIER) 74 | 75 | 76 | 77 | ``` 78 | 79 | The `` value should be the literal value of the Bundle Identifier with no $ variables, for example: `dennysegura.auth0.com`. 80 | 81 | ### Callback URL(s) 82 | 83 | Callback URLs are the URLs that Auth0 invokes after the authentication process. Auth0 routes your application back to this URL and appends additional parameters to it, including a token. Since callback URLs can be manipulated, you will need to add this URL to your Application's **Allowed Callback URLs** for security. This will enable Auth0 to recognize these URLs as valid. If omitted, authentication will not be successful. 84 | 85 | > Callback URLs must have a valid scheme value as defined by the [specification](https://tools.ietf.org/html/rfc3986#page-17). A "Redirect URI is not valid" error will raise if this format is not respected. 86 | 87 | 88 | Go to the [Auth0 Dashboard](https://manage.auth0.com/#/applications), select your application and make sure that **Allowed Callback URLs** contains the following: 89 | 90 | #### iOS 91 | 92 | ```text 93 | {YOUR_BUNDLE_IDENTIFIER}://${YOUR_AUTH0_DOMAIN}/ios/{YOUR_BUNDLE_IDENTIFIER}/callback 94 | ``` 95 | 96 | #### Android 97 | 98 | ```text 99 | {YOUR_APP_PACKAGE_NAME}://{YOUR_AUTH0_DOMAIN}/android/{YOUR_APP_PACKAGE_NAME}/callback 100 | ``` 101 | 102 | ## Usage 103 | 104 | ```dart 105 | import 'package:flutter_auth0/flutter_auth0.dart'; 106 | 107 | class ... { 108 | Auth0 auth0; 109 | 110 | @override 111 | void initState() { 112 | ... 113 | auth0 = Auth0(baseUrl: 'https://$domain/', clientId: 'auth0-client-id'); 114 | super.initState(); 115 | } 116 | } 117 | ``` 118 | 119 | ### Web Authentication 120 | 121 | #### Log in 122 | 123 | ```dart 124 | try { 125 | var response = await 126 | auth0. 127 | webAuth. 128 | authorize({ 129 | 'audience': 'https://$domain/userinfo', 130 | 'scope': 'openid email offline_access', 131 | }); 132 | DateTime now = DateTime.now(); 133 | showInfo('Web Login', ''' 134 | \ntoken_type: ${response['token_type']} 135 | \nexpires_in: ${DateTime.fromMillisecondsSinceEpoch(response['expires_in'] + now.millisecondsSinceEpoch)} 136 | \nrefreshToken: ${response['refresh_token']} 137 | \naccess_token: ${response['access_token']} 138 | '''); 139 | webLogged = true; 140 | currentWebAuth = Map.from(response); 141 | setState(() {}); 142 | } catch (e) { 143 | print('Error: $e'); 144 | } 145 | ``` 146 | 147 | > This snippet sets the `audience` to ensure OIDC compliant responses, this can also be achieved by enabling the **OIDC Conformant** switch in your Auth0 dashboard under `Application / Settings / Advanced OAuth`. For more information please check [this documentation](https://auth0.com/docs/api-auth/intro#how-to-use-the-new-flows). 148 | 149 | #### Log out 150 | 151 | ```dart 152 | try { 153 | await auth0. 154 | webAuth. 155 | clearSession(); 156 | webLogged = false; 157 | setState(() {}); 158 | } catch (e) { 159 | print('Error: $e'); 160 | } 161 | ``` 162 | 163 | ### Authentication API 164 | 165 | ### Important: Database Connection Authentication 166 | 167 | Since June 2017 new Clients no longer have the **Password Grant Type*** enabled by default. 168 | If you are accessing a Database Connection using `passwordRealm` then you will need to enable the Password Grant Type, please follow [this guide](https://auth0.com/docs/clients/client-grant-types#how-to-edit-the-client-grant_types-property). 169 | 170 | #### Login with Password Realm Grant 171 | 172 | ```dart 173 | try { 174 | var response = await auth0.auth.passwordRealm({ 175 | 'username': 'info@auth0.com', 176 | 'password': 'password', 177 | 'realm': 'Username-Password-Authentication' 178 | }); 179 | showInfo('Sign In', ''' 180 | \nAccess Token: ${response['access_token']} 181 | '''); 182 | } catch (e) { 183 | print(e); 184 | } 185 | ``` 186 | 187 | #### Get user information using user's access_token 188 | 189 | ```dart 190 | try { 191 | var authClient = Auth0Auth( 192 | auth0.auth.clientId, auth0.auth.client.baseUrl, 193 | bearer: 'user access_token'); 194 | var info = await authClient.getUserInfo(); 195 | String buffer = ''; 196 | info.forEach((k, v) => buffer = '$buffer\n$k: $v'); 197 | showInfo('User Info', buffer); 198 | } catch (e) { 199 | print(e); 200 | } 201 | ``` 202 | 203 | #### Getting new access token with refresh token 204 | 205 | ```dart 206 | try { 207 | var response = await auth0.client.refreshToken({ 208 | 'refreshToken': 'user refresh_token', 209 | }); 210 | DateTime now = DateTime.now(); 211 | showInfo('Refresh Token', ''' 212 | \ntoken_type: ${response['token_type']} 213 | \nexpires_in: ${DateTime.fromMillisecondsSinceEpoch(response['expires_in'] + now.millisecondsSinceEpoch)} 214 | \naccess_token: ${response['access_token']} 215 | '''); 216 | } catch (e) { 217 | print('Error: $e'); 218 | } 219 | ``` 220 | 221 | #### Create user in database connection 222 | 223 | ```dart 224 | try { 225 | var response = await auth0.auth.createUser({ 226 | 'email': 'info@auth0.com', 227 | 'password': 'password', 228 | 'connection': 'Username-Password-Authentication' 229 | }); 230 | showInfo('Sign Up', ''' 231 | \nid: ${response['_id']} 232 | \nusername/email: ${response['email']} 233 | '''); 234 | } catch (e) { 235 | print(e); 236 | } 237 | ``` 238 | 239 | ### Management API (Users) 240 | 241 | #### Patch user with user_metadata 242 | 243 | ```dart 244 | try { 245 | var response = await auth0 246 | .users('user token') 247 | .patchUser({'id': 'user_id', 248 | 'metadata': {'first_name': 'John', 'last_name': 'Doe'} 249 | }); 250 | print(response); 251 | } catch (e) { 252 | print(e); 253 | } 254 | ``` 255 | 256 | ### Get full user profile 257 | 258 | ```dart 259 | try { 260 | var response = await auth0 261 | .users('user token') 262 | .getUser({id: "user_id"}); 263 | print(response); 264 | } catch (e) { 265 | print(e); 266 | } 267 | ``` -------------------------------------------------------------------------------- /example/android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | android 4 | Project android created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /example/android/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir= 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /example/android/app/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /example/android/app/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | app 4 | Project app 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/android/app/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | connection.project.dir=.. 2 | eclipse.preferences.version=1 3 | -------------------------------------------------------------------------------- /example/android/app/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=12 3 | org.eclipse.jdt.core.compiler.compliance=12 4 | org.eclipse.jdt.core.compiler.source=12 5 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.example.flutterauth0" 37 | minSdkVersion 16 38 | targetSdkVersion 28 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | testImplementation 'junit:junit:4.12' 59 | androidTestImplementation 'androidx.test:runner:1.0.2' 60 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.0.2' 61 | } -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 10 | 15 | 19 | 26 | 30 | 33 | 34 | 35 | 36 | 37 | 38 | 41 | 42 | 43 | 44 | 45 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/flutterauth0/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.flutterauth0; 2 | 3 | import android.os.Bundle; 4 | import io.flutter.app.FlutterActivity; 5 | import io.flutter.plugins.GeneratedPluginRegistrant; 6 | 7 | public class MainActivity extends FlutterActivity { 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | GeneratedPluginRegistrant.registerWith(this); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/flutterauth0/RedirectUriReceiver.java: -------------------------------------------------------------------------------- 1 | package com.example.flutterauth0; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.os.Bundle; 7 | import io.flutter.plugins.flutterauth0.FlutterAuth0Plugin; 8 | import com.example.flutterauth0.MainActivity; 9 | 10 | public class RedirectUriReceiver extends Activity { 11 | private static final String TAG = RedirectUriReceiver.class.getName(); 12 | 13 | public void onCreate(Bundle savedInstanceBundle) { 14 | super.onCreate(savedInstanceBundle); 15 | // Intent intent = this.getIntent(); 16 | // Uri uri = intent.getData(); 17 | // String access_token = uri.getQueryParameter("code"); 18 | // String error = uri.getQueryParameter("error"); 19 | // FlutterAuth0Plugin.resolveWebAuthentication(access_token, error); 20 | // Intent openMainActivity = new Intent(RedirectUriReceiver.this, MainActivity.class); 21 | // openMainActivity.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); 22 | // startActivityIfNeeded(openMainActivity, 0); 23 | // this.finish(); 24 | } 25 | } -------------------------------------------------------------------------------- /example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java: -------------------------------------------------------------------------------- 1 | package io.flutter.plugins; 2 | 3 | import io.flutter.plugin.common.PluginRegistry; 4 | import io.flutter.plugins.flutterauth0.FlutterAuth0Plugin; 5 | 6 | /** 7 | * Generated file. Do not edit. 8 | */ 9 | public final class GeneratedPluginRegistrant { 10 | public static void registerWith(PluginRegistry registry) { 11 | if (alreadyRegisteredWith(registry)) { 12 | return; 13 | } 14 | FlutterAuth0Plugin.registerWith(registry.registrarFor("io.flutter.plugins.flutterauth0.FlutterAuth0Plugin")); 15 | } 16 | 17 | private static boolean alreadyRegisteredWith(PluginRegistry registry) { 18 | final String key = GeneratedPluginRegistrant.class.getCanonicalName(); 19 | if (registry.hasPlugin(key)) { 20 | return true; 21 | } 22 | registry.registrarFor(key); 23 | return false; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /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/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.4.1' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | project.evaluationDependsOn(':app') 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip -------------------------------------------------------------------------------- /example/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /example/flutter_auth0.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /example/flutter_auth0_android.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /example/ios/.symlinks/flutter: -------------------------------------------------------------------------------- 1 | /Users/dennysegura/development/flutter/bin/cache/artifacts/engine -------------------------------------------------------------------------------- /example/ios/.symlinks/plugins/flutter_auth0: -------------------------------------------------------------------------------- 1 | /Users/dennysegura/Dev/Libs/flutter/flutter-auth0 -------------------------------------------------------------------------------- /example/ios/Flutter/App.framework/App: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Flutter/App.framework/App -------------------------------------------------------------------------------- /example/ios/Flutter/App.framework/Info.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 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /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 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /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/Flutter.framework/Flutter: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Flutter/Flutter.framework/Flutter -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Headers/Flutter.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_FLUTTER_H_ 6 | #define FLUTTER_FLUTTER_H_ 7 | 8 | /** 9 | BREAKING CHANGES: 10 | 11 | December 17, 2018: 12 | - Changed designated initializer on FlutterEngine 13 | 14 | October 5, 2018: 15 | - Removed FlutterNavigationController.h/.mm 16 | - Changed return signature of `FlutterDartHeadlessCodeRunner.run*` from void 17 | to bool 18 | - Removed HeadlessPlatformViewIOS 19 | - Marked FlutterDartHeadlessCodeRunner deprecated 20 | 21 | August 31, 2018: Marked -[FlutterDartProject 22 | initFromDefaultSourceForConfiguration] and FlutterStandardBigInteger as 23 | unavailable. 24 | 25 | July 26, 2018: Marked -[FlutterDartProject 26 | initFromDefaultSourceForConfiguration] deprecated. 27 | 28 | February 28, 2018: Removed "initWithFLXArchive" and 29 | "initWithFLXArchiveWithScriptSnapshot". 30 | 31 | January 15, 2018: Marked "initWithFLXArchive" and 32 | "initWithFLXArchiveWithScriptSnapshot" as unavailable following the 33 | deprecation from December 11, 2017. Scheduled to be removed on February 34 | 19, 2018. 35 | 36 | January 09, 2018: Deprecated "FlutterStandardBigInteger" and its use in 37 | "FlutterStandardMessageCodec" and "FlutterStandardMethodCodec". Scheduled to 38 | be marked as unavailable once the deprecation has been available on the 39 | flutter/flutter alpha branch for four weeks. "FlutterStandardBigInteger" was 40 | needed because the Dart 1.0 int type had no size limit. With Dart 2.0, the 41 | int type is a fixed-size, 64-bit signed integer. If you need to communicate 42 | larger integers, use NSString encoding instead. 43 | 44 | December 11, 2017: Deprecated "initWithFLXArchive" and 45 | "initWithFLXArchiveWithScriptSnapshot" and scheculed the same to be marked as 46 | unavailable on January 15, 2018. Instead, "initWithFlutterAssets" and 47 | "initWithFlutterAssetsWithScriptSnapshot" should be used. The reason for this 48 | change is that the FLX archive will be deprecated and replaced with a flutter 49 | assets directory containing the same files as the FLX did. 50 | 51 | November 29, 2017: Added a BREAKING CHANGES section. 52 | */ 53 | 54 | #include "FlutterAppDelegate.h" 55 | #include "FlutterBinaryMessenger.h" 56 | #include "FlutterCallbackCache.h" 57 | #include "FlutterChannels.h" 58 | #include "FlutterCodecs.h" 59 | #include "FlutterDartProject.h" 60 | #include "FlutterEngine.h" 61 | #include "FlutterHeadlessDartRunner.h" 62 | #include "FlutterMacros.h" 63 | #include "FlutterPlatformViews.h" 64 | #include "FlutterPlugin.h" 65 | #include "FlutterPluginAppLifeCycleDelegate.h" 66 | #include "FlutterTexture.h" 67 | #include "FlutterViewController.h" 68 | 69 | #endif // FLUTTER_FLUTTER_H_ 70 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Headers/FlutterAppDelegate.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_FLUTTERAPPDELEGATE_H_ 6 | #define FLUTTER_FLUTTERAPPDELEGATE_H_ 7 | 8 | #import 9 | 10 | #include "FlutterMacros.h" 11 | #include "FlutterPlugin.h" 12 | 13 | /** 14 | * `UIApplicationDelegate` subclass for simple apps that want default behavior. 15 | * 16 | * This class implements the following behaviors: 17 | * * Status bar touches are forwarded to the key window's root view 18 | * `FlutterViewController`, in order to trigger scroll to top. 19 | * * Keeps the Flutter connection open in debug mode when the phone screen 20 | * locks. 21 | * 22 | * App delegates for Flutter applications are *not* required to inherit from 23 | * this class. Developers of custom app delegate classes should copy and paste 24 | * code as necessary from FlutterAppDelegate.mm. 25 | */ 26 | FLUTTER_EXPORT 27 | @interface FlutterAppDelegate 28 | : UIResponder 29 | 30 | @property(strong, nonatomic) UIWindow* window; 31 | 32 | @end 33 | 34 | #endif // FLUTTER_FLUTTERDARTPROJECT_H_ 35 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Headers/FlutterBinaryMessenger.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_FLUTTERBINARYMESSENGER_H_ 6 | #define FLUTTER_FLUTTERBINARYMESSENGER_H_ 7 | 8 | #import 9 | 10 | #include "FlutterMacros.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | /** 14 | * A message reply callback. 15 | * 16 | * Used for submitting a binary reply back to a Flutter message sender. Also used 17 | * in for handling a binary message reply received from Flutter. 18 | * 19 | * @param reply The reply. 20 | */ 21 | typedef void (^FlutterBinaryReply)(NSData* _Nullable reply); 22 | 23 | /** 24 | * A strategy for handling incoming binary messages from Flutter and to send 25 | * asynchronous replies back to Flutter. 26 | * 27 | * @param message The message. 28 | * @param reply A callback for submitting an asynchronous reply to the sender. 29 | */ 30 | typedef void (^FlutterBinaryMessageHandler)(NSData* _Nullable message, FlutterBinaryReply reply); 31 | 32 | /** 33 | * A facility for communicating with the Flutter side using asynchronous message 34 | * passing with binary messages. 35 | * 36 | * Implementated by: 37 | * - `FlutterBasicMessageChannel`, which supports communication using structured 38 | * messages. 39 | * - `FlutterMethodChannel`, which supports communication using asynchronous 40 | * method calls. 41 | * - `FlutterEventChannel`, which supports commuication using event streams. 42 | */ 43 | FLUTTER_EXPORT 44 | @protocol FlutterBinaryMessenger 45 | /** 46 | * Sends a binary message to the Flutter side on the specified channel, expecting 47 | * no reply. 48 | * 49 | * @param channel The channel name. 50 | * @param message The message. 51 | */ 52 | - (void)sendOnChannel:(NSString*)channel message:(NSData* _Nullable)message; 53 | 54 | /** 55 | * Sends a binary message to the Flutter side on the specified channel, expecting 56 | * an asynchronous reply. 57 | * 58 | * @param channel The channel name. 59 | * @param message The message. 60 | * @param callback A callback for receiving a reply. 61 | */ 62 | - (void)sendOnChannel:(NSString*)channel 63 | message:(NSData* _Nullable)message 64 | binaryReply:(FlutterBinaryReply _Nullable)callback; 65 | 66 | /** 67 | * Registers a message handler for incoming binary messages from the Flutter side 68 | * on the specified channel. 69 | * 70 | * Replaces any existing handler. Use a `nil` handler for unregistering the 71 | * existing handler. 72 | * 73 | * @param channel The channel name. 74 | * @param handler The message handler. 75 | */ 76 | - (void)setMessageHandlerOnChannel:(NSString*)channel 77 | binaryMessageHandler:(FlutterBinaryMessageHandler _Nullable)handler; 78 | @end 79 | NS_ASSUME_NONNULL_END 80 | #endif // FLUTTER_FLUTTERBINARYMESSENGER_H_ 81 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Headers/FlutterCallbackCache.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_FLUTTERCALLBACKCACHE_H_ 6 | #define FLUTTER_FLUTTERCALLBACKCACHE_H_ 7 | 8 | #import 9 | 10 | #include "FlutterMacros.h" 11 | 12 | /** 13 | * An object containing the result of `FlutterCallbackCache`'s `lookupCallbackInformation` 14 | * method. 15 | */ 16 | FLUTTER_EXPORT 17 | @interface FlutterCallbackInformation : NSObject 18 | /** 19 | * The name of the callback. 20 | */ 21 | @property(retain) NSString* callbackName; 22 | /** 23 | * The class name of the callback. 24 | */ 25 | @property(retain) NSString* callbackClassName; 26 | /** 27 | * The library path of the callback. 28 | */ 29 | @property(retain) NSString* callbackLibraryPath; 30 | @end 31 | 32 | /** 33 | * The cache containing callback information for spawning a 34 | * `FlutterHeadlessDartRunner`. 35 | */ 36 | FLUTTER_EXPORT 37 | @interface FlutterCallbackCache : NSObject 38 | /** 39 | * Returns the callback information for the given callback handle. 40 | * This callback information can be used when spawning a 41 | * `FlutterHeadlessDartRunner`. 42 | * 43 | * @param handle The handle for a callback, provided by the 44 | * Dart method `PluginUtilities.getCallbackHandle`. 45 | * @return A `FlutterCallbackInformation` object which contains the name of the 46 | * callback, the name of the class in which the callback is defined, and the 47 | * path of the library which contains the callback. If the provided handle is 48 | * invalid, nil is returned. 49 | */ 50 | + (FlutterCallbackInformation*)lookupCallbackInformation:(int64_t)handle; 51 | 52 | @end 53 | 54 | #endif // FLUTTER_FLUTTERCALLBACKCACHE_H_ 55 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Headers/FlutterDartProject.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_FLUTTERDARTPROJECT_H_ 6 | #define FLUTTER_FLUTTERDARTPROJECT_H_ 7 | 8 | #import 9 | 10 | #include "FlutterMacros.h" 11 | 12 | /** 13 | * A set of Flutter and Dart assets used by a `FlutterEngine` to initialize execution. 14 | */ 15 | FLUTTER_EXPORT 16 | @interface FlutterDartProject : NSObject 17 | 18 | /** 19 | * Initializes a Flutter Dart project from a bundle. 20 | */ 21 | - (instancetype)initWithPrecompiledDartBundle:(NSBundle*)bundle NS_DESIGNATED_INITIALIZER; 22 | 23 | /** 24 | * Unavailable - use `init` instead. 25 | */ 26 | - (instancetype)initFromDefaultSourceForConfiguration FLUTTER_UNAVAILABLE("Use -init instead."); 27 | 28 | /** 29 | * Returns the file name for the given asset. If the bundle with the identifier 30 | * "io.flutter.flutter.app" exists, it will try use that bundle; otherwise, it 31 | * will use the main bundle. To specify a different bundle, use 32 | * `-lookupKeyForAsset:asset:fromBundle`. 33 | * 34 | * @param asset The name of the asset. The name can be hierarchical. 35 | * @return the file name to be used for lookup in the main bundle. 36 | */ 37 | + (NSString*)lookupKeyForAsset:(NSString*)asset; 38 | 39 | /** 40 | * Returns the file name for the given asset. 41 | * The returned file name can be used to access the asset in the supplied bundle. 42 | * 43 | * @param asset The name of the asset. The name can be hierarchical. 44 | * @param bundle The `NSBundle` to use for looking up the asset. 45 | * @return the file name to be used for lookup in the main bundle. 46 | */ 47 | + (NSString*)lookupKeyForAsset:(NSString*)asset fromBundle:(NSBundle*)bundle; 48 | 49 | /** 50 | * Returns the file name for the given asset which originates from the specified package. 51 | * The returned file name can be used to access the asset in the application's main bundle. 52 | * 53 | * @param asset The name of the asset. The name can be hierarchical. 54 | * @param package The name of the package from which the asset originates. 55 | * @return the file name to be used for lookup in the main bundle. 56 | */ 57 | + (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package; 58 | 59 | /** 60 | * Returns the file name for the given asset which originates from the specified package. 61 | * The returned file name can be used to access the asset in the specified bundle. 62 | * 63 | * @param asset The name of the asset. The name can be hierarchical. 64 | * @param package The name of the package from which the asset originates. 65 | * @param bundle The bundle to use when doing the lookup. 66 | * @return the file name to be used for lookup in the main bundle. 67 | */ 68 | + (NSString*)lookupKeyForAsset:(NSString*)asset 69 | fromPackage:(NSString*)package 70 | fromBundle:(NSBundle*)bundle; 71 | 72 | /** 73 | * Returns the default identifier for the bundle where we expect to find the Flutter Dart 74 | * application. 75 | */ 76 | + (NSString*)defaultBundleIdentifier; 77 | 78 | @end 79 | 80 | #endif // FLUTTER_FLUTTERDARTPROJECT_H_ 81 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Headers/FlutterEngine.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_FLUTTERENGINE_H_ 6 | #define FLUTTER_FLUTTERENGINE_H_ 7 | 8 | #import 9 | #import 10 | 11 | #include "FlutterBinaryMessenger.h" 12 | #include "FlutterDartProject.h" 13 | #include "FlutterMacros.h" 14 | #include "FlutterPlugin.h" 15 | #include "FlutterTexture.h" 16 | 17 | @class FlutterViewController; 18 | 19 | /** 20 | * The FlutterEngine class coordinates a single instance of execution for a 21 | * `FlutterDartProject`. It may have zero or one `FlutterViewController` at a 22 | * time, which can be specified via `-setViewController:`. 23 | * `FlutterViewController`'s `initWithEngine` initializer will automatically call 24 | * `-setViewController:` for itself. 25 | * 26 | * A FlutterEngine can be created independently of a `FlutterViewController` for 27 | * headless execution. It can also persist across the lifespan of multiple 28 | * `FlutterViewController` instances to maintain state and/or asynchronous tasks 29 | * (such as downloading a large file). 30 | * 31 | * Alternatively, you can simply create a new `FlutterViewController` with only a 32 | * `FlutterDartProject`. That `FlutterViewController` will internally manage its 33 | * own instance of a FlutterEngine, but will not guarantee survival of the engine 34 | * beyond the life of the ViewController. 35 | * 36 | * A newly initialized FlutterEngine will not actually run a Dart Isolate until 37 | * either `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI` is invoked. 38 | * One of these methods must be invoked before calling `-setViewController:`. 39 | */ 40 | FLUTTER_EXPORT 41 | @interface FlutterEngine : NSObject 42 | /** 43 | * Initialize this FlutterEngine with a `FlutterDartProject`. 44 | * 45 | * If the FlutterDartProject is not specified, the FlutterEngine will attempt to locate 46 | * the project in a default location (the flutter_assets folder in the iOS application 47 | * bundle). 48 | * 49 | * A newly initialized engine will not run the `FlutterDartProject` until either 50 | * `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI:` is called. 51 | * 52 | * FlutterEngine created with this method will have allowHeadlessExecution set to `YES`. 53 | * This means that the engine will continue to run regardless of whether a `FlutterViewController` 54 | * is attached to it or not, until `-destroyContext:` is called or the process finishes. 55 | * 56 | * @param labelPrefix The label prefix used to identify threads for this instance. Should 57 | * be unique across FlutterEngine instances, and is used in instrumentation to label 58 | * the threads used by this FlutterEngine. 59 | * @param projectOrNil The `FlutterDartProject` to run. 60 | */ 61 | - (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)projectOrNil; 62 | 63 | /** 64 | * Initialize this FlutterEngine with a `FlutterDartProject`. 65 | * 66 | * If the FlutterDartProject is not specified, the FlutterEngine will attempt to locate 67 | * the project in a default location (the flutter_assets folder in the iOS application 68 | * bundle). 69 | * 70 | * A newly initialized engine will not run the `FlutterDartProject` until either 71 | * `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI:` is called. 72 | * 73 | * @param labelPrefix The label prefix used to identify threads for this instance. Should 74 | * be unique across FlutterEngine instances, and is used in instrumentation to label 75 | * the threads used by this FlutterEngine. 76 | * @param projectOrNil The `FlutterDartProject` to run. 77 | * @param allowHeadlessExecution Whether or not to allow this instance to continue 78 | * running after passing a nil `FlutterViewController` to `-setViewController:`. 79 | */ 80 | - (instancetype)initWithName:(NSString*)labelPrefix 81 | project:(FlutterDartProject*)projectOrNil 82 | allowHeadlessExecution:(BOOL)allowHeadlessExecution NS_DESIGNATED_INITIALIZER; 83 | 84 | /** 85 | * The default initializer is not available for this object. 86 | * Callers must use `-[FlutterEngine initWithName:project:]`. 87 | */ 88 | - (instancetype)init NS_UNAVAILABLE; 89 | 90 | + (instancetype)new NS_UNAVAILABLE; 91 | 92 | /** 93 | * Runs a Dart program on an Isolate from the main Dart library (i.e. the library that 94 | * contains `main()`). 95 | * 96 | * The first call to this method will create a new Isolate. Subsequent calls will return 97 | * immediately. 98 | * 99 | * @param entrypoint The name of a top-level function from the same Dart 100 | * library that contains the app's main() function. If this is nil, it will 101 | * default to `main()`. If it is not the app's main() function, that function 102 | * must be decorated with `@pragma(vm:entry-point)` to ensure the method is not 103 | * tree-shaken by the Dart compiler. 104 | * @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. 105 | */ 106 | - (BOOL)runWithEntrypoint:(NSString*)entrypoint; 107 | 108 | /** 109 | * Runs a Dart program on an Isolate using the specified entrypoint and Dart library, 110 | * which may not be the same as the library containing the Dart program's `main()` function. 111 | * 112 | * The first call to this method will create a new Isolate. Subsequent calls will return 113 | * immediately. 114 | * 115 | * @param entrypoint The name of a top-level function from a Dart library. If nil, this will 116 | * default to `main()`. If it is not the app's main() function, that function 117 | * must be decorated with `@pragma(vm:entry-point)` to ensure the method is not 118 | * tree-shaken by the Dart compiler. 119 | * @param uri The URI of the Dart library which contains the entrypoint method. IF nil, 120 | * this will default to the same library as the `main()` function in the Dart program. 121 | * @return YES if the call succeeds in creating and running a Flutter Engine instance; NO otherwise. 122 | */ 123 | - (BOOL)runWithEntrypoint:(NSString*)entrypoint libraryURI:(NSString*)uri; 124 | 125 | /** 126 | * Destroy running context for an engine. 127 | * 128 | * This method can be used to force the FlutterEngine object to release all resources. 129 | * After sending this message, the object will be in an unusable state until it is deallocated. 130 | * Accessing properties or sending messages to it will result in undefined behavior or runtime 131 | * errors. 132 | */ 133 | - (void)destroyContext; 134 | 135 | /** 136 | * Ensures that Flutter will generate a semantics tree. 137 | * 138 | * This is enabled by default if certain accessibility services are turned on by 139 | * the user, or when using a Simulator. This method allows a user to turn 140 | * semantics on when they would not ordinarily be generated and the performance 141 | * overhead is not a concern, e.g. for UI testing. Note that semantics should 142 | * never be programmatically turned off, as it would potentially disable 143 | * accessibility services an end user has requested. 144 | * 145 | * This method must only be called after launching the engine via 146 | * `-runWithEntrypoint:` or `-runWithEntryPoint:libraryURI`. 147 | * 148 | * Although this method returns synchronously, it does not guarantee that a 149 | * semantics tree is actually available when the method returns. It 150 | * synchronously ensures that the next frame the Flutter framework creates will 151 | * have a semantics tree. 152 | * 153 | * You can subscribe to semantics updates via `NSNotificationCenter` by adding 154 | * an observer for the name `FlutterSemanticsUpdateNotification`. The `object` 155 | * parameter will be the `FlutterViewController` associated with the semantics 156 | * update. This will asynchronously fire after a semantics tree has actually 157 | * built (which may be some time after the frame has been rendered). 158 | */ 159 | - (void)ensureSemanticsEnabled; 160 | 161 | /** 162 | * Sets the `FlutterViewController` for this instance. The FlutterEngine must be 163 | * running (e.g. a successful call to `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI`) 164 | * before calling this method. Callers may pass nil to remove the viewController 165 | * and have the engine run headless in the current process. 166 | * 167 | * A FlutterEngine can only have one `FlutterViewController` at a time. If there is 168 | * already a `FlutterViewController` associated with this instance, this method will replace 169 | * the engine's current viewController with the newly specified one. 170 | * 171 | * Setting the viewController will signal the engine to start animations and drawing, and unsetting 172 | * it will signal the engine to stop animations and drawing. However, neither will impact the state 173 | * of the Dart program's execution. 174 | */ 175 | @property(nonatomic, weak) FlutterViewController* viewController; 176 | 177 | /** 178 | * The `FlutterMethodChannel` used for localization related platform messages, such as 179 | * setting the locale. 180 | */ 181 | @property(nonatomic, readonly) FlutterMethodChannel* localizationChannel; 182 | /** 183 | * The `FlutterMethodChannel` used for navigation related platform messages. 184 | * 185 | * @see [Navigation 186 | * Channel](https://docs.flutter.io/flutter/services/SystemChannels/navigation-constant.html) 187 | * @see [Navigator Widget](https://docs.flutter.io/flutter/widgets/Navigator-class.html) 188 | */ 189 | @property(nonatomic, readonly) FlutterMethodChannel* navigationChannel; 190 | 191 | /** 192 | * The `FlutterMethodChannel` used for core platform messages, such as 193 | * information about the screen orientation. 194 | */ 195 | @property(nonatomic, readonly) FlutterMethodChannel* platformChannel; 196 | 197 | /** 198 | * The `FlutterMethodChannel` used to communicate text input events to the 199 | * Dart Isolate. 200 | * 201 | * @see [Text Input 202 | * Channel](https://docs.flutter.io/flutter/services/SystemChannels/textInput-constant.html) 203 | */ 204 | @property(nonatomic, readonly) FlutterMethodChannel* textInputChannel; 205 | 206 | /** 207 | * The `FlutterBasicMessageChannel` used to communicate app lifecycle events 208 | * to the Dart Isolate. 209 | * 210 | * @see [Lifecycle 211 | * Channel](https://docs.flutter.io/flutter/services/SystemChannels/lifecycle-constant.html) 212 | */ 213 | @property(nonatomic, readonly) FlutterBasicMessageChannel* lifecycleChannel; 214 | 215 | /** 216 | * The `FlutterBasicMessageChannel` used for communicating system events, such as 217 | * memory pressure events. 218 | * 219 | * @see [System 220 | * Channel](https://docs.flutter.io/flutter/services/SystemChannels/system-constant.html) 221 | */ 222 | @property(nonatomic, readonly) FlutterBasicMessageChannel* systemChannel; 223 | 224 | /** 225 | * The `FlutterBasicMessageChannel` used for communicating user settings such as 226 | * clock format and text scale. 227 | */ 228 | @property(nonatomic, readonly) FlutterBasicMessageChannel* settingsChannel; 229 | 230 | /** 231 | * The `NSURL` of the observatory for the service isolate. 232 | * 233 | * This is only set in debug and profile runtime modes, and only after the 234 | * observatory service is ready. In release mode or before the observatory has 235 | * started, it returns `nil`. 236 | */ 237 | @property(nonatomic, readonly) NSURL* observatoryUrl; 238 | 239 | /** 240 | * The `FlutterBinaryMessenger` associated with this FlutterEngine (used for communicating with 241 | * channels). 242 | */ 243 | @property(nonatomic, readonly) NSObject* binaryMessenger; 244 | 245 | /** 246 | * The UI Isolate ID of of the engine. 247 | * 248 | * This property will be nil if the engine is not running. 249 | */ 250 | @property(nonatomic, readonly, copy) NSString* isolateId; 251 | 252 | @end 253 | 254 | #endif // FLUTTER_FLUTTERENGINE_H_ 255 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Headers/FlutterHeadlessDartRunner.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_FLUTTERHEADLESSDARTRUNNER_H_ 6 | #define FLUTTER_FLUTTERHEADLESSDARTRUNNER_H_ 7 | 8 | #import 9 | 10 | #include "FlutterBinaryMessenger.h" 11 | #include "FlutterDartProject.h" 12 | #include "FlutterEngine.h" 13 | #include "FlutterMacros.h" 14 | 15 | /** 16 | * A callback for when FlutterHeadlessDartRunner has attempted to start a Dart 17 | * Isolate in the background. 18 | * 19 | * @param success YES if the Isolate was started and run successfully, NO 20 | * otherwise. 21 | */ 22 | typedef void (^FlutterHeadlessDartRunnerCallback)(BOOL success); 23 | 24 | /** 25 | * The FlutterHeadlessDartRunner runs Flutter Dart code with a null rasterizer, 26 | * and no native drawing surface. It is appropriate for use in running Dart 27 | * code e.g. in the background from a plugin. 28 | * 29 | * Most callers should prefer using `FlutterEngine` directly; this interface exists 30 | * for legacy support. 31 | */ 32 | FLUTTER_EXPORT 33 | FLUTTER_DEPRECATED("FlutterEngine should be used rather than FlutterHeadlessDartRunner") 34 | @interface FlutterHeadlessDartRunner : FlutterEngine 35 | 36 | /** 37 | * Iniitalize this FlutterHeadlessDartRunner with a `FlutterDartProject`. 38 | * 39 | * If the FlutterDartProject is not specified, the FlutterHeadlessDartRunner will attempt to locate 40 | * the project in a default location. 41 | * 42 | * A newly initialized engine will not run the `FlutterDartProject` until either 43 | * `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI` is called. 44 | * 45 | * @param labelPrefix The label prefix used to identify threads for this instance. Should 46 | * be unique across FlutterEngine instances 47 | * @param projectOrNil The `FlutterDartProject` to run. 48 | */ 49 | - (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)projectOrNil; 50 | 51 | /** 52 | * Iniitalize this FlutterHeadlessDartRunner with a `FlutterDartProject`. 53 | * 54 | * If the FlutterDartProject is not specified, the FlutterHeadlessDartRunner will attempt to locate 55 | * the project in a default location. 56 | * 57 | * A newly initialized engine will not run the `FlutterDartProject` until either 58 | * `-runWithEntrypoint:` or `-runWithEntrypoint:libraryURI` is called. 59 | * 60 | * @param labelPrefix The label prefix used to identify threads for this instance. Should 61 | * be unique across FlutterEngine instances 62 | * @param projectOrNil The `FlutterDartProject` to run. 63 | * @param allowHeadlessExecution Must be set to `YES`. 64 | */ 65 | - (instancetype)initWithName:(NSString*)labelPrefix 66 | project:(FlutterDartProject*)projectOrNil 67 | allowHeadlessExecution:(BOOL)allowHeadlessExecution NS_DESIGNATED_INITIALIZER; 68 | 69 | /** 70 | * Not recommended for use - will initialize with a default label ("io.flutter.headless") 71 | * and the default FlutterDartProject. 72 | */ 73 | - (instancetype)init; 74 | 75 | @end 76 | 77 | #endif // FLUTTER_FLUTTERHEADLESSDARTRUNNER_H_ 78 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Headers/FlutterMacros.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_FLUTTERMACROS_H_ 6 | #define FLUTTER_FLUTTERMACROS_H_ 7 | 8 | #if defined(FLUTTER_FRAMEWORK) 9 | 10 | #define FLUTTER_EXPORT __attribute__((visibility("default"))) 11 | 12 | #else // defined(FLUTTER_SDK) 13 | 14 | #define FLUTTER_EXPORT 15 | 16 | #endif // defined(FLUTTER_SDK) 17 | 18 | #ifndef NS_ASSUME_NONNULL_BEGIN 19 | #define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") 20 | #define NS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") 21 | #endif // defined(NS_ASSUME_NONNULL_BEGIN) 22 | 23 | /** 24 | * Indicates that the API has been deprecated for the specified reason. Code 25 | * that uses the deprecated API will continue to work as before. However, the 26 | * API will soon become unavailable and users are encouraged to immediately take 27 | * the appropriate action mentioned in the deprecation message and the BREAKING 28 | * CHANGES section present in the Flutter.h umbrella header. 29 | */ 30 | #define FLUTTER_DEPRECATED(msg) __attribute__((__deprecated__(msg))) 31 | 32 | /** 33 | * Indicates that the previously deprecated API is now unavailable. Code that 34 | * uses the API will not work and the declaration of the API is only a stub 35 | * meant to display the given message detailing the actions for the user to take 36 | * immediately. 37 | */ 38 | #define FLUTTER_UNAVAILABLE(msg) __attribute__((__unavailable__(msg))) 39 | 40 | #endif // FLUTTER_FLUTTERMACROS_H_ 41 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Headers/FlutterPlatformViews.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_FLUTTERPLATFORMVIEWS_H_ 6 | #define FLUTTER_FLUTTERPLATFORMVIEWS_H_ 7 | 8 | #import 9 | 10 | #import "FlutterCodecs.h" 11 | #import "FlutterMacros.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | /** 16 | * Wraps a `UIView` for embedding in the Flutter hierarchy 17 | */ 18 | @protocol FlutterPlatformView 19 | /** 20 | * Returns a reference to the `UIView` that is wrapped by this `FlutterPlatformView`. 21 | */ 22 | - (UIView*)view; 23 | @end 24 | 25 | FLUTTER_EXPORT 26 | @protocol FlutterPlatformViewFactory 27 | /** 28 | * Create a `FlutterPlatformView`. 29 | * 30 | * Implemented by iOS code that expose a `UIView` for embedding in a Flutter app. 31 | * 32 | * The implementation of this method should create a new `UIView` and return it. 33 | * 34 | * @param frame The rectangle for the newly created `UIView` measued in points. 35 | * @param viewId A unique identifier for this `UIView`. 36 | * @param args Parameters for creating the `UIView` sent from the Dart side of the Flutter app. 37 | * If `createArgsCodec` is not implemented, or if no creation arguments were sent from the Dart 38 | * code, this will be null. Otherwise this will be the value sent from the Dart code as decoded by 39 | * `createArgsCodec`. 40 | */ 41 | - (NSObject*)createWithFrame:(CGRect)frame 42 | viewIdentifier:(int64_t)viewId 43 | arguments:(id _Nullable)args; 44 | 45 | /** 46 | * Returns the `FlutterMessageCodec` for decoding the args parameter of `createWithFrame`. 47 | * 48 | * Only needs to be implemented if `createWithFrame` needs an arguments parameter. 49 | */ 50 | @optional 51 | - (NSObject*)createArgsCodec; 52 | @end 53 | 54 | NS_ASSUME_NONNULL_END 55 | 56 | #endif // FLUTTER_FLUTTERPLATFORMVIEWS_H_ 57 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Headers/FlutterPluginAppLifeCycleDelegate.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_FLUTTERPLUGINAPPLIFECYCLEDELEGATE_H_ 6 | #define FLUTTER_FLUTTERPLUGINAPPLIFECYCLEDELEGATE_H_ 7 | 8 | #include "FlutterPlugin.h" 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | /** 13 | * Propagates `UIAppDelegate` callbacks to registered plugins. 14 | */ 15 | FLUTTER_EXPORT 16 | @interface FlutterPluginAppLifeCycleDelegate : NSObject 17 | 18 | /** 19 | * Registers `delegate` to receive life cycle callbacks via this FlutterPluginAppLifecycleDelegate 20 | * as long as it is alive. 21 | * 22 | * `delegate` will only referenced weakly. 23 | */ 24 | - (void)addDelegate:(NSObject*)delegate; 25 | 26 | /** 27 | * Calls all plugins registered for `UIApplicationDelegate` callbacks. 28 | * 29 | * @return `NO` if any plugin vetoes application launch. 30 | */ 31 | - (BOOL)application:(UIApplication*)application 32 | didFinishLaunchingWithOptions:(NSDictionary*)launchOptions; 33 | 34 | /** 35 | * Calls all plugins registered for `UIApplicationDelegate` callbacks. 36 | * 37 | * @return `NO` if any plugin vetoes application launch. 38 | */ 39 | - (BOOL)application:(UIApplication*)application 40 | willFinishLaunchingWithOptions:(NSDictionary*)launchOptions; 41 | 42 | /** 43 | * Called if this plugin has been registered for `UIApplicationDelegate` callbacks. 44 | */ 45 | - (void)application:(UIApplication*)application 46 | didRegisterUserNotificationSettings:(UIUserNotificationSettings*)notificationSettings 47 | API_DEPRECATED( 48 | "See -[UIApplicationDelegate application:didRegisterUserNotificationSettings:] deprecation", 49 | ios(8.0, 10.0)); 50 | 51 | /** 52 | * Calls all plugins registered for `UIApplicationDelegate` callbacks. 53 | */ 54 | - (void)application:(UIApplication*)application 55 | didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken; 56 | 57 | /** 58 | * Calls all plugins registered for `UIApplicationDelegate` callbacks. 59 | */ 60 | - (void)application:(UIApplication*)application 61 | didReceiveRemoteNotification:(NSDictionary*)userInfo 62 | fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler; 63 | 64 | /** 65 | * Calls all plugins registered for `UIApplicationDelegate` callbacks. 66 | */ 67 | - (void)application:(UIApplication*)application 68 | didReceiveLocalNotification:(UILocalNotification*)notification 69 | API_DEPRECATED( 70 | "See -[UIApplicationDelegate application:didReceiveLocalNotification:] deprecation", 71 | ios(4.0, 10.0)); 72 | 73 | /** 74 | * Calls all plugins registered for `UNUserNotificationCenterDelegate` callbacks. 75 | */ 76 | - (void)userNotificationCenter:(UNUserNotificationCenter*)center 77 | willPresentNotification:(UNNotification*)notification 78 | withCompletionHandler: 79 | (void (^)(UNNotificationPresentationOptions options))completionHandler 80 | API_AVAILABLE(ios(10)); 81 | 82 | /** 83 | * Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until 84 | * some plugin handles the request. 85 | * 86 | * @return `YES` if any plugin handles the request. 87 | */ 88 | - (BOOL)application:(UIApplication*)application 89 | openURL:(NSURL*)url 90 | options:(NSDictionary*)options; 91 | 92 | /** 93 | * Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until 94 | * some plugin handles the request. 95 | * 96 | * @return `YES` if any plugin handles the request. 97 | */ 98 | - (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url; 99 | 100 | /** 101 | * Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until 102 | * some plugin handles the request. 103 | * 104 | * @return `YES` if any plugin handles the request. 105 | */ 106 | - (BOOL)application:(UIApplication*)application 107 | openURL:(NSURL*)url 108 | sourceApplication:(NSString*)sourceApplication 109 | annotation:(id)annotation; 110 | 111 | /** 112 | * Calls all plugins registered for `UIApplicationDelegate` callbacks. 113 | */ 114 | - (void)application:(UIApplication*)application 115 | performActionForShortcutItem:(UIApplicationShortcutItem*)shortcutItem 116 | completionHandler:(void (^)(BOOL succeeded))completionHandler 117 | API_AVAILABLE(ios(9.0)); 118 | 119 | /** 120 | * Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until 121 | * some plugin handles the request. 122 | * 123 | * @return `YES` if any plugin handles the request. 124 | */ 125 | - (BOOL)application:(UIApplication*)application 126 | handleEventsForBackgroundURLSession:(nonnull NSString*)identifier 127 | completionHandler:(nonnull void (^)(void))completionHandler; 128 | 129 | /** 130 | * Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until 131 | * some plugin handles the request. 132 | * 133 | * @returns `YES` if any plugin handles the request. 134 | */ 135 | - (BOOL)application:(UIApplication*)application 136 | performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler; 137 | 138 | /** 139 | * Calls all plugins registered for `UIApplicationDelegate` callbacks in order of registration until 140 | * some plugin handles the request. 141 | * 142 | * @return `YES` if any plugin handles the request. 143 | */ 144 | - (BOOL)application:(UIApplication*)application 145 | continueUserActivity:(NSUserActivity*)userActivity 146 | restorationHandler:(void (^)(NSArray*))restorationHandler; 147 | @end 148 | 149 | NS_ASSUME_NONNULL_END 150 | 151 | #endif // FLUTTER_FLUTTERPLUGINAPPLIFECYCLEDELEGATE_H_ 152 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Headers/FlutterTexture.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_FLUTTERTEXTURE_H_ 6 | #define FLUTTER_FLUTTERTEXTURE_H_ 7 | 8 | #import 9 | #import 10 | 11 | #include "FlutterMacros.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | FLUTTER_EXPORT 16 | @protocol FlutterTexture 17 | - (CVPixelBufferRef _Nullable)copyPixelBuffer; 18 | @end 19 | 20 | FLUTTER_EXPORT 21 | @protocol FlutterTextureRegistry 22 | - (int64_t)registerTexture:(NSObject*)texture; 23 | - (void)textureFrameAvailable:(int64_t)textureId; 24 | - (void)unregisterTexture:(int64_t)textureId; 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | 29 | #endif // FLUTTER_FLUTTERTEXTURE_H_ 30 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Headers/FlutterViewController.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef FLUTTER_FLUTTERVIEWCONTROLLER_H_ 6 | #define FLUTTER_FLUTTERVIEWCONTROLLER_H_ 7 | 8 | #import 9 | #include 10 | 11 | #include "FlutterBinaryMessenger.h" 12 | #include "FlutterDartProject.h" 13 | #include "FlutterEngine.h" 14 | #include "FlutterMacros.h" 15 | #include "FlutterPlugin.h" 16 | #include "FlutterTexture.h" 17 | 18 | @class FlutterEngine; 19 | 20 | /** 21 | * The name used for semantic update notifications via `NSNotificationCenter`. 22 | * 23 | * The object passed as the sender is the `FlutterViewController` associated 24 | * with the update. 25 | */ 26 | FLUTTER_EXPORT 27 | extern NSNotificationName const FlutterSemanticsUpdateNotification; 28 | 29 | /** 30 | * A `UIViewController` implementation for Flutter views. 31 | * 32 | * Dart execution, channel communication, texture registration, and plugin registration are all 33 | * handled by `FlutterEngine`. Calls on this class to those members all proxy through to the 34 | * `FlutterEngine` attached FlutterViewController. 35 | * 36 | * A FlutterViewController can be initialized either with an already-running `FlutterEngine` via 37 | * the `initWithEngine:` initializer, or it can be initialized with a `FlutterDartProject` that 38 | * will be used to implicitly spin up a new `FlutterEngine`. Creating a `FlutterEngine before 39 | * showing a `FlutterViewController` can be used to pre-initialize the Dart VM and to prepare the 40 | * isolate in order to reduce the latency to the first rendered frame. Holding a `FlutterEngine` 41 | * independently of FlutterViewControllers can also be used to not to lose Dart-related state and 42 | * asynchronous tasks when navigating back and forth between a FlutterViewController and other 43 | * `UIViewController`s. 44 | */ 45 | FLUTTER_EXPORT 46 | @interface FlutterViewController : UIViewController 47 | 48 | /** 49 | * Initializes this FlutterViewController with the specified `FlutterEngine`. 50 | * 51 | * The initialized viewcontroller will attach itself to the engine as part of this process. 52 | * 53 | * @param engine The `FlutterEngine` instance to attach to. 54 | * @param nibNameOrNil The NIB name to initialize this UIViewController with. 55 | * @param nibBundleOrNil The NIB bundle. 56 | */ 57 | - (instancetype)initWithEngine:(FlutterEngine*)engine 58 | nibName:(NSString*)nibNameOrNil 59 | bundle:(NSBundle*)nibBundleOrNil NS_DESIGNATED_INITIALIZER; 60 | 61 | /** 62 | * Initializes a new FlutterViewController and `FlutterEngine` with the specified 63 | * `FlutterDartProject`. 64 | * 65 | * @param projectOrNil The `FlutterDartProject` to initialize the `FlutterEngine` with. 66 | * @param nibNameOrNil The NIB name to initialize this UIViewController with. 67 | * @param nibBundleOrNil The NIB bundle. 68 | */ 69 | - (instancetype)initWithProject:(FlutterDartProject*)projectOrNil 70 | nibName:(NSString*)nibNameOrNil 71 | bundle:(NSBundle*)nibBundleOrNil NS_DESIGNATED_INITIALIZER; 72 | 73 | - (void)handleStatusBarTouches:(UIEvent*)event; 74 | 75 | /** 76 | * Registers a callback that will be invoked when the Flutter view has been rendered. 77 | * The callback will be fired only once. 78 | * 79 | * Replaces an existing callback. Use a `nil` callback to unregister the existing one. 80 | */ 81 | - (void)setFlutterViewDidRenderCallback:(void (^)(void))callback; 82 | 83 | /** 84 | * Returns the file name for the given asset. 85 | * The returned file name can be used to access the asset in the application's 86 | * main bundle. 87 | * 88 | * @param asset The name of the asset. The name can be hierarchical. 89 | * @return The file name to be used for lookup in the main bundle. 90 | */ 91 | - (NSString*)lookupKeyForAsset:(NSString*)asset; 92 | 93 | /** 94 | * Returns the file name for the given asset which originates from the specified 95 | * package. 96 | * The returned file name can be used to access the asset in the application's 97 | * main bundle. 98 | * 99 | * @param asset The name of the asset. The name can be hierarchical. 100 | * @param package The name of the package from which the asset originates. 101 | * @return The file name to be used for lookup in the main bundle. 102 | */ 103 | - (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package; 104 | 105 | /** 106 | * Sets the first route that the Flutter app shows. The default is "/". 107 | * This method will guarnatee that the initial route is delivered, even if the 108 | * Flutter window hasn't been created yet when called. It cannot be used to update 109 | * the current route being shown in a visible FlutterViewController (see pushRoute 110 | * and popRoute). 111 | * 112 | * @param route The name of the first route to show. 113 | */ 114 | - (void)setInitialRoute:(NSString*)route; 115 | 116 | /** 117 | * Instructs the Flutter Navigator (if any) to go back. 118 | */ 119 | - (void)popRoute; 120 | 121 | /** 122 | * Instructs the Flutter Navigator (if any) to push a route on to the navigation 123 | * stack. The setInitialRoute method should be preferred if this is called before the 124 | * FlutterViewController has come into view. 125 | * 126 | * @param route The name of the route to push to the navigation stack. 127 | */ 128 | - (void)pushRoute:(NSString*)route; 129 | 130 | /** 131 | * The `FlutterPluginRegistry` used by this FlutterViewController. 132 | */ 133 | - (id)pluginRegistry; 134 | 135 | /** 136 | * True if at least one frame has rendered and the ViewController has appeared. 137 | * 138 | * This property is reset to false when the ViewController disappears. It is 139 | * guaranteed to only alternate between true and false for observers. 140 | */ 141 | @property(nonatomic, readonly, getter=isDisplayingFlutterUI) BOOL displayingFlutterUI; 142 | 143 | /** 144 | * Specifies the view to use as a splash screen. Flutter's rendering is asynchronous, so the first 145 | * frame rendered by the Flutter application might not immediately appear when theFlutter view is 146 | * initially placed in the view hierarchy. The splash screen view will be used as 147 | * a replacement until the first frame is rendered. 148 | * 149 | * The view used should be appropriate for multiple sizes; an autoresizing mask to 150 | * have a flexible width and height will be applied automatically. 151 | */ 152 | @property(strong, nonatomic) UIView* splashScreenView; 153 | 154 | /** 155 | * Attempts to set the `splashScreenView` property from the `UILaunchStoryboardName` from the 156 | * main bundle's `Info.plist` file. This method will not change the value of `splashScreenView` 157 | * if it cannot find a default one from a storyboard or nib. 158 | * 159 | * @return `YES` if successful, `NO` otherwise. 160 | */ 161 | - (BOOL)loadDefaultSplashScreenView; 162 | 163 | /** 164 | * Controls whether the created view will be opaque or not. 165 | * 166 | * Default is `YES`. Note that setting this to `NO` may negatively impact performance 167 | * when using hardware acceleration, and toggling this will trigger a re-layout of the 168 | * view. 169 | */ 170 | @property(nonatomic, getter=isViewOpaque) BOOL viewOpaque; 171 | 172 | /** 173 | * The `FlutterEngine` instance for this view controller. 174 | */ 175 | @property(weak, nonatomic, readonly) FlutterEngine* engine; 176 | 177 | /** 178 | * The `FlutterBinaryMessenger` associated with this FlutterViewController (used for communicating 179 | * with channels). 180 | * 181 | * This is just a convenient way to get the |FlutterEngine|'s binary messenger. 182 | */ 183 | @property(nonatomic, readonly) NSObject* binaryMessenger; 184 | 185 | @end 186 | 187 | #endif // FLUTTER_FLUTTERVIEWCONTROLLER_H_ 188 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | Flutter 9 | CFBundleIdentifier 10 | io.flutter.flutter 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Flutter 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | FlutterEngine 26 | 72283b64196cb5df16eb4d1a782da08f320a8014 27 | ClangVersion 28 | Fuchsia clang version 8.0.0 (based on LLVM 8.0.0svn) 29 | 30 | 31 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module Flutter { 2 | umbrella header "Flutter.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/Flutter/Flutter.framework/icudtl.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Flutter/Flutter.framework/icudtl.dat -------------------------------------------------------------------------------- /example/ios/Flutter/Generated.xcconfig: -------------------------------------------------------------------------------- 1 | // This is a generated file; do not edit or check into version control. 2 | FLUTTER_ROOT=/Users/dennysegura/development/flutter 3 | FLUTTER_APPLICATION_PATH=/Users/dennysegura/Dev/Libs/flutter/flutter-auth0/example 4 | FLUTTER_TARGET=/Users/dennysegura/Dev/Libs/flutter/flutter-auth0/example/lib/main.dart 5 | FLUTTER_BUILD_DIR=build 6 | SYMROOT=${SOURCE_ROOT}/../build/ios 7 | FLUTTER_FRAMEWORK_DIR=/Users/dennysegura/development/flutter/bin/cache/artifacts/engine/ios 8 | FLUTTER_BUILD_NAME=1.0.0 9 | FLUTTER_BUILD_NUMBER=1 10 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/flutter_assets/AssetManifest.json: -------------------------------------------------------------------------------- 1 | {"packages/cupertino_icons/assets/CupertinoIcons.ttf":["packages/cupertino_icons/assets/CupertinoIcons.ttf"]} -------------------------------------------------------------------------------- /example/ios/Flutter/flutter_assets/FontManifest.json: -------------------------------------------------------------------------------- 1 | [{"fonts":[{"asset":"fonts/MaterialIcons-Regular.ttf"}],"family":"MaterialIcons"},{"family":"packages/cupertino_icons/CupertinoIcons","fonts":[{"asset":"packages/cupertino_icons/assets/CupertinoIcons.ttf"}]}] -------------------------------------------------------------------------------- /example/ios/Flutter/flutter_assets/fonts/MaterialIcons-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Flutter/flutter_assets/fonts/MaterialIcons-Regular.ttf -------------------------------------------------------------------------------- /example/ios/Flutter/flutter_assets/isolate_snapshot_data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Flutter/flutter_assets/isolate_snapshot_data -------------------------------------------------------------------------------- /example/ios/Flutter/flutter_assets/kernel_blob.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Flutter/flutter_assets/kernel_blob.bin -------------------------------------------------------------------------------- /example/ios/Flutter/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Flutter/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf -------------------------------------------------------------------------------- /example/ios/Flutter/flutter_assets/vm_snapshot_data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Flutter/flutter_assets/vm_snapshot_data -------------------------------------------------------------------------------- /example/ios/Flutter/flutter_export_environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is a generated file; do not edit or check into version control. 3 | export "FLUTTER_ROOT=/Users/dennysegura/development/flutter" 4 | export "FLUTTER_APPLICATION_PATH=/Users/dennysegura/Dev/Libs/flutter/flutter-auth0/example" 5 | export "FLUTTER_TARGET=/Users/dennysegura/Dev/Libs/flutter/flutter-auth0/example/lib/main.dart" 6 | export "FLUTTER_BUILD_DIR=build" 7 | export "SYMROOT=${SOURCE_ROOT}/../build/ios" 8 | export "FLUTTER_FRAMEWORK_DIR=/Users/dennysegura/development/flutter/bin/cache/artifacts/engine/ios" 9 | export "FLUTTER_BUILD_NAME=1.0.0" 10 | export "FLUTTER_BUILD_NUMBER=1" 11 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '9.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 parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | pods_ary = [] 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) { |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | pods_ary.push({:name => podname, :path => podpath}); 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | } 32 | return pods_ary 33 | end 34 | 35 | target 'Runner' do 36 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 37 | # referring to absolute paths on developers' machines. 38 | system('rm -rf .symlinks') 39 | system('mkdir -p .symlinks/plugins') 40 | 41 | # Flutter Pods 42 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') 43 | if generated_xcode_build_settings.empty? 44 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." 45 | end 46 | generated_xcode_build_settings.map { |p| 47 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR' 48 | symlink = File.join('.symlinks', 'flutter') 49 | File.symlink(File.dirname(p[:path]), symlink) 50 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) 51 | end 52 | } 53 | 54 | # Plugin Pods 55 | plugin_pods = parse_KV_file('../.flutter-plugins') 56 | plugin_pods.map { |p| 57 | symlink = File.join('.symlinks', 'plugins', p[:name]) 58 | File.symlink(p[:path], symlink) 59 | pod p[:name], :path => File.join(symlink, 'ios') 60 | } 61 | end 62 | 63 | post_install do |installer| 64 | installer.pods_project.targets.each do |target| 65 | target.build_configurations.each do |config| 66 | config.build_settings['ENABLE_BITCODE'] = 'NO' 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /example/ios/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/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Original 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcuserdata/tangdev.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Runner.xcworkspace/xcuserdata/tangdev.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #import "FlutterAuth0Plugin.h" 3 | #include "GeneratedPluginRegistrant.h" 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application 8 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 9 | [GeneratedPluginRegistrant registerWithRegistry:self]; 10 | // Override point for customization after application launch. 11 | [super application:application didFinishLaunchingWithOptions:launchOptions]; 12 | return YES; 13 | } 14 | 15 | - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { 16 | return [FlutterAuth0Plugin application:app openURL:url options:options]; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/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/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /example/ios/Runner/GeneratedPluginRegistrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #ifndef GeneratedPluginRegistrant_h 6 | #define GeneratedPluginRegistrant_h 7 | 8 | #import 9 | 10 | @interface GeneratedPluginRegistrant : NSObject 11 | + (void)registerWithRegistry:(NSObject*)registry; 12 | @end 13 | 14 | #endif /* GeneratedPluginRegistrant_h */ 15 | -------------------------------------------------------------------------------- /example/ios/Runner/GeneratedPluginRegistrant.m: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #import "GeneratedPluginRegistrant.h" 6 | #import 7 | 8 | @implementation GeneratedPluginRegistrant 9 | 10 | + (void)registerWithRegistry:(NSObject*)registry { 11 | [FlutterAuth0Plugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterAuth0Plugin"]]; 12 | } 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | Auth0 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | flutter_auth0 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleURLTypes 24 | 25 | 26 | CFBundleTypeRole 27 | None 28 | CFBundleURLName 29 | auth0 30 | CFBundleURLSchemes 31 | 32 | $(PRODUCT_BUNDLE_IDENTIFIER) 33 | 34 | 35 | 36 | CFBundleVersion 37 | $(FLUTTER_BUILD_NUMBER) 38 | LSRequiresIPhoneOS 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIMainStoryboardFile 43 | Main 44 | UISupportedInterfaceOrientations 45 | 46 | UIInterfaceOrientationPortrait 47 | 48 | UISupportedInterfaceOrientations~ipad 49 | 50 | UIInterfaceOrientationPortrait 51 | UIInterfaceOrientationPortraitUpsideDown 52 | UIInterfaceOrientationLandscapeLeft 53 | UIInterfaceOrientationLandscapeRight 54 | 55 | UIViewControllerBasedStatusBarAppearance 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /example/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/ios/ServiceDefinitions.json: -------------------------------------------------------------------------------- 1 | {"services":[]} -------------------------------------------------------------------------------- /example/lib/demo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_auth0/flutter_auth0.dart'; 3 | 4 | import 'pkce.dart'; 5 | import 'standard.dart'; 6 | 7 | final String clientId = 'XIpuO0OchFaayJZRq8RvpQefOdfJkgSL'; 8 | final String domain = 'dennysegura.auth0.com'; 9 | 10 | class MyHomePage extends StatefulWidget { 11 | MyHomePage({Key key, this.title}) : super(key: key); 12 | 13 | final String title; 14 | 15 | @override 16 | _MyHomePageState createState() => _MyHomePageState(); 17 | } 18 | 19 | class _MyHomePageState extends State 20 | with SingleTickerProviderStateMixin { 21 | TabController controller; 22 | Auth0 auth; 23 | final GlobalKey skey = GlobalKey(); 24 | 25 | @override 26 | void initState() { 27 | super.initState(); 28 | controller = TabController(vsync: this, initialIndex: 0, length: 2); 29 | auth = Auth0(baseUrl: 'https://$domain/', clientId: clientId); 30 | } 31 | 32 | void showInfo(String text, String message) { 33 | showDialog( 34 | context: context, 35 | builder: (BuildContext context) { 36 | return AlertDialog( 37 | title: Text(text), 38 | content: Text(message), 39 | actions: [ 40 | FlatButton( 41 | child: Text("Close"), 42 | onPressed: () { 43 | Navigator.of(context).pop(); 44 | }, 45 | ), 46 | ], 47 | ); 48 | }, 49 | ); 50 | } 51 | 52 | @override 53 | Widget build(BuildContext context) { 54 | return Scaffold( 55 | key: skey, 56 | appBar: AppBar( 57 | elevation: 0.7, 58 | centerTitle: false, 59 | leading: Image.network( 60 | 'https://cdn.auth0.com/styleguide/components/1.0.8/media/logos/img/logo-grey.png', 61 | height: 40, 62 | ), 63 | backgroundColor: Color.fromRGBO(0, 0, 0, 1.0), 64 | title: Text(widget.title), 65 | bottom: TabBar( 66 | controller: controller, 67 | indicatorColor: Colors.white, 68 | tabs: [ 69 | Tab( 70 | text: 'PKCE Flow', 71 | ), 72 | Tab( 73 | text: 'Standard Flow', 74 | ) 75 | ], 76 | ), 77 | ), 78 | body: LayoutBuilder( 79 | builder: (ctx, constraints) { 80 | return Container( 81 | constraints: constraints, 82 | color: Colors.white, 83 | child: TabBarView( 84 | controller: controller, 85 | children: [ 86 | PKCEPage(auth, showInfo), 87 | StandardPage(auth, showInfo), 88 | ], 89 | ), 90 | ); 91 | }, 92 | ), 93 | ); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'demo.dart'; 5 | 6 | void main() async { 7 | runZoned>(() async { 8 | runApp(MyApp()); 9 | }, onError: (error, stackTrace) async { 10 | debugPrint(error.toString()); 11 | }); 12 | } 13 | 14 | class MyApp extends StatelessWidget { 15 | @override 16 | Widget build(BuildContext context) { 17 | return MaterialApp( 18 | title: 'Flutter Auth0 Demo', 19 | home: MyHomePage(title: 'Demo'), 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /example/lib/pkce.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_auth0/flutter_auth0.dart'; 3 | 4 | class PKCEPage extends StatefulWidget { 5 | final auth; 6 | final Function showInfo; 7 | const PKCEPage(this.auth, this.showInfo); 8 | @override 9 | _PKCEPageState createState() => _PKCEPageState(); 10 | } 11 | 12 | class _PKCEPageState extends State { 13 | bool webLogged; 14 | dynamic currentWebAuth; 15 | 16 | @override 17 | void initState() { 18 | super.initState(); 19 | webLogged = false; 20 | } 21 | 22 | Auth0 get auth { 23 | return widget.auth; 24 | } 25 | 26 | Function get showInfo { 27 | return widget.showInfo; 28 | } 29 | 30 | void webLogin() async { 31 | try { 32 | var response = await auth.webAuth.authorize({ 33 | 'audience': 'https://${auth.auth.client.domain}/userinfo', 34 | 'scope': 'openid email offline_access', 35 | }); 36 | DateTime now = DateTime.now(); 37 | showInfo('Web Login', ''' 38 | \ntoken_type: ${response['token_type']} 39 | \nexpires_in: ${DateTime.fromMillisecondsSinceEpoch(response['expires_in'] + now.millisecondsSinceEpoch)} 40 | \nrefreshToken: ${response['refresh_token']} 41 | \naccess_token: ${response['access_token']} 42 | '''); 43 | webLogged = true; 44 | currentWebAuth = Map.from(response); 45 | setState(() {}); 46 | } catch (e) { 47 | print('Error: $e'); 48 | } 49 | } 50 | 51 | void webRefreshToken() async { 52 | try { 53 | var response = await auth.webAuth.client.refreshToken({ 54 | 'refreshToken': currentWebAuth['refresh_token'], 55 | }); 56 | DateTime now = DateTime.now(); 57 | showInfo('Refresh Token', ''' 58 | \ntoken_type: ${response['token_type']} 59 | \nexpires_in: ${DateTime.fromMillisecondsSinceEpoch(response['expires_in'] + now.millisecondsSinceEpoch)} 60 | \naccess_token: ${response['access_token']} 61 | '''); 62 | } catch (e) { 63 | print('Error: $e'); 64 | } 65 | } 66 | 67 | void closeSessions() async { 68 | try { 69 | await auth.webAuth.clearSession(); 70 | webLogged = false; 71 | setState(() {}); 72 | } catch (e) { 73 | print('Error: $e'); 74 | } 75 | } 76 | 77 | @override 78 | Widget build(BuildContext context) { 79 | return Container( 80 | padding: EdgeInsets.symmetric(horizontal: 16.0), 81 | child: Column( 82 | crossAxisAlignment: CrossAxisAlignment.start, 83 | children: [ 84 | MaterialButton( 85 | color: Colors.lightBlueAccent, 86 | textColor: Colors.white, 87 | child: const Text('Test Login'), 88 | onPressed: !webLogged ? webLogin : null, 89 | ), 90 | MaterialButton( 91 | color: Colors.blueAccent, 92 | textColor: Colors.white, 93 | child: const Text('Test Refresh Token'), 94 | onPressed: webLogged ? webRefreshToken : null, 95 | ), 96 | MaterialButton( 97 | color: Colors.redAccent, 98 | textColor: Colors.white, 99 | child: const Text('Test Clear Sessions'), 100 | onPressed: webLogged ? closeSessions : null, 101 | ), 102 | ], 103 | ), 104 | ); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /example/lib/standard.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_auth0/flutter_auth0.dart'; 3 | 4 | class StandardPage extends StatefulWidget { 5 | final auth; 6 | final Function showInfo; 7 | const StandardPage(this.auth, this.showInfo); 8 | @override 9 | _StandardPageState createState() => _StandardPageState(); 10 | } 11 | 12 | class _StandardPageState extends State { 13 | bool logged; 14 | dynamic currentAuth; 15 | TextEditingController uctrl; 16 | TextEditingController pctrl; 17 | 18 | @override 19 | void initState() { 20 | super.initState(); 21 | logged = false; 22 | uctrl = TextEditingController(); 23 | pctrl = TextEditingController(); 24 | } 25 | 26 | Auth0 get auth { 27 | return widget.auth; 28 | } 29 | 30 | Function get showInfo { 31 | return widget.showInfo; 32 | } 33 | 34 | void _signUp() async { 35 | try { 36 | var response = await auth.auth.createUser({ 37 | 'email': uctrl.text, 38 | 'password': pctrl.text, 39 | 'connection': 'Username-Password-Authentication' 40 | }); 41 | showInfo('Sign Up', ''' 42 | \nid: ${response['_id']} 43 | \nusername/email: ${response['email']} 44 | '''); 45 | } catch (e) { 46 | print(e); 47 | } 48 | } 49 | 50 | void _signIn() async { 51 | try { 52 | var response = await auth.auth.passwordRealm({ 53 | 'username': uctrl.text, 54 | 'password': pctrl.text, 55 | 'realm': 'Username-Password-Authentication' 56 | }); 57 | showInfo('Sign In', ''' 58 | \nAccess Token: ${response['access_token']} 59 | '''); 60 | } catch (e) { 61 | print(e); 62 | } 63 | } 64 | 65 | void _userInfo() async { 66 | try { 67 | var response = await auth.auth.passwordRealm({ 68 | 'username': uctrl.text, 69 | 'password': pctrl.text, 70 | 'realm': 'Username-Password-Authentication' 71 | }); 72 | Auth0Auth authClient = Auth0Auth( 73 | auth.auth.clientId, auth.auth.client.baseUrl, 74 | bearer: response['access_token']); 75 | var info = await authClient.getUserInfo(); 76 | String buffer = ''; 77 | info.forEach((k, v) => buffer = '$buffer\n$k: $v'); 78 | showInfo('User Info', buffer); 79 | } catch (e) { 80 | print(e); 81 | } 82 | } 83 | 84 | void _resetPassword() async { 85 | try { 86 | var success = await auth.auth.resetPassword({ 87 | 'email': uctrl.text, 88 | 'connection': 'Username-Password-Authentication' 89 | }); 90 | showInfo('Reset Password', 'Password Restarted: $success'); 91 | } catch (e) { 92 | print(e); 93 | } 94 | } 95 | 96 | @override 97 | Widget build(BuildContext context) { 98 | bool canSignIn = (uctrl.text != null && 99 | pctrl.text != null && 100 | uctrl.text.isNotEmpty && 101 | pctrl.text.isNotEmpty); 102 | return Container( 103 | padding: EdgeInsets.symmetric(horizontal: 16.0), 104 | child: Column( 105 | crossAxisAlignment: CrossAxisAlignment.start, 106 | children: [ 107 | TextField( 108 | enabled: !logged, 109 | controller: uctrl, 110 | decoration: const InputDecoration( 111 | hintText: 'Email/Username', 112 | ), 113 | onChanged: (e) { 114 | setState(() {}); 115 | }, 116 | ), 117 | TextField( 118 | enabled: !logged, 119 | controller: pctrl, 120 | obscureText: true, 121 | decoration: const InputDecoration( 122 | hintText: 'Password', 123 | ), 124 | onChanged: (e) { 125 | setState(() {}); 126 | }, 127 | ), 128 | MaterialButton( 129 | child: const Text('Test Sign Up'), 130 | color: Colors.blueAccent, 131 | textColor: Colors.white, 132 | onPressed: canSignIn ? _signUp : null, 133 | ), 134 | MaterialButton( 135 | child: const Text('Test Sign In'), 136 | color: Colors.redAccent, 137 | textColor: Colors.white, 138 | onPressed: canSignIn && !logged ? _signIn : null, 139 | ), 140 | MaterialButton( 141 | color: Colors.indigo, 142 | textColor: Colors.white, 143 | child: const Text('Test User Info'), 144 | onPressed: canSignIn ? _userInfo : null, 145 | ), 146 | MaterialButton( 147 | color: Colors.greenAccent, 148 | child: const Text('Test Reset Password'), 149 | onPressed: uctrl.text != null && uctrl.text.isNotEmpty 150 | ? _resetPassword 151 | : null, 152 | ), 153 | ], 154 | ), 155 | ); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | archive: 5 | dependency: transitive 6 | description: 7 | name: archive 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "2.0.11" 11 | args: 12 | dependency: transitive 13 | description: 14 | name: args 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "1.5.2" 18 | async: 19 | dependency: transitive 20 | description: 21 | name: async 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.4.0" 25 | boolean_selector: 26 | dependency: transitive 27 | description: 28 | name: boolean_selector 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.0.5" 32 | charcode: 33 | dependency: transitive 34 | description: 35 | name: charcode 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.1.2" 39 | collection: 40 | dependency: transitive 41 | description: 42 | name: collection 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.14.11" 46 | convert: 47 | dependency: transitive 48 | description: 49 | name: convert 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "2.1.1" 53 | crypto: 54 | dependency: transitive 55 | description: 56 | name: crypto 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "2.1.3" 60 | cupertino_icons: 61 | dependency: "direct main" 62 | description: 63 | name: cupertino_icons 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "0.1.2" 67 | flutter: 68 | dependency: "direct main" 69 | description: flutter 70 | source: sdk 71 | version: "0.0.0" 72 | flutter_auth0: 73 | dependency: "direct main" 74 | description: 75 | path: ".." 76 | relative: true 77 | source: path 78 | version: "0.5.0" 79 | flutter_test: 80 | dependency: "direct dev" 81 | description: flutter 82 | source: sdk 83 | version: "0.0.0" 84 | http: 85 | dependency: transitive 86 | description: 87 | name: http 88 | url: "https://pub.dartlang.org" 89 | source: hosted 90 | version: "0.12.0+2" 91 | http_parser: 92 | dependency: transitive 93 | description: 94 | name: http_parser 95 | url: "https://pub.dartlang.org" 96 | source: hosted 97 | version: "3.1.3" 98 | image: 99 | dependency: transitive 100 | description: 101 | name: image 102 | url: "https://pub.dartlang.org" 103 | source: hosted 104 | version: "2.1.4" 105 | matcher: 106 | dependency: transitive 107 | description: 108 | name: matcher 109 | url: "https://pub.dartlang.org" 110 | source: hosted 111 | version: "0.12.6" 112 | meta: 113 | dependency: transitive 114 | description: 115 | name: meta 116 | url: "https://pub.dartlang.org" 117 | source: hosted 118 | version: "1.1.8" 119 | path: 120 | dependency: transitive 121 | description: 122 | name: path 123 | url: "https://pub.dartlang.org" 124 | source: hosted 125 | version: "1.6.4" 126 | pedantic: 127 | dependency: transitive 128 | description: 129 | name: pedantic 130 | url: "https://pub.dartlang.org" 131 | source: hosted 132 | version: "1.8.0+1" 133 | petitparser: 134 | dependency: transitive 135 | description: 136 | name: petitparser 137 | url: "https://pub.dartlang.org" 138 | source: hosted 139 | version: "2.4.0" 140 | quiver: 141 | dependency: transitive 142 | description: 143 | name: quiver 144 | url: "https://pub.dartlang.org" 145 | source: hosted 146 | version: "2.0.5" 147 | sky_engine: 148 | dependency: transitive 149 | description: flutter 150 | source: sdk 151 | version: "0.0.99" 152 | source_span: 153 | dependency: transitive 154 | description: 155 | name: source_span 156 | url: "https://pub.dartlang.org" 157 | source: hosted 158 | version: "1.5.5" 159 | stack_trace: 160 | dependency: transitive 161 | description: 162 | name: stack_trace 163 | url: "https://pub.dartlang.org" 164 | source: hosted 165 | version: "1.9.3" 166 | stream_channel: 167 | dependency: transitive 168 | description: 169 | name: stream_channel 170 | url: "https://pub.dartlang.org" 171 | source: hosted 172 | version: "2.0.0" 173 | string_scanner: 174 | dependency: transitive 175 | description: 176 | name: string_scanner 177 | url: "https://pub.dartlang.org" 178 | source: hosted 179 | version: "1.0.5" 180 | term_glyph: 181 | dependency: transitive 182 | description: 183 | name: term_glyph 184 | url: "https://pub.dartlang.org" 185 | source: hosted 186 | version: "1.1.0" 187 | test_api: 188 | dependency: transitive 189 | description: 190 | name: test_api 191 | url: "https://pub.dartlang.org" 192 | source: hosted 193 | version: "0.2.11" 194 | typed_data: 195 | dependency: transitive 196 | description: 197 | name: typed_data 198 | url: "https://pub.dartlang.org" 199 | source: hosted 200 | version: "1.1.6" 201 | vector_math: 202 | dependency: transitive 203 | description: 204 | name: vector_math 205 | url: "https://pub.dartlang.org" 206 | source: hosted 207 | version: "2.0.8" 208 | xml: 209 | dependency: transitive 210 | description: 211 | name: xml 212 | url: "https://pub.dartlang.org" 213 | source: hosted 214 | version: "3.5.0" 215 | sdks: 216 | dart: ">=2.4.0 <3.0.0" 217 | flutter: ">=1.10.0 <2.0.0" 218 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_auth0_example 2 | description: A new Flutter project. 3 | 4 | version: 1.0.0+1 5 | 6 | environment: 7 | sdk: ">=2.2.0 <3.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | cupertino_icons: ^0.1.2 13 | flutter_auth0: 14 | path: ../ 15 | 16 | dev_dependencies: 17 | flutter_test: 18 | sdk: flutter 19 | 20 | flutter: 21 | uses-material-design: true 22 | 23 | -------------------------------------------------------------------------------- /flutter_auth0.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /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 | 13 | *.pbxuser 14 | *.mode1v3 15 | *.mode2v3 16 | *.perspectivev3 17 | 18 | !default.pbxuser 19 | !default.mode1v3 20 | !default.mode2v3 21 | !default.perspectivev3 22 | 23 | xcuserdata 24 | 25 | *.moved-aside 26 | 27 | *.pyc 28 | *sync/ 29 | Icon? 30 | .tags* -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devdennysegura/flutter-auth0/cf9420653208ceb56ebe61c0ab78c8f346c81e1f/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /ios/Classes/FlutterAuth0Plugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface FlutterAuth0Plugin : NSObject 4 | + (BOOL)application:(nonnull UIApplication *)app 5 | openURL:(nonnull NSURL *)URL 6 | options:(nonnull NSDictionary *)options; 7 | @end -------------------------------------------------------------------------------- /ios/Classes/FlutterAuth0Plugin.m: -------------------------------------------------------------------------------- 1 | #import "FlutterAuth0Plugin.h" 2 | #import 3 | #import 4 | 5 | @interface Auth0Session : NSObject 6 | @end 7 | 8 | @implementation Auth0Session { 9 | FlutterResult _flutterResult; 10 | SFSafariViewController *_viewController; 11 | } 12 | - (instancetype)initWithFlutterResult:result withController:controller{ 13 | self = [super init]; 14 | if (self) { 15 | _flutterResult = result; 16 | _viewController = controller; 17 | } 18 | return self; 19 | } 20 | - (void)getAccessToken:(NSURL *)url { 21 | NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO]; 22 | NSArray *queryItems = urlComponents.queryItems; 23 | NSString *code = [self valueForKey:@"code" fromQueryItems:queryItems]; 24 | _flutterResult(code); 25 | [_viewController dismissViewControllerAnimated:YES completion:nil]; 26 | } 27 | - (void)message:(NSString *)msg detail:(NSString *)det{ 28 | _flutterResult([FlutterError errorWithCode:@"Error" message:msg details:det]); 29 | } 30 | - (NSString *)valueForKey:(NSString *)key 31 | fromQueryItems:(NSArray *)queryItems{ 32 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name=%@", key]; 33 | NSURLQueryItem *queryItem = [[queryItems filteredArrayUsingPredicate:predicate] firstObject]; 34 | return queryItem.value; 35 | } 36 | @end 37 | 38 | Auth0Session *_currentSession; 39 | 40 | @interface FlutterAuth0Plugin () 41 | @property (weak, nonatomic) SFSafariViewController *last; 42 | @property (assign, nonatomic) BOOL closeOnLoad; 43 | @end 44 | 45 | @implementation FlutterAuth0Plugin 46 | 47 | + (void)registerWithRegistrar:(NSObject*)registrar { 48 | FlutterMethodChannel* channel = [FlutterMethodChannel 49 | methodChannelWithName:@"io.flutter.plugins/auth0" 50 | binaryMessenger:[registrar messenger]]; 51 | FlutterAuth0Plugin* instance = [[FlutterAuth0Plugin alloc] init]; 52 | [registrar addMethodCallDelegate:instance channel:channel]; 53 | } 54 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 55 | if ([@"getPlatformVersion" isEqualToString:call.method]) { 56 | result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); 57 | } else if ([@"authorize" isEqualToString:call.method]) { 58 | NSString *url = call.arguments; 59 | BOOL closeOnLoad = false; 60 | [self presentSafariWithURL:url result:result]; 61 | self.closeOnLoad = closeOnLoad; 62 | } else if ([@"parameters" isEqualToString:call.method]) { 63 | result([self generateOAuthParameters]); 64 | } else if ([@"bundleIdentifier" isEqualToString:call.method]) { 65 | NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; 66 | result(bundleIdentifier); 67 | } else { 68 | result(FlutterMethodNotImplemented); 69 | } 70 | } 71 | + (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { 72 | if (_currentSession != nil) { 73 | [_currentSession getAccessToken:url]; 74 | _currentSession = nil; 75 | } 76 | return YES; 77 | } 78 | - (BOOL)canLaunchURL:(NSString *)urlString { 79 | NSURL *url = [NSURL URLWithString:urlString]; 80 | UIApplication *application = [UIApplication sharedApplication]; 81 | return [application canOpenURL:url]; 82 | } 83 | 84 | #pragma mark - Internal methods 85 | - (void)presentSafariWithURL:(NSString *)urlString result:(FlutterResult)result { 86 | if((BOOL)@([self canLaunchURL:urlString])){ 87 | NSURL *url = [NSURL URLWithString:urlString]; 88 | UIWindow *window = [[UIApplication sharedApplication] keyWindow]; 89 | SFSafariViewController *controller = [[SFSafariViewController alloc] initWithURL:url]; 90 | controller.delegate = self; 91 | _currentSession = [[Auth0Session alloc] initWithFlutterResult:result withController: controller]; 92 | [[self topViewControllerWithRootViewController:window.rootViewController] presentViewController:controller animated:YES completion:nil]; 93 | self.last = controller; 94 | }else{ 95 | [_currentSession message:@"Only one Safari can be visible" detail:@"Failed to load"]; 96 | } 97 | } 98 | - (void)terminateWithError:(id)error dismissing:(BOOL)dismissing animated:(BOOL)animated{ 99 | if (dismissing) { 100 | [self.last.presentingViewController dismissViewControllerAnimated:animated completion:^{ 101 | if (error) { 102 | [_currentSession message:error detail:nil]; 103 | } 104 | }]; 105 | } else if (error) { 106 | [_currentSession message:error detail:nil]; 107 | } 108 | self.last = nil; 109 | self.closeOnLoad = NO; 110 | } 111 | 112 | #pragma mark - Internal methods 113 | - (NSString *)randomValue { 114 | NSMutableData *data = [NSMutableData dataWithLength:32]; 115 | int result __attribute__((unused)) = SecRandomCopyBytes(kSecRandomDefault, 32, data.mutableBytes); 116 | NSString *value = [[[[data base64EncodedStringWithOptions:0] 117 | stringByReplacingOccurrencesOfString:@"+" withString:@"-"] 118 | stringByReplacingOccurrencesOfString:@"/" withString:@"_"] 119 | stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"="]]; 120 | return value; 121 | } 122 | - (NSString *)sign:(NSString*)value { 123 | CC_SHA256_CTX ctx; 124 | 125 | uint8_t * hashBytes = malloc(CC_SHA256_DIGEST_LENGTH * sizeof(uint8_t)); 126 | memset(hashBytes, 0x0, CC_SHA256_DIGEST_LENGTH); 127 | 128 | NSData *valueData = [value dataUsingEncoding:NSUTF8StringEncoding]; 129 | 130 | CC_SHA256_Init(&ctx); 131 | CC_SHA256_Update(&ctx, [valueData bytes], (CC_LONG)[valueData length]); 132 | CC_SHA256_Final(hashBytes, &ctx); 133 | 134 | NSData *hash = [NSData dataWithBytes:hashBytes length:CC_SHA256_DIGEST_LENGTH]; 135 | 136 | if (hashBytes) { 137 | free(hashBytes); 138 | } 139 | 140 | return [[[[hash base64EncodedStringWithOptions:0] 141 | stringByReplacingOccurrencesOfString:@"+" withString:@"-"] 142 | stringByReplacingOccurrencesOfString:@"/" withString:@"_"] 143 | stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"="]]; 144 | } 145 | - (NSDictionary *)generateOAuthParameters { 146 | NSString *verifier = [self randomValue]; 147 | return @{ 148 | @"verifier": verifier, 149 | @"code_challenge": [self sign:verifier], 150 | @"code_challenge_method": @"S256", 151 | @"state": [self randomValue] 152 | }; 153 | } 154 | 155 | #pragma mark - SFSafariViewControllerDelegate 156 | - (void)safariViewControllerDidFinish:(SFSafariViewController *)controller { 157 | [_currentSession message:@"a0.session.user_cancelled" detail:@"User cancelled the Auth"]; 158 | [controller dismissViewControllerAnimated:YES completion:nil]; 159 | } 160 | - (void)safariViewController:(SFSafariViewController *)controller didCompleteInitialLoad:(BOOL)didLoadSuccessfully { 161 | printf("safariViewController"); 162 | if (self.closeOnLoad && didLoadSuccessfully) { 163 | [controller dismissViewControllerAnimated:YES completion:nil]; 164 | } else if (!didLoadSuccessfully) { 165 | [_currentSession message:@"a0.session.failed_load" detail:@"Failed to load url"]; 166 | [controller dismissViewControllerAnimated:YES completion:nil]; 167 | } 168 | } 169 | 170 | # pragma mark - Utility 171 | - (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController { 172 | if ([rootViewController isKindOfClass:[UITabBarController class]]) { 173 | UITabBarController* tabBarController = (UITabBarController*)rootViewController; 174 | return [self topViewControllerWithRootViewController:tabBarController.selectedViewController]; 175 | } else if ([rootViewController isKindOfClass:[UINavigationController class]]) { 176 | UINavigationController* navigationController = (UINavigationController*)rootViewController; 177 | return [self topViewControllerWithRootViewController:navigationController.visibleViewController]; 178 | } else if (rootViewController.presentedViewController) { 179 | UIViewController* presentedViewController = rootViewController.presentedViewController; 180 | return [self topViewControllerWithRootViewController:presentedViewController]; 181 | } else { 182 | return rootViewController; 183 | } 184 | } 185 | 186 | @end -------------------------------------------------------------------------------- /ios/flutter_auth0.podspec: -------------------------------------------------------------------------------- 1 | 2 | # 3 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'flutter_auth0' 7 | s.version = '0.0.1' 8 | s.summary = 'A new flutter plugin project.' 9 | s.description = <<-DESC 10 | A new flutter plugin project. 11 | DESC 12 | s.homepage = 'https://github.com/devdennysegura/flutter-auth0' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Denny Segura' => 'devdennysegura@gmail.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.public_header_files = 'Classes/**/*.h' 18 | s.dependency 'Flutter' 19 | 20 | s.ios.deployment_target = '9.0' 21 | end -------------------------------------------------------------------------------- /lib/flutter_auth0.dart: -------------------------------------------------------------------------------- 1 | library auth0_auth; 2 | 3 | import 'dart:async'; 4 | import 'dart:convert'; 5 | import 'dart:io'; 6 | 7 | import 'package:flutter/services.dart'; 8 | import 'package:http/http.dart' as http; 9 | 10 | part 'src/auth_exeption.dart'; 11 | part 'src/auth0_error.dart'; 12 | part 'src/user_info.dart'; 13 | part 'src/auth/index.dart'; 14 | part 'src/webauth/index.dart'; 15 | part 'src/networking/client.dart'; 16 | part 'src/networking/telemetry.dart'; 17 | part 'src/management/users.dart'; 18 | 19 | class Auth0 { 20 | final Auth0Auth auth; 21 | final WebAuth webAuth; 22 | final dynamic options; 23 | 24 | Auth0._(this.auth, this.webAuth, this.options); 25 | 26 | factory Auth0({String baseUrl, String clientId}) { 27 | assert(baseUrl != null && clientId != null); 28 | final auth = Auth0Auth(clientId, baseUrl); 29 | final webAuth = new WebAuth(auth); 30 | return Auth0._(auth, webAuth, {'baseUrl': baseUrl, 'clientId': clientId}); 31 | } 32 | 33 | /* 34 | * Creates a Users API client 35 | * https://manage.auth0.com/#/apis/management/explorer 36 | * @param {String} token for Management API 37 | * @return {Users} 38 | */ 39 | Users users(String token) { 40 | return Users(Map.from(this.options)..addAll({'token': token})); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/src/auth/index.dart: -------------------------------------------------------------------------------- 1 | part of auth0_auth; 2 | 3 | class Auth0Auth { 4 | final Auth0Client client; 5 | final String clientId; 6 | 7 | Auth0Auth._(this.client, this.clientId); 8 | 9 | factory Auth0Auth(String clientId, String url, {dynamic bearer}) { 10 | assert(clientId != null); 11 | final _client = new Auth0Client(url, telemetry: telemetry, token: bearer); 12 | return Auth0Auth._(_client, clientId); 13 | } 14 | 15 | Future responseHandler(http.Response response) { 16 | if (response.statusCode == 200) { 17 | return jsonDecode(response.body); 18 | } 19 | else if (response.statusCode == 401) { 20 | throw Auth0Exeption(description: response.body); 21 | } 22 | throw jsonDecode(response.body); 23 | } 24 | 25 | Future responseDataHandler(http.Response response) async { 26 | if (response.statusCode == 200) { 27 | dynamic value = jsonDecode(response.body); 28 | return Map.from(value); 29 | } 30 | else if (response.statusCode == 401) { 31 | throw Auth0Exeption(description: response.body); 32 | } 33 | throw jsonDecode(response.body); 34 | } 35 | 36 | // 37 | // Builds the full authorize endpoint url in the Authorization Server (AS) with given parameters. 38 | // parameters [params] to send to /authorize 39 | // @param {String} params.responseType type of the response to get from /authorize. 40 | // @param {String} params.redirectUri where the AS will redirect back after success or failure. 41 | // @param {String} params.state random string to prevent CSRF attacks. 42 | // @returns {String} authorize url with specified params to redirect to for AuthZ/AuthN. 43 | // [ref link]: https://auth0.com/docs/api/authentication#authorize-client 44 | // 45 | String authorizeUrl(dynamic params) { 46 | assert(params['redirectUri'] != null && 47 | params['responseType'] != null && 48 | params['state'] != null); 49 | var query = Map.from(params) 50 | ..addAll({ 51 | 'redirect_uri': params['redirectUri'], 52 | 'response_type': params['responseType'], 53 | 'state': params['state'], 54 | }); 55 | return this.client.url( 56 | '/authorize', 57 | query: Map.from({'client_id': this.clientId})..addAll(query), 58 | includeTelemetry: true, 59 | ); 60 | } 61 | 62 | // 63 | // Builds the full logout endpoint url in the Authorization Server (AS) with given parameters. 64 | // [params] to send to /v2/logout 65 | // @param {Boolean} [params.federated] if the logout should include removing session for federated IdP. 66 | // @param {String} [params.clientId] client identifier of the one requesting the logout 67 | // @param {String} [params.returnTo] url where the user is redirected to after logout. It must be declared in you Auth0 Dashboard 68 | // @returns {String} logout url with specified parameters 69 | // [ref link]: https://auth0.com/docs/api/authentication#logout 70 | // 71 | String logoutUrl(dynamic params) { 72 | var query = Map.from(params) 73 | ..addAll({ 74 | 'client_id': params['clientId'], 75 | 'returnTo': params['returnTo'], 76 | }); 77 | return this.client.url( 78 | '/v2/logout', 79 | query: Map.from(query), 80 | includeTelemetry: true, 81 | ); 82 | } 83 | 84 | // 85 | // Exchanges a code obtained via /authorize (w/PKCE) for the user's tokens 86 | // [params] used to obtain tokens from a code 87 | // @param {String} params.code code returned by /authorize. 88 | // @param {String} params.redirectUri original redirectUri used when calling /authorize. 89 | // @param {String} params.verifier value used to generate the code challenge sent to /authorize. 90 | // @returns a Future with userInfo 91 | // [ref link]: https://auth0.com/docs/api-auth/grant/authorization-code-pkce 92 | // 93 | Future exchange(dynamic params) async { 94 | try { 95 | assert(params['code'] != null && 96 | params['verifier'] != null && 97 | params['redirectUri'] != null); 98 | var payload = Map.from(params) 99 | ..addAll({ 100 | 'code_verifier': params['verifier'], 101 | 'redirect_uri': params['redirectUri'], 102 | 'client_id': this.clientId, 103 | 'grant_type': 'authorization_code', 104 | }); 105 | http.Response res = await this.client.mutate('/oauth/token', payload); 106 | return await responseDataHandler(res); 107 | } catch (e) { 108 | throw new Auth0Exeption(description: e); 109 | } 110 | } 111 | 112 | // 113 | // Performs Auth with user credentials using the Password Realm Grant 114 | // [params] to send realm parameters 115 | // @param {String} params.username user's username or email 116 | // @param {String} params.password user's password 117 | // @param {String} params.realm name of the Realm where to Auth (or connection name) 118 | // @param {String} [params.audience] identifier of Resource Server (RS) to be included as audience (aud claim) of the issued access token 119 | // @param {String} [params.scope] scopes requested for the issued tokens. e.g. openid profile 120 | // @returns a Future with userInfo 121 | // [ref link]: https://auth0.com/docs/api-auth/grant/password#realm-support 122 | // 123 | Future passwordRealm(dynamic params) async { 124 | assert(params['username'] != null && 125 | params['password'] != null && 126 | params['realm'] != null); 127 | try { 128 | var payload = Map.from(params) 129 | ..addAll({ 130 | 'client_id': this.clientId, 131 | 'grant_type': 'http://auth0.com/oauth/grant-type/password-realm', 132 | }); 133 | http.Response res = await this.client.mutate('/oauth/token', payload); 134 | return await responseDataHandler(res); 135 | } catch (e) { 136 | throw new Auth0Exeption( 137 | name: e['name'] ?? e['error'], 138 | description: 139 | e['message'] ?? e['description'] ?? e['error_description']); 140 | } 141 | } 142 | 143 | // 144 | // Obtain new tokens using the Refresh Token obtained during Auth (requesting offline_access scope) 145 | // @param {Object} params refresh token params 146 | // @param {String} params.refreshToken user's issued refresh token 147 | // @param {String} [params.scope] scopes requested for the issued tokens. e.g. openid profile 148 | // @returns {Future} 149 | // [ref link]: https://auth0.com/docs/tokens/refresh-token/current#use-a-refresh-token 150 | // 151 | Future refreshToken(dynamic params) async { 152 | assert(params['refreshToken'] != null); 153 | try { 154 | var payload = Map.from(params) 155 | ..addAll({ 156 | 'refresh_token': params['refreshToken'], 157 | 'client_id': this.clientId, 158 | 'grant_type': 'refresh_token', 159 | }); 160 | http.Response res = await this.client.mutate('/oauth/token', payload); 161 | return await responseDataHandler(res); 162 | } catch (e) { 163 | throw new Auth0Exeption(description: e); 164 | } 165 | } 166 | 167 | // 168 | // Return user information using an access token 169 | // @param {String} token user's access token 170 | // @returns {Future} 171 | // 172 | Future getUserInfo() async { 173 | try { 174 | http.Response res = await this.client.query('/userinfo'); 175 | return await responseDataHandler(res); 176 | } catch (e) { 177 | throw new Auth0Exeption(description: e); 178 | } 179 | } 180 | 181 | // 182 | // Revoke an issued refresh token 183 | // @param {Object} params revoke token params 184 | // @param {String} params.refreshToken user's issued refresh token 185 | // @returns {Future} 186 | // 187 | dynamic revoke(dynamic params) { 188 | assert(params['refreshToken'] != null); 189 | var payload = Map.from(params) 190 | ..addAll({ 191 | 'token': params['refreshToken'], 192 | 'client_id': this.clientId, 193 | }); 194 | return this 195 | .client 196 | .mutate('/oauth/revoke', payload) 197 | .then((http.Response response) { 198 | if (response.statusCode == 200) { 199 | return {}; 200 | } 201 | throw new Auth0Exeption(description: jsonDecode(response.body)); 202 | }); 203 | } 204 | 205 | // 206 | // Return user information using an access token 207 | // @param {Object} params user info params 208 | // @param {String} params.token user's access token 209 | // @returns {Future} 210 | // 211 | dynamic userInfo(dynamic params) { 212 | assert(params['token'] != null); 213 | var _client = new Auth0Client(this.client.baseUrl, 214 | telemetry: this.client.telemetry, token: params['token']); 215 | return _client.query('/userinfo').then(responseHandler); 216 | } 217 | 218 | // 219 | // Request an email with instructions to change password of a user 220 | // @param {Object} parameters reset password parameters 221 | // @param {String} parameters.email user's email 222 | // @param {String} parameters.connection name of the connection of the user 223 | // @returns {Future} 224 | // 225 | dynamic resetPassword(dynamic params) { 226 | assert(params['email'] != null && params['connection'] != null); 227 | var payload = Map.from(params)..addAll({'client_id': this.clientId}); 228 | return this 229 | .client 230 | .mutate('/dbconnections/change_password', payload) 231 | .then((http.Response response) { 232 | if (response.statusCode == 200) { 233 | return true; 234 | } 235 | throw jsonDecode(response.body); 236 | }); 237 | } 238 | 239 | // 240 | // @param {Object} params create user params 241 | // @param {String} params.email user's email 242 | // @param {String} [params.username] user's username 243 | // @param {String} params.password user's password 244 | // @param {String} params.connection name of the database connection where to create the user 245 | // @param {String} [params.metadata] additional user information that will be stored in user_metadata 246 | // @returns {Future} 247 | // 248 | Future createUser(dynamic params) async { 249 | assert(params['email'] != null && 250 | params['password'] != null && 251 | params['connection'] != null); 252 | try { 253 | var payload = Map.from(params)..addAll({'client_id': this.clientId}); 254 | if (params['metadata'] != null) 255 | payload..addAll({'user_metadata': params['metadata']}); 256 | http.Response res = await this.client.mutate( 257 | '/dbconnections/signup', 258 | payload, 259 | ); 260 | return await responseDataHandler(res); 261 | } catch (e) { 262 | throw new Auth0Exeption( 263 | name: e['name'], description: e['message'] ?? e['description']); 264 | } 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /lib/src/auth0_error.dart: -------------------------------------------------------------------------------- 1 | part of auth0_auth; 2 | 3 | class Auth0Exeption implements Exception { 4 | final String name; 5 | final String description; 6 | Auth0Exeption( 7 | {this.name = 'a0.response.invalid', this.description = 'unknown error'}); 8 | 9 | String toString() { 10 | return '$name: $description'; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/src/auth_exeption.dart: -------------------------------------------------------------------------------- 1 | part of auth0_auth; 2 | 3 | class AuthExeption implements Exception { 4 | final String name; 5 | final String description; 6 | AuthExeption( 7 | {this.name = 'a0.response.invalid', this.description = 'unknown error'}); 8 | } 9 | -------------------------------------------------------------------------------- /lib/src/management/users.dart: -------------------------------------------------------------------------------- 1 | part of auth0_auth; 2 | 3 | class Users { 4 | final Auth0Client client; 5 | 6 | Users._(this.client); 7 | 8 | factory Users(dynamic options) { 9 | assert(options['token'] != null && options['baseUrl'] != null); 10 | var client = Auth0Client(options['baseUrl'], 11 | telemetry: telemetry, token: options['token']); 12 | return Users._(client); 13 | } 14 | 15 | Future responseHandler(http.Response response) async { 16 | if (response.statusCode == 200) { 17 | dynamic value = jsonDecode(response.body); 18 | return Map.from(value); 19 | } 20 | else if (response.statusCode == 401) { 21 | throw Auth0Exeption(description: response.body); 22 | } 23 | throw jsonDecode(response.body); 24 | } 25 | 26 | ///Returns the user by identifier 27 | ///@param {Object} parameters get user by identifier parameters 28 | ///@param {String} parameters.id identifier of the user to obtain 29 | ///@returns {Promise} 30 | ///[ref link]: https://auth0.com/docs/api/management/v2#!/Users/get_users_by_id 31 | ///@memberof Users 32 | Future getUser(dynamic parameters) async { 33 | assert(parameters['id'] != null); 34 | var payload = Map.from(parameters); 35 | http.Response response = 36 | await this.client.query('/api/v2/users/${payload['id']}'); 37 | return await responseHandler(response); 38 | } 39 | 40 | ///Patch a user's `user_metadata` 41 | ///@param {Object} parameters patch user metadata parameters 42 | ///@param {String} parameters.id identifier of the user to patch 43 | ///@param {Object} parameters.metadata object with attributes to store in user_metadata. 44 | ///@returns {Promise} 45 | ///[ref link]: https://auth0.com/docs/api/management/v2#!/Users/patch_users_by_id 46 | ///@memberof Users 47 | Future patchUser(dynamic parameters) async { 48 | assert(parameters['id'] != null && parameters['metadata'] != null); 49 | var payload = Map.from(parameters); 50 | http.Response response = 51 | await this.client.update('/api/v2/users/${payload['id']}', { 52 | 'user_metadata': payload['metadata'], 53 | }); 54 | return await responseHandler(response); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/src/networking/client.dart: -------------------------------------------------------------------------------- 1 | part of auth0_auth; 2 | 3 | class Auth0Client { 4 | final String protocol; 5 | final String domain; 6 | final dynamic telemetry; 7 | final String bearer; 8 | final String baseUrl; 9 | 10 | Auth0Client.fromClient(Auth0Client client, {String bearer}) 11 | : protocol = client.protocol, 12 | domain = client.domain, 13 | telemetry = client.telemetry, 14 | bearer = client.bearer ?? bearer, 15 | baseUrl = client.baseUrl; 16 | 17 | Auth0Client._( 18 | this.protocol, this.domain, this.telemetry, this.bearer, this.baseUrl); 19 | 20 | factory Auth0Client(String baseUrl, {dynamic telemetry, dynamic token}) { 21 | assert(baseUrl != null); 22 | var parsed = Uri.parse(baseUrl); 23 | final String scheme = parsed.scheme; 24 | final String host = parsed.host; 25 | final String authorization = token != null ? 'Bearer $token' : null; 26 | return Auth0Client._(scheme, host, telemetry, authorization, baseUrl); 27 | } 28 | 29 | Future mutate(String path, dynamic body) async { 30 | return this.request('POST', url(path), body: body); 31 | } 32 | 33 | Future update(String path, dynamic body) async { 34 | return this.request('PATCH', url(path), body: body); 35 | } 36 | 37 | Future query(String path, {dynamic params}) async { 38 | return this.request('GET', url(path, query: params)); 39 | } 40 | 41 | String url(String path, {dynamic query, bool includeTelemetry = false}) { 42 | dynamic params = query ?? {}; 43 | if (includeTelemetry) { 44 | params['auth0Client'] = this.encodedTelemetry(); 45 | } 46 | var parsed = Uri( 47 | scheme: protocol, 48 | host: domain, 49 | path: path, 50 | queryParameters: Map.from(params), 51 | ); 52 | return parsed.query.isEmpty 53 | ? parsed.toString().replaceAll('?', '') 54 | : parsed.toString(); 55 | } 56 | 57 | Future request(String method, String url, 58 | {dynamic body, dynamic headers}) async { 59 | Map headers = { 60 | 'Accept': 'application/json', 61 | 'Content-Type': 'application/json', 62 | 'Auth0-Client': this.encodedTelemetry() 63 | }; 64 | if (bearer != null) { 65 | headers['Authorization'] = this.bearer; 66 | } 67 | var _client = new http.Client(); 68 | Map> handler = { 69 | 'POST': _client.post(url, body: Map.from((body ?? {}))), 70 | 'GET': _client.get(url, headers: headers), 71 | 'PATCH': _client.patch(url, body: Map.from((body ?? {}))), 72 | }; 73 | http.Response uriResponse; 74 | try { 75 | uriResponse = await handler[method]; 76 | } catch (e) { 77 | print(e); 78 | } finally { 79 | _client.close(); 80 | } 81 | return uriResponse; 82 | } 83 | 84 | String encodedTelemetry() { 85 | return base64.encode(utf8.encode(jsonEncode(telemetry))); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /lib/src/networking/telemetry.dart: -------------------------------------------------------------------------------- 1 | part of auth0_auth; 2 | 3 | const telemetry = {'name': 'flutter_auth0', 'version': '1.0.0'}; 4 | -------------------------------------------------------------------------------- /lib/src/user_info.dart: -------------------------------------------------------------------------------- 1 | part of auth0_auth; 2 | 3 | class Auth0User { 4 | String accessToken; 5 | String refreshToken; 6 | String idToken; 7 | String scope; 8 | DateTime expiresDate; 9 | String tokenType; 10 | 11 | Auth0User.fromMap(Map snapshot) 12 | : accessToken = snapshot['access_token'], 13 | refreshToken = snapshot['refresh_token'], 14 | idToken = snapshot['id_token'], 15 | scope = snapshot['scope'], 16 | expiresDate = 17 | DateTime.now().add(Duration(seconds: snapshot['expires_in'] = 0)), 18 | tokenType = snapshot['token_type']; 19 | 20 | toJson() { 21 | return { 22 | 'access_token': accessToken, 23 | 'refresh_token': refreshToken, 24 | 'id_token': idToken, 25 | 'scope': scope, 26 | 'expires_in': expiresDate, 27 | 'token_type': tokenType 28 | }; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lib/src/webauth/index.dart: -------------------------------------------------------------------------------- 1 | part of auth0_auth; 2 | 3 | const MethodChannel auth0Channel = 4 | const MethodChannel('io.flutter.plugins/auth0'); 5 | var platformName = Platform.isAndroid ? 'android' : 'ios'; 6 | 7 | Future callbackUri(String domain) async { 8 | var bundleIdentifier = await auth0Channel.invokeMethod('bundleIdentifier'); 9 | return '$bundleIdentifier://$domain/$platformName/$bundleIdentifier/callback'; 10 | } 11 | 12 | /* 13 | * Helper to perform Auth against Auth0 hosted login page 14 | * 15 | * It will use `/authorize` endpoint of the Authorization Server (AS) 16 | * with Code Grant and Proof Key for Challenge Exchange (PKCE). 17 | * 18 | * @export 19 | * @class WebAuth 20 | * [ref link]: https://auth0.com/docs/api-auth/grant/authorization-code-pkce 21 | */ 22 | class WebAuth { 23 | final Auth0Auth client; 24 | final String domain; 25 | final String clientId; 26 | 27 | WebAuth(this.client) 28 | : this.domain = client.client.domain, 29 | this.clientId = client.clientId; 30 | 31 | /* 32 | * Starts the AuthN/AuthZ transaction against the AS in the in-app browser. 33 | * 34 | * In iOS it will use `SFSafariViewController` and in Android Chrome Custom Tabs. 35 | * 36 | * To learn more about how to customize the authorize call, check the Universal Login Page 37 | * article at https://auth0.com/docs/hosted-pages/login 38 | * 39 | * @param {Object} parameters options to send 40 | * @param {String} [options.audience] identifier of Resource Server (RS) to be included as audience (aud claim) of the issued access token 41 | * @param {String} [options.scope] scopes requested for the issued tokens. e.g. `openid profile` 42 | * @returns {Future} 43 | * [ref link]: https://auth0.com/docs/api/authentication#authorize-client 44 | * 45 | * @memberof WebAuth 46 | */ 47 | Future authorize(dynamic options) async { 48 | return await auth0Channel 49 | .invokeMethod('parameters') 50 | .then((dynamic params) async { 51 | var redirectUri = await callbackUri(this.domain); 52 | dynamic query = Map.from(options) 53 | ..addAll({ 54 | 'clientId': this.clientId, 55 | 'responseType': 'code', 56 | 'redirectUri': redirectUri, 57 | }) 58 | ..addAll(params); 59 | var authorizeUrl = this.client.authorizeUrl(query); 60 | return await auth0Channel 61 | .invokeMethod('authorize', authorizeUrl) 62 | .then((accessToken) async { 63 | return await this.client.exchange({ 64 | 'code': accessToken, 65 | 'verifier': params['verifier'], 66 | 'redirectUri': redirectUri 67 | }); 68 | }); 69 | }); 70 | } 71 | 72 | /* 73 | * Removes Auth0 session and optionally remove the Identity Provider session. 74 | * 75 | * In iOS it will use `SFSafariViewController` and in Android Chrome Custom Tabs. 76 | * 77 | * @param {Object} parameters parameters to send 78 | * @param {Bool} federated Optionally remove the IdP session. 79 | * @returns {Future} 80 | * [ref link]: https://auth0.com/docs/logout 81 | * 82 | * @memberof WebAuth 83 | */ 84 | clearSession({bool federated = false}) async { 85 | var payload = Map.from({ 86 | 'clientId': this.clientId, 87 | 'returnTo': await callbackUri(this.domain) 88 | }); 89 | 90 | if (federated) { 91 | payload['federated'] = federated.toString(); 92 | } 93 | 94 | var logoutUrl = this.client.logoutUrl(payload); 95 | return auth0Channel.invokeMethod('authorize', logoutUrl); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | analyzer: 5 | dependency: transitive 6 | description: 7 | name: analyzer 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "0.37.0" 11 | args: 12 | dependency: transitive 13 | description: 14 | name: args 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "1.5.2" 18 | async: 19 | dependency: transitive 20 | description: 21 | name: async 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.3.0" 25 | boolean_selector: 26 | dependency: transitive 27 | description: 28 | name: boolean_selector 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.0.5" 32 | charcode: 33 | dependency: transitive 34 | description: 35 | name: charcode 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.1.2" 39 | collection: 40 | dependency: transitive 41 | description: 42 | name: collection 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.14.11" 46 | convert: 47 | dependency: transitive 48 | description: 49 | name: convert 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "2.1.1" 53 | crypto: 54 | dependency: transitive 55 | description: 56 | name: crypto 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "2.1.1+1" 60 | csslib: 61 | dependency: transitive 62 | description: 63 | name: csslib 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "0.16.1" 67 | flutter: 68 | dependency: "direct main" 69 | description: flutter 70 | source: sdk 71 | version: "0.0.0" 72 | front_end: 73 | dependency: transitive 74 | description: 75 | name: front_end 76 | url: "https://pub.dartlang.org" 77 | source: hosted 78 | version: "0.1.20" 79 | glob: 80 | dependency: transitive 81 | description: 82 | name: glob 83 | url: "https://pub.dartlang.org" 84 | source: hosted 85 | version: "1.1.7" 86 | html: 87 | dependency: transitive 88 | description: 89 | name: html 90 | url: "https://pub.dartlang.org" 91 | source: hosted 92 | version: "0.14.0+2" 93 | http: 94 | dependency: "direct main" 95 | description: 96 | name: http 97 | url: "https://pub.dartlang.org" 98 | source: hosted 99 | version: "0.12.0+2" 100 | http_multi_server: 101 | dependency: transitive 102 | description: 103 | name: http_multi_server 104 | url: "https://pub.dartlang.org" 105 | source: hosted 106 | version: "2.1.0" 107 | http_parser: 108 | dependency: transitive 109 | description: 110 | name: http_parser 111 | url: "https://pub.dartlang.org" 112 | source: hosted 113 | version: "3.1.3" 114 | io: 115 | dependency: transitive 116 | description: 117 | name: io 118 | url: "https://pub.dartlang.org" 119 | source: hosted 120 | version: "0.3.3" 121 | js: 122 | dependency: transitive 123 | description: 124 | name: js 125 | url: "https://pub.dartlang.org" 126 | source: hosted 127 | version: "0.6.1+1" 128 | kernel: 129 | dependency: transitive 130 | description: 131 | name: kernel 132 | url: "https://pub.dartlang.org" 133 | source: hosted 134 | version: "0.3.20" 135 | matcher: 136 | dependency: transitive 137 | description: 138 | name: matcher 139 | url: "https://pub.dartlang.org" 140 | source: hosted 141 | version: "0.12.5" 142 | meta: 143 | dependency: "direct main" 144 | description: 145 | name: meta 146 | url: "https://pub.dartlang.org" 147 | source: hosted 148 | version: "1.1.8" 149 | mime: 150 | dependency: transitive 151 | description: 152 | name: mime 153 | url: "https://pub.dartlang.org" 154 | source: hosted 155 | version: "0.9.6+3" 156 | multi_server_socket: 157 | dependency: transitive 158 | description: 159 | name: multi_server_socket 160 | url: "https://pub.dartlang.org" 161 | source: hosted 162 | version: "1.0.2" 163 | node_preamble: 164 | dependency: transitive 165 | description: 166 | name: node_preamble 167 | url: "https://pub.dartlang.org" 168 | source: hosted 169 | version: "1.4.6" 170 | package_config: 171 | dependency: transitive 172 | description: 173 | name: package_config 174 | url: "https://pub.dartlang.org" 175 | source: hosted 176 | version: "1.0.5" 177 | package_resolver: 178 | dependency: transitive 179 | description: 180 | name: package_resolver 181 | url: "https://pub.dartlang.org" 182 | source: hosted 183 | version: "1.0.10" 184 | path: 185 | dependency: transitive 186 | description: 187 | name: path 188 | url: "https://pub.dartlang.org" 189 | source: hosted 190 | version: "1.6.4" 191 | pedantic: 192 | dependency: transitive 193 | description: 194 | name: pedantic 195 | url: "https://pub.dartlang.org" 196 | source: hosted 197 | version: "1.8.0+1" 198 | pool: 199 | dependency: transitive 200 | description: 201 | name: pool 202 | url: "https://pub.dartlang.org" 203 | source: hosted 204 | version: "1.4.0" 205 | pub_semver: 206 | dependency: transitive 207 | description: 208 | name: pub_semver 209 | url: "https://pub.dartlang.org" 210 | source: hosted 211 | version: "1.4.2" 212 | shelf: 213 | dependency: transitive 214 | description: 215 | name: shelf 216 | url: "https://pub.dartlang.org" 217 | source: hosted 218 | version: "0.7.5" 219 | shelf_packages_handler: 220 | dependency: transitive 221 | description: 222 | name: shelf_packages_handler 223 | url: "https://pub.dartlang.org" 224 | source: hosted 225 | version: "1.0.4" 226 | shelf_static: 227 | dependency: transitive 228 | description: 229 | name: shelf_static 230 | url: "https://pub.dartlang.org" 231 | source: hosted 232 | version: "0.2.8" 233 | shelf_web_socket: 234 | dependency: transitive 235 | description: 236 | name: shelf_web_socket 237 | url: "https://pub.dartlang.org" 238 | source: hosted 239 | version: "0.2.3" 240 | sky_engine: 241 | dependency: transitive 242 | description: flutter 243 | source: sdk 244 | version: "0.0.99" 245 | source_map_stack_trace: 246 | dependency: transitive 247 | description: 248 | name: source_map_stack_trace 249 | url: "https://pub.dartlang.org" 250 | source: hosted 251 | version: "1.1.5" 252 | source_maps: 253 | dependency: transitive 254 | description: 255 | name: source_maps 256 | url: "https://pub.dartlang.org" 257 | source: hosted 258 | version: "0.10.8" 259 | source_span: 260 | dependency: transitive 261 | description: 262 | name: source_span 263 | url: "https://pub.dartlang.org" 264 | source: hosted 265 | version: "1.5.5" 266 | stack_trace: 267 | dependency: transitive 268 | description: 269 | name: stack_trace 270 | url: "https://pub.dartlang.org" 271 | source: hosted 272 | version: "1.9.3" 273 | stream_channel: 274 | dependency: transitive 275 | description: 276 | name: stream_channel 277 | url: "https://pub.dartlang.org" 278 | source: hosted 279 | version: "2.0.0" 280 | stream_transform: 281 | dependency: transitive 282 | description: 283 | name: stream_transform 284 | url: "https://pub.dartlang.org" 285 | source: hosted 286 | version: "0.0.19" 287 | string_scanner: 288 | dependency: transitive 289 | description: 290 | name: string_scanner 291 | url: "https://pub.dartlang.org" 292 | source: hosted 293 | version: "1.0.5" 294 | term_glyph: 295 | dependency: transitive 296 | description: 297 | name: term_glyph 298 | url: "https://pub.dartlang.org" 299 | source: hosted 300 | version: "1.1.0" 301 | test: 302 | dependency: "direct dev" 303 | description: 304 | name: test 305 | url: "https://pub.dartlang.org" 306 | source: hosted 307 | version: "1.6.5" 308 | test_api: 309 | dependency: transitive 310 | description: 311 | name: test_api 312 | url: "https://pub.dartlang.org" 313 | source: hosted 314 | version: "0.2.6" 315 | test_core: 316 | dependency: transitive 317 | description: 318 | name: test_core 319 | url: "https://pub.dartlang.org" 320 | source: hosted 321 | version: "0.2.7" 322 | typed_data: 323 | dependency: transitive 324 | description: 325 | name: typed_data 326 | url: "https://pub.dartlang.org" 327 | source: hosted 328 | version: "1.1.6" 329 | vector_math: 330 | dependency: transitive 331 | description: 332 | name: vector_math 333 | url: "https://pub.dartlang.org" 334 | source: hosted 335 | version: "2.0.8" 336 | vm_service_lib: 337 | dependency: transitive 338 | description: 339 | name: vm_service_lib 340 | url: "https://pub.dartlang.org" 341 | source: hosted 342 | version: "3.22.2+1" 343 | watcher: 344 | dependency: transitive 345 | description: 346 | name: watcher 347 | url: "https://pub.dartlang.org" 348 | source: hosted 349 | version: "0.9.7+12" 350 | web_socket_channel: 351 | dependency: transitive 352 | description: 353 | name: web_socket_channel 354 | url: "https://pub.dartlang.org" 355 | source: hosted 356 | version: "1.0.15" 357 | yaml: 358 | dependency: transitive 359 | description: 360 | name: yaml 361 | url: "https://pub.dartlang.org" 362 | source: hosted 363 | version: "2.1.16" 364 | sdks: 365 | dart: ">=2.2.2 <3.0.0" 366 | flutter: ">=1.10.0 <2.0.0" 367 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_auth0 2 | description: Flutter toolkit for Auth0 API and web pkce flow authentication 3 | author: Denny Segura 4 | homepage: https://github.com/devdennysegura/flutter-auth0 5 | version: 0.5.0 6 | 7 | environment: 8 | sdk: ">=2.1.0 <3.0.0" 9 | flutter: ">=1.10.0 <2.0.0" 10 | 11 | dependencies: 12 | meta: ^1.1.6 13 | http: ^0.12.0+2 14 | flutter: 15 | sdk: flutter 16 | 17 | dev_dependencies: 18 | test: ^1.6.5 19 | 20 | flutter: 21 | plugin: 22 | platforms: 23 | android: 24 | package: io.flutter.plugins.flutterauth0 25 | pluginClass: FlutterAuth0Plugin -------------------------------------------------------------------------------- /test/flutter_auth0_test.dart: -------------------------------------------------------------------------------- 1 | // import 'package:test/test.dart'; 2 | // import 'package:flutter_auth0/flutter_auth0.dart'; 3 | 4 | // Auth0 auth = new Auth0( 5 | // clientId: 'XIpuO0OchFaayJZRq8RvpQefOdfJkgSL', 6 | // domain: 'dennysegura.auth0.com'); 7 | 8 | // void main() { 9 | // test('sign-up', () async { 10 | // try { 11 | // dynamic user = await auth.createUser( 12 | // email: 'test@flutter.auth0', 13 | // password: '****', 14 | // connection: 'Username-Password-Authentication', 15 | // waitResponse: true); 16 | // expect(user['_id'], isNotNull); 17 | // } catch (e) { 18 | // print(e); 19 | // } 20 | // }); 21 | // test('sign-in', () async { 22 | // Auth0User user = await auth.passwordRealm( 23 | // username: 'test@flutter.auth0', 24 | // password: '****', 25 | // realm: 'Username-Password-Authentication'); 26 | // expect(user.accessToken, isNotNull); 27 | // }); 28 | // test('getting delegation token', () async { 29 | // Auth0User user = await auth.passwordRealm( 30 | // username: 'test@flutter.auth0', 31 | // password: '****', 32 | // realm: 'Username-Password-Authentication'); 33 | // String response = await auth.delegate(token: user.idToken, api: 'firebase'); 34 | // expect(response, isNotNull); 35 | // }); 36 | // test('reset password', () async { 37 | // try { 38 | // dynamic success = await auth.resetPassword( 39 | // email: 'test@flutter.auth0', 40 | // connection: 'Username-Password-Authentication'); 41 | // expect(success, true); 42 | // } catch (e) { 43 | // print(e); 44 | // } 45 | // }); 46 | // test('user info sucess', () async { 47 | // Auth0User user = await auth.passwordRealm( 48 | // username: 'test@flutter.auth0', 49 | // password: '****', 50 | // realm: 'Username-Password-Authentication'); 51 | // dynamic response = await auth.userInfo(token: user.accessToken); 52 | // expect(response, isNotNull); 53 | // }); 54 | // test('user info fail', () async { 55 | // dynamic user = await auth.userInfo(token: 'invalid access token'); 56 | // expect(user, isNull); 57 | // }); 58 | // } 59 | --------------------------------------------------------------------------------