Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polyfills needed for IE 11? #113

Closed
jstayton opened this issue Jul 25, 2019 · 13 comments · Fixed by #154
Closed

Polyfills needed for IE 11? #113

jstayton opened this issue Jul 25, 2019 · 13 comments · Fixed by #154

Comments

@jstayton
Copy link

Hey 👋

I have a Vue CLI app that I've adding this package to via npm. I have it all working in modern browsers, but IE 11 throws a number of errors related to missing features (i.e., String.prototype.startsWith).

I could be totally off here, but it looks like dist/auth0-spa-js.production.js is built to be ES5 compatible, and work in IE 11?

If not, my follow-up question: What are the polyfills this package needs for IE 11?

Vue CLI recommends either explicitly including the polyfills needed (which I've done with other dependencies), or just including all polyfills for your target browsers. I'd rather not include all polyfills if possible.

@ed-sparkes
Copy link

I am getting similar issue in IE

Unhandled promise rejection ReferenceError: 'crypto' is undefined

seems to be coming from loginWithRedirect

@echee
Copy link

echee commented Aug 8, 2019

yep, I mentioned this in another ticket as well, I think a fix for at least Crypto, will be in the next release #98

@izzmeifter
Copy link

Does anyone have a suggested "quick fix" for the Unhandled promise rejection ReferenceError: 'crypto' is undefined problem??

We're getting beat up bad right now as a lot of our users on using windows 11 unfortunately.

Thanks.

@jstayton
Copy link
Author

jstayton commented Aug 9, 2019

@izzmeifter This is the polyfill they use in the legacy build:

if (!window.crypto && (<any>window).msCrypto) {
(<any>window).crypto = (<any>window).msCrypto;
}

@ed-sparkes
Copy link

if (!window.crypto && (window).msCrypto) {
(window).crypto = (window).msCrypto;
}

This solves the crypto issue but immediately exposes another issue for me.

it appears that crypto.getRandomValues(new Uint8Array(43)) returns an object rather than an array in IE11 and as such the subsequent line which does a foreach fails
randomValues.forEach(v => (random += charset[v % charset.length]));

@PapaMufflon
Copy link

@ed-sparkes I think this should be solved by #98 (ES5 compatibility) which is in the next release as well. Eagerly awaiting the release now... :)

@jstayton
Copy link
Author

@PapaMufflon It looks like #98 has already been released in v1.1.1: https://github.com/auth0/auth0-spa-js/blob/master/CHANGELOG.md

@PapaMufflon
Copy link

@jstayton @ed-sparkes You are correct, my bad. It still does not work on IE11.

@PapaMufflon
Copy link

Finally got it working. I had to polyfill Uint8Array.slice, Array.includes and windows.crypto with a getRandomValues method returning a new Array (used a modified version of webcrypto-shim for that).

@ed-sparkes
Copy link

@PapaMufflon can you share your code for this polyfill thanks

@PapaMufflon
Copy link

Sure, I'm using Angular and am very sure that there are better solutions. In main.ts:

// IE11 fetch polyfill
import 'unfetch/polyfill/index';

auth0Ie11Polyfill();

// standard angular-stuff
if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));

// auth0-IE11 polyfill begins here
function auth0Ie11Polyfill() {
  webcryptoShim(window);

  if (!Uint8Array.prototype.slice) {
    Object.defineProperty(Uint8Array.prototype, 'slice', {
      value: function (begin, end)
       {
          return new Uint8Array(Array.prototype.slice.call(this, begin, end));
       }
    });
  }
  
  if (!Array.prototype.includes) {
    Array.prototype.includes = x => Array.prototype.indexOf(x) >= 0;
  }
}

class AesGcmEncryptResult {
  ciphertext: ArrayBuffer;
  tag: ArrayBuffer;
}

