diff --git a/Makefile b/Makefile index 8d9c9e8..d609676 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ else endif EXTENSION = supabase_vault -EXTVERSION = 0.3.2 +EXTVERSION = 0.3.3 DATA = $(wildcard sql/*--*.sql) diff --git a/flake.lock b/flake.lock index 704715e..0f9a553 100644 --- a/flake.lock +++ b/flake.lock @@ -43,16 +43,16 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1791394750, - "narHash": "sha256-SMv4EKUaGmfUyXyeGHW3AiX1vbef7El56RKTIxio8jQ=", + "lastModified": 1793674321, + "narHash": "sha256-wLcCioA8+xi7ck/gdZmBeZo/NJfXxvYYCVOpAGvCgK8=", "owner": "supabase", "repo": "xpg", - "rev": "8f2a2005e8e020e0db5a7cbb94a87a9dd3227411", + "rev": "27aedcb0a23bce2879e7b114369e9c937665082d", "type": "github" }, "original": { "owner": "supabase", - "ref": "v2.6.0", + "ref": "v2.7.0", "repo": "xpg", "type": "github" } diff --git a/nix/plpgsql-check.nix b/nix/plpgsql-check.nix index 3031ce4..f48d234 100644 --- a/nix/plpgsql-check.nix +++ b/nix/plpgsql-check.nix @@ -7,13 +7,15 @@ stdenv.mkDerivation rec { pname = "plpgsql-check"; - version = "2.10.15"; + version = "6afcb44a5f9ec06de7b74d8f8ebbeb638ac7b945"; src = fetchFromGitHub { owner = "okbob"; repo = "plpgsql_check"; - rev = "v${version}"; - hash = "sha256-war+GVHMDegfDXjxdIsUkrPPDntKeyb/bGxibHVbpDo="; + # rev = "v${version}"; + rev = "6afcb44a5f9ec06de7b74d8f8ebbeb638ac7b945"; + + hash = "sha256-AQGJglOiuUC5djHNiJHpzDErfpmqglvs7djxfX8mHEc="; }; buildInputs = [ postgresql ]; diff --git a/sql/supabase_vault--0.3.2--0.3.3.sql b/sql/supabase_vault--0.3.2--0.3.3.sql new file mode 100644 index 0000000..a9756a5 --- /dev/null +++ b/sql/supabase_vault--0.3.2--0.3.3.sql @@ -0,0 +1,56 @@ +CREATE OR REPLACE FUNCTION vault.create_secret(new_secret text + , new_name text = CAST(NULL AS text) + , new_description text = CAST('' AS text) + , new_key_id uuid = CAST(NULL AS uuid)) +RETURNS uuid +LANGUAGE plpgsql SECURITY DEFINER SET search_path TO 'pg_catalog', 'pg_temp' +AS $$ +DECLARE + rec record; +BEGIN + INSERT INTO vault.secrets (secret, name, description) + VALUES ( + new_secret, + new_name, + new_description + ) + RETURNING * INTO rec; + UPDATE vault.secrets s + SET secret = pg_catalog.encode(vault._crypto_aead_det_encrypt( + message := pg_catalog.convert_to(rec.secret, 'utf8'), + additional := pg_catalog.convert_to(s.id::pg_catalog.text, 'utf8'), + key_id := 0, + context := 'pgsodium'::pg_catalog.bytea, + nonce := rec.nonce + ), 'base64') + WHERE s.id OPERATOR(pg_catalog.=) rec.id; + RETURN rec.id; +END +$$; + + +CREATE OR REPLACE FUNCTION vault.update_secret(secret_id uuid + , new_secret text = CAST(NULL AS text) + , new_name text = CAST(NULL AS text) + , new_description text = CAST(NULL AS text) + , new_key_id uuid = CAST(NULL AS uuid)) +RETURNS void +LANGUAGE plpgsql SECURITY DEFINER SET search_path TO 'pg_catalog', 'pg_temp' +AS $$ +BEGIN + UPDATE vault.secrets s + SET + secret = CASE WHEN new_secret IS NULL THEN s.secret + ELSE pg_catalog.encode(vault._crypto_aead_det_encrypt( + message := pg_catalog.convert_to(new_secret, 'utf8'), + additional := pg_catalog.convert_to(s.id::pg_catalog.text, 'utf8'), + key_id := 0, + context := 'pgsodium'::pg_catalog.bytea, + nonce := s.nonce + ), 'base64') END, + name = coalesce(new_name, s.name), + description = coalesce(new_description, s.description), + updated_at = pg_catalog.now() + WHERE s.id OPERATOR(pg_catalog.=) secret_id; +END +$$; diff --git a/supabase_vault.sql b/supabase_vault.sql index de0b3be..49f39f4 100644 --- a/supabase_vault.sql +++ b/supabase_vault.sql @@ -49,14 +49,14 @@ BEGIN ) RETURNING * INTO rec; UPDATE vault.secrets s - SET secret = encode(vault._crypto_aead_det_encrypt( - message := convert_to(rec.secret, 'utf8'), - additional := convert_to(s.id::text, 'utf8'), + SET secret = pg_catalog.encode(vault._crypto_aead_det_encrypt( + message := pg_catalog.convert_to(rec.secret, 'utf8'), + additional := pg_catalog.convert_to(s.id::pg_catalog.text, 'utf8'), key_id := 0, - context := 'pgsodium'::bytea, + context := 'pgsodium'::pg_catalog.bytea, nonce := rec.nonce ), 'base64') - WHERE id = rec.id; + WHERE s.id OPERATOR(pg_catalog.=) rec.id; RETURN rec.id; END $$; @@ -75,17 +75,17 @@ BEGIN UPDATE vault.secrets s SET secret = CASE WHEN new_secret IS NULL THEN s.secret - ELSE encode(vault._crypto_aead_det_encrypt( - message := convert_to(new_secret, 'utf8'), - additional := convert_to(s.id::text, 'utf8'), + ELSE pg_catalog.encode(vault._crypto_aead_det_encrypt( + message := pg_catalog.convert_to(new_secret, 'utf8'), + additional := pg_catalog.convert_to(s.id::pg_catalog.text, 'utf8'), key_id := 0, - context := 'pgsodium'::bytea, + context := 'pgsodium'::pg_catalog.bytea, nonce := s.nonce ), 'base64') END, name = coalesce(new_name, s.name), description = coalesce(new_description, s.description), - updated_at = now() - WHERE s.id = secret_id; + updated_at = pg_catalog.now() + WHERE s.id OPERATOR(pg_catalog.=) secret_id; END $$; diff --git a/test/expected/test.out b/test/expected/test.out index f176917..8ab78ee 100644 --- a/test/expected/test.out +++ b/test/expected/test.out @@ -85,7 +85,7 @@ where name = 'empty_secret'; SELECT extversion FROM pg_extension where extname = 'supabase_vault'; extversion ------------ - 0.3.2 + 0.3.3 (1 row) -- Validate that each security definer function explicitly specifies pg_temp and @@ -139,7 +139,8 @@ FROM SELECT plpgsql_check_function_tb(pg_proc.oid, COALESCE(pg_trigger.tgrelid, 0), oldtable=>pg_trigger.tgoldtable, - newtable=>pg_trigger.tgnewtable) AS pcf + newtable=>pg_trigger.tgnewtable, + extra_security_warnings_level=>4) AS pcf FROM pg_proc LEFT JOIN pg_trigger ON (pg_trigger.tgfoid = pg_proc.oid) diff --git a/test/sql/test.sql b/test/sql/test.sql index 09b2086..e0a4ccc 100644 --- a/test/sql/test.sql +++ b/test/sql/test.sql @@ -114,7 +114,8 @@ FROM SELECT plpgsql_check_function_tb(pg_proc.oid, COALESCE(pg_trigger.tgrelid, 0), oldtable=>pg_trigger.tgoldtable, - newtable=>pg_trigger.tgnewtable) AS pcf + newtable=>pg_trigger.tgnewtable, + extra_security_warnings_level=>4) AS pcf FROM pg_proc LEFT JOIN pg_trigger ON (pg_trigger.tgfoid = pg_proc.oid)