Skip to content

Commit

Permalink
Don't overwrite Web Streams Polyfill to globals
Browse files Browse the repository at this point in the history
Instead, use the ponyfill that's now included in web-stream-tools.
Also, convert back to native ReadableStream when we used the ponyfill.
  • Loading branch information
twiss committed Feb 9, 2021
1 parent 430145a commit 2fffc76
Show file tree
Hide file tree
Showing 15 changed files with 108 additions and 97 deletions.
2 changes: 1 addition & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ module.exports = function(grunt) {
["babelify", {
global: true,
// Only babelify web-streams-polyfill, web-stream-tools, asmcrypto, email-addresses and seek-bzip in node_modules
only: /^(?:.*\/node_modules\/@mattiasbuelens\/web-streams-polyfill\/|.*\/node_modules\/web-stream-tools\/|.*\/node_modules\/asmcrypto\.js\/|.*\/node_modules\/email-addresses\/|.*\/node_modules\/seek-bzip\/|(?!.*\/node_modules\/)).*$/,
only: /^(?:.*\/node_modules\/web-streams-polyfill\/|.*\/node_modules\/web-stream-tools\/|.*\/node_modules\/asmcrypto\.js\/|.*\/node_modules\/email-addresses\/|.*\/node_modules\/seek-bzip\/|(?!.*\/node_modules\/)).*$/,
ignore: ['*.min.js'],
plugins,
presets
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ Where the value can be any of:

```js
(async () => {
const readableStream = new ReadableStream({
const readableStream = new openpgp.stream.ReadableStream({
start(controller) {
controller.enqueue(new Uint8Array([0x01, 0x02, 0x03]));
controller.close();
Expand Down Expand Up @@ -331,7 +331,7 @@ its [Reader class](https://openpgpjs.org/web-stream-tools/Reader.html).
const privateKey = (await openpgp.key.readArmored([privateKeyArmored])).keys[0];
await privateKey.decrypt(passphrase);

const readableStream = new ReadableStream({
const readableStream = new openpgp.stream.ReadableStream({
start(controller) {
controller.enqueue('Hello, world!');
controller.close();
Expand Down Expand Up @@ -513,7 +513,7 @@ Using the private key:

```js
(async () => {
var readableStream = new ReadableStream({
var readableStream = new openpgp.stream.ReadableStream({
start(controller) {
controller.enqueue(new Uint8Array([0x01, 0x02, 0x03]));
controller.close();
Expand Down
23 changes: 16 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
"sinon": "^4.3.0",
"text-encoding-utf-8": "^1.0.2",
"whatwg-fetch": "^2.0.3",
"@mattiasbuelens/web-streams-polyfill": "^0.3.1",
"asmcrypto.js": "github:openpgpjs/asmcrypto#475cffa5ccb2cf2556427056679414acf3610d1b",
"bn.js": "^4.11.8",
"buffer": "^5.0.8",
Expand All @@ -79,10 +78,11 @@
"pako": "^1.0.6",
"seek-bzip": "github:openpgpjs/seek-bzip#6187fc025851d35c4e104a25ea15a10b9b8d6f7d",
"tweetnacl": "github:openpgpjs/tweetnacl-js#3dae25bd3eaa77173f3405676b595721dde92eec",
"web-stream-tools": "github:openpgpjs/web-stream-tools#619abcbe2d9115bb005047f609b72d71108edadb",
"web-stream-tools": "github:openpgpjs/web-stream-tools#699d88c8d8f78d1513769e16cf557929c97bf83c",
"email-addresses": "3.1.0"
},
"dependencies": {
"@mattiasbuelens/web-streams-adapter": "0.1.0-alpha.3",
"asn1.js": "^5.0.0",
"node-fetch": "^2.1.2",
"node-localstorage": "~1.3.0"
Expand Down
120 changes: 62 additions & 58 deletions src/openpgp.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
*/

import stream from 'web-stream-tools';
import { createReadableStreamWrapper } from '@mattiasbuelens/web-streams-adapter';
import * as messageLib from './message';
import { CleartextMessage } from './cleartext';
import { generate, reformat } from './key';
Expand All @@ -49,6 +50,8 @@ import './polyfills';
import util from './util';
import AsyncProxy from './worker/async_proxy';

const toNativeReadable = global.ReadableStream && createReadableStreamWrapper(global.ReadableStream);

//////////////////////////
// //
// Web Worker setup //
Expand Down Expand Up @@ -284,22 +287,22 @@ export function encryptKey({ privateKey, passphrase }) {
/**
* Encrypts message text/data with public keys, passwords or both at once. At least either public keys or passwords
* must be specified. If private keys are specified, those will be used to sign the message.
* @param {Message} message message to be encrypted as created by openpgp.message.fromText or openpgp.message.fromBinary
* @param {Key|Array<Key>} publicKeys (optional) array of keys or single key, used to encrypt the message
* @param {Key|Array<Key>} privateKeys (optional) private keys for signing. If omitted message will not be signed
* @param {String|Array<String>} passwords (optional) array of passwords or a single password to encrypt the message
* @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String }
* @param {module:enums.compression} compression (optional) which compression algorithm to compress the message with, defaults to what is specified in config
* @param {Boolean} armor (optional) whether the return values should be ascii armored (true, the default) or binary (false)
* @param {'web'|'node'|false} streaming (optional) whether to return data as a stream. Defaults to the type of stream `message` was created from, if any.
* @param {Boolean} detached (optional) if the signature should be detached (if true, signature will be added to returned object)
* @param {Signature} signature (optional) a detached signature to add to the encrypted message
* @param {Boolean} returnSessionKey (optional) if the unencrypted session key should be added to returned object
* @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs
* @param {Date} date (optional) override the creation date of the message signature
* @param {Array} fromUserIds (optional) array of user IDs to sign with, one per key in `privateKeys`, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
* @param {Array} toUserIds (optional) array of user IDs to encrypt for, one per key in `publicKeys`, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }]
* @returns {Promise<Object>} Object containing encrypted (and optionally signed) message in the form:
* @param {Message} message message to be encrypted as created by openpgp.message.fromText or openpgp.message.fromBinary
* @param {Key|Array<Key>} publicKeys (optional) array of keys or single key, used to encrypt the message
* @param {Key|Array<Key>} privateKeys (optional) private keys for signing. If omitted message will not be signed
* @param {String|Array<String>} passwords (optional) array of passwords or a single password to encrypt the message
* @param {Object} sessionKey (optional) session key in the form: { data:Uint8Array, algorithm:String }
* @param {module:enums.compression} compression (optional) which compression algorithm to compress the message with, defaults to what is specified in config
* @param {Boolean} armor (optional) whether the return values should be ascii armored (true, the default) or binary (false)
* @param {'web'|'ponyfill'|'node'|false} streaming (optional) whether to return data as a stream. Defaults to the type of stream `message` was created from, if any.
* @param {Boolean} detached (optional) if the signature should be detached (if true, signature will be added to returned object)
* @param {Signature} signature (optional) a detached signature to add to the encrypted message
* @param {Boolean} returnSessionKey (optional) if the unencrypted session key should be added to returned object
* @param {Boolean} wildcard (optional) use a key ID of 0 instead of the public key IDs
* @param {Date} date (optional) override the creation date of the message signature
* @param {Array} fromUserIds (optional) array of user IDs to sign with, one per key in `privateKeys`, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
* @param {Array} toUserIds (optional) array of user IDs to encrypt for, one per key in `publicKeys`, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }]
* @returns {Promise<Object>} Object containing encrypted (and optionally signed) message in the form:
*
* {
* data: String|ReadableStream<String>|NodeStream, (if `armor` was true, the default)
Expand Down Expand Up @@ -345,16 +348,16 @@ export function encrypt({ message, publicKeys, privateKeys, passwords, sessionKe
/**
* Decrypts a message with the user's private key, a session key or a password. Either a private key,
* a session key or a password must be specified.
* @param {Message} message the message object with the encrypted data
* @param {Key|Array<Key>} privateKeys (optional) private keys with decrypted secret key data or session key
* @param {String|Array<String>} passwords (optional) passwords to decrypt the message
* @param {Object|Array<Object>} sessionKeys (optional) session keys in the form: { data:Uint8Array, algorithm:String }
* @param {Key|Array<Key>} publicKeys (optional) array of public keys or single key, to verify signatures
* @param {'utf8'|'binary'} format (optional) whether to return data as a string(Stream) or Uint8Array(Stream). If 'utf8' (the default), also normalize newlines.
* @param {'web'|'node'|false} streaming (optional) whether to return data as a stream. Defaults to the type of stream `message` was created from, if any.
* @param {Signature} signature (optional) detached signature for verification
* @param {Date} date (optional) use the given date for verification instead of the current time
* @returns {Promise<Object>} Object containing decrypted and verified message in the form:
* @param {Message} message the message object with the encrypted data
* @param {Key|Array<Key>} privateKeys (optional) private keys with decrypted secret key data or session key
* @param {String|Array<String>} passwords (optional) passwords to decrypt the message
* @param {Object|Array<Object>} sessionKeys (optional) session keys in the form: { data:Uint8Array, algorithm:String }
* @param {Key|Array<Key>} publicKeys (optional) array of public keys or single key, to verify signatures
* @param {'utf8'|'binary'} format (optional) whether to return data as a string(Stream) or Uint8Array(Stream). If 'utf8' (the default), also normalize newlines.
* @param {'web'|'ponyfill'|'node'|false} streaming (optional) whether to return data as a stream. Defaults to the type of stream `message` was created from, if any.
* @param {Signature} signature (optional) detached signature for verification
* @param {Date} date (optional) use the given date for verification instead of the current time
* @returns {Promise<Object>} Object containing decrypted and verified message in the form:
*
* {
* data: String|ReadableStream<String>|NodeStream, (if format was 'utf8', the default)
Expand Down Expand Up @@ -404,14 +407,14 @@ export function decrypt({ message, privateKeys, passwords, sessionKeys, publicKe

/**
* Signs a cleartext message.
* @param {CleartextMessage|Message} message (cleartext) message to be signed
* @param {Key|Array<Key>} privateKeys array of keys or single key with decrypted secret key data to sign cleartext
* @param {Boolean} armor (optional) whether the return values should be ascii armored (true, the default) or binary (false)
* @param {'web'|'node'|false} streaming (optional) whether to return data as a stream. Defaults to the type of stream `message` was created from, if any.
* @param {Boolean} detached (optional) if the return value should contain a detached signature
* @param {Date} date (optional) override the creation date of the signature
* @param {Array} fromUserIds (optional) array of user IDs to sign with, one per key in `privateKeys`, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
* @returns {Promise<Object>} Object containing signed message in the form:
* @param {CleartextMessage|Message} message (cleartext) message to be signed
* @param {Key|Array<Key>} privateKeys array of keys or single key with decrypted secret key data to sign cleartext
* @param {Boolean} armor (optional) whether the return values should be ascii armored (true, the default) or binary (false)
* @param {'web'|'ponyfill'|'node'|false} streaming (optional) whether to return data as a stream. Defaults to the type of stream `message` was created from, if any.
* @param {Boolean} detached (optional) if the return value should contain a detached signature
* @param {Date} date (optional) override the creation date of the signature
* @param {Array} fromUserIds (optional) array of user IDs to sign with, one per key in `privateKeys`, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
* @returns {Promise<Object>} Object containing signed message in the form:
*
* {
* data: String|ReadableStream<String>|NodeStream, (if `armor` was true, the default)
Expand Down Expand Up @@ -459,13 +462,13 @@ export function sign({ message, privateKeys, armor = true, streaming = message &

/**
* Verifies signatures of cleartext signed message
* @param {Key|Array<Key>} publicKeys array of publicKeys or single key, to verify signatures
* @param {CleartextMessage|Message} message (cleartext) message object with signatures
* @param {'utf8'|'binary'} format (optional) whether to return data as a string(Stream) or Uint8Array(Stream). If 'utf8' (the default), also normalize newlines.
* @param {'web'|'node'|false} streaming (optional) whether to return data as a stream. Defaults to the type of stream `message` was created from, if any.
* @param {Signature} signature (optional) detached signature for verification
* @param {Date} date (optional) use the given date for verification instead of the current time
* @returns {Promise<Object>} Object containing verified message in the form:
* @param {Key|Array<Key>} publicKeys array of publicKeys or single key, to verify signatures
* @param {CleartextMessage|Message} message (cleartext) message object with signatures
* @param {'utf8'|'binary'} format (optional) whether to return data as a string(Stream) or Uint8Array(Stream). If 'utf8' (the default), also normalize newlines.
* @param {'web'|'ponyfill'|'node'|false} streaming (optional) whether to return data as a stream. Defaults to the type of stream `message` was created from, if any.
* @param {Signature} signature (optional) detached signature for verification
* @param {Date} date (optional) use the given date for verification instead of the current time
* @returns {Promise<Object>} Object containing verified message in the form:
*
* {
* data: String|ReadableStream<String>|NodeStream, (if `message` was a CleartextMessage)
Expand Down Expand Up @@ -614,37 +617,38 @@ function toArray(param) {

/**
* Convert data to or from Stream
* @param {Object} data the data to convert
* @param {'web'|'node'|false} streaming (optional) whether to return a ReadableStream
* @param {'utf8'|'binary'} encoding (optional) how to return data in Node Readable streams
* @returns {Object} the data in the respective format
* @param {Object} data the data to convert
* @param {'web'|'ponyfill'|'node'|false} streaming (optional) whether to return a ReadableStream, and of what type
* @param {'utf8'|'binary'} encoding (optional) how to return data in Node Readable streams
* @returns {Object} the data in the respective format
*/
async function convertStream(data, streaming, encoding = 'utf8') {
if (!streaming && util.isStream(data)) {
let streamType = util.isStream(data);
if (!streaming && streamType) {
return stream.readToEnd(data);
}
if (streaming && !util.isStream(data)) {
data = new ReadableStream({
start(controller) {
controller.enqueue(data);
controller.close();
}
});
if (streaming && !streamType) {
data = stream.toStream(data);
streamType = util.isStream(data);
}
if (streaming === 'node') {
data = stream.webToNode(data);
if (encoding !== 'binary') data.setEncoding(encoding);
return data;
}
if (streaming === 'web' && streamType === 'ponyfill' && toNativeReadable) {
return toNativeReadable(data);
}
return data;
}

/**
* Convert object properties from Stream
* @param {Object} obj the data to convert
* @param {'web'|'node'|false} streaming (optional) whether to return ReadableStreams
* @param {'utf8'|'binary'} encoding (optional) how to return data in Node Readable streams
* @param {Array<String>} keys (optional) which keys to return as streams, if possible
* @returns {Object} the data in the respective format
* @param {Object} obj the data to convert
* @param {'web'|'ponyfill'|'node'|false} streaming (optional) whether to return ReadableStreams, and of what type
* @param {'utf8'|'binary'} encoding (optional) how to return data in Node Readable streams
* @param {Array<String>} keys (optional) which keys to return as streams, if possible
* @returns {Object} the data in the respective format
*/
async function convertStreams(obj, streaming, encoding = 'utf8', keys = []) {
if (Object.prototype.isPrototypeOf(obj) && !Uint8Array.prototype.isPrototypeOf(obj)) {
Expand Down
2 changes: 1 addition & 1 deletion src/packet/packet.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export default {
const supportsStreaming = this.supportsStreaming(tag);
let packet = null;
if (streaming && supportsStreaming) {
const transform = new TransformStream();
const transform = new stream.TransformStream();
writer = stream.getWriter(transform.writable);
packet = transform.readable;
callbackReturned = callback({ tag, packet });
Expand Down
Loading

0 comments on commit 2fffc76

Please sign in to comment.