mirror of
https://github.com/openpgpjs/openpgpjs.git
synced 2025-06-04 13:16:42 +00:00
Drop support for native Node Readable stream: require passing Node Web Streams (#1716)
Breaking change: all functions taking streams as inputs will now require passing Web Streams in Node.js . If given a native `stream.Readable` input, they will throw. The browser build is unaffected by this change. Utils to convert from and to Web Streams in Node are available from v17, see https://nodejs.org/api/stream.html#streamreadabletowebstreamreadable-options . Previously, we automatically converted between Node native streams and custom, Web-like Readable streams. This led to occasional issues.
This commit is contained in:
parent
591b9399a8
commit
99899d1d5c
2
.github/workflows/benchmark.yml
vendored
2
.github/workflows/benchmark.yml
vendored
@ -20,6 +20,8 @@ jobs:
|
||||
ref: main
|
||||
path: main
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '>=20.6.0'
|
||||
|
||||
- name: Run pull request time benchmark
|
||||
run: cd pr && npm install && npm run --silent benchmark-time > benchmarks.txt && cat benchmarks.txt
|
||||
|
75
openpgp.d.ts
vendored
75
openpgp.d.ts
vendored
@ -7,9 +7,19 @@
|
||||
* - Errietta Kostala <https://github.com/errietta>
|
||||
*/
|
||||
|
||||
import type { WebStream as GenericWebStream, NodeStream as GenericNodeStream } from '@openpgp/web-stream-tools';
|
||||
import type { WebStream as GenericWebStream, NodeWebStream as GenericNodeWebStream } from '@openpgp/web-stream-tools';
|
||||
|
||||
/* ############## v5 KEY #################### */
|
||||
/* ############## STREAM #################### */
|
||||
type Data = Uint8Array | string;
|
||||
// web-stream-tools might end up supporting additional data types, so we re-declare the types
|
||||
// to enforce the type contraint that we need.
|
||||
export type WebStream<T extends Data> = GenericWebStream<T>;
|
||||
export type NodeWebStream<T extends Data> = GenericNodeWebStream<T>;
|
||||
export type Stream<T extends Data> = WebStream<T> | NodeWebStream<T>;
|
||||
export type MaybeStream<T extends Data> = T | Stream<T>;
|
||||
type MaybeArray<T> = T | Array<T>;
|
||||
|
||||
/* ############## KEY #################### */
|
||||
// The Key and PublicKey types can be used interchangably since TS cannot detect the difference, as they have the same class properties.
|
||||
// The declared readKey(s) return type is Key instead of a PublicKey since it seems more obvious that a Key can be cast to a PrivateKey.
|
||||
export function readKey(options: { armoredKey: string, config?: PartialConfig }): Promise<Key>;
|
||||
@ -118,13 +128,13 @@ export interface PrimaryUser {
|
||||
selfCertification: SignaturePacket;
|
||||
}
|
||||
|
||||
type AlgorithmInfo = {
|
||||
export type AlgorithmInfo = {
|
||||
algorithm: enums.publicKeyNames;
|
||||
bits?: number;
|
||||
curve?: EllipticCurveName;
|
||||
};
|
||||
|
||||
/* ############## v5 SIG #################### */
|
||||
/* ############## SIG #################### */
|
||||
|
||||
export function readSignature(options: { armoredSignature: string, config?: PartialConfig }): Promise<Signature>;
|
||||
export function readSignature(options: { binarySignature: Uint8Array, config?: PartialConfig }): Promise<Signature>;
|
||||
@ -143,7 +153,7 @@ interface VerificationResult {
|
||||
signature: Promise<Signature>;
|
||||
}
|
||||
|
||||
/* ############## v5 CLEARTEXT #################### */
|
||||
/* ############## CLEARTEXT #################### */
|
||||
|
||||
export function readCleartextMessage(options: { cleartextMessage: string, config?: PartialConfig }): Promise<CleartextMessage>;
|
||||
|
||||
@ -176,7 +186,7 @@ export class CleartextMessage {
|
||||
verify(keys: PublicKey[], date?: Date, config?: Config): Promise<VerificationResult[]>;
|
||||
}
|
||||
|
||||
/* ############## v5 MSG #################### */
|
||||
/* ############## MSG #################### */
|
||||
export function generateSessionKey(options: { encryptionKeys: MaybeArray<PublicKey>, date?: Date, encryptionUserIDs?: MaybeArray<UserID>, config?: PartialConfig }): Promise<SessionKey>;
|
||||
export function encryptSessionKey(options: EncryptSessionKeyOptions & { format?: 'armored' }): Promise<string>;
|
||||
export function encryptSessionKey(options: EncryptSessionKeyOptions & { format: 'binary' }): Promise<Uint8Array>;
|
||||
@ -191,24 +201,24 @@ export function createMessage<T extends MaybeStream<Uint8Array>>(options: { bina
|
||||
|
||||
export function encrypt<T extends MaybeStream<Data>>(options: EncryptOptions & { message: Message<T>, format?: 'armored' }): Promise<
|
||||
T extends WebStream<infer X> ? WebStream<string> :
|
||||
T extends NodeStream<infer X> ? NodeStream<string> :
|
||||
T extends NodeWebStream<infer X> ? NodeWebStream<string> :
|
||||
string
|
||||
>;
|
||||
export function encrypt<T extends MaybeStream<Data>>(options: EncryptOptions & { message: Message<T>, format: 'binary' }): Promise<
|
||||
T extends WebStream<infer X> ? WebStream<Uint8Array> :
|
||||
T extends NodeStream<infer X> ? NodeStream<Uint8Array> :
|
||||
T extends NodeWebStream<infer X> ? NodeWebStream<Uint8Array> :
|
||||
Uint8Array
|
||||
>;
|
||||
export function encrypt<T extends MaybeStream<Data>>(options: EncryptOptions & { message: Message<T>, format: 'object' }): Promise<Message<T>>;
|
||||
|
||||
export function sign<T extends MaybeStream<Data>>(options: SignOptions & { message: Message<T>, format?: 'armored' }): Promise<
|
||||
T extends WebStream<infer X> ? WebStream<string> :
|
||||
T extends NodeStream<infer X> ? NodeStream<string> :
|
||||
T extends NodeWebStream<infer X> ? NodeWebStream<string> :
|
||||
string
|
||||
>;
|
||||
export function sign<T extends MaybeStream<Data>>(options: SignOptions & { message: Message<T>, format: 'binary' }): Promise<
|
||||
T extends WebStream<infer X> ? WebStream<Uint8Array> :
|
||||
T extends NodeStream<infer X> ? NodeStream<Uint8Array> :
|
||||
T extends NodeWebStream<infer X> ? NodeWebStream<Uint8Array> :
|
||||
Uint8Array
|
||||
>;
|
||||
export function sign<T extends MaybeStream<Data>>(options: SignOptions & { message: Message<T>, format: 'object' }): Promise<Message<T>>;
|
||||
@ -218,25 +228,25 @@ export function sign(options: SignOptions & { message: CleartextMessage, format:
|
||||
export function decrypt<T extends MaybeStream<Data>>(options: DecryptOptions & { message: Message<T>, format: 'binary' }): Promise<DecryptMessageResult & {
|
||||
data:
|
||||
T extends WebStream<infer X> ? WebStream<Uint8Array> :
|
||||
T extends NodeStream<infer X> ? NodeStream<Uint8Array> :
|
||||
T extends NodeWebStream<infer X> ? NodeWebStream<Uint8Array> :
|
||||
Uint8Array
|
||||
}>;
|
||||
export function decrypt<T extends MaybeStream<Data>>(options: DecryptOptions & { message: Message<T> }): Promise<DecryptMessageResult & {
|
||||
data:
|
||||
T extends WebStream<infer X> ? WebStream<string> :
|
||||
T extends NodeStream<infer X> ? NodeStream<string> :
|
||||
T extends NodeWebStream<infer X> ? NodeWebStream<string> :
|
||||
string
|
||||
}>;
|
||||
|
||||
export function verify(options: VerifyOptions & { message: CleartextMessage, format?: 'utf8' }): Promise<VerifyMessageResult<string>>;
|
||||
export function verify<T extends MaybeStream<Data>>(options: VerifyOptions & { message: Message<T>, format: 'binary' }): Promise<VerifyMessageResult<
|
||||
T extends WebStream<infer X> ? WebStream<Uint8Array> :
|
||||
T extends NodeStream<infer X> ? NodeStream<Uint8Array> :
|
||||
T extends NodeWebStream<infer X> ? NodeWebStream<Uint8Array> :
|
||||
Uint8Array
|
||||
>>;
|
||||
export function verify<T extends MaybeStream<Data>>(options: VerifyOptions & { message: Message<T> }): Promise<VerifyMessageResult<
|
||||
T extends WebStream<infer X> ? WebStream<string> :
|
||||
T extends NodeStream<infer X> ? NodeStream<string> :
|
||||
T extends NodeWebStream<infer X> ? NodeWebStream<string> :
|
||||
string
|
||||
>>;
|
||||
|
||||
@ -305,7 +315,7 @@ export class Message<T extends MaybeStream<Data>> {
|
||||
}
|
||||
|
||||
|
||||
/* ############## v5 CONFIG #################### */
|
||||
/* ############## CONFIG #################### */
|
||||
|
||||
interface Config {
|
||||
preferredHashAlgorithm: enums.hash;
|
||||
@ -347,11 +357,11 @@ export var config: Config;
|
||||
|
||||
// PartialConfig has the same properties as Config, but declared as optional.
|
||||
// This interface is relevant for top-level functions, which accept a subset of configuration options
|
||||
interface PartialConfig extends Partial<Config> {}
|
||||
export interface PartialConfig extends Partial<Config> {}
|
||||
|
||||
/* ############## v5 PACKET #################### */
|
||||
/* ############## PACKET #################### */
|
||||
|
||||
declare abstract class BasePacket {
|
||||
export declare abstract class BasePacket {
|
||||
static readonly tag: enums.packet;
|
||||
public read(bytes: Uint8Array): void;
|
||||
public write(): Uint8Array;
|
||||
@ -561,16 +571,7 @@ export class PacketList<T extends AnyPacket> extends Array<T> {
|
||||
public findPacket(tag: enums.packet): T | undefined;
|
||||
}
|
||||
|
||||
/* ############## v5 STREAM #################### */
|
||||
|
||||
type Data = Uint8Array | string;
|
||||
export interface WebStream<T extends Data> extends GenericWebStream<T> {}
|
||||
export interface NodeStream<T extends Data> extends GenericNodeStream<T> {}
|
||||
export type Stream<T extends Data> = WebStream<T> | NodeStream<T>;
|
||||
export type MaybeStream<T extends Data> = T | Stream<T>;
|
||||
|
||||
/* ############## v5 GENERAL #################### */
|
||||
type MaybeArray<T> = T | Array<T>;
|
||||
/* ############## GENERAL #################### */
|
||||
|
||||
export interface UserID { name?: string; email?: string; comment?: string; }
|
||||
export interface SessionKey {
|
||||
@ -586,7 +587,7 @@ export interface DecryptedSessionKey {
|
||||
|
||||
export interface ReasonForRevocation { flag?: enums.reasonForRevocation, string?: string }
|
||||
|
||||
interface EncryptOptions {
|
||||
export interface EncryptOptions {
|
||||
/** message to be encrypted as created by createMessage */
|
||||
message: Message<MaybeStream<Data>>;
|
||||
/** (optional) array of keys or single key, used to encrypt the message */
|
||||
@ -618,7 +619,7 @@ interface EncryptOptions {
|
||||
config?: PartialConfig;
|
||||
}
|
||||
|
||||
interface DecryptOptions {
|
||||
export interface DecryptOptions {
|
||||
/** the message object with the encrypted data */
|
||||
message: Message<MaybeStream<Data>>;
|
||||
/** (optional) private keys with decrypted secret key data or session key */
|
||||
@ -640,7 +641,7 @@ interface DecryptOptions {
|
||||
config?: PartialConfig;
|
||||
}
|
||||
|
||||
interface SignOptions {
|
||||
export interface SignOptions {
|
||||
message: CleartextMessage | Message<MaybeStream<Data>>;
|
||||
signingKeys: MaybeArray<PrivateKey>;
|
||||
format?: 'armored' | 'binary' | 'object';
|
||||
@ -652,7 +653,7 @@ interface SignOptions {
|
||||
config?: PartialConfig;
|
||||
}
|
||||
|
||||
interface VerifyOptions {
|
||||
export interface VerifyOptions {
|
||||
/** (cleartext) message object with signatures */
|
||||
message: CleartextMessage | Message<MaybeStream<Data>>;
|
||||
/** array of publicKeys or single key, to verify signatures */
|
||||
@ -668,7 +669,7 @@ interface VerifyOptions {
|
||||
config?: PartialConfig;
|
||||
}
|
||||
|
||||
interface EncryptSessionKeyOptions extends SessionKey {
|
||||
export interface EncryptSessionKeyOptions extends SessionKey {
|
||||
encryptionKeys?: MaybeArray<PublicKey>,
|
||||
passwords?: MaybeArray<string>,
|
||||
format?: 'armored' | 'binary' | 'object',
|
||||
@ -704,7 +705,7 @@ interface GenerateKeyOptions {
|
||||
}
|
||||
export type KeyOptions = GenerateKeyOptions;
|
||||
|
||||
interface SubkeyOptions {
|
||||
export interface SubkeyOptions {
|
||||
type?: 'ecc' | 'rsa';
|
||||
curve?: EllipticCurveName;
|
||||
rsaBits?: number;
|
||||
@ -714,20 +715,20 @@ interface SubkeyOptions {
|
||||
config?: PartialConfig;
|
||||
}
|
||||
|
||||
declare class KeyID {
|
||||
export declare class KeyID {
|
||||
bytes: string;
|
||||
equals(keyID: KeyID, matchWildcard?: boolean): boolean;
|
||||
toHex(): string;
|
||||
static fromID(hex: string): KeyID;
|
||||
}
|
||||
|
||||
interface DecryptMessageResult {
|
||||
export interface DecryptMessageResult {
|
||||
data: MaybeStream<Data>;
|
||||
signatures: VerificationResult[];
|
||||
filename: string;
|
||||
}
|
||||
|
||||
interface VerifyMessageResult<T extends MaybeStream<Data> = MaybeStream<Data>> {
|
||||
export interface VerifyMessageResult<T extends MaybeStream<Data> = MaybeStream<Data>> {
|
||||
data: T;
|
||||
signatures: VerificationResult[];
|
||||
}
|
||||
|
97
package-lock.json
generated
97
package-lock.json
generated
@ -18,10 +18,10 @@
|
||||
"@openpgp/noble-hashes": "^1.3.3-0",
|
||||
"@openpgp/seek-bzip": "^1.0.5-git",
|
||||
"@openpgp/tweetnacl": "^1.0.4-1",
|
||||
"@openpgp/web-stream-tools": "^0.0.14",
|
||||
"@openpgp/web-stream-tools": "~0.1.1",
|
||||
"@rollup/plugin-alias": "^5.0.0",
|
||||
"@rollup/plugin-commonjs": "^24.0.1",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@rollup/plugin-node-resolve": "^15.2.1",
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@rollup/plugin-terser": "^0.4.0",
|
||||
"@rollup/plugin-wasm": "^6.1.2",
|
||||
@ -52,11 +52,11 @@
|
||||
"rollup": "^3.29.4",
|
||||
"sinon": "^15.1.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.1.2",
|
||||
"typescript": "^5.3.3",
|
||||
"web-streams-polyfill": "^3.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16.0.0"
|
||||
"node": ">= 16.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aashutoshrathi/word-wrap": {
|
||||
@ -630,10 +630,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@openpgp/web-stream-tools": {
|
||||
"version": "0.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.14.tgz",
|
||||
"integrity": "sha512-6btCNVf6YSsmlyIS7yw+IbzXeXCEcJxeSpxvSxkDuZj9B/ekt4fXkZj4oOaIxG4SKTftIK1svnlVroJ1cCMT4g==",
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.1.1.tgz",
|
||||
"integrity": "sha512-1WkV+z78S8DJNlUiCPxSjsna6gfAGCVuepL2KUDlBztXzhvplwWr4lAvsWcYzFkHykaFoCSOV9ssiRRq7QzydQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 16.5.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.2"
|
||||
},
|
||||
@ -729,9 +732,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-node-resolve": {
|
||||
"version": "15.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.2.tgz",
|
||||
"integrity": "sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg==",
|
||||
"version": "15.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz",
|
||||
"integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
@ -745,7 +748,7 @@
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^2.78.0||^3.0.0"
|
||||
"rollup": "^2.78.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
@ -1004,10 +1007,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "13.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.2.tgz",
|
||||
"integrity": "sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==",
|
||||
"dev": true
|
||||
"version": "20.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.4.tgz",
|
||||
"integrity": "sha512-6I0fMH8Aoy2lOejL3s4LhyIYX34DPwY8bl5xlNjBvUEk8OHrcuzsFt+Ied4LvJihbtXPM+8zUqdydfIti86v9g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/normalize-package-data": {
|
||||
"version": "2.4.3",
|
||||
@ -3145,9 +3151,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
@ -6486,16 +6492,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "4.9.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
||||
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
|
||||
"integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.2.0"
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/ua-parser-js": {
|
||||
@ -6544,6 +6550,12 @@
|
||||
"integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/union": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
|
||||
@ -7247,9 +7259,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@openpgp/web-stream-tools": {
|
||||
"version": "0.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.0.14.tgz",
|
||||
"integrity": "sha512-6btCNVf6YSsmlyIS7yw+IbzXeXCEcJxeSpxvSxkDuZj9B/ekt4fXkZj4oOaIxG4SKTftIK1svnlVroJ1cCMT4g==",
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@openpgp/web-stream-tools/-/web-stream-tools-0.1.1.tgz",
|
||||
"integrity": "sha512-1WkV+z78S8DJNlUiCPxSjsna6gfAGCVuepL2KUDlBztXzhvplwWr4lAvsWcYzFkHykaFoCSOV9ssiRRq7QzydQ==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
@ -7310,9 +7322,9 @@
|
||||
}
|
||||
},
|
||||
"@rollup/plugin-node-resolve": {
|
||||
"version": "15.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.2.tgz",
|
||||
"integrity": "sha512-Y35fRGUjC3FaurG722uhUuG8YHOJRJQbI6/CkbRkdPotSpDj9NtIN85z1zrcyDcCQIW4qp5mgG72U+gJ0TAFEg==",
|
||||
"version": "15.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz",
|
||||
"integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
@ -7531,10 +7543,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "13.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.2.tgz",
|
||||
"integrity": "sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A==",
|
||||
"dev": true
|
||||
"version": "20.11.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.4.tgz",
|
||||
"integrity": "sha512-6I0fMH8Aoy2lOejL3s4LhyIYX34DPwY8bl5xlNjBvUEk8OHrcuzsFt+Ied4LvJihbtXPM+8zUqdydfIti86v9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"@types/normalize-package-data": {
|
||||
"version": "2.4.3",
|
||||
@ -9186,9 +9201,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
@ -11718,9 +11733,9 @@
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.9.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
||||
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
|
||||
"integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
|
||||
"dev": true
|
||||
},
|
||||
"ua-parser-js": {
|
||||
@ -11753,6 +11768,12 @@
|
||||
"integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==",
|
||||
"dev": true
|
||||
},
|
||||
"undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||
"dev": true
|
||||
},
|
||||
"union": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
|
||||
|
@ -5,7 +5,7 @@
|
||||
"license": "LGPL-3.0+",
|
||||
"homepage": "https://openpgpjs.org/",
|
||||
"engines": {
|
||||
"node": ">= 16.0.0"
|
||||
"node": ">= 16.5.0"
|
||||
},
|
||||
"keywords": [
|
||||
"crypto",
|
||||
@ -68,10 +68,10 @@
|
||||
"@openpgp/noble-hashes": "^1.3.3-0",
|
||||
"@openpgp/seek-bzip": "^1.0.5-git",
|
||||
"@openpgp/tweetnacl": "^1.0.4-1",
|
||||
"@openpgp/web-stream-tools": "^0.0.14",
|
||||
"@openpgp/web-stream-tools": "~0.1.1",
|
||||
"@rollup/plugin-alias": "^5.0.0",
|
||||
"@rollup/plugin-commonjs": "^24.0.1",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@rollup/plugin-node-resolve": "^15.2.1",
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@rollup/plugin-terser": "^0.4.0",
|
||||
"@rollup/plugin-wasm": "^6.1.2",
|
||||
@ -102,7 +102,7 @@
|
||||
"rollup": "^3.29.4",
|
||||
"sinon": "^15.1.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.1.2",
|
||||
"typescript": "^5.3.3",
|
||||
"web-streams-polyfill": "^3.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -287,7 +287,7 @@ export async function encrypt({ message, encryptionKeys, signingKeys, passwords,
|
||||
if (!signingKeys) {
|
||||
signingKeys = [];
|
||||
}
|
||||
const streaming = message.fromStream;
|
||||
|
||||
try {
|
||||
if (signingKeys.length || signature) { // sign the message only if signing keys or signature is specified
|
||||
message = await message.sign(signingKeys, signature, signingKeyIDs, date, signingUserIDs, signatureNotations, config);
|
||||
@ -301,7 +301,7 @@ export async function encrypt({ message, encryptionKeys, signingKeys, passwords,
|
||||
// serialize data
|
||||
const armor = format === 'armored';
|
||||
const data = armor ? message.armor(config) : message.write();
|
||||
return convertStream(data, streaming, armor ? 'utf8' : 'binary');
|
||||
return convertStream(data);
|
||||
} catch (err) {
|
||||
throw util.wrapError('Error encrypting message', err);
|
||||
}
|
||||
@ -372,7 +372,7 @@ export async function decrypt({ message, decryptionKeys, passwords, sessionKeys,
|
||||
})
|
||||
]);
|
||||
}
|
||||
result.data = await convertStream(result.data, message.fromStream, format);
|
||||
result.data = await convertStream(result.data);
|
||||
return result;
|
||||
} catch (err) {
|
||||
throw util.wrapError('Error decrypting message', err);
|
||||
@ -438,7 +438,7 @@ export async function sign({ message, signingKeys, format = 'armored', detached
|
||||
]);
|
||||
});
|
||||
}
|
||||
return convertStream(signature, message.fromStream, armor ? 'utf8' : 'binary');
|
||||
return convertStream(signature);
|
||||
} catch (err) {
|
||||
throw util.wrapError('Error signing message', err);
|
||||
}
|
||||
@ -501,7 +501,7 @@ export async function verify({ message, verificationKeys, expectSigned = false,
|
||||
})
|
||||
]);
|
||||
}
|
||||
result.data = await convertStream(result.data, message.fromStream, format);
|
||||
result.data = await convertStream(result.data);
|
||||
return result;
|
||||
} catch (err) {
|
||||
throw util.wrapError('Error verifying signed message', err);
|
||||
@ -672,22 +672,15 @@ function toArray(param) {
|
||||
/**
|
||||
* Convert data to or from Stream
|
||||
* @param {Object} data - the data to convert
|
||||
* @param {'web'|'node'|false} streaming - Whether to return a ReadableStream, and of what type
|
||||
* @param {'utf8'|'binary'} [encoding] - How to return data in Node Readable streams
|
||||
* @returns {Promise<Object>} The data in the respective format.
|
||||
* @async
|
||||
* @private
|
||||
*/
|
||||
async function convertStream(data, streaming, encoding = 'utf8') {
|
||||
async function convertStream(data) {
|
||||
const streamType = util.isStream(data);
|
||||
if (streamType === 'array') {
|
||||
return stream.readToEnd(data);
|
||||
}
|
||||
if (streaming === 'node') {
|
||||
data = stream.webToNode(data);
|
||||
if (encoding !== 'binary') data.setEncoding(encoding);
|
||||
return data;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -143,29 +143,10 @@ export default CompressedDataPacket;
|
||||
// //
|
||||
//////////////////////////
|
||||
|
||||
|
||||
const nodeZlib = util.getNodeZlib();
|
||||
|
||||
function uncompressed(data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
function node_zlib(func, create, options = {}) {
|
||||
return function (data) {
|
||||
if (!util.isStream(data) || stream.isArrayStream(data)) {
|
||||
return stream.fromAsync(() => stream.readToEnd(data).then(data => {
|
||||
return new Promise((resolve, reject) => {
|
||||
func(data, options, (err, result) => {
|
||||
if (err) return reject(err);
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
}));
|
||||
}
|
||||
return stream.nodeToWeb(stream.webToNode(data).pipe(create(options)));
|
||||
};
|
||||
}
|
||||
|
||||
function fflate_zlib(ZlibStreamedConstructor, options) {
|
||||
return data => {
|
||||
if (!util.isStream(data) || stream.isArrayStream(data)) {
|
||||
@ -216,20 +197,12 @@ function bzip2(func) {
|
||||
};
|
||||
}
|
||||
|
||||
const compress_fns = nodeZlib ? {
|
||||
zip: /*#__PURE__*/ (compressed, level) => node_zlib(nodeZlib.deflateRaw, nodeZlib.createDeflateRaw, { level })(compressed),
|
||||
zlib: /*#__PURE__*/ (compressed, level) => node_zlib(nodeZlib.deflate, nodeZlib.createDeflate, { level })(compressed)
|
||||
} : {
|
||||
const compress_fns = {
|
||||
zip: /*#__PURE__*/ (compressed, level) => fflate_zlib(Deflate, { level })(compressed),
|
||||
zlib: /*#__PURE__*/ (compressed, level) => fflate_zlib(Zlib, { level })(compressed)
|
||||
};
|
||||
|
||||
const decompress_fns = nodeZlib ? {
|
||||
uncompressed: uncompressed,
|
||||
zip: /*#__PURE__*/ node_zlib(nodeZlib.inflateRaw, nodeZlib.createInflateRaw),
|
||||
zlib: /*#__PURE__*/ node_zlib(nodeZlib.inflate, nodeZlib.createInflate),
|
||||
bzip2: /*#__PURE__*/ bzip2(BunzipDecode)
|
||||
} : {
|
||||
const decompress_fns = {
|
||||
uncompressed: uncompressed,
|
||||
zip: /*#__PURE__*/ fflate_zlib(Inflate),
|
||||
zlib: /*#__PURE__*/ fflate_zlib(Unzlib),
|
||||
|
@ -173,7 +173,7 @@ class MemoryBenchamrkSuite {
|
||||
|
||||
const passwords = 'password';
|
||||
const config = { aeadProtect: false, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed };
|
||||
const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: new Uint8Array(ONE_MEGABYTE), numberOfChunks: 1 }));
|
||||
const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: new Uint8Array(ONE_MEGABYTE), numberOfChunks: 1 }));
|
||||
const plaintextMessage = await openpgp.createMessage({ binary: inputStream });
|
||||
assert(plaintextMessage.fromStream);
|
||||
|
||||
@ -183,10 +183,8 @@ class MemoryBenchamrkSuite {
|
||||
assert.ok(encryptedMessage.packets[1].version === 1);
|
||||
const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config });
|
||||
// read out output stream to trigger decryption
|
||||
await new Promise(resolve => {
|
||||
decryptedData.pipe(require('fs').createWriteStream('/dev/null'));
|
||||
decryptedData.on('end', resolve);
|
||||
});
|
||||
const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null'));
|
||||
await decryptedData.pipeTo(sink);
|
||||
});
|
||||
|
||||
suite.add('openpgp.encrypt/decrypt (CFB, text, with streaming)', async () => {
|
||||
@ -199,7 +197,7 @@ class MemoryBenchamrkSuite {
|
||||
|
||||
const passwords = 'password';
|
||||
const config = { aeadProtect: false, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed };
|
||||
const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 1 }));
|
||||
const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 1 }));
|
||||
const plaintextMessage = await openpgp.createMessage({ text: inputStream });
|
||||
assert(plaintextMessage.fromStream);
|
||||
|
||||
@ -209,10 +207,8 @@ class MemoryBenchamrkSuite {
|
||||
assert.ok(encryptedMessage.packets[1].version === 1);
|
||||
const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config });
|
||||
// read out output stream to trigger decryption
|
||||
await new Promise(resolve => {
|
||||
decryptedData.pipe(require('fs').createWriteStream('/dev/null'));
|
||||
decryptedData.on('end', resolve);
|
||||
});
|
||||
const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null'));
|
||||
await decryptedData.pipeTo(sink);
|
||||
});
|
||||
|
||||
suite.add('openpgp.encrypt/decrypt (AEAD, binary, with streaming)', async () => {
|
||||
@ -225,7 +221,7 @@ class MemoryBenchamrkSuite {
|
||||
|
||||
const passwords = 'password';
|
||||
const config = { aeadProtect: true, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed };
|
||||
const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: new Uint8Array(ONE_MEGABYTE), numberOfChunks: 1 }));
|
||||
const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: new Uint8Array(ONE_MEGABYTE), numberOfChunks: 1 }));
|
||||
const plaintextMessage = await openpgp.createMessage({ binary:inputStream });
|
||||
assert(plaintextMessage.fromStream);
|
||||
|
||||
@ -235,10 +231,8 @@ class MemoryBenchamrkSuite {
|
||||
assert.ok(encryptedMessage.packets[1].version === 2);
|
||||
const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config });
|
||||
// read out output stream to trigger decryption
|
||||
await new Promise(resolve => {
|
||||
decryptedData.pipe(require('fs').createWriteStream('/dev/null'));
|
||||
decryptedData.on('end', resolve);
|
||||
});
|
||||
const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null'));
|
||||
await decryptedData.pipeTo(sink);
|
||||
});
|
||||
|
||||
suite.add('openpgp.encrypt/decrypt (AEAD, text, with streaming)', async () => {
|
||||
@ -251,7 +245,7 @@ class MemoryBenchamrkSuite {
|
||||
|
||||
const passwords = 'password';
|
||||
const config = { aeadProtect: true, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed };
|
||||
const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 1 }));
|
||||
const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 1 }));
|
||||
const plaintextMessage = await openpgp.createMessage({ text: inputStream });
|
||||
assert(plaintextMessage.fromStream);
|
||||
|
||||
@ -261,10 +255,8 @@ class MemoryBenchamrkSuite {
|
||||
assert.ok(encryptedMessage.packets[1].version === 2);
|
||||
const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config });
|
||||
// read out output stream to trigger decryption
|
||||
await new Promise(resolve => {
|
||||
decryptedData.pipe(require('fs').createWriteStream('/dev/null'));
|
||||
decryptedData.on('end', resolve);
|
||||
});
|
||||
const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null'));
|
||||
await decryptedData.pipeTo(sink);
|
||||
});
|
||||
|
||||
suite.add('openpgp.encrypt/decrypt (CFB, text @ 10MB, with streaming)', async () => {
|
||||
@ -277,7 +269,7 @@ class MemoryBenchamrkSuite {
|
||||
|
||||
const passwords = 'password';
|
||||
const config = { aeadProtect: false, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed };
|
||||
const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 20 }));
|
||||
const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 20 }));
|
||||
const plaintextMessage = await openpgp.createMessage({ text: inputStream });
|
||||
assert(plaintextMessage.fromStream);
|
||||
|
||||
@ -287,10 +279,8 @@ class MemoryBenchamrkSuite {
|
||||
assert.ok(encryptedMessage.packets[1].version === 1);
|
||||
const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config });
|
||||
// read out output stream to trigger decryption
|
||||
await new Promise(resolve => {
|
||||
decryptedData.pipe(require('fs').createWriteStream('/dev/null'));
|
||||
decryptedData.on('end', resolve);
|
||||
});
|
||||
const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null'));
|
||||
await decryptedData.pipeTo(sink);
|
||||
});
|
||||
|
||||
suite.add('openpgp.encrypt/decrypt (CFB, text @ 10MB, with unauthenticated streaming)', async () => {
|
||||
@ -303,7 +293,7 @@ class MemoryBenchamrkSuite {
|
||||
|
||||
const passwords = 'password';
|
||||
const config = { aeadProtect: false, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed };
|
||||
const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 20 }));
|
||||
const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 20 }));
|
||||
const plaintextMessage = await openpgp.createMessage({ text: inputStream });
|
||||
assert(plaintextMessage.fromStream);
|
||||
|
||||
@ -317,10 +307,8 @@ class MemoryBenchamrkSuite {
|
||||
config: { ...config, allowUnauthenticatedStream: true }
|
||||
});
|
||||
// read out output stream to trigger decryption
|
||||
await new Promise(resolve => {
|
||||
decryptedData.pipe(require('fs').createWriteStream('/dev/null'));
|
||||
decryptedData.on('end', resolve);
|
||||
});
|
||||
const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null'));
|
||||
await decryptedData.pipeTo(sink);
|
||||
});
|
||||
|
||||
suite.add('openpgp.encrypt/decrypt (AEAD, text @ 10MB, with streaming)', async () => {
|
||||
@ -333,7 +321,7 @@ class MemoryBenchamrkSuite {
|
||||
|
||||
const passwords = 'password';
|
||||
const config = { aeadProtect: true, preferredCompressionAlgorithm: openpgp.enums.compression.uncompressed };
|
||||
const inputStream = require('stream').Readable.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 20 }));
|
||||
const inputStream = require('stream/web').ReadableStream.from(largeDataGenerator({ chunk: 'a'.repeat(ONE_MEGABYTE / 2), numberOfChunks: 20 }));
|
||||
const plaintextMessage = await openpgp.createMessage({ text: inputStream });
|
||||
assert(plaintextMessage.fromStream);
|
||||
|
||||
@ -343,10 +331,8 @@ class MemoryBenchamrkSuite {
|
||||
assert.ok(encryptedMessage.packets[1].version === 2);
|
||||
const { data: decryptedData } = await openpgp.decrypt({ message: encryptedMessage, passwords, config });
|
||||
// read out output stream to trigger decryption
|
||||
await new Promise(resolve => {
|
||||
decryptedData.pipe(require('fs').createWriteStream('/dev/null'));
|
||||
decryptedData.on('end', resolve);
|
||||
});
|
||||
const sink = require('stream').Writable.toWeb(require('fs').createWriteStream('/dev/null'));
|
||||
await decryptedData.pipeTo(sink);
|
||||
});
|
||||
|
||||
const stats = await suite.run();
|
||||
|
@ -3840,9 +3840,7 @@ XfA3pqV4mTzF
|
||||
packets.push(message.packets.findPacket(openpgp.enums.packet.signature));
|
||||
packets.push(message.packets.findPacket(openpgp.enums.packet.literalData));
|
||||
verifyOpt.message = await openpgp.readMessage({
|
||||
binaryMessage: stream[
|
||||
globalThis.ReadableStream ? 'toStream' : 'webToNode'
|
||||
](packets.write())
|
||||
binaryMessage: stream.toStream(packets.write())
|
||||
});
|
||||
return openpgp.verify(verifyOpt);
|
||||
}).then(async function (verified) {
|
||||
|
@ -416,7 +416,7 @@ function tests() {
|
||||
expect(stream.isStream(encrypted)).to.equal(expectedType);
|
||||
|
||||
const message = await openpgp.readMessage({
|
||||
armoredMessage: stream[expectedType === 'node' ? 'webToNode' : 'toStream'](stream.transform(encrypted, value => {
|
||||
armoredMessage: stream.toStream(stream.transform(encrypted, value => {
|
||||
value += '';
|
||||
const newlineIndex = value.indexOf('\n', 500);
|
||||
if (value.length > 1000) return value.slice(0, newlineIndex - 1) + (value[newlineIndex - 1] === 'a' ? 'b' : 'a') + value.slice(newlineIndex);
|
||||
@ -453,7 +453,7 @@ function tests() {
|
||||
expect(stream.isStream(encrypted)).to.equal(expectedType);
|
||||
|
||||
const message = await openpgp.readMessage({
|
||||
armoredMessage: stream[expectedType === 'node' ? 'webToNode' : 'toStream'](stream.transform(encrypted, value => {
|
||||
armoredMessage: stream.toStream(stream.transform(encrypted, value => {
|
||||
value += '';
|
||||
const newlineIndex = value.indexOf('\n', 500);
|
||||
if (value.length > 1000) return value.slice(0, newlineIndex - 1) + (value[newlineIndex - 1] === 'a' ? 'b' : 'a') + value.slice(newlineIndex);
|
||||
@ -486,7 +486,7 @@ function tests() {
|
||||
expect(stream.isStream(signed)).to.equal(expectedType);
|
||||
|
||||
const message = await openpgp.readMessage({
|
||||
armoredMessage: stream[expectedType === 'node' ? 'webToNode' : 'toStream'](stream.transform(signed, value => {
|
||||
armoredMessage: stream.toStream(stream.transform(signed, value => {
|
||||
value += '';
|
||||
const newlineIndex = value.indexOf('\n', 500);
|
||||
if (value.length > 1000) return value.slice(0, newlineIndex - 1) + (value[newlineIndex - 1] === 'a' ? 'b' : 'a') + value.slice(newlineIndex);
|
||||
@ -872,6 +872,7 @@ function tests() {
|
||||
|
||||
export default () => describe('Streaming', function() {
|
||||
let currentTest = 0;
|
||||
const needsStreamPolyfills = !globalThis.ReadableStream;
|
||||
|
||||
before(async function() {
|
||||
pubKey = await openpgp.readKey({ armoredKey: pub_key });
|
||||
@ -916,40 +917,41 @@ export default () => describe('Streaming', function() {
|
||||
|
||||
tests();
|
||||
|
||||
if (detectNode()) {
|
||||
if (detectNode() && !needsStreamPolyfills) { // ReadableStream polyfills interfere with these tests
|
||||
const fs = util.nodeRequire('fs');
|
||||
const { Readable: NodeReadableStream } = util.nodeRequire('stream');
|
||||
const { fileURLToPath } = util.nodeRequire('url');
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
|
||||
it('Node: Encrypt and decrypt text message roundtrip', async function() {
|
||||
dataArrived(); // Do not wait until data arrived.
|
||||
const plaintext = fs.readFileSync(__filename.replace('streaming.js', 'openpgp.js'), 'utf8'); // eslint-disable-line no-sync
|
||||
const data = fs.createReadStream(__filename.replace('streaming.js', 'openpgp.js'), { encoding: 'utf8' });
|
||||
const data = NodeReadableStream.toWeb(fs.createReadStream(__filename.replace('streaming.js', 'openpgp.js'), { encoding: 'utf8' }));
|
||||
const encrypted = await openpgp.encrypt({
|
||||
message: await openpgp.createMessage({ text: data }),
|
||||
passwords: ['test']
|
||||
});
|
||||
expect(stream.isStream(encrypted)).to.equal('node');
|
||||
expect(stream.isStream(encrypted)).to.equal('web');
|
||||
|
||||
const message = await openpgp.readMessage({ armoredMessage: encrypted });
|
||||
const decrypted = await openpgp.decrypt({
|
||||
passwords: ['test'],
|
||||
message
|
||||
});
|
||||
expect(stream.isStream(decrypted.data)).to.equal('node');
|
||||
expect(stream.isStream(decrypted.data)).to.equal('web');
|
||||
expect(await stream.readToEnd(decrypted.data)).to.equal(plaintext);
|
||||
});
|
||||
|
||||
it('Node: Encrypt and decrypt binary message roundtrip', async function() {
|
||||
dataArrived(); // Do not wait until data arrived.
|
||||
const plaintext = fs.readFileSync(__filename.replace('streaming.js', 'openpgp.js')); // eslint-disable-line no-sync
|
||||
const data = fs.createReadStream(__filename.replace('streaming.js', 'openpgp.js'));
|
||||
const data = NodeReadableStream.toWeb(fs.createReadStream(__filename.replace('streaming.js', 'openpgp.js')));
|
||||
const encrypted = await openpgp.encrypt({
|
||||
message: await openpgp.createMessage({ binary: data }),
|
||||
passwords: ['test'],
|
||||
format: 'binary'
|
||||
});
|
||||
expect(stream.isStream(encrypted)).to.equal('node');
|
||||
expect(stream.isStream(encrypted)).to.equal('web');
|
||||
|
||||
const message = await openpgp.readMessage({ binaryMessage: encrypted });
|
||||
const decrypted = await openpgp.decrypt({
|
||||
@ -957,7 +959,7 @@ export default () => describe('Streaming', function() {
|
||||
message,
|
||||
format: 'binary'
|
||||
});
|
||||
expect(stream.isStream(decrypted.data)).to.equal('node');
|
||||
expect(stream.isStream(decrypted.data)).to.equal('web');
|
||||
expect(await stream.readToEnd(decrypted.data)).to.deep.equal(plaintext);
|
||||
});
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
*/
|
||||
import { ReadableStream as WebReadableStream } from 'web-streams-polyfill';
|
||||
import { createReadStream } from 'fs';
|
||||
import { Readable as NodeNativeReadableStream } from 'stream';
|
||||
|
||||
import { expect } from 'chai';
|
||||
import {
|
||||
@ -15,7 +16,7 @@ import {
|
||||
encrypt, decrypt, sign, verify, config, enums,
|
||||
generateSessionKey, encryptSessionKey, decryptSessionKeys,
|
||||
LiteralDataPacket, PacketList, CompressedDataPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, CleartextMessage,
|
||||
WebStream, NodeStream,
|
||||
WebStream, NodeWebStream,
|
||||
} from 'openpgp';
|
||||
|
||||
(async () => {
|
||||
@ -207,9 +208,9 @@ import {
|
||||
|
||||
// Streaming - encrypt text message (armored output)
|
||||
try {
|
||||
const nodeTextStream = createReadStream('non-existent-file', { encoding: 'utf8' });
|
||||
const nodeTextStream = NodeNativeReadableStream.toWeb(createReadStream('non-existent-file', { encoding: 'utf8' }));
|
||||
const messageFromNodeTextStream = await createMessage({ text: nodeTextStream });
|
||||
(await encrypt({ message: messageFromNodeTextStream, passwords: 'password', format: 'armored' })) as NodeStream<string>;
|
||||
(await encrypt({ message: messageFromNodeTextStream, passwords: 'password', format: 'armored' })) as NodeWebStream<string>;
|
||||
} catch (err) {}
|
||||
const webTextStream = new WebReadableStream<string>();
|
||||
const messageFromWebTextStream = await createMessage({ text: webTextStream });
|
||||
@ -219,9 +220,9 @@ import {
|
||||
|
||||
// Streaming - encrypt binary message (binary output)
|
||||
try {
|
||||
const nodeBinaryStream = createReadStream('non-existent-file');
|
||||
const nodeBinaryStream = NodeNativeReadableStream.toWeb(createReadStream('non-existent-file'));
|
||||
const messageFromNodeBinaryStream = await createMessage({ binary: nodeBinaryStream });
|
||||
(await encrypt({ message: messageFromNodeBinaryStream, passwords: 'password', format: 'binary' })) as NodeStream<Uint8Array>;
|
||||
(await encrypt({ message: messageFromNodeBinaryStream, passwords: 'password', format: 'binary' })) as NodeWebStream<Uint8Array>;
|
||||
} catch (err) {}
|
||||
const webBinaryStream = new WebReadableStream<Uint8Array>();
|
||||
const messageFromWebBinaryStream = await createMessage({ binary: webBinaryStream });
|
||||
|
@ -27,7 +27,10 @@ globalThis.tryTests = function(name, tests, options) {
|
||||
};
|
||||
|
||||
globalThis.loadStreamsPolyfill = function() {
|
||||
return import('web-streams-polyfill');
|
||||
// do not polyfill Node
|
||||
const detectNodeWebStreams = () => typeof globalThis.process === 'object' && typeof globalThis.process.versions === 'object' && globalThis.ReadableStream;
|
||||
|
||||
return detectNodeWebStreams() || import('web-streams-polyfill');
|
||||
};
|
||||
|
||||
import runWorkerTests from './worker';
|
||||
|
Loading…
x
Reference in New Issue
Block a user