New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

eme-encryption-scheme-polyfill

Package Overview
Dependencies
Maintainers
3
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eme-encryption-scheme-polyfill - npm Package Compare versions

Comparing version 1.0.3 to 2.0.0

7

CHANGELOG.md

@@ -0,1 +1,8 @@

## 2.0.0 (2019-12-12)
Features:
- Added support for polyfilling MediaCapabilities, too
- https://github.com/w3c/media-capabilities/issues/100
## 1.0.3 (2019-12-05)

@@ -2,0 +9,0 @@

2

dist/eme-encryption-scheme-polyfill.js

@@ -8,2 +8,2 @@ /*!

!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).EmeEncryptionSchemePolyfill=e()}}(function(){var e={exports:{}};function i(e,i,t){return t?i?i(e):e:(e&&e.then||(e=Promise.resolve(e)),i?e.then(i):e)}var t=function(){function e(){}return e.install=function(){e.originalRMKSA_||navigator.requestMediaKeySystemAccess&&MediaKeySystemAccess.prototype.getConfiguration&&(e.originalRMKSA_=navigator.requestMediaKeySystemAccess,navigator.requestMediaKeySystemAccess=e.probeRMKSA_)},e.guessSupportedScheme_=function(e){return e.startsWith("com.widevine")?"cenc":e.startsWith("com.microsoft")?"cenc":e.startsWith("com.adobe")?"cenc":e.startsWith("org.w3")?"cenc":e.startsWith("com.apple")?"cbcs-1-9":(console.warn("EmeEncryptionSchemePolyfill: Unknown key system:",e,"Please contribute!"),null)},e.probeRMKSA_=function(t,r){try{var n=this;return i(e.originalRMKSA_.call(n,t,r),function(i){var a=i.getConfiguration(),o=a.videoCapabilities&&a.videoCapabilities[0],s=a.audioCapabilities&&a.audioCapabilities[0];return void 0!==(o||s).encryptionScheme?(navigator.requestMediaKeySystemAccess=e.originalRMKSA_,i):(navigator.requestMediaKeySystemAccess=e.polyfillRMKSA_,e.polyfillRMKSA_.call(n,t,r))})}catch(a){return Promise.reject(a)}},e.polyfillRMKSA_=function(t,n){try{var a=e.guessSupportedScheme_(t),o=[],s=n,l=Array.isArray(s),c=0;for(s=l?s:s[Symbol.iterator]();;){var u;if(l){if(c>=s.length)break;u=s[c++]}else{if((c=s.next()).done)break;u=c.value}var f=u,p=e.filterCapabilities_(f.videoCapabilities,a),y=e.filterCapabilities_(f.audioCapabilities,a);if(f.videoCapabilities&&f.videoCapabilities.length&&!p.length);else if(f.audioCapabilities&&f.audioCapabilities.length&&!y.length);else{var d=Object.assign({},f);d.videoCapabilities=p,d.audioCapabilities=y,o.push(d)}}if(!o.length){var m=new Error("Unsupported keySystem or supportedConfigurations.");throw m.name="NotSupportedError",m.code=DOMException.NOT_SUPPORTED_ERR,m}return i(e.originalRMKSA_.call(this,t,o),function(e){return new r(e,a)})}catch(h){return Promise.reject(h)}},e.filterCapabilities_=function(e,i){return e?e.filter(function(e){return!e.encryptionScheme||e.encryptionScheme==i}):e},e}(),r=function(){function e(e,i){this.mksa_=e,this.scheme_=i,this.keySystem=e.keySystem}var i=e.prototype;return i.getConfiguration=function(){var e=this.mksa_.getConfiguration();if(e.videoCapabilities){var i=e.videoCapabilities,t=Array.isArray(i),r=0;for(i=t?i:i[Symbol.iterator]();;){var n;if(t){if(r>=i.length)break;n=i[r++]}else{if((r=i.next()).done)break;n=r.value}n.encryptionScheme=this.scheme_}}if(e.audioCapabilities){var a=e.audioCapabilities,o=Array.isArray(a),s=0;for(a=o?a:a[Symbol.iterator]();;){var l;if(o){if(s>=a.length)break;l=a[s++]}else{if((s=a.next()).done)break;l=s.value}l.encryptionScheme=this.scheme_}}return e},i.createMediaKeys=function(){return this.mksa_.createMediaKeys()},e}();return t.originalRMKSA_,e.exports&&(e.exports=t),e=e.exports});
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).EncryptionSchemePolyfills=e()}}(function(){var e={exports:{}};function i(e,i,t){return t?i?i(e):e:(e&&e.then||(e=Promise.resolve(e)),i?e.then(i):e)}var t=function(){function e(){}return e.install=function(){e.originalRMKSA_||navigator.requestMediaKeySystemAccess&&MediaKeySystemAccess.prototype.getConfiguration&&(e.originalRMKSA_=navigator.requestMediaKeySystemAccess,navigator.requestMediaKeySystemAccess=e.probeRMKSA_)},e.probeRMKSA_=function(t,n){try{var o=this;return i(e.originalRMKSA_.call(o,t,n),function(i){return a(i)?(navigator.requestMediaKeySystemAccess=e.originalRMKSA_,i):(navigator.requestMediaKeySystemAccess=e.polyfillRMKSA_,e.polyfillRMKSA_.call(o,t,n))})}catch(r){return Promise.reject(r)}},e.polyfillRMKSA_=function(t,n){try{var a=r(t),s=[],c=n,l=Array.isArray(c),f=0;for(c=l?c:c[Symbol.iterator]();;){var u;if(l){if(f>=c.length)break;u=c[f++]}else{if((f=c.next()).done)break;u=f.value}var d=u,y=e.filterCapabilities_(d.videoCapabilities,a),p=e.filterCapabilities_(d.audioCapabilities,a);if(d.videoCapabilities&&d.videoCapabilities.length&&!y.length);else if(d.audioCapabilities&&d.audioCapabilities.length&&!p.length);else{var g=Object.assign({},d);g.videoCapabilities=y,g.audioCapabilities=p,s.push(g)}}if(!s.length){var m=new Error("Unsupported keySystem or supportedConfigurations.");throw m.name="NotSupportedError",m.code=DOMException.NOT_SUPPORTED_ERR,m}return i(e.originalRMKSA_.call(this,t,s),function(e){return new o(e,a)})}catch(h){return Promise.reject(h)}},e.filterCapabilities_=function(e,i){return e?e.filter(function(e){return!e.encryptionScheme||e.encryptionScheme==i}):e},e}(),n=function(){function e(){}return e.install=function(){navigator.mediaCapabilities&&(e.originalDecodingInfo_=navigator.mediaCapabilities.decodingInfo,navigator.mediaCapabilities.decodingInfo=e.probeDecodingInfo_)},e.probeDecodingInfo_=function(t){try{var n=this;return i(e.originalDecodingInfo_.call(n,t),function(i){return t.keySystemConfiguration?a(i.keySystemAccess)?(navigator.mediaCapabilities.decodingInfo=e.originalDecodingInfo_,i):(navigator.mediaCapabilities.decodingInfo=e.polyfillDecodingInfo_,e.polyfillDecodingInfo_.call(n,t)):i})}catch(o){return Promise.reject(o)}},e.polyfillDecodingInfo_=function(t){try{var n=null;if(t.keySystemConfiguration){var a=t.keySystemConfiguration,s=a.keySystem,c=a.audio&&a.audio.encryptionScheme,l=a.video&&a.video.encryptionScheme;n=r(s);var f={powerEfficient:!1,smooth:!1,supported:!1,keySystemAccess:null,configuration:t};if(c&&c!=n)return f;if(l&&l!=n)return f}return i(e.originalDecodingInfo_.call(this,t),function(e){return e.keySystemAccess&&(e.keySystemAccess=new o(e.keySystemAccess,n)),e})}catch(u){return Promise.reject(u)}},e}(),o=function(){function e(e,i){this.mksa_=e,this.scheme_=i,this.keySystem=e.keySystem}var i=e.prototype;return i.getConfiguration=function(){var e=this.mksa_.getConfiguration();if(e.videoCapabilities){var i=e.videoCapabilities,t=Array.isArray(i),n=0;for(i=t?i:i[Symbol.iterator]();;){var o;if(t){if(n>=i.length)break;o=i[n++]}else{if((n=i.next()).done)break;o=n.value}o.encryptionScheme=this.scheme_}}if(e.audioCapabilities){var r=e.audioCapabilities,a=Array.isArray(r),s=0;for(r=a?r:r[Symbol.iterator]();;){var c;if(a){if(s>=r.length)break;c=r[s++]}else{if((s=r.next()).done)break;c=s.value}c.encryptionScheme=this.scheme_}}return e},i.createMediaKeys=function(){return this.mksa_.createMediaKeys()},e}();function r(e){return e.startsWith("com.widevine")?"cenc":e.startsWith("com.microsoft")?"cenc":e.startsWith("com.adobe")?"cenc":e.startsWith("org.w3")?"cenc":e.startsWith("com.apple")?"cbcs-1-9":(console.warn("EmeEncryptionSchemePolyfill: Unknown key system:",e,"Please contribute!"),null)}function a(e){var i=e.getConfiguration(),t=i.videoCapabilities&&i.videoCapabilities[0],n=i.audioCapabilities&&i.audioCapabilities[0];return void 0!==(t||n).encryptionScheme}t.originalRMKSA_,n.originalDecodingInfo_;var s=function(){function e(){}return e.install=function(){t.install(),n.install()},e}();return e.exports&&(e.exports=s),e=e.exports});

@@ -59,34 +59,2 @@ /*!

/**
* Guess the supported encryption scheme for the key system.
*
* @param {string} keySystem The key system ID.
* @return {?string} A guess at the encryption scheme this key system
* supports.
* @private
*/
static guessSupportedScheme_(keySystem) {
if (keySystem.startsWith('com.widevine')) {
return 'cenc';
} else if (keySystem.startsWith('com.microsoft')) {
return 'cenc';
} else if (keySystem.startsWith('com.adobe')) {
return 'cenc';
} else if (keySystem.startsWith('org.w3')) {
return 'cenc';
} else if (keySystem.startsWith('com.apple')) {
return 'cbcs-1-9';
}
// We don't have this key system in our map!
// Log a warning. The only way the request will succeed now is if the
// app doesn't specify an encryption scheme in their own configs.
// Use bracket notation to keep this from being stripped from the build.
console['warn']('EmeEncryptionSchemePolyfill: Unknown key system:',
keySystem, 'Please contribute!');
return null;
}
/**
* A shim for navigator.requestMediaKeySystemAccess to check for

@@ -114,16 +82,3 @@ * encryptionScheme support. Only used until we know if the browser has

const configuration = mediaKeySystemAccess.getConfiguration();
// It doesn't matter which capability we look at. For this check, they
// should all produce the same result.
const firstVideoCapability =
configuration.videoCapabilities && configuration.videoCapabilities[0];
const firstAudioCapability =
configuration.audioCapabilities && configuration.audioCapabilities[0];
const firstCapability = firstVideoCapability || firstAudioCapability;
// If supported by the browser, the encryptionScheme field must appear in
// the returned configuration, regardless of whether or not it was
// specified in the supportedConfigurations given by the application.
if (firstCapability['encryptionScheme'] !== undefined) {
if (hasEncryptionScheme(mediaKeySystemAccess)) {
// The browser supports the encryptionScheme field!

@@ -175,4 +130,3 @@ // No need for a patch. Revert back to the original implementation.

const supportedScheme = EmeEncryptionSchemePolyfill.guessSupportedScheme_(
keySystem);
const supportedScheme = guessSupportedScheme(keySystem);

@@ -263,2 +217,171 @@ // Filter the application's configurations based on our guess of what

/**
* A polyfill to add support for EncryptionScheme queries in MediaCapabilities.
*
* Because this polyfill can't know what schemes the UA or CDM actually support,
* it assumes support for the historically-supported schemes of each well-known
* key system.
*
* In source form, this is compatible with the Closure Compiler, CommonJS, and
* AMD module formats. It can also be directly included via a script tag.
*
* The minified bundle is a standalone module compatible with the CommonJS and
* AMD module formats, and can also be directly included via a script tag.
*
* @see https://wicg.github.io/encrypted-media-encryption-scheme/
* @see https://github.com/w3c/encrypted-media/pull/457
* @export
*/
class McEncryptionSchemePolyfill {
/**
* Installs the polyfill. To avoid the possibility of extra user prompts,
* this will shim MC so long as it exists, without checking support for
* encryptionScheme upfront. The support check will happen on-demand the
* first time MC is used.
*
* @export
*/
static install() {
if (!navigator.mediaCapabilities) {
console.debug('McEncryptionSchemePolyfill: MediaCapabilities not found');
// No MediaCapabilities.
return;
}
// Save the original.
McEncryptionSchemePolyfill.originalDecodingInfo_ =
navigator.mediaCapabilities.decodingInfo;
// Patch in a method which will check for support on the first call.
console.debug('McEncryptionSchemePolyfill: ' +
'Waiting to detect encryptionScheme support.');
navigator.mediaCapabilities.decodingInfo =
McEncryptionSchemePolyfill.probeDecodingInfo_;
}
/**
* A shim for mediaCapabilities.decodingInfo to check for encryptionScheme
* support. Only used until we know if the browser has native support for the
* encryptionScheme field.
*
* @this {MediaCapabilities}
* @param {!MediaDecodingConfiguration} requestedConfiguration The requested
* decoding configuration.
* @return {!Promise.<!MediaCapabilitiesDecodingInfo>} A Promise to a result
* describing the capabilities of the browser in the request configuration.
* @private
*/
static async probeDecodingInfo_(requestedConfiguration) {
console.assert(this == navigator.mediaCapabilities,
'bad "this" for decodingInfo');
// Call the original version. If the call succeeds, we look at the result
// to decide if the encryptionScheme field is supported or not.
const capabilities =
await McEncryptionSchemePolyfill.originalDecodingInfo_.call(
this, requestedConfiguration);
if (!requestedConfiguration.keySystemConfiguration) {
// This was not a query regarding encrypted content. The results are
// valid, but won't tell us anything about native support for
// encryptionScheme. Just return the results.
return capabilities;
}
const mediaKeySystemAccess = capabilities.keySystemAccess;
if (hasEncryptionScheme(mediaKeySystemAccess)) {
// The browser supports the encryptionScheme field!
// No need for a patch. Revert back to the original implementation.
console.debug('McEncryptionSchemePolyfill: ' +
'Native encryptionScheme support found.');
// eslint-disable-next-line require-atomic-updates
navigator.mediaCapabilities.decodingInfo =
McEncryptionSchemePolyfill.originalDecodingInfo_;
// Return the results, which are completely valid.
return capabilities;
}
// If we land here, the browser does _not_ support the encryptionScheme
// field. So we install another patch to check the encryptionScheme field
// in future calls.
console.debug('McEncryptionSchemePolyfill: ' +
'No native encryptionScheme support found. '+
'Patching encryptionScheme support.');
// eslint-disable-next-line require-atomic-updates
navigator.mediaCapabilities.decodingInfo =
McEncryptionSchemePolyfill.polyfillDecodingInfo_;
// The results we have may not be valid. Run the query again through our
// polyfill.
return McEncryptionSchemePolyfill.polyfillDecodingInfo_.call(
this, requestedConfiguration);
}
/**
* A polyfill for mediaCapabilities.decodingInfo to handle the
* encryptionScheme field in browsers that don't support it. It uses the
* user-agent string to guess what encryption schemes are supported, then
* those guesses are used to reject unsupported schemes.
*
* @this {MediaCapabilities}
* @param {!MediaDecodingConfiguration} requestedConfiguration The requested
* decoding configuration.
* @return {!Promise.<!MediaCapabilitiesDecodingInfo>} A Promise to a result
* describing the capabilities of the browser in the request configuration.
* @private
*/
static async polyfillDecodingInfo_(requestedConfiguration) {
console.assert(this == navigator.mediaCapabilities,
'bad "this" for decodingInfo');
let supportedScheme = null;
if (requestedConfiguration.keySystemConfiguration) {
const keySystemConfig = requestedConfiguration.keySystemConfiguration;
const keySystem = keySystemConfig.keySystem;
const audioScheme = keySystemConfig.audio &&
keySystemConfig.audio.encryptionScheme;
const videoScheme = keySystemConfig.video &&
keySystemConfig.video.encryptionScheme;
supportedScheme = guessSupportedScheme(keySystem);
const notSupportedResult = {
powerEfficient: false,
smooth: false,
supported: false,
keySystemAccess: null,
configuration: requestedConfiguration,
};
if (audioScheme && audioScheme != supportedScheme) {
return notSupportedResult;
}
if (videoScheme && videoScheme != supportedScheme) {
return notSupportedResult;
}
}
// At this point, either it's unencrypted or we assume the encryption scheme
// is supported. So delegate to the original decodingInfo() method.
const capabilities =
await McEncryptionSchemePolyfill.originalDecodingInfo_.call(
this, requestedConfiguration);
if (capabilities.keySystemAccess) {
// If the result is supported and encrypted, this will be a
// MediaKeySystemAccess instance. Wrap the MKSA object in ours to provide
// the missing field in the returned configuration.
capabilities.keySystemAccess =
new EmeEncryptionSchemePolyfillMediaKeySystemAccess(
capabilities.keySystemAccess, supportedScheme);
}
return capabilities;
}
}
/**
* A wrapper around MediaKeySystemAccess that adds encryptionScheme

@@ -323,2 +446,58 @@ * fields to the configuration, to emulate what a browser with native support

/**
* Guess the supported encryption scheme for the key system.
*
* @param {string} keySystem The key system ID.
* @return {?string} A guess at the encryption scheme this key system
* supports.
*/
function guessSupportedScheme(keySystem) {
if (keySystem.startsWith('com.widevine')) {
return 'cenc';
} else if (keySystem.startsWith('com.microsoft')) {
return 'cenc';
} else if (keySystem.startsWith('com.adobe')) {
return 'cenc';
} else if (keySystem.startsWith('org.w3')) {
return 'cenc';
} else if (keySystem.startsWith('com.apple')) {
return 'cbcs-1-9';
}
// We don't have this key system in our map!
// Log a warning. The only way the request will succeed now is if the
// app doesn't specify an encryption scheme in their own configs.
// Use bracket notation to keep this from being stripped from the build.
console['warn']('EmeEncryptionSchemePolyfill: Unknown key system:',
keySystem, 'Please contribute!');
return null;
}
/**
* @param {?MediaKeySystemAccess} mediaKeySystemAccess A native
* MediaKeySystemAccess instance from the browser.
* @return {boolean} True if browser natively supports encryptionScheme.
*/
function hasEncryptionScheme(mediaKeySystemAccess) {
const configuration = mediaKeySystemAccess.getConfiguration();
// It doesn't matter which capability we look at. For this check, they
// should all produce the same result.
const firstVideoCapability =
configuration.videoCapabilities && configuration.videoCapabilities[0];
const firstAudioCapability =
configuration.audioCapabilities && configuration.audioCapabilities[0];
const firstCapability = firstVideoCapability || firstAudioCapability;
// If supported by the browser, the encryptionScheme field must appear in
// the returned configuration, regardless of whether or not it was
// specified in the supportedConfigurations given by the application.
if (firstCapability['encryptionScheme'] !== undefined) {
return true;
}
return false;
}
/**
* The original requestMediaKeySystemAccess, before we patched it.

@@ -336,2 +515,31 @@ *

/**
* The original decodingInfo, before we patched it.
*
* @type {
* function(this:MediaCapabilities,
* !MediaDecodingConfiguration
* ):!Promise.<!MediaCapabilitiesDecodingInfo>
* }
* @private
*/
McEncryptionSchemePolyfill.originalDecodingInfo_;
/**
* A single entry point for both polyfills (EME & MC).
*
* @export
*/
class EncryptionSchemePolyfills {
/**
* Installs both polyfills (EME & MC).
*
* @export
*/
static install() {
EmeEncryptionSchemePolyfill.install();
McEncryptionSchemePolyfill.install();
}
}
// Support for CommonJS and AMD module formats.

