From 00a2a1012918574648905f64d3f1707cae21c275 Mon Sep 17 00:00:00 2001 From: David Mihalcik Date: Mon, 21 Oct 2024 20:19:15 -0400 Subject: [PATCH] fix(sdk): Remove stray call to node:Buffer Update assertion.ts fix(lib): Removes all refs to node:buffer I could find - removes the polyfill from the web-test-runner, to make sure we aren't accidentally including it (at least in things that covers) - updates all .spec and .test files, in turn - renames a bunch of things called `buffer` to something else so I can search for this easier Update cli.ts --- cli/package-lock.json | 53 ++----------------- cli/src/cli.ts | 12 +++-- lib/package-lock.json | 24 +-------- lib/package.json | 1 - lib/src/nanotdf/models/Header.ts | 20 +++---- lib/src/nanotdf/models/Payload.ts | 12 ++--- .../nanotdf/models/Policy/EmbeddedPolicy.ts | 12 ++--- lib/src/nanotdf/models/Policy/RemotePolicy.ts | 10 ++-- lib/src/nanotdf/models/ResourceLocator.ts | 12 ++--- lib/src/nanotdf/models/Signature.ts | 8 +-- lib/tdf3/src/ciphers/aes-gcm-cipher.ts | 8 +-- lib/tdf3/src/client/builders.ts | 29 +++++----- lib/tdf3/src/tdf.ts | 2 +- lib/tdf3/src/utils/chunkers.ts | 4 +- lib/tdf3/src/utils/index.ts | 18 +++---- lib/tdf3/src/utils/zip-reader.ts | 11 ++-- lib/tests/mocha/unit/keysplits.spec.ts | 4 +- lib/tests/mocha/unit/tdf.spec.ts | 8 +-- lib/tests/mocha/unit/zip.spec.ts | 11 ++-- lib/tests/server.ts | 18 +++++-- lib/webpack.test.config.cjs | 5 -- remote-store/package-lock.json | 53 ++----------------- web-app/package-lock.json | 24 +++++---- 23 files changed, 125 insertions(+), 234 deletions(-) diff --git a/cli/package-lock.json b/cli/package-lock.json index 407e104c..ea4320a5 100644 --- a/cli/package-lock.json +++ b/cli/package-lock.json @@ -36,9 +36,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", - "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -372,14 +372,13 @@ "node_modules/@opentdf/client": { "version": "2.1.0", "resolved": "file:../lib/opentdf-client-2.1.0.tgz", - "integrity": "sha512-Us1uiGHNgs8dZDyfVutDVyo2vXISJOBfxtUTknOOgrnZuz8ZvJtoNvTLb+QW9ha4wdW1eQaiu7bogxlYbOcGAA==", + "integrity": "sha512-1KZVuJLh+MBXPwAx/RiDw0clFvbFqLDaqfi4T5rMgKlFJ4rNX5immyQcZnu7YS8degBed/4CHONgvFya33NGFA==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", @@ -973,30 +972,6 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -1844,26 +1819,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", diff --git a/cli/src/cli.ts b/cli/src/cli.ts index fd066c47..10755f69 100644 --- a/cli/src/cli.ts +++ b/cli/src/cli.ts @@ -19,6 +19,7 @@ import { import { CLIError, Level, log } from './logger.js'; import { webcrypto } from 'crypto'; import { attributeFQNsAsValues } from '@opentdf/client/nano'; +import { base64 } from '@opentdf/client/encodings'; type AuthToProcess = { auth?: string; @@ -37,8 +38,9 @@ const bindingTypes = ['ecdsa', 'gmac']; const containerTypes = ['tdf3', 'nano', 'dataset', 'ztdf']; const parseJwt = (jwt: string, field = 1) => { - return JSON.parse(Buffer.from(jwt.split('.')[field], 'base64').toString()); + return JSON.parse(base64.decode(jwt.split('.')[field])); }; + const parseJwtComplete = (jwt: string) => { return { header: parseJwt(jwt, 0), payload: parseJwt(jwt) }; }; @@ -413,9 +415,9 @@ export const handleArgs = (args: string[]) => { log('DEBUG', 'Handle output.'); if (argv.output) { - await writeFile(argv.output, Buffer.from(plaintext)); + await writeFile(argv.output, new Uint8Array(plaintext)); } else { - console.log(Buffer.from(plaintext).toString('utf8')); + console.log(new TextDecoder().decode(plaintext)); } } const lastRequest = authProvider.requestLog[authProvider.requestLog.length - 1]; @@ -503,9 +505,9 @@ export const handleArgs = (args: string[]) => { log('DEBUG', `Handle cyphertext output ${JSON.stringify(cyphertext)}`); if (argv.output) { - await writeFile(argv.output, Buffer.from(cyphertext)); + await writeFile(argv.output, new Uint8Array(cyphertext)); } else { - console.log(Buffer.from(cyphertext).toString('base64')); + console.log(base64.encodeArrayBuffer(cyphertext)); } } } diff --git a/lib/package-lock.json b/lib/package-lock.json index 9fb728a9..0267c2b5 100644 --- a/lib/package-lock.json +++ b/lib/package-lock.json @@ -13,7 +13,6 @@ "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", @@ -2676,28 +2675,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "6.0.3", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/buffer-crc32": { "version": "0.2.13", "license": "MIT", @@ -5148,6 +5125,7 @@ }, "node_modules/ieee754": { "version": "1.2.1", + "dev": true, "funding": [ { "type": "github", diff --git a/lib/package.json b/lib/package.json index f9e8da2e..6e7d0539 100644 --- a/lib/package.json +++ b/lib/package.json @@ -64,7 +64,6 @@ "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", diff --git a/lib/src/nanotdf/models/Header.ts b/lib/src/nanotdf/models/Header.ts index 7a11d7c3..71577e3e 100644 --- a/lib/src/nanotdf/models/Header.ts +++ b/lib/src/nanotdf/models/Header.ts @@ -232,20 +232,20 @@ export default class Header { /** * Copy the contents of the header to buffer */ - copyToBuffer(buffer: Uint8Array): void { - if (this.length > buffer.length) { + copyToBuffer(target: Uint8Array): void { + if (this.length > target.length) { throw new InvalidFileError('invalid buffer size to copy tdf header'); } let offset = 0; // Write Magic number and version - buffer.set(this.magicNumberVersion, 0); + target.set(this.magicNumberVersion, 0); offset += this.magicNumberVersion.length; // Write kas resource locator const kasResourceLocatorBuf = this.kas.toBuffer(); - buffer.set(kasResourceLocatorBuf, offset); + target.set(kasResourceLocatorBuf, offset); offset += kasResourceLocatorBuf.length; // Write ECC & Binding Mode @@ -253,7 +253,7 @@ export default class Header { const eccBingingMode = (ecdsaBinding << 7) | this.ephemeralCurveName; const eccBingingModeAsByte = new Uint8Array(1); eccBingingModeAsByte[0] = eccBingingMode; - buffer.set(eccBingingModeAsByte, offset); + target.set(eccBingingModeAsByte, offset); offset += eccBingingModeAsByte.length; // Write symmetric & payload config @@ -262,16 +262,16 @@ export default class Header { (isSignatureEnable << 7) | this.signatureCurveName | this.symmetricCipher; const symmetricPayloadConfigAsByte = new Uint8Array(1); symmetricPayloadConfigAsByte[0] = symmetricPayloadConfig; - buffer.set(symmetricPayloadConfigAsByte, offset); + target.set(symmetricPayloadConfigAsByte, offset); offset += symmetricPayloadConfigAsByte.length; // Write the policy const policyBuffer = this.policy.toBuffer(); - buffer.set(policyBuffer, offset); + target.set(policyBuffer, offset); offset += policyBuffer.length; // Write the ephemeral public key - buffer.set(this.ephemeralPublicKey, offset); + target.set(this.ephemeralPublicKey, offset); } /** @@ -304,8 +304,8 @@ export default class Header { */ toBuffer(): ArrayBuffer { const arrayBuffer = new ArrayBuffer(this.length); - const buffer = new Uint8Array(arrayBuffer); - this.copyToBuffer(buffer); + const target = new Uint8Array(arrayBuffer); + this.copyToBuffer(target); return arrayBuffer; } diff --git a/lib/src/nanotdf/models/Payload.ts b/lib/src/nanotdf/models/Payload.ts index 37645a82..55ae7336 100644 --- a/lib/src/nanotdf/models/Payload.ts +++ b/lib/src/nanotdf/models/Payload.ts @@ -167,8 +167,8 @@ export default class Payload { /** * Copy the contents of the signature to buffer */ - copyToBuffer(buffer: Uint8Array): void { - if (this.length > buffer.length) { + copyToBuffer(target: Uint8Array): void { + if (this.length > target.length) { throw new Error('internal: invalid buffer size to copy payload'); } @@ -188,9 +188,9 @@ export default class Payload { payloadSizeAsBg[1] = lengthAsUint24[1]; payloadSizeAsBg[2] = lengthAsUint24[0]; - buffer.set(payloadSizeAsBg, 0); - buffer.set(this.iv, payloadSizeAsBg.length); - buffer.set(this.ciphertext, payloadSizeAsBg.length + this.iv.length); - buffer.set(this.authTag, payloadSizeAsBg.length + this.iv.length + this.ciphertext.length); + target.set(payloadSizeAsBg, 0); + target.set(this.iv, payloadSizeAsBg.length); + target.set(this.ciphertext, payloadSizeAsBg.length + this.iv.length); + target.set(this.authTag, payloadSizeAsBg.length + this.iv.length + this.ciphertext.length); } } diff --git a/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts b/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts index 3b8c3de4..321b760b 100644 --- a/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts +++ b/lib/src/nanotdf/models/Policy/EmbeddedPolicy.ts @@ -69,13 +69,13 @@ class EmbeddedPolicy extends AbstractPolicy implements EmbeddedPolicyInterface { * Return the content of the policy */ override toBuffer(): Uint8Array { - const buffer = new Uint8Array(this.getLength()); + const target = new Uint8Array(this.getLength()); if (this.content.length > EmbeddedPolicy.MAX_POLICY_SIZE) { throw new ConfigurationError("TDF Policy can't be more that 2^16"); } - buffer.set([this.type], 0); + target.set([this.type], 0); // Write the policy length, assuming the host system is little endian // TODO: There should be better way to convert to big endian @@ -86,15 +86,15 @@ class EmbeddedPolicy extends AbstractPolicy implements EmbeddedPolicyInterface { const policyContentSizeAsBg = new Uint8Array(2); policyContentSizeAsBg[0] = temp[1]; policyContentSizeAsBg[1] = temp[0]; - buffer.set(policyContentSizeAsBg, 1); + target.set(policyContentSizeAsBg, 1); // Write the policy content - buffer.set(this.content, policyContentSizeAsBg.length + 1); + target.set(this.content, policyContentSizeAsBg.length + 1); // Write the binding. - buffer.set(this.binding, this.content.length + policyContentSizeAsBg.length + 1); + target.set(this.binding, this.content.length + policyContentSizeAsBg.length + 1); - return buffer; + return target; } } diff --git a/lib/src/nanotdf/models/Policy/RemotePolicy.ts b/lib/src/nanotdf/models/Policy/RemotePolicy.ts index 59131533..0a94c472 100644 --- a/lib/src/nanotdf/models/Policy/RemotePolicy.ts +++ b/lib/src/nanotdf/models/Policy/RemotePolicy.ts @@ -56,18 +56,18 @@ class RemotePolicy extends AbstractPolicy implements RemotePolicyInterface { * Return the content of the policy */ override toBuffer(): Uint8Array { - const buffer = new Uint8Array(this.getLength()); + const target = new Uint8Array(this.getLength()); - buffer.set([PolicyTypeEnum.Remote], 0); + target.set([PolicyTypeEnum.Remote], 0); // Write the remote policy location const resourceLocatorAsBuf = this.remotePolicy.toBuffer(); - buffer.set(resourceLocatorAsBuf, 1); + target.set(resourceLocatorAsBuf, 1); // Write the binding. - buffer.set(this.binding, resourceLocatorAsBuf.length + 1); + target.set(this.binding, resourceLocatorAsBuf.length + 1); - return buffer; + return target; } } diff --git a/lib/src/nanotdf/models/ResourceLocator.ts b/lib/src/nanotdf/models/ResourceLocator.ts index 0944407c..efd1aa9f 100644 --- a/lib/src/nanotdf/models/ResourceLocator.ts +++ b/lib/src/nanotdf/models/ResourceLocator.ts @@ -178,7 +178,7 @@ export default class ResourceLocator { * Return the contents of the Resource Locator in buffer */ toBuffer(): Uint8Array { - const buffer = new Uint8Array(ResourceLocator.BODY_OFFSET + this.body.length + this.idType); + const target = new Uint8Array(ResourceLocator.BODY_OFFSET + this.body.length + this.idType); let idTypeNibble = 0; switch (this.idType) { case ResourceLocatorIdentifierEnum.TwoBytes: @@ -191,13 +191,13 @@ export default class ResourceLocator { idTypeNibble = ResourceLocator.IDENTIFIER_32_BYTE; break; } - buffer.set([this.protocol | idTypeNibble], ResourceLocator.PROTOCOL_OFFSET); - buffer.set([this.lengthOfBody], ResourceLocator.LENGTH_OFFSET); - buffer.set(new TextEncoder().encode(this.body), ResourceLocator.BODY_OFFSET); + target.set([this.protocol | idTypeNibble], ResourceLocator.PROTOCOL_OFFSET); + target.set([this.lengthOfBody], ResourceLocator.LENGTH_OFFSET); + target.set(new TextEncoder().encode(this.body), ResourceLocator.BODY_OFFSET); if (this.id) { - buffer.set(new TextEncoder().encode(this.id), ResourceLocator.BODY_OFFSET + this.body.length); + target.set(new TextEncoder().encode(this.id), ResourceLocator.BODY_OFFSET + this.body.length); } - return buffer; + return target; } /** diff --git a/lib/src/nanotdf/models/Signature.ts b/lib/src/nanotdf/models/Signature.ts index 05610bbf..091b6283 100644 --- a/lib/src/nanotdf/models/Signature.ts +++ b/lib/src/nanotdf/models/Signature.ts @@ -74,12 +74,12 @@ export default class Signature { /** * Copy the contents of the signature to buffer */ - copyToBuffer(buffer: Uint8Array): void { - if (this.length > buffer.length) { + copyToBuffer(target: Uint8Array): void { + if (this.length > target.length) { throw new ConfigurationError('Invalid buffer size to copy signature'); } - buffer.set(this.publicKey, 0); - buffer.set(this.signature, this.publicKey.length); + target.set(this.publicKey, 0); + target.set(this.signature, this.publicKey.length); } } diff --git a/lib/tdf3/src/ciphers/aes-gcm-cipher.ts b/lib/tdf3/src/ciphers/aes-gcm-cipher.ts index 3797ad36..dade0160 100644 --- a/lib/tdf3/src/ciphers/aes-gcm-cipher.ts +++ b/lib/tdf3/src/ciphers/aes-gcm-cipher.ts @@ -18,15 +18,15 @@ type ProcessGcmPayload = { payloadAuthTag: Binary; }; // Should this be a Binary, Buffer, or... both? -function processGcmPayload(buffer: ArrayBuffer): ProcessGcmPayload { +function processGcmPayload(source: ArrayBuffer): ProcessGcmPayload { // Read the 12 byte IV from the beginning of the stream - const payloadIv = Binary.fromArrayBuffer(buffer.slice(0, 12)); + const payloadIv = Binary.fromArrayBuffer(source.slice(0, 12)); // Slice the final 16 bytes of the buffer for the authentication tag - const payloadAuthTag = Binary.fromArrayBuffer(buffer.slice(-16)); + const payloadAuthTag = Binary.fromArrayBuffer(source.slice(-16)); return { - payload: Binary.fromArrayBuffer(buffer.slice(12, -16)), + payload: Binary.fromArrayBuffer(source.slice(12, -16)), payloadIv, payloadAuthTag, }; diff --git a/lib/tdf3/src/client/builders.ts b/lib/tdf3/src/client/builders.ts index 10752d63..5eb382ce 100644 --- a/lib/tdf3/src/client/builders.ts +++ b/lib/tdf3/src/client/builders.ts @@ -149,7 +149,7 @@ class EncryptParamsBuilder { /** * Specify the content to encrypt, in buffer form. - * @param {Buffer} buf - a buffer to encrypt. + * @param buf to encrypt. */ setBufferSource(buf: ArrayBuffer) { const stream = new ReadableStream({ @@ -163,10 +163,9 @@ class EncryptParamsBuilder { /** * Specify the content to encrypt, in buffer form. Returns this object for method chaining. - * @param {Buffer} buf - a buffer to encrypt - * @return {EncryptParamsBuilder} - this object. + * @param buf - a buffer to encrypt */ - withBufferSource(buf: ArrayBuffer) { + withBufferSource(buf: ArrayBuffer): this { this.setBufferSource(buf); return this; } @@ -554,7 +553,7 @@ class DecryptParamsBuilder { /** * Set the TDF ciphertext to decrypt, in buffer form. - * @param {Buffer} buffer - a buffer to decrypt. + * @param buffer to decrypt. */ setBufferSource(buffer: Uint8Array) { this._params.source = { type: 'buffer', location: buffer }; @@ -562,10 +561,9 @@ class DecryptParamsBuilder { /** * Set the TDF ciphertext to decrypt, in buffer form. Returns this object for method chaining. - * @param {Buffer} buffer - a buffer to decrypt. - * @return {DecryptParamsBuilder} - this object. + * @param buffer to decrypt. */ - withBufferSource(buffer: Uint8Array): DecryptParamsBuilder { + withBufferSource(buffer: Uint8Array): this { this.setBufferSource(buffer); return this; } @@ -587,7 +585,7 @@ class DecryptParamsBuilder { * @param {string} url - a tdf3 remote URL. * @return {DecryptParamsBuilder} - this object. */ - withUrlSource(url: string): DecryptParamsBuilder { + withUrlSource(url: string): this { this.setUrlSource(url); return this; } @@ -602,10 +600,9 @@ class DecryptParamsBuilder { /** * Specify the TDF ciphertext to decrypt, in stream form. Returns this object for method chaining. - * @param {Readable} stream - a Readable stream to decrypt. - * @return {DecryptParamsBuilder} - this object. + * @param stream to decrypt. */ - withStreamSource(stream: ReadableStream) { + withStreamSource(stream: ReadableStream): this { if (!stream?.getReader) { throw new ConfigurationError( `Source must be a WebReadableStream. Run node streams through stream.Readable.toWeb()` @@ -621,7 +618,7 @@ class DecryptParamsBuilder { * @param {string} string - a string to decrypt. */ setStringSource(string: string) { - this.setBufferSource(Buffer.from(string, 'binary')); + this.setBufferSource(new TextEncoder().encode(string)); } /** @@ -629,7 +626,7 @@ class DecryptParamsBuilder { * @param {string} string - a string to decrypt. * @return {DecryptParamsBuilder} - this object. */ - withStringSource(string: string): DecryptParamsBuilder { + withStringSource(string: string): this { this.setStringSource(string); return this; } @@ -648,7 +645,7 @@ class DecryptParamsBuilder { * Returns this object for method chaining. * @param source (node) the path of the local file to decrypt, or the Blob (browser/node) */ - withFileSource(source: Blob): DecryptParamsBuilder { + withFileSource(source: Blob): this { this.setFileSource(source); return this; } @@ -672,7 +669,7 @@ class DecryptParamsBuilder { * @param {ArrayBuffer} arraybuffer - the ArrayBuffer used to load file content from a browser * @return {DecryptParamsBuilder} - this object. */ - withArrayBufferSource(arraybuffer: ArrayBuffer): DecryptParamsBuilder { + withArrayBufferSource(arraybuffer: ArrayBuffer): this { this.setArrayBufferSource(arraybuffer); return this; } diff --git a/lib/tdf3/src/tdf.ts b/lib/tdf3/src/tdf.ts index 7b686f32..9d6ce933 100644 --- a/lib/tdf3/src/tdf.ts +++ b/lib/tdf3/src/tdf.ts @@ -838,7 +838,7 @@ export async function writeStream(cfg: EncryptConfiguration): Promise { }; }; -export const fromBuffer = (buffer: Uint8Array | Buffer): Chunker => { +export const fromBuffer = (source: Uint8Array | Buffer): Chunker => { return (byteStart?: number, byteEnd?: number) => { - return Promise.resolve(buffer.slice(byteStart, byteEnd)); + return Promise.resolve(source.slice(byteStart, byteEnd)); }; }; diff --git a/lib/tdf3/src/utils/index.ts b/lib/tdf3/src/utils/index.ts index 0fa41f7a..b8bf7494 100644 --- a/lib/tdf3/src/utils/index.ts +++ b/lib/tdf3/src/utils/index.ts @@ -130,39 +130,39 @@ function base64Slice(buf: Uint8Array, start: number, end: number): string { // https://github.com/feross/buffer/blob/master/index.js#L483 export function buffToString( - buffer: Uint8Array, + source: Uint8Array, encoding: SupportedEncoding = 'utf8', start = 0, - end = buffer.length + end = source.length ) { if (start < 0) { start = 0; } - if (end > buffer.length) { - end = buffer.length; + if (end > source.length) { + end = source.length; } // Return early if start > buffer.length. Done here to prevent potential uint32 // coercion fail below. - if (start > buffer.length || end <= 0 || end <= start) { + if (start > source.length || end <= 0 || end <= start) { return ''; } switch (encoding) { case 'hex': - return hexSlice(buffer, start, end); + return hexSlice(source, start, end); case 'utf8': case 'utf-8': - return utf8Slice(buffer, start, end); + return utf8Slice(source, start, end); case 'latin1': case 'binary': - return latin1Slice(buffer, start, end); + return latin1Slice(source, start, end); case 'base64': - return base64Slice(buffer, start, end); + return base64Slice(source, start, end); } } diff --git a/lib/tdf3/src/utils/zip-reader.ts b/lib/tdf3/src/utils/zip-reader.ts index 1fd6cdbe..1b59fb57 100644 --- a/lib/tdf3/src/utils/zip-reader.ts +++ b/lib/tdf3/src/utils/zip-reader.ts @@ -69,8 +69,8 @@ export class ZipReader { /** * Utility function to get the centralDirectory for the zip file. - * @param {Buffer} chunkBuffer Takes a buffer of a portion of the file - * @return {Object} The central directory represented as an object + * It reads the end of the file to find it. + * @return The central directory represented as an object */ async getCentralDirectory(): Promise { const chunk = await this.getChunk(-1000); @@ -138,10 +138,9 @@ export class ZipReader { } /** - * Takes a portion of a ZIP (must be the last portion of a ZIP to work) and returns an array of Buffers - * that correspond to each central directory. - * @param {Buffer} chunkBuffer The last portion of a zip file - * @returns {Array} An array of buffers + * extracts the CD buffer entries from the end of a zip file. + * @param chunkBuffer The last portion of a zip file + * @returns an array of typed arrays, each element corresponding to a central directory record */ getCDBuffers(chunkBuffer: Uint8Array): Uint8Array[] { const cdBuffers = []; diff --git a/lib/tests/mocha/unit/keysplits.spec.ts b/lib/tests/mocha/unit/keysplits.spec.ts index f46638bb..4d6bad44 100644 --- a/lib/tests/mocha/unit/keysplits.spec.ts +++ b/lib/tests/mocha/unit/keysplits.spec.ts @@ -8,8 +8,8 @@ import * as defaultCryptoService from '../../../tdf3/src/crypto/index.js'; describe('keysplits', () => { it('binary xor', () => { - expect(bxor(Buffer.from([0x0f]), Buffer.from([0xf0]))).to.eql(Buffer.from([0xff])); - expect(bxor(Buffer.from([0x0f]), Buffer.from([0x0f]))).to.eql(Buffer.from([0x00])); + expect(bxor(new Uint8Array([0x0f]), new Uint8Array([0xf0]))).to.eql(new Uint8Array([0xff])); + expect(bxor(new Uint8Array([0x0f]), new Uint8Array([0x0f]))).to.eql(new Uint8Array([0x00])); }); it('should return the original byte array with split set to one part', async () => { diff --git a/lib/tests/mocha/unit/tdf.spec.ts b/lib/tests/mocha/unit/tdf.spec.ts index 62404aea..f30c5432 100644 --- a/lib/tests/mocha/unit/tdf.spec.ts +++ b/lib/tests/mocha/unit/tdf.spec.ts @@ -43,13 +43,9 @@ HJg= describe('TDF', () => { it('Encodes the postMessage origin properly in wrapHtml', () => { - const cipherText = 'abcezas123'; + const cipherText = new TextEncoder().encode('abcezas123'); const transferUrl = 'https://local.virtru.com/start?htmlProtocol=1'; - const wrapped = TDF.wrapHtml( - Buffer.from(cipherText), - JSON.stringify({ thisIs: 'metadata' }), - transferUrl - ); + const wrapped = TDF.wrapHtml(cipherText, JSON.stringify({ thisIs: 'metadata' }), transferUrl); const rawHtml = new TextDecoder().decode(wrapped); expect(rawHtml).to.include("'https://local.virtru.com', [channel.port2]);"); }); diff --git a/lib/tests/mocha/unit/zip.spec.ts b/lib/tests/mocha/unit/zip.spec.ts index a48a33e5..a38b34e2 100644 --- a/lib/tests/mocha/unit/zip.spec.ts +++ b/lib/tests/mocha/unit/zip.spec.ts @@ -32,24 +32,25 @@ describe('zip utilities', () => { describe('writeUInt64LE', () => { it('not too different', () => { - const b0 = Buffer.alloc(8); + // allocate a new uint8array with 8 bytes + const b0 = new Uint8Array(8); new DataView(b0.buffer).setBigUint64(0, BigInt(1), true); - const b1 = Buffer.alloc(8); + const b1 = new Uint8Array(8); writeUInt64LE(b1, 1, 0); expect(b1).to.eql(b0); }); it('unsafe ints throw', () => { - expect(() => writeUInt64LE(Buffer.alloc(0), 2 ** 54, 0)).to.throw(/unsafe number/); + expect(() => writeUInt64LE(new Uint8Array(0), 2 ** 54, 0)).to.throw(/unsafe number/); }); }); describe('readUInt64LE', () => { it('one', () => { - const b0 = Buffer.alloc(8); + const b0 = new Uint8Array(8); new DataView(b0.buffer).setBigUint64(0, 1n, true); expect(readUInt64LE(b0, 0)).to.equal(1); }); it('unsafe ints throw', () => { - const b0 = Buffer.alloc(8); + const b0 = new Uint8Array(8); new DataView(b0.buffer).setBigUint64(0, 9007199254740992n, true); expect(() => readUInt64LE(b0, 0)).to.throw(/exceeds/); }); diff --git a/lib/tests/server.ts b/lib/tests/server.ts index 972cada3..9041db3f 100644 --- a/lib/tests/server.ts +++ b/lib/tests/server.ts @@ -35,6 +35,18 @@ type RewrapBody = { clientPublicKey: string; }; +function concat(b: ArrayBufferView[]) { + const length = b.reduce((lk, ak) => lk + ak.byteLength, 0); + const buf = new Uint8Array(length); + let offset = 0; + for (const v of b) { + const uint8view = new Uint8Array(v.buffer, v.byteOffset, v.byteLength); + buf.set(uint8view, offset); + offset += uint8view.byteLength; + } + return buf; +} + function getBody(request: IncomingMessage): Promise { return new Promise((resolve, reject) => { const bodyParts: Uint8Array[] = []; @@ -43,7 +55,7 @@ function getBody(request: IncomingMessage): Promise { bodyParts.push(chunk); }) .on('end', () => { - resolve(Buffer.concat(bodyParts)); + resolve(concat(bodyParts)); }) .on('error', reject); }); @@ -237,11 +249,11 @@ const kas: RequestListener = async (req, res) => { res.statusCode = 206; // Partial Content res.setHeader('Content-Type', 'application/octet-stream'); res.setHeader('Content-Length', rangeData.length); - res.end(Buffer.from(rangeData.buffer)); + res.end(rangeData); } else { res.statusCode = 200; // OK res.setHeader('Content-Type', 'application/octet-stream'); - res.end(Buffer.from(fullRange.buffer)); + res.end(fullRange); } } else if (url.pathname === '/attributes/*/fqn') { const fqnAttributeValues: Record = {}; diff --git a/lib/webpack.test.config.cjs b/lib/webpack.test.config.cjs index 192703f9..814e9606 100644 --- a/lib/webpack.test.config.cjs +++ b/lib/webpack.test.config.cjs @@ -9,11 +9,6 @@ module.exports = { path: path.resolve(__dirname, 'tests/mocha/dist'), filename: '[name].js', }, - plugins: [ - new webpack.ProvidePlugin({ - Buffer: ['buffer', 'Buffer'], - }), - ], resolve: { extensions: ['.js'], }, diff --git a/remote-store/package-lock.json b/remote-store/package-lock.json index 99ef279a..b64231fc 100644 --- a/remote-store/package-lock.json +++ b/remote-store/package-lock.json @@ -1536,9 +1536,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", - "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -1821,14 +1821,13 @@ "node_modules/@opentdf/client": { "version": "2.1.0", "resolved": "file:../lib/opentdf-client-2.1.0.tgz", - "integrity": "sha512-Us1uiGHNgs8dZDyfVutDVyo2vXISJOBfxtUTknOOgrnZuz8ZvJtoNvTLb+QW9ha4wdW1eQaiu7bogxlYbOcGAA==", + "integrity": "sha512-1KZVuJLh+MBXPwAx/RiDw0clFvbFqLDaqfi4T5rMgKlFJ4rNX5immyQcZnu7YS8degBed/4CHONgvFya33NGFA==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", @@ -3383,30 +3382,6 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -4234,26 +4209,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", diff --git a/web-app/package-lock.json b/web-app/package-lock.json index c8c1493c..ad42f581 100644 --- a/web-app/package-lock.json +++ b/web-app/package-lock.json @@ -350,9 +350,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", - "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -607,14 +607,13 @@ "node_modules/@opentdf/client": { "version": "2.1.0", "resolved": "file:../lib/opentdf-client-2.1.0.tgz", - "integrity": "sha512-Us1uiGHNgs8dZDyfVutDVyo2vXISJOBfxtUTknOOgrnZuz8ZvJtoNvTLb+QW9ha4wdW1eQaiu7bogxlYbOcGAA==", + "integrity": "sha512-1KZVuJLh+MBXPwAx/RiDw0clFvbFqLDaqfi4T5rMgKlFJ4rNX5immyQcZnu7YS8degBed/4CHONgvFya33NGFA==", "license": "BSD-3-Clause-Clear", "dependencies": { "axios": "^1.6.1", "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", @@ -1295,6 +1294,7 @@ }, "node_modules/buffer": { "version": "6.0.3", + "dev": true, "funding": [ { "type": "github", @@ -2152,6 +2152,7 @@ }, "node_modules/ieee754": { "version": "1.2.1", + "dev": true, "funding": [ { "type": "github", @@ -3958,9 +3959,9 @@ } }, "@babel/runtime": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.9.tgz", - "integrity": "sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "requires": { "regenerator-runtime": "^0.14.0" } @@ -4118,13 +4119,12 @@ }, "@opentdf/client": { "version": "file:../lib/opentdf-client-2.1.0.tgz", - "integrity": "sha512-Us1uiGHNgs8dZDyfVutDVyo2vXISJOBfxtUTknOOgrnZuz8ZvJtoNvTLb+QW9ha4wdW1eQaiu7bogxlYbOcGAA==", + "integrity": "sha512-1KZVuJLh+MBXPwAx/RiDw0clFvbFqLDaqfi4T5rMgKlFJ4rNX5immyQcZnu7YS8degBed/4CHONgvFya33NGFA==", "requires": { "axios": "^1.6.1", "axios-retry": "^3.9.0", "base64-js": "^1.5.1", "browser-fs-access": "^0.34.1", - "buffer": "^6.0.3", "buffer-crc32": "^0.2.13", "dpop": "^1.2.0", "eventemitter3": "^5.0.1", @@ -4526,6 +4526,7 @@ }, "buffer": { "version": "6.0.3", + "dev": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" @@ -5047,7 +5048,8 @@ "dev": true }, "ieee754": { - "version": "1.2.1" + "version": "1.2.1", + "dev": true }, "ignore": { "version": "5.2.4",