diff --git a/CHANGELOG.md b/CHANGELOG.md index b5f7884..2dbc65a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,9 @@ Types of changes - `Security` in case of vulnerabilities. ## 5.1.0 -### Changed -- +### Added +- `userAgent` can now be set in `OAuthConfiguration` and `BaseConfiguration`. +- `useHybridComposition` can now be set in `OAuthConfiguration` and `BaseConfiguration`. ## 5.0.0+1 ### Changed diff --git a/README.md b/README.md index c6f5dab..35b7914 100644 --- a/README.md +++ b/README.md @@ -25,10 +25,11 @@ With this plugin you will get: - Users will not be affected by any system browser problem cache and also will be able to clean app browser cache from the authentication screen itself. - Authentication page locale can be set from app using the `contentLocale` property to ensure the same locale. By default Operating System locale will be used if no `contentLocale` is specified. - Custom headers can be set if necessary. +- Custom UserAgent can be set if necessary. **Notes:** - `contentLocale` will apply only if the authentication page supports the specified `Locale('...')` and accepts the header: `'Accept-Language': 'es-ES'`. -- Web implementation deson't allow `contentLocale`, custom headers, nor full control over UI, because web implementation loads the page directly in the browser. +- Web implementation deson't allow `contentLocale`, custom headers, custom UserAgent, nor full control over UI, because web implementation loads the page directly in the browser. ## Migration from ^1.0.0 to ^2.0.0 - Static constants key for tooltips, message and hero tags were moved from `OAuthWebView` to `BaseWebView` diff --git a/example/pubspec.lock b/example/pubspec.lock index 49a68cd..032c3f6 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -246,7 +246,7 @@ packages: path: ".." relative: true source: path - version: "6.0.0" + version: "5.1.0" path: dependency: transitive description: diff --git a/lib/src/base/model/base_configuration.dart b/lib/src/base/model/base_configuration.dart index e6c8456..b12f4dd 100644 --- a/lib/src/base/model/base_configuration.dart +++ b/lib/src/base/model/base_configuration.dart @@ -32,9 +32,26 @@ class BaseConfiguration { /// Not available for Web final CertificateValidator? onCertificateValidate; + ///A dictionary containing all of the HTTP header fields for a request. /// Not available for Web final Map headers; + /// Sets the user-agent for the WebView. + /// Not available for Web + /// Defaults to: 'Mozilla/5.0' + /// Notes: Make sure the user-agent is compliant with the security constraints of Google's OAuth2 policies (https://developers.googleblog.com/2021/06/upcoming-security-changes-to-googles-oauth-2.0-authorization-endpoint.html) + final String userAgent; + + ///Set to `false` to disable Flutter Hybrid Composition. The default value is `true`. + ///Hybrid Composition is supported starting with Flutter v1.20+. + /// + ///**NOTE for Android native WebView**: It is recommended to use Hybrid Composition only on Android 10+ for a release app, + ///as it can cause framerate drops on animations in Android 9 and lower (see [Hybrid-Composition#performance](https://github.com/flutter/flutter/wiki/Hybrid-Composition#performance)). + /// + ///**Officially Supported Platforms/Implementations**: + ///- Android native WebView + final bool useHybridComposition; + /// Use this stream when you need to asynchronously navigate to a specific url /// Not available for Web final Stream? urlStream; @@ -62,6 +79,8 @@ class BaseConfiguration { this.onCancel, this.onCertificateValidate, Map? headers, + String? userAgent, + bool? useHybridComposition, this.urlStream, this.themeData, this.textLocales, @@ -72,6 +91,8 @@ class BaseConfiguration { bool? clearCacheBtnVisible, bool? closeBtnVisible, }) : headers = headers ?? const {}, + userAgent = userAgent ?? 'Mozilla/5.0', + useHybridComposition = useHybridComposition ?? true, goBackBtnVisible = goBackBtnVisible ?? true, goForwardBtnVisible = goForwardBtnVisible ?? true, refreshBtnVisible = refreshBtnVisible ?? true, @@ -95,6 +116,8 @@ class BaseConfiguration { VoidCallback? onCancel, CertificateValidator? onCertificateValidate, Map? headers, + String? userAgent, + bool? useHybridComposition, Stream? urlStream, ThemeData? themeData, Map? textLocales, @@ -114,6 +137,8 @@ class BaseConfiguration { onCertificateValidate: onCertificateValidate ?? this.onCertificateValidate, headers: headers ?? this.headers, + userAgent: userAgent ?? this.userAgent, + useHybridComposition: useHybridComposition ?? this.useHybridComposition, urlStream: urlStream ?? this.urlStream, themeData: themeData ?? this.themeData, textLocales: textLocales ?? this.textLocales, diff --git a/lib/src/base/model/oauth_configuration.dart b/lib/src/base/model/oauth_configuration.dart index 9bdb28a..e9279d7 100644 --- a/lib/src/base/model/oauth_configuration.dart +++ b/lib/src/base/model/oauth_configuration.dart @@ -96,6 +96,8 @@ class OAuthConfiguration extends BaseConfiguration { super.onCancel, super.onCertificateValidate, super.headers, + super.userAgent, + super.useHybridComposition, super.urlStream, super.themeData, super.textLocales, @@ -131,6 +133,8 @@ class OAuthConfiguration extends BaseConfiguration { super.onCancel, super.onCertificateValidate, super.headers, + super.userAgent, + super.useHybridComposition, super.urlStream, super.themeData, super.textLocales, @@ -164,6 +168,8 @@ class OAuthConfiguration extends BaseConfiguration { VoidCallback? onCancel, CertificateValidator? onCertificateValidate, Map? headers, + String? userAgent, + bool? useHybridComposition, Stream? urlStream, ThemeData? themeData, Map? textLocales, @@ -197,6 +203,8 @@ class OAuthConfiguration extends BaseConfiguration { onCertificateValidate: onCertificateValidate ?? this.onCertificateValidate, headers: headers ?? this.headers, + userAgent: userAgent ?? this.userAgent, + useHybridComposition: useHybridComposition ?? this.useHybridComposition, urlStream: urlStream ?? this.urlStream, themeData: themeData ?? this.themeData, textLocales: textLocales ?? this.textLocales, diff --git a/lib/src/base_web_screen.dart b/lib/src/base_web_screen.dart index 42acda2..6115fa6 100644 --- a/lib/src/base_web_screen.dart +++ b/lib/src/base_web_screen.dart @@ -91,8 +91,9 @@ class BaseWebScreen extends StatelessWidget { configuration.onCancel?.call(); } - Future onBackPressed(dynamic result) async { - if (!((await globalKey.currentState?.onBackPressed(result)) ?? false)) { + Future onBackPressed({dynamic result}) async { + if (!((await globalKey.currentState?.onBackPressed(result: result)) ?? + false)) { return false; } configuration.onCancel?.call(); diff --git a/lib/src/base_web_view.dart b/lib/src/base_web_view.dart index 2c6974e..cd1656e 100644 --- a/lib/src/base_web_view.dart +++ b/lib/src/base_web_view.dart @@ -118,10 +118,8 @@ class BaseWebViewState extends State useShouldOverrideUrlLoading: true, supportZoom: false, transparentBackground: true, - - /// This custom userAgent is mandatory due to security constraints of Google's OAuth2 policies (https://developers.googleblog.com/2021/06/upcoming-security-changes-to-googles-oauth-2.0-authorization-endpoint.html) - userAgent: 'Mozilla/5.0', - useHybridComposition: true, + userAgent: configuration.userAgent, + useHybridComposition: configuration.useHybridComposition, ), initialUrlRequest: URLRequest(url: WebUri(initialUri.toString()), headers: { @@ -438,7 +436,7 @@ class BaseWebViewState extends State } } - Future onBackPressed(dynamic result) async { + Future onBackPressed({dynamic result}) async { if (await controllerCanGoBack()) { controllerGoBack(); return false; diff --git a/lib/src/oauth_web_screen.dart b/lib/src/oauth_web_screen.dart index 0d8a230..1f1ffba 100644 --- a/lib/src/oauth_web_screen.dart +++ b/lib/src/oauth_web_screen.dart @@ -88,8 +88,9 @@ class OAuthWebScreen extends StatelessWidget { configuration.onCancel?.call(); } - Future onBackPressed(dynamic result) async { - if (!((await globalKey.currentState?.onBackPressed(result)) ?? false)) { + Future onBackPressed({dynamic result}) async { + if (!((await globalKey.currentState?.onBackPressed(result: result)) ?? + false)) { return false; } configuration.onCancel?.call(); diff --git a/lib/src/utils/custom_pop_scope.dart b/lib/src/utils/custom_pop_scope.dart index f9242f9..74d8356 100644 --- a/lib/src/utils/custom_pop_scope.dart +++ b/lib/src/utils/custom_pop_scope.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -typedef CanGoBackCallback = Future Function(T? result); +typedef CanGoBackCallback = Future Function({T? result}); class CustomPopScope extends StatelessWidget { const CustomPopScope({ @@ -21,7 +21,7 @@ class CustomPopScope extends StatelessWidget { onPopInvokedWithResult: onPopInvokedWithResult ?? (bool didPop, T? result) { if (didPop) return; - canGoBack?.call(result).then((canPop) { + canGoBack?.call(result: result).then((canPop) { if (canPop && context.mounted) { Navigator.of(context).pop(result); }