diff --git a/dom/push/PushManager.cpp b/dom/push/PushManager.cpp index 4534291e429c..878519284734 100644 --- a/dom/push/PushManager.cpp +++ b/dom/push/PushManager.cpp @@ -419,6 +419,41 @@ bool PushManager::IsEnabled(JSContext* aCx, JSObject* aGlobal) { return StaticPrefs::dom_push_enabled() && ServiceWorkersEnabled(aCx, aGlobal); } +// https://w3c.github.io/push-api/#dom-pushmanager-supportedcontentencodings +void PushManager::GetSupportedContentEncodings( + GlobalObject& aGlobal, JS::MutableHandle aEncodings, + ErrorResult& aRv) { + JSContext* cx = aGlobal.Context(); + + nsTArray encodings{u"aes128gcm"_ns}; + if (StaticPrefs::dom_push_indicate_aesgcm_support_enabled()) { + // The spec does not define orders, but Chrome is returning ["aes128gcm", + // "aesgcm"] and there are a bunch of code like below, which is copypasted + // from Minishlink/web-push-php-example endorsed by + // web-push-libs/web-push-php. Which means practically the preferred + // algorithm should go to the first place. + // + // (PushManager.supportedContentEncodings || ['aesgcm'])[0]; + encodings.AppendElement(u"aesgcm"_ns); + } + + JS::Rooted encodingsValue(cx); + if (!ToJSValue(cx, encodings, &encodingsValue)) { + if (JS_IsThrowingOutOfMemory(cx)) { + MOZ_CRASH("Out of memory"); + } else { + aRv.NoteJSContextException(cx); + return; + } + }; + JS::Rooted object(cx, &encodingsValue.toObject()); + if (!JS_FreezeObject(cx, object)) { + aRv.NoteJSContextException(cx); + return; + } + aEncodings.set(object); +} + already_AddRefed PushManager::Subscribe( const PushSubscriptionOptionsInit& aOptions, ErrorResult& aRv) { if (mImpl) { diff --git a/dom/push/PushManager.h b/dom/push/PushManager.h index f951e0a2baa7..80a6aee9172a 100644 --- a/dom/push/PushManager.h +++ b/dom/push/PushManager.h @@ -83,6 +83,12 @@ class PushManager final : public nsISupports, public nsWrapperCache { SubscriptionAction aAction, const PushSubscriptionOptionsInit& aOptions, ErrorResult& aRv); + // Web IDL members: + + static void GetSupportedContentEncodings( + GlobalObject& aGlobal, JS::MutableHandle aEncodings, + ErrorResult& aRv); + already_AddRefed Subscribe( const PushSubscriptionOptionsInit& aOptions, ErrorResult& aRv); diff --git a/dom/webidl/PushManager.webidl b/dom/webidl/PushManager.webidl index ff99e294b535..285688ea7070 100644 --- a/dom/webidl/PushManager.webidl +++ b/dom/webidl/PushManager.webidl @@ -31,6 +31,14 @@ interface PushManager { [Throws, ChromeOnly] constructor(DOMString scope); + // TODO: Use FrozenArray once available. (Bug 1236777) + // [SameObject] static readonly attribute FrozenArray supportedContentEncodings; + // XXX: We can't use sequence here either: + // 1. [Cached] is not supported for static members (Bug 1363870) + // 2. [Cached] is required for sequence typed attributes + // [Frozen, Cached, Pure] static readonly attribute sequence supportedContentEncodings; + [Throws] static readonly attribute object supportedContentEncodings; + [Throws, UseCounter] Promise subscribe(optional PushSubscriptionOptionsInit options = {}); [Throws] diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 36bb5bfd8ed0..f244254da60b 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -3490,6 +3490,15 @@ value: true mirror: always +# Indicate the deprecated aesgcm support in PushManager.supportedContentEncodings. +# +# This does not affect actual aesgcm support, any new and existing subscriptions +# can still use aesgcm regardless of this pref. +- name: dom.push.indicate_aesgcm_support.enabled + type: RelaxedAtomicBool + value: false + mirror: always + # Preference that is primarily used for testing of problematic file paths. # It can also be used for switching between different storage directories, but # such feature is not officially supported. diff --git a/testing/web-platform/meta/push-api/supported-encodings.https.any.js.ini b/testing/web-platform/meta/push-api/supported-encodings.https.any.js.ini new file mode 100644 index 000000000000..0654b7be82e5 --- /dev/null +++ b/testing/web-platform/meta/push-api/supported-encodings.https.any.js.ini @@ -0,0 +1,18 @@ +[supported-encodings.https.any.html] + [supportedContentEncodings must be FrozenArray] + expected: FAIL + + +[supported-encodings.https.any.sharedworker.html] + [supportedContentEncodings must be FrozenArray] + expected: FAIL + + +[supported-encodings.https.any.serviceworker.html] + [supportedContentEncodings must be FrozenArray] + expected: FAIL + + +[supported-encodings.https.any.worker.html] + [supportedContentEncodings must be FrozenArray] + expected: FAIL diff --git a/testing/web-platform/tests/push-api/supported-encodings.https.any.js b/testing/web-platform/tests/push-api/supported-encodings.https.any.js new file mode 100644 index 000000000000..45b5ed1cba46 --- /dev/null +++ b/testing/web-platform/tests/push-api/supported-encodings.https.any.js @@ -0,0 +1,26 @@ +// META: global=window,worker + +"use strict" +// (for FrozenArray assign test) + +test(() => { + assert_true( + PushManager.supportedContentEncodings.includes("aes128gcm"), + "PushManager.supportedContentEncodings must include aes128gcm" + ); +}, "aes128gcm must be supported"); + +test(() => { + assert_throws_js( + TypeError, + () => PushManager.supportedContentEncodings[0] = "aes1024gcm", + "supportedContentEncodings must be frozen" + ); + + // Intentionally not using assert_array_equals to check same-object + assert_equals( + PushManager.supportedContentEncodings, + PushManager.supportedContentEncodings, + "supportedContentEncodings must be cached" + ); +}, "supportedContentEncodings must be FrozenArray")