From 9cd5ef4b49127792f49872d6b5e8032899fc2edb Mon Sep 17 00:00:00 2001 From: Sam Willis Date: Thu, 1 Aug 2024 12:01:57 +0100 Subject: [PATCH] contrib/pgcrypto --- packages/pglite/src/contrib/pgcrypto.ts | 16 ++++ .../pglite/tests/contrib/pgcrypto.test.js | 85 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 packages/pglite/src/contrib/pgcrypto.ts create mode 100644 packages/pglite/tests/contrib/pgcrypto.test.js diff --git a/packages/pglite/src/contrib/pgcrypto.ts b/packages/pglite/src/contrib/pgcrypto.ts new file mode 100644 index 000000000..220e852d8 --- /dev/null +++ b/packages/pglite/src/contrib/pgcrypto.ts @@ -0,0 +1,16 @@ +import type { + Extension, + ExtensionSetupResult, + PGliteInterface, +} from "../interface"; + +const setup = async (_pg: PGliteInterface, _emscriptenOpts: any) => { + return { + bundlePath: new URL("../../release/pgcrypto.tar.gz", import.meta.url), + } satisfies ExtensionSetupResult; +}; + +export const pgcrypto = { + name: "pgcrypto", + setup, +} satisfies Extension; diff --git a/packages/pglite/tests/contrib/pgcrypto.test.js b/packages/pglite/tests/contrib/pgcrypto.test.js new file mode 100644 index 000000000..d780e8c03 --- /dev/null +++ b/packages/pglite/tests/contrib/pgcrypto.test.js @@ -0,0 +1,85 @@ +import { describe, it, expect } from 'vitest' +import { PGlite } from '../../dist/index.js' +import { pgcrypto } from '../../dist/contrib/pgcrypto.js' + +describe('pg_pgcryptotrgm', () => { + it('digest', async () => { + const pg = new PGlite({ + extensions: { + pgcrypto, + }, + }) + + await pg.exec('CREATE EXTENSION IF NOT EXISTS pgcrypto;') + + const res = await pg.query( + "SELECT encode(digest(convert_to('test', 'UTF8'), 'sha1'), 'hex') as value;", + ) + expect(res.rows[0].value, 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3') + }) + + it('hmac', async () => { + const pg = new PGlite({ + extensions: { + pgcrypto, + }, + }) + + await pg.exec('CREATE EXTENSION IF NOT EXISTS pgcrypto;') + + const res = await pg.query( + "SELECT encode(hmac(convert_to('test', 'UTF8'), convert_to('key', 'UTF8'), 'sha1'), 'hex') as value;", + ) + expect(res.rows[0].value).toEqual( + '671f54ce0c540f78ffe1e26dcf9c2a047aea4fda', + ) + }) + + it('crypt', async () => { + const pg = new PGlite({ + extensions: { + pgcrypto, + }, + }) + + await pg.exec('CREATE EXTENSION IF NOT EXISTS pgcrypto;') + + const res = await pg.query("SELECT crypt('test', gen_salt('bf')) as value;") + expect(res.rows[0].value.length).toEqual(60) + }) + + it('gen_salt', async () => { + const pg = new PGlite({ + extensions: { + pgcrypto, + }, + }) + + await pg.exec('CREATE EXTENSION IF NOT EXISTS pgcrypto;') + + const res = await pg.query("SELECT gen_salt('bf') as value;") + expect(res.rows[0].value.length).toEqual(29) + }) + + it('pgp_sym_encrypt and pgp_sym_decrypt', async () => { + const pg = new PGlite({ + extensions: { + pgcrypto, + }, + }) + + await pg.exec('CREATE EXTENSION IF NOT EXISTS pgcrypto;') + + const res = await pg.query( + "SELECT pgp_sym_encrypt('test', 'key') as value;", + ) + const encrypted = res.rows[0].value + + const res2 = await pg.query("SELECT pgp_sym_decrypt($1, 'key') as value;", [ + encrypted, + ]) + expect(res2.rows[0].value).toEqual('test') + }) +}) + +// TODO: pgp_pub_encrypt and pgp_pub_decrypt