@@ -341,4 +549,4 @@ /** @suppress {undefinedVars} */

if (typeof module !== 'undefined' && module.exports) {
module.exports = EmeEncryptionSchemePolyfill;
module.exports = EncryptionSchemePolyfills;
}
})();
{
"name": "eme-encryption-scheme-polyfill",
"description": "A polyfill for the encryptionScheme field in EME",
"version": "1.0.3",
"version": "2.0.0",
"license": "Apache-2.0",

@@ -20,3 +20,3 @@ "author": "Google",

"closure-compiler-check": "google-closure-compiler -O ADVANCED --generate_exports --js_output_file /dev/null --jscomp_error '*' closure-compiler-check/* index.js",
"build": "browserify index.js -s EmeEncryptionSchemePolyfill -t babelify -t stripify -p tinyify -p browserify-header -o dist/eme-encryption-scheme-polyfill.js",
"build": "browserify index.js -s EncryptionSchemePolyfills -t babelify -t stripify -p tinyify -p browserify-header -o dist/eme-encryption-scheme-polyfill.js",
"prepublishOnly": "npm run-script lint && npm run-script closure-compiler-check && npm run-script build"

@@ -23,0 +23,0 @@ },

@@ -1,4 +0,5 @@

# EME Encryption Scheme Polyfill
# EME & MediaCapabilities Encryption Scheme Polyfill
A polyfill to add support for EncryptionScheme queries in EME.
A polyfill to add support for EncryptionScheme queries in EME and
MediaCapabilities.

@@ -8,2 +9,3 @@ - https://wicg.github.io/encrypted-media-encryption-scheme/

- https://github.com/WICG/encrypted-media-encryption-scheme/issues/13
- https://github.com/w3c/media-capabilities/issues/100

@@ -19,8 +21,8 @@ Because this polyfill can't know what schemes the UA or CDM actually support,

module compatible with the CommonJS and AMD module formats, and can also be
directly included via a script tag. It is about 3.1kB uncompressed, and gzips
to about 1.2kB.
directly included via a script tag. It is about 4.4kB uncompressed, and gzips
to about 1.5kB.
To avoid the possibility of extra user prompts, this will shim EME so long as
it exists, without checking support for `encryptionScheme` upfront. The
support check will happen on-demand the first time EME is used.
To avoid the possibility of extra user prompts, this will shim EME & MC so long
as they exist, without checking support for `encryptionScheme` upfront. The
support check will happen on-demand the first time EME/MC are used.

@@ -39,3 +41,8 @@

```js
// Install both EME & MC polyfills at once:
EncryptionSchemePolyfills.install();
// Install each one separately (unminified source only):
EmeEncryptionSchemePolyfill.install();
McEncryptionSchemePolyfill.install();
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc