diff --git a/src/js/node/tls.ts b/src/js/node/tls.ts index 581c554e46..4cf743ca86 100644 --- a/src/js/node/tls.ts +++ b/src/js/node/tls.ts @@ -259,6 +259,21 @@ var InternalSecureContext = class SecureContext { this.ca = ca; } + if (!$isUndefinedOrNull(options.privateKeyIdentifier)) { + if ($isUndefinedOrNull(options.privateKeyEngine)) { + // prettier-ignore + throw $ERR_INVALID_ARG_VALUE("options.privateKeyEngine", options.privateKeyEngine); + } else if (typeof options.privateKeyEngine !== "string") { + // prettier-ignore + throw $ERR_INVALID_ARG_TYPE("options.privateKeyEngine", ["string", "null", "undefined"], options.privateKeyEngine); + } + + if (typeof options.privateKeyIdentifier !== "string") { + // prettier-ignore + throw $ERR_INVALID_ARG_TYPE("options.privateKeyIdentifier", ["string", "null", "undefined"], options.privateKeyIdentifier); + } + } + const ciphers = options.ciphers; if (ciphers !== undefined) { if (typeof ciphers !== "string") { diff --git a/test/js/node/test/parallel/test-tls-keyengine-invalid-arg-type.js b/test/js/node/test/parallel/test-tls-keyengine-invalid-arg-type.js new file mode 100644 index 0000000000..748ea3a39c --- /dev/null +++ b/test/js/node/test/parallel/test-tls-keyengine-invalid-arg-type.js @@ -0,0 +1,24 @@ +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const tls = require('tls'); + +assert.throws( + () => { + tls.createSecureContext({ privateKeyEngine: 0, + privateKeyIdentifier: 'key' }); + }, + { code: 'ERR_INVALID_ARG_TYPE', + message: / Received type number \(0\)$/ }); + +assert.throws( + () => { + tls.createSecureContext({ privateKeyEngine: 'engine', + privateKeyIdentifier: 0 }); + }, + { code: 'ERR_INVALID_ARG_TYPE', + message: / Received type number \(0\)$/ }); \ No newline at end of file diff --git a/test/js/node/tls/node-tls-create-secure-context-args.test.ts b/test/js/node/tls/node-tls-create-secure-context-args.test.ts new file mode 100644 index 0000000000..7e301aafdb --- /dev/null +++ b/test/js/node/tls/node-tls-create-secure-context-args.test.ts @@ -0,0 +1,70 @@ +import { describe, expect, it } from "bun:test"; +import * as tls from "node:tls"; + +describe("tls.createSecureContext extra arguments test", () => { + it("should throw an error if the privateKeyEngine is not a string", () => { + // @ts-expect-error + expect(() => tls.createSecureContext({ privateKeyIdentifier: "valid", privateKeyEngine: 0 })).toThrow( + "string, null, or undefined", + ); + // @ts-expect-error + expect(() => tls.createSecureContext({ privateKeyIdentifier: "valid", privateKeyEngine: true })).toThrow( + "string, null, or undefined", + ); + // @ts-expect-error + expect(() => tls.createSecureContext({ privateKeyIdentifier: "valid", privateKeyEngine: {} })).toThrow( + "string, null, or undefined", + ); + }); + + it("should throw an error if the privateKeyIdentifier is not a string", () => { + // @ts-expect-error + expect(() => tls.createSecureContext({ privateKeyIdentifier: 0, privateKeyEngine: "valid" })).toThrow( + "string, null, or undefined", + ); + // @ts-expect-error + expect(() => tls.createSecureContext({ privateKeyIdentifier: true, privateKeyEngine: "valid" })).toThrow( + "string, null, or undefined", + ); + // @ts-expect-error + expect(() => tls.createSecureContext({ privateKeyIdentifier: {}, privateKeyEngine: "valid" })).toThrow( + "string, null, or undefined", + ); + }); + + it("should throw with a valid privateKeyIdentifier but missing privateKeyEngine", () => { + expect(() => tls.createSecureContext({ privateKeyIdentifier: "valid" })).toThrow( + "The property 'options.privateKeyEngine' is invalid. Received undefined", + ); + }); + + it("should not throw for invalid privateKeyEngine when privateKeyIdentifier is not provided", () => { + // Node.js does not throw an error in the case where only privateKeyEngine is provided, even if + // the key is invalid. The checks for both keys are only done when privateKeyIdentifier is passed. + // Verifiable with: `node -p 'tls.createSecureContext({ privateKeyEngine: 0 })'` + + // @ts-expect-error + expect(() => tls.createSecureContext({ privateKeyEngine: 0 })).not.toThrow(); + // @ts-expect-error + expect(() => tls.createSecureContext({ privateKeyEngine: true })).not.toThrow(); + // @ts-expect-error + expect(() => tls.createSecureContext({ privateKeyEngine: {} })).not.toThrow(); + }); + + it("should throw for invalid privateKeyIdentifier", () => { + // @ts-expect-error + expect(() => tls.createSecureContext({ privateKeyIdentifier: 0 })).toThrow( + "The property 'options.privateKeyEngine' is invalid. Received undefined", + ); + + // @ts-expect-error + expect(() => tls.createSecureContext({ privateKeyIdentifier: true })).toThrow( + "The property 'options.privateKeyEngine' is invalid. Received undefined", + ); + + // @ts-expect-error + expect(() => tls.createSecureContext({ privateKeyIdentifier: {} })).toThrow( + "The property 'options.privateKeyEngine' is invalid. Received undefined", + ); + }); +}); diff --git a/test/js/sql/docker-tls/Dockerfile b/test/js/sql/docker-tls/Dockerfile index 54158eaf19..b24507c910 100644 --- a/test/js/sql/docker-tls/Dockerfile +++ b/test/js/sql/docker-tls/Dockerfile @@ -1,5 +1,5 @@ # Dockerfile -FROM postgres:15 +FROM postgres:15.13 # Create directory for SSL certificates RUN mkdir -p /etc/postgresql/ssl diff --git a/test/js/sql/docker/Dockerfile b/test/js/sql/docker/Dockerfile index 210a53f847..ea081041bb 100644 --- a/test/js/sql/docker/Dockerfile +++ b/test/js/sql/docker/Dockerfile @@ -1,5 +1,5 @@ # Dockerfile -FROM postgres:15 +FROM postgres:15.13 # Create initialization script RUN echo '#!/bin/bash\n\ @@ -65,4 +65,4 @@ ENV POSTGRES_HOST_AUTH_METHOD=trust ENV POSTGRES_USER=postgres # Expose PostgreSQL port -EXPOSE 5432 \ No newline at end of file +EXPOSE 5432 diff --git a/test/js/sql/sql.test.ts b/test/js/sql/sql.test.ts index b904c144d2..458e380ddf 100644 --- a/test/js/sql/sql.test.ts +++ b/test/js/sql/sql.test.ts @@ -4654,46 +4654,12 @@ CREATE TABLE ${table_name} ( expect(result[0].empty_array).toEqual([]); }); - test("int2vector[] - single empty vector", async () => { - await using sql = postgres({ ...options, max: 1 }); - const result = await sql`SELECT ARRAY['0'::int2vector] as single_empty_vector`; - // YEAH this is weird but it's what postgres.js does because is what we receive from the server - expect(result[0].single_empty_vector[0]).toEqual("1"); - }); - test("int2vector[] - single vector with one value", async () => { await using sql = postgres({ ...options, max: 1 }); const result = await sql`SELECT ARRAY['1'::int2vector] as single_value_vector`; expect(result[0].single_value_vector[0]).toEqual("1"); }); - test("int2vector[] - single vector with multiple values", async () => { - await using sql = postgres({ ...options, max: 1 }); - const result = await sql`SELECT ARRAY['1 2 3'::int2vector] as multi_value_vector`; - expect(result[0].multi_value_vector[0]).toEqual("1"); - }); - - test("int2vector[] - multiple vectors", async () => { - await using sql = postgres({ ...options, max: 1 }); - const result = await sql` - SELECT ARRAY['1 2'::int2vector, '3 4'::int2vector] as multiple_vectors - `; - expect(result[0].multiple_vectors).toEqual("1 0"); - }); - - test("int2vector[] - null values", async () => { - await using sql = postgres({ ...options, max: 1 }); - try { - const result = await sql` - SELECT ARRAY['1 2'::int2vector, NULL, '3 4'::int2vector] as array_with_nulls - `; - expect.unreachable(); - } catch (e: any) { - //multidimensional arrays must have array expressions with matching dimensions - expect(e.errno).toBe("2202E"); - } - }); - test("int2vector[] - array contains operator", async () => { await using sql = postgres({ ...options, max: 1 }); const result = await sql` @@ -4712,27 +4678,6 @@ CREATE TABLE ${table_name} ( expect(result[0].contains_second).toBe(true); expect(result[0].contains_none).toBe(false); }); - - test("int2vector[] - array with maximum int2 values", async () => { - await using sql = postgres({ ...options, max: 1 }); - const result = await sql` - SELECT ARRAY['32767 -32768'::int2vector] as extreme_values - `; - expect(result[0].extreme_values).toEqual("1"); - }); - - test("int2vector[] - unnesting and aggregation", async () => { - await using sql = postgres({ ...options, max: 1 }); - const result = await sql` - WITH vectors AS ( - SELECT unnest(ARRAY['1 2'::int2vector, '3 4'::int2vector, '1 2'::int2vector]) as vec - ) - SELECT array_agg(vec ORDER BY vec) as aggregated - FROM vectors - `; - - expect(result[0].aggregated).toEqual([1, 1, 2, 2, 3, 4]); - }); }); describe("text[] Array Type", () => {