// from https://github.com/vibornoff/webcrypto-shim/blob/master/webcrypto-shim.js
function webcryptoShim(global: any) {
  if ( typeof Promise !== 'function' )
      throw "Promise support required";

  var _crypto = global.crypto || global.msCrypto;
  if ( !_crypto ) return;

  var _subtle = _crypto.subtle || _crypto.webkitSubtle;
  if ( !_subtle ) return;

  var _Crypto     = global.Crypto || _crypto.constructor || Object,
      _SubtleCrypto = global.SubtleCrypto || _subtle.constructor || Object,
      _CryptoKey  = global.CryptoKey || global.Key || Object;

  var isEdge = global.navigator.userAgent.indexOf('Edge/') > -1;
  var isIE    = !!global.msCrypto && !isEdge;
  var isWebkit = !_crypto.subtle && !!_crypto.webkitSubtle;
  if ( !isIE && !isWebkit ) return;

  function s2a ( s ) {
      return btoa(s).replace(/\=+$/, '').replace(/\+/g, '-').replace(/\//g, '_');
  }

  function a2s ( s ) {
      s += '===', s = s.slice( 0, -s.length % 4 );
      return atob( s.replace(/-/g, '+').replace(/_/g, '/') );
  }

  function s2b ( s ) {
      var b = new Uint8Array(s.length);
      for ( var i = 0; i < s.length; i++ ) b[i] = s.charCodeAt(i);
      return b;
  }

  function b2s ( b ) {
      if ( b instanceof ArrayBuffer ) b = new Uint8Array(b);
      return String.fromCharCode.apply( String, b );
  }

  function alg ( a ) {
      var r = { 'name': (a.name || a || '').toUpperCase().replace('V','v') };
      switch ( r.name ) {
          case 'SHA-1':
          case 'SHA-256':
          case 'SHA-384':
          case 'SHA-512':
              break;
          case 'AES-CBC':
          case 'AES-GCM':
          case 'AES-KW':
              if ( a.length ) r['length'] = a.length;
              break;
          case 'HMAC':
              if ( a.hash ) r['hash'] = alg(a.hash);
              if ( a.length ) r['length'] = a.length;
              break;
          case 'RSAES-PKCS1-v1_5':
              if ( a.publicExponent ) r['publicExponent'] = new Uint8Array(a.publicExponent);
              if ( a.modulusLength ) r['modulusLength'] = a.modulusLength;
              break;
          case 'RSASSA-PKCS1-v1_5':
          case 'RSA-OAEP':
              if ( a.hash ) r['hash'] = alg(a.hash);
              if ( a.publicExponent ) r['publicExponent'] = new Uint8Array(a.publicExponent);
              if ( a.modulusLength ) r['modulusLength'] = a.modulusLength;
              break;
          default:
              throw new SyntaxError("Bad algorithm name");
      }
      return r;
  };

  function jwkAlg ( a ) {
      return {
          'HMAC': {
              'SHA-1': 'HS1',
              'SHA-256': 'HS256',
              'SHA-384': 'HS384',
              'SHA-512': 'HS512',
          },
          'RSASSA-PKCS1-v1_5': {
              'SHA-1': 'RS1',
              'SHA-256': 'RS256',
              'SHA-384': 'RS384',
              'SHA-512': 'RS512',
          },
          'RSAES-PKCS1-v1_5': {
              '': 'RSA1_5',
          },
          'RSA-OAEP': {
              'SHA-1': 'RSA-OAEP',
              'SHA-256': 'RSA-OAEP-256',
          },
          'AES-KW': {
              '128': 'A128KW',
              '192': 'A192KW',
              '256': 'A256KW',
          },
          'AES-GCM': {
              '128': 'A128GCM',
              '192': 'A192GCM',
              '256': 'A256GCM',
          },
          'AES-CBC': {
              '128': 'A128CBC',
              '192': 'A192CBC',
              '256': 'A256CBC',
          },
      }[a.name][ ( a.hash || {} ).name || a.length || '' ];
  }

  function b2jwk ( k ) {
      if ( k instanceof ArrayBuffer || k instanceof Uint8Array ) k = JSON.parse( decodeURIComponent( escape( b2s(k) ) ) );
      var jwk:any = { 'kty': k.kty, 'alg': k.alg, 'ext': k.ext || k.extractable };
      switch ( jwk.kty ) {
          case 'oct':
              jwk.k = k.k;
          case 'RSA':
              [ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi', 'oth' ].forEach( function ( x ) { if ( x in k ) jwk[x] = k[x] } );
              break;
          default:
              throw new TypeError("Unsupported key type");
      }
      return jwk;
  }

  function jwk2b ( k ) {
      var jwk = b2jwk(k);
      if ( isIE ) jwk['extractable'] = jwk.ext, delete jwk.ext;
      return s2b( unescape( encodeURIComponent( JSON.stringify(jwk) ) ) ).buffer;
  }

  function pkcs2jwk ( k ) {
      var info = b2der(k), prv = false;
      if ( info.length > 2 ) prv = true, info.shift(); // remove version from PKCS#8 PrivateKeyInfo structure
      var jwk = { 'ext': true };
      switch ( info[0][0] ) {
          case '1.2.840.113549.1.1.1':
              var rsaComp = [ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi' ],
                  rsaKey  = b2der( info[1] );
              if ( prv ) rsaKey.shift(); // remove version from PKCS#1 RSAPrivateKey structure
              for ( var i = 0; i < rsaKey.length; i++ ) {
                  if ( !rsaKey[i][0] ) rsaKey[i] = rsaKey[i].subarray(1);
                  jwk[ rsaComp[i] ] = s2a( b2s( rsaKey[i] ) );
              }
              jwk['kty'] = 'RSA';
              break;
          default:
              throw new TypeError("Unsupported key type");
      }
      return jwk;
  }

  function jwk2pkcs ( k ) {
      var key, info:any = [ [ '', null ] ], prv = false;
      switch ( k.kty ) {
          case 'RSA':
              var rsaComp = [ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi' ],
                  rsaKey = [];
              for ( var i = 0; i < rsaComp.length; i++ ) {
                  if ( !( rsaComp[i] in k ) ) break;
                  var b = rsaKey[i] = s2b( a2s( k[ rsaComp[i] ] ) );
                  if ( b[0] & 0x80 ) rsaKey[i] = new Uint8Array(b.length + 1), rsaKey[i].set( b, 1 );
              }
              if ( rsaKey.length > 2 ) prv = true, rsaKey.unshift( new Uint8Array([0]) ); // add version to PKCS#1 RSAPrivateKey structure
              info[0][0] = '1.2.840.113549.1.1.1';
              key = rsaKey;
              break;
          default:
              throw new TypeError("Unsupported key type");
      }
      info.push( new Uint8Array( der2b(key) ).buffer );
      if ( !prv ) info[1] = { 'tag': 0x03, 'value': info[1] };
      else info.unshift( new Uint8Array([0]) ); // add version to PKCS#8 PrivateKeyInfo structure
      return new Uint8Array( der2b(info) ).buffer;
  }

  var oid2str = { 'KoZIhvcNAQEB': '1.2.840.113549.1.1.1' },
      str2oid = { '1.2.840.113549.1.1.1': 'KoZIhvcNAQEB' };

  function b2der ( buf, ctx? ) {
      if ( buf instanceof ArrayBuffer ) buf = new Uint8Array(buf);
      if ( !ctx ) ctx = { pos: 0, end: buf.length };

      if ( ctx.end - ctx.pos < 2 || ctx.end > buf.length ) throw new RangeError("Malformed DER");

      var tag = buf[ctx.pos++],
          len = buf[ctx.pos++];

      if ( len >= 0x80 ) {
          len &= 0x7f;
          if ( ctx.end - ctx.pos < len ) throw new RangeError("Malformed DER");
          for ( var xlen = 0; len--; ) xlen <<= 8, xlen |= buf[ctx.pos++];
          len = xlen;
      }

      if ( ctx.end - ctx.pos < len ) throw new RangeError("Malformed DER");

      var rv;

      switch ( tag ) {
          case 0x02: // Universal Primitive INTEGER
              rv = buf.subarray( ctx.pos, ctx.pos += len );
              break;
          case 0x03: // Universal Primitive BIT STRING
              if ( buf[ctx.pos++] ) throw new Error( "Unsupported bit string" );
              len--;
          case 0x04: // Universal Primitive OCTET STRING
              rv = new Uint8Array( buf.subarray( ctx.pos, ctx.pos += len ) ).buffer;
              break;
          case 0x05: // Universal Primitive NULL
              rv = null;
              break;
          case 0x06: // Universal Primitive OBJECT IDENTIFIER
              var oid = btoa( b2s( buf.subarray( ctx.pos, ctx.pos += len ) ) );
              if ( !( oid in oid2str ) ) throw new Error( "Unsupported OBJECT ID " + oid );
              rv = oid2str[oid];
              break;
          case 0x30: // Universal Constructed SEQUENCE
              rv = [];
              for ( var end = ctx.pos + len; ctx.pos < end; ) rv.push( b2der( buf, ctx ) );
              break;
          default:
              throw new Error( "Unsupported DER tag 0x" + tag.toString(16) );
      }

      return rv;
  }

  function der2b ( val, buf? ) {
      if ( !buf ) buf = [];

      var tag = 0, len = 0,
          pos = buf.length + 2;

      buf.push( 0, 0 ); // placeholder

      if ( val instanceof Uint8Array ) {  // Universal Primitive INTEGER
          tag = 0x02, len = val.length;
          for ( var i = 0; i < len; i++ ) buf.push( val[i] );
      }
      else if ( val instanceof ArrayBuffer ) { // Universal Primitive OCTET STRING
          tag = 0x04, len = val.byteLength, val = new Uint8Array(val);
          for ( var i = 0; i < len; i++ ) buf.push( val[i] );
      }
      else if ( val === null ) { // Universal Primitive NULL
          tag = 0x05, len = 0;
      }
      else if ( typeof val === 'string' && val in str2oid ) { // Universal Primitive OBJECT IDENTIFIER
          var oid = s2b( atob( str2oid[val] ) );
          tag = 0x06, len = oid.length;
          for ( var i = 0; i < len; i++ ) buf.push( oid[i] );
      }
      else if ( val instanceof Array ) { // Universal Constructed SEQUENCE
          for ( var i = 0; i < val.length; i++ ) der2b( val[i], buf );
          tag = 0x30, len = buf.length - pos;
      }
      else if ( typeof val === 'object' && val.tag === 0x03 && val.value instanceof ArrayBuffer ) { // Tag hint
          val = new Uint8Array(val.value), tag = 0x03, len = val.byteLength;
          buf.push(0); for ( var i = 0; i < len; i++ ) buf.push( val[i] );
          len++;
      }
      else {
          throw new Error( "Unsupported DER value " + val );
      }

      if ( len >= 0x80 ) {
          var xlen = len, len = 4;
          buf.splice( pos, 0, (xlen >> 24) & 0xff, (xlen >> 16) & 0xff, (xlen >> 8) & 0xff, xlen & 0xff );
          while ( len > 1 && !(xlen >> 24) ) xlen <<= 8, len--;
          if ( len < 4 ) buf.splice( pos, 4 - len );
          len |= 0x80;
      }

      buf.splice( pos - 2, 2, tag, len );

      return buf;
  }

  function CryptoKey ( key, alg, ext, use ) {
      Object.defineProperties( this, {
          _key: {
              value: key
          },
          type: {
              value: key.type,
              enumerable: true,
          },
          extractable: {
              value: (ext === undefined) ? key.extractable : ext,
              enumerable: true,
          },
          algorithm: {
              value: (alg === undefined) ? key.algorithm : alg,
              enumerable: true,
          },
          usages: {
              value: (use === undefined) ? key.usages : use,
              enumerable: true,
          },
      });
  }

  function isPubKeyUse ( u ) {
      return u === 'verify' || u === 'encrypt' || u === 'wrapKey';
  }

  function isPrvKeyUse ( u ) {
      return u === 'sign' || u === 'decrypt' || u === 'unwrapKey';
  }

  [ 'generateKey', 'importKey', 'unwrapKey' ]
      .forEach( function ( m ) {
          var _fn = _subtle[m];

          _subtle[m] = function ( a, b, c ) {
              var args = [].slice.call(arguments),
                  ka, kx, ku;

              switch ( m ) {
                  case 'generateKey':
                      ka = alg(a), kx = b, ku = c;
                      break;
                  case 'importKey':
                      ka = alg(c), kx = args[3], ku = args[4];
                      if ( a === 'jwk' ) {
                          b = b2jwk(b);
                          if ( !b.alg ) b.alg = jwkAlg(ka);
                          if ( !b.key_ops ) b.key_ops = ( b.kty !== 'oct' ) ? ( 'd' in b ) ? ku.filter(isPrvKeyUse) : ku.filter(isPubKeyUse) : ku.slice();
                          args[1] = jwk2b(b);
                      }
                      break;
                  case 'unwrapKey':
                      ka = args[4], kx = args[5], ku = args[6];
                      args[2] = c._key;
                      break;
              }

              if ( m === 'generateKey' && ka.name === 'HMAC' && ka.hash ) {
                  ka.length = ka.length || { 'SHA-1': 512, 'SHA-256': 512, 'SHA-384': 1024, 'SHA-512': 1024 }[ka.hash.name];
                  return _subtle.importKey( 'raw', _crypto.getRandomValues( new Uint8Array( (ka.length+7)>>3 ) ), ka, kx, ku );
              }

              if ( isWebkit && m === 'generateKey' && ka.name === 'RSASSA-PKCS1-v1_5' && ( !ka.modulusLength || ka.modulusLength >= 2048 ) ) {
                  a = alg(a), a.name = 'RSAES-PKCS1-v1_5', delete a.hash;
                  return _subtle.generateKey( a, true, [ 'encrypt', 'decrypt' ] )
                      .then( function ( k ) {
                          return Promise.all([
                              _subtle.exportKey( 'jwk', k.publicKey ),
                              _subtle.exportKey( 'jwk', k.privateKey ),
                          ]);
                      })
                      .then( function ( keys ) {
                          keys[0].alg = keys[1].alg = jwkAlg(ka);
                          keys[0].key_ops = ku.filter(isPubKeyUse), keys[1].key_ops = ku.filter(isPrvKeyUse);
                          return Promise.all([
                              _subtle.importKey( 'jwk', keys[0], ka, true, keys[0].key_ops ),
                              _subtle.importKey( 'jwk', keys[1], ka, kx, keys[1].key_ops ),
                          ]);
                      })
                      .then( function ( keys ) {
                          return {
                              publicKey: keys[0],
                              privateKey: keys[1],
                          };
                      });
              }

              if ( ( isWebkit || ( isIE && ( ka.hash || {} ).name === 'SHA-1' ) )
                      && m === 'importKey' && a === 'jwk' && ka.name === 'HMAC' && b.kty === 'oct' ) {
                  return _subtle.importKey( 'raw', s2b( a2s(b.k) ), c, args[3], args[4] );
              }

              if ( isWebkit && m === 'importKey' && ( a === 'spki' || a === 'pkcs8' ) ) {
                  return _subtle.importKey( 'jwk', pkcs2jwk(b), c, args[3], args[4] );
              }

              if ( isIE && m === 'unwrapKey' ) {
                  return _subtle.decrypt( args[3], c, b )
                      .then( function ( k ) {
                          return _subtle.importKey( a, k, args[4], args[5], args[6] );
                      });
              }

              var op;
              try {
                  op = _fn.apply( _subtle, args );
              }
              catch ( e ) {
                  return Promise.reject(e);
              }

              if ( isIE ) {
                  op = new Promise( function ( res, rej ) {
                      op.onabort =
                      op.onerror =    function ( e ) { rej(e)               };
                      op.oncomplete = function ( r ) { res(r.target.result) };
                  });
              }

              op = op.then( function ( k ) {
                  if ( ka.name === 'HMAC' ) {
                      if ( !ka.length ) ka.length = 8 * k.algorithm.length;
                  }
                  if ( ka.name.search('RSA') == 0 ) {
                      if ( !ka.modulusLength ) ka.modulusLength = (k.publicKey || k).algorithm.modulusLength;
                      if ( !ka.publicExponent ) ka.publicExponent = (k.publicKey || k).algorithm.publicExponent;
                  }
                  if ( k.publicKey && k.privateKey ) {
                      k = {
                          publicKey: new CryptoKey( k.publicKey, ka, kx, ku.filter(isPubKeyUse) ),
                          privateKey: new CryptoKey( k.privateKey, ka, kx, ku.filter(isPrvKeyUse) ),
                      };
                  }
                  else {
                      k = new CryptoKey( k, ka, kx, ku );
                  }
                  return k;
              });

              return op;
          }
      });

  [ 'exportKey', 'wrapKey' ]
      .forEach( function ( m ) {
          var _fn = _subtle[m];

          _subtle[m] = function ( a, b, c ) {
              var args = [].slice.call(arguments);

              switch ( m ) {
                  case 'exportKey':
                      args[1] = b._key;
                      break;
                  case 'wrapKey':
                      args[1] = b._key, args[2] = c._key;
                      break;
              }

              if ( ( isWebkit || ( isIE && ( b.algorithm.hash || {} ).name === 'SHA-1' ) )
                      && m === 'exportKey' && a === 'jwk' && b.algorithm.name === 'HMAC' ) {
                  args[0] = 'raw';
              }

              if ( isWebkit && m === 'exportKey' && ( a === 'spki' || a === 'pkcs8' ) ) {
                  args[0] = 'jwk';
              }

              if ( isIE && m === 'wrapKey' ) {
                  return _subtle.exportKey( a, b )
                      .then( function ( k ) {
                          if ( a === 'jwk' ) k = s2b( unescape( encodeURIComponent( JSON.stringify( b2jwk(k) ) ) ) );
                          return  _subtle.encrypt( args[3], c, k );
                      });
              }

              var op;
              try {
                  op = _fn.apply( _subtle, args );
              }
              catch ( e ) {
                  return Promise.reject(e);
              }

              if ( isIE ) {
                  op = new Promise( function ( res, rej ) {
                      op.onabort =
                      op.onerror =    function ( e ) { rej(e)               };
                      op.oncomplete = function ( r ) { res(r.target.result) };
                  });
              }

              if ( m === 'exportKey' && a === 'jwk' ) {
                  op = op.then( function ( k ) {
                      if ( ( isWebkit || ( isIE && ( b.algorithm.hash || {} ).name === 'SHA-1' ) )
                              && b.algorithm.name === 'HMAC') {
                          return { 'kty': 'oct', 'alg': jwkAlg(b.algorithm), 'key_ops': b.usages.slice(), 'ext': true, 'k': s2a( b2s(k) ) };
                      }
                      k = b2jwk(k);
                      if ( !k.alg ) k['alg'] = jwkAlg(b.algorithm);
                      if ( !k.key_ops ) k['key_ops'] = ( b.type === 'public' ) ? b.usages.filter(isPubKeyUse) : ( b.type === 'private' ) ? b.usages.filter(isPrvKeyUse) : b.usages.slice();
                      return k;
                  });
              }

              if ( isWebkit && m === 'exportKey' && ( a === 'spki' || a === 'pkcs8' ) ) {
                  op = op.then( function ( k ) {
                      k = jwk2pkcs( b2jwk(k) );
                      return k;
                  });
              }

              return op;
          }
      });

  [ 'encrypt', 'decrypt', 'sign', 'verify' ]
      .forEach( function ( m ) {
          var _fn = _subtle[m];

          _subtle[m] = function ( a, b, c, d ) {
              if ( isIE && ( !c.byteLength || ( d && !d.byteLength ) ) )
                  throw new Error("Empy input is not allowed");

              var args = [].slice.call(arguments),
                  ka = alg(a);

              if ( isIE && ( m === 'encrypt' || m === 'decrypt' ) && b.algorithm.hash ) {
                  args[0].hash = args[0].hash || b.algorithm.hash;
              }

              if ( isIE && m === 'decrypt' && ka.name === 'AES-GCM' ) {
                  var tl = a.tagLength >> 3;
                  args[2] = (c.buffer || c).slice( 0, c.byteLength - tl ),
                  a.tag = (c.buffer || c).slice( c.byteLength - tl );
              }

              args[1] = b._key;

              var op;
              try {
                  op = _fn.apply( _subtle, args );
              }
              catch ( e ) {
                  return Promise.reject(e);
              }

              if ( isIE ) {
                  op = new Promise( function ( res, rej ) {
                      op.onabort =
                      op.onerror = function ( e ) {
                          rej(e);
                      };

                      op.oncomplete = function ( r ) {
                          var r = r.target.result;

                          if ( m === 'encrypt' && r instanceof AesGcmEncryptResult ) {
                              var c = r.ciphertext, t = r.tag;
                              r = new Uint8Array( c.byteLength + t.byteLength );
                              r.set( new Uint8Array(c), 0 );
                              r.set( new Uint8Array(t), c.byteLength );
                              r = r.buffer;
                          }

                          res(r);
                      };
                  });
              }

              return op;
          }
      });

  if ( isIE ) {
      var _digest = _subtle.digest;

      _subtle['digest'] = function ( a, b ) {
          if ( !b.byteLength )
              throw new Error("Empy input is not allowed");

          var op;
          try {
              op = _digest.call( _subtle, a, b );
          }
          catch ( e ) {
              return Promise.reject(e);
          }

          op = new Promise( function ( res, rej ) {
              op.onabort =
              op.onerror =    function ( e ) { rej(e)               };
              op.oncomplete = function ( r ) { res(r.target.result) };
          });

          return op;
      };

      global.crypto = Object.create( _crypto, {
          getRandomValues: { value: function ( a ) { return new Array(_crypto.getRandomValues(a)) } },
          subtle:          { value: _subtle },
      });

      global.CryptoKey = CryptoKey;
  }

  if ( isWebkit ) {
      _crypto.subtle = _subtle;

      global.Crypto = _Crypto;
      global.SubtleCrypto = _SubtleCrypto;
      global.CryptoKey = CryptoKey;
  }
};

@luisrudge
Copy link
Contributor

Hi folks. Sorry to keep you all waiting. I'm doing some cleanup in the polyfills to make sure we only load what we need (we'll also get rid of the legacy entrypoint and just have the regular bundle be ie11 compatible).

@keithrz
Copy link

keithrz commented Aug 23, 2019

Build please!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants