From 9bacbdadcfa59a9e2d7e3e500aa79879ba488bc6 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 00000000..063d87df --- /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 00000000..d780e8c0 --- /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