[web] Use TrustedTypes from pkg web. (#6273)

During the `package:web` migration, some packages that needed the TrustedTypes API defined those as custom JS-interop.

In `google_identity_services_web`, the names of the JS-interop types clashed with those from the incoming package:web, breaking the build.

In `google_maps_flutter_web`, the whole definition code is redundant now that the standard API is exposed through package:web.

Part of: https://github.com/flutter/flutter/issues/117022
This commit is contained in:
David Iglesias
2024-03-05 14:25:59 -08:00
committed by GitHub
parent 420017724f
commit 83b72baf6e
9 changed files with 45 additions and 128 deletions

View File

@ -1,3 +1,7 @@
## 0.3.1+1
* Uses `TrustedTypes` from `web: ^0.5.1`.
## 0.3.1 ## 0.3.1
* Updates web code to package `web: ^0.5.0`. * Updates web code to package `web: ^0.5.0`.

View File

@ -3,8 +3,8 @@ description: An example for the google_identity_services_web package, OneTap.
publish_to: 'none' publish_to: 'none'
environment: environment:
flutter: ">=3.16.0" sdk: ^3.3.0
sdk: ">=3.2.0 <4.0.0" flutter: ">=3.19.0"
dependencies: dependencies:
flutter: flutter:
@ -12,7 +12,7 @@ dependencies:
google_identity_services_web: google_identity_services_web:
path: ../ path: ../
http: ">=0.13.0 <2.0.0" http: ">=0.13.0 <2.0.0"
web: ^0.5.0 web: ^0.5.1
dev_dependencies: dev_dependencies:
build_runner: ^2.1.10 # To extract README excerpts only. build_runner: ^2.1.10 # To extract README excerpts only.

View File

@ -17,60 +17,20 @@ extension NullableTrustedTypesGetter on web.Window {
/// ///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API /// See: https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API
@JS('trustedTypes') @JS('trustedTypes')
external TrustedTypePolicyFactory? get nullableTrustedTypes; external web.TrustedTypePolicyFactory? get nullableTrustedTypes;
/// Bindings to window.trustedTypes.
///
/// This will crash if accessed in a browser that doesn't support the
/// Trusted Types API.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API
@JS('trustedTypes')
external TrustedTypePolicyFactory get trustedTypes;
} }
/// This extension allows setting a TrustedScriptURL as the src of a script element, /// Allows setting a TrustedScriptURL as the src of a script element.
/// which currently only accepts a string.
extension TrustedTypeSrcAttribute on web.HTMLScriptElement { extension TrustedTypeSrcAttribute on web.HTMLScriptElement {
@JS('src') @JS('src')
external set trustedSrc(TrustedScriptURL value); external set trustedSrc(web.TrustedScriptURL value);
} }
// TODO(kevmoo): drop all of this once `pkg:web` publishes `0.5.1`. /// Allows creating a script URL only from a string, with no arguments.
extension CreateScriptUrlNoArgs on web.TrustedTypePolicy {
/// Bindings to a JS TrustedScriptURL. /// Allows calling `createScriptURL` with only the `input` argument.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/TrustedScriptURL
extension type TrustedScriptURL._(JSObject _) implements JSObject {}
/// Bindings to a JS TrustedTypePolicyFactory.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory
extension type TrustedTypePolicyFactory._(JSObject _) implements JSObject {
///
external TrustedTypePolicy createPolicy(
String policyName, [
TrustedTypePolicyOptions policyOptions,
]);
}
/// Bindings to a JS TrustedTypePolicy.
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicy
extension type TrustedTypePolicy._(JSObject _) implements JSObject {
///
@JS('createScriptURL') @JS('createScriptURL')
external TrustedScriptURL createScriptURLNoArgs( external web.TrustedScriptURL createScriptURLNoArgs(
String input, String input,
); );
} }
/// Bindings to a JS TrustedTypePolicyOptions (anonymous).
///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory/createPolicy#policyoptions
extension type TrustedTypePolicyOptions._(JSObject _) implements JSObject {
///
external factory TrustedTypePolicyOptions({
JSFunction createScriptURL,
});
}

View File

@ -25,15 +25,15 @@ Future<void> loadWebSdk({
onGoogleLibraryLoad = () => completer.complete(); onGoogleLibraryLoad = () => completer.complete();
// If TrustedTypes are available, prepare a trusted URL. // If TrustedTypes are available, prepare a trusted URL.
TrustedScriptURL? trustedUrl; web.TrustedScriptURL? trustedUrl;
if (web.window.nullableTrustedTypes != null) { if (web.window.nullableTrustedTypes != null) {
web.console.debug( web.console.debug(
'TrustedTypes available. Creating policy: $trustedTypePolicyName'.toJS, 'TrustedTypes available. Creating policy: $trustedTypePolicyName'.toJS,
); );
try { try {
final TrustedTypePolicy policy = web.window.trustedTypes.createPolicy( final web.TrustedTypePolicy policy = web.window.trustedTypes.createPolicy(
trustedTypePolicyName, trustedTypePolicyName,
TrustedTypePolicyOptions( web.TrustedTypePolicyOptions(
createScriptURL: ((JSString url) => _url).toJS, createScriptURL: ((JSString url) => _url).toJS,
)); ));
trustedUrl = policy.createScriptURLNoArgs(_url); trustedUrl = policy.createScriptURLNoArgs(_url);

View File

@ -2,14 +2,14 @@ name: google_identity_services_web
description: A Dart JS-interop layer for Google Identity Services. Google's new sign-in SDK for Web that supports multiple types of credentials. description: A Dart JS-interop layer for Google Identity Services. Google's new sign-in SDK for Web that supports multiple types of credentials.
repository: https://github.com/flutter/packages/tree/main/packages/google_identity_services_web repository: https://github.com/flutter/packages/tree/main/packages/google_identity_services_web
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_identiy_services_web%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_identiy_services_web%22
version: 0.3.1 version: 0.3.1+1
environment: environment:
sdk: ^3.3.0 sdk: ^3.3.0
dependencies: dependencies:
meta: ^1.3.0 meta: ^1.3.0
web: ^0.5.0 web: ^0.5.1
dev_dependencies: dev_dependencies:
path: ^1.8.1 path: ^1.8.1

View File

@ -1,3 +1,7 @@
## 0.5.6+2
* Uses `TrustedTypes` from `web: ^0.5.1`.
## 0.5.6+1 ## 0.5.6+1
* Fixes an issue where `dart:js_interop` object literal factories did not * Fixes an issue where `dart:js_interop` object literal factories did not

View File

@ -9,6 +9,9 @@ final gmaps.LatLng _nullGmapsLatLng = gmaps.LatLng(0, 0);
final gmaps.LatLngBounds _nullGmapsLatLngBounds = final gmaps.LatLngBounds _nullGmapsLatLngBounds =
gmaps.LatLngBounds(_nullGmapsLatLng, _nullGmapsLatLng); gmaps.LatLngBounds(_nullGmapsLatLng, _nullGmapsLatLng);
// The TrustedType Policy used by this plugin. Used to sanitize InfoWindow contents.
TrustedTypePolicy? _gmapsTrustedTypePolicy;
// Converts a [Color] into a valid CSS value #RRGGBB. // Converts a [Color] into a valid CSS value #RRGGBB.
String _getCssColor(Color color) { String _getCssColor(Color color) {
return '#${color.value.toRadixString(16).padLeft(8, '0').substring(2)}'; return '#${color.value.toRadixString(16).padLeft(8, '0').substring(2)}';
@ -222,17 +225,17 @@ gmaps.InfoWindowOptions? _infoWindowOptionsFromMarker(Marker marker) {
// Firefox and Safari don't support Trusted Types yet. // Firefox and Safari don't support Trusted Types yet.
// See https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory#browser_compatibility // See https://developer.mozilla.org/en-US/docs/Web/API/TrustedTypePolicyFactory#browser_compatibility
if (window.nullableTrustedTypes != null) { if (window.nullableTrustedTypes != null) {
final GoogleMapsTrustedTypePolicy trustedTypePolicy = _gmapsTrustedTypePolicy ??= window.trustedTypes.createPolicy(
window.nullableTrustedTypes!.getGoogleMapsTrustedTypesPolicy( 'google_maps_flutter_sanitize',
GoogleMapsTrustedTypePolicyOptions( TrustedTypePolicyOptions(
createHTML: (String html, JSAny? arguments) { createHTML: (String html) {
return sanitizeHtml(html); return sanitizeHtml(html).toJS;
}.toJS, }.toJS,
), ),
); );
snippet.trustedInnerHTML = snippet.trustedInnerHTML =
trustedTypePolicy.createHTML(markerSnippet, null); _gmapsTrustedTypePolicy!.createHTMLNoArgs(markerSnippet);
} else { } else {
// `sanitizeHtml` is used to clean the (potential) user input from (potential) // `sanitizeHtml` is used to clean the (potential) user input from (potential)
// XSS attacks through the contents of the marker InfoWindow. // XSS attacks through the contents of the marker InfoWindow.

View File

@ -9,7 +9,6 @@
library; library;
import 'dart:js_interop'; import 'dart:js_interop';
import 'package:web/web.dart' as web; import 'package:web/web.dart' as web;
/// This extension gives [web.Window] a nullable getter to the `trustedTypes` /// This extension gives [web.Window] a nullable getter to the `trustedTypes`
@ -21,75 +20,22 @@ extension NullableTrustedTypesGetter on web.Window {
/// ///
/// See: https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API /// See: https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API
@JS('trustedTypes') @JS('trustedTypes')
external GoogleMapsTrustedTypePolicyFactory? get nullableTrustedTypes; external web.TrustedTypePolicyFactory? get nullableTrustedTypes;
} }
// TODO(ditman): remove this extension type when we depend on package:web 0.5.1
/// This extension exists as a stop gap until `package:web 0.5.1` is released.
/// That version provides the `TrustedTypes` API.
@JS('TrustedTypePolicyFactory')
extension type GoogleMapsTrustedTypePolicyFactory._(JSObject _)
implements JSObject {
/// The `TrustedTypePolicy` for Google Maps Flutter.
static GoogleMapsTrustedTypePolicy? _policy;
@JS('createPolicy')
external GoogleMapsTrustedTypePolicy _createPolicy(
String policyName, [
GoogleMapsTrustedTypePolicyOptions policyOptions,
]);
/// Get a new [GoogleMapsTrustedTypePolicy].
///
/// If a policy already exists, it will be returned.
/// Otherwise, a new policy is created.
///
/// Because of we only cache one _policy, this method
/// specifically hardcoded to the GoogleMaps use case.
GoogleMapsTrustedTypePolicy getGoogleMapsTrustedTypesPolicy(
GoogleMapsTrustedTypePolicyOptions policyOptions,
) {
const String policyName = 'google_maps_flutter_sanitize';
_policy ??= _createPolicy(policyName, policyOptions);
return _policy!;
}
}
// TODO(ditman): remove this extension type when we depend on package:web 0.5.1
/// This extension exists as a stop gap until `package:web 0.5.1` is released.
/// That version provides the `TrustedTypes` API.
@JS('TrustedTypePolicy')
extension type GoogleMapsTrustedTypePolicy._(JSObject _) implements JSObject {
/// Create a new `TrustedHTML` instance with the given [input] and [arguments].
external GoogleMapsTrustedHTML createHTML(
String input,
JSAny? arguments,
);
}
// TODO(ditman): remove this extension type when we depend on package:web 0.5.1
/// This extension exists as a stop gap until `package:web 0.5.1` is released.
/// That version provides the `TrustedTypes` API.
@JS('TrustedTypePolicyOptions')
extension type GoogleMapsTrustedTypePolicyOptions._(JSObject _)
implements JSObject {
/// Create a new `TrustedTypePolicyOptions` instance.
external factory GoogleMapsTrustedTypePolicyOptions({
JSFunction createHTML,
});
}
// TODO(ditman): remove this extension type when we depend on package:web 0.5.1
/// This extension exists as a stop gap until `package:web 0.5.1` is released.
/// That version provides the `TrustedTypes` API.
@JS('TrustedHTML')
extension type GoogleMapsTrustedHTML._(JSObject _) implements JSObject {}
/// This extension provides a setter for the [web.HTMLElement] `innerHTML` property, /// This extension provides a setter for the [web.HTMLElement] `innerHTML` property,
/// that accepts trusted HTML only. /// that accepts trusted HTML only.
extension TrustedInnerHTML on web.HTMLElement { extension TrustedInnerHTML on web.HTMLElement {
/// Set the inner HTML of this element to the given [trustedHTML]. /// Set the inner HTML of this element to the given [trustedHTML].
@JS('innerHTML') @JS('innerHTML')
external set trustedInnerHTML(GoogleMapsTrustedHTML trustedHTML); external set trustedInnerHTML(web.TrustedHTML trustedHTML);
}
/// Allows creating a TrustedHTML object from a string, with no arguments.
extension CreateHTMLNoArgs on web.TrustedTypePolicy {
/// Allows calling `createHTML` with only the `input` argument.
@JS('createHTML')
external web.TrustedHTML createHTMLNoArgs(
String input,
);
} }

View File

@ -2,7 +2,7 @@ name: google_maps_flutter_web
description: Web platform implementation of google_maps_flutter description: Web platform implementation of google_maps_flutter
repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_web repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_web
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
version: 0.5.6+1 version: 0.5.6+2
environment: environment:
sdk: ^3.3.0 sdk: ^3.3.0
@ -26,7 +26,7 @@ dependencies:
google_maps_flutter_platform_interface: ^2.5.0 google_maps_flutter_platform_interface: ^2.5.0
sanitize_html: ^2.0.0 sanitize_html: ^2.0.0
stream_transform: ^2.0.0 stream_transform: ^2.0.0
web: ^0.5.0 web: ^0.5.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: