@nextblock-cms/db 0.22.1 → 0.22.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/README.md +47 -47
  2. package/package.json +1 -1
  3. package/supabase/migrations/02000_catchup_gen1.sql +5880 -5880
  4. package/supabase/migrations/02001_baseline_schema.sql +2734 -2734
  5. package/supabase/migrations/02002_baseline_constraints_and_indexes.sql +1262 -1262
  6. package/supabase/migrations/02003_baseline_security_and_grants.sql +1577 -1577
  7. package/supabase/migrations/02004_baseline_seed.sql +565 -565
  8. package/supabase/migrations/02005_home_live_demo_promo_cadence_15min.sql +53 -53
  9. package/supabase/migrations/02006_home_marketing_contrast.sql +56 -56
  10. package/supabase/migrations/02007_home_pillar_caption_contrast.sql +44 -44
  11. package/supabase/migrations/02008_home_fr_parity.sql +89 -89
  12. package/supabase/migrations/02009_fr_cortex_posts.sql +67 -67
  13. package/supabase/migrations/02010_shop_hero_redesign.sql +72 -72
  14. package/supabase/migrations/02011_drop_backdrop_blur_on_pages.sql +26 -26
  15. package/supabase/migrations/02012_drop_variant_backdrop_blur.sql +17 -17
  16. package/supabase/migrations/02013_advisor_rls_and_trigger_grants.sql +102 -102
  17. package/supabase/migrations/02014_package_activations_staff_read.sql +18 -18
  18. package/supabase/migrations/02018_install_paths_and_seed_copy_accuracy.sql +1820 -1820
  19. package/supabase/migrations/02019_open_handed_licensing_and_mcp_clients.sql +448 -448
  20. package/supabase/migrations/02020_commerce_product_accuracy.sql +93 -93
  21. package/supabase/migrations/02021_profiles_staff_read_and_role_guard.sql +362 -362
  22. package/supabase/migrations/02022_security_hardening_writer_boundary_and_aal.sql +504 -504
  23. package/supabase/migrations/02024_advisor_trigger_grants_and_pg_net_schema.sql +113 -0
@@ -0,0 +1,113 @@
1
+ -- 02024: clear the Supabase Security Advisor warnings that came back after the 02022/02023
2
+ -- deploys, and move a `pg_net` that was installed in `public` into `extensions`.
3
+ --
4
+ -- Why the SECURITY DEFINER warnings (lints 0028/0029) returned
5
+ -- 02013 revoked anon/authenticated EXECUTE on the two SECURITY DEFINER trigger functions
6
+ -- (handle_new_user(), update_product_ratings()) and the advisor was clean. But every
7
+ -- production build runs apps/nextblock/tools/build-migrate.mjs, whose migrate-core.mjs
8
+ -- ends with a blanket `grant execute on all functions in schema public to anon,
9
+ -- authenticated, service_role` and, unlike lib/setup/schema-apply.ts (the /setup path),
10
+ -- had no pass taking that EXECUTE back off trigger functions or re-applying the API-role
11
+ -- revokes of 02021/02022. So each deploy silently handed the privilege back. The hook is
12
+ -- fixed in the same change (and a test now keeps the two files' SQL identical); this
13
+ -- migration repairs the databases that were already re-granted. Postgres checks EXECUTE
14
+ -- on a trigger function only at CREATE TRIGGER time, never when the trigger fires, and
15
+ -- PostgREST cannot call a `RETURNS trigger` function via /rpc, so nothing loses access.
16
+ --
17
+ -- Why `pg_net` (lint 0014, "Extension in Public")
18
+ -- A bare `create extension pg_net` lands in `public` (the first search_path entry), which
19
+ -- exposes its objects through the API schema. pg_net is NOT relocatable, so the lint's
20
+ -- `alter extension … set schema` is refused; the only way out is drop + re-create WITH
21
+ -- SCHEMA extensions. Its own objects live in the `net` schema either way; only the
22
+ -- extension's registration moves, and the request queue / response log are transient.
23
+ -- pg_cron job commands are plain text (no dependency), so a scheduled `net.http_get`
24
+ -- keeps working. Guarded: a database without pg_net, or with it already outside
25
+ -- `public`, is untouched. Same statement tools/scripts/schedule-sandbox-reset.js runs.
26
+ --
27
+ -- Everything here is idempotent and safe on a fresh install, the sandbox replay and a
28
+ -- /setup-installed database. The two Auth-dashboard warnings (leaked password protection,
29
+ -- MFA options) are project settings, not schema, and are not addressed here.
30
+
31
+ -- ---------------------------------------------------------------------------
32
+ -- 1. Trigger functions: the API roles never need EXECUTE
33
+ -- (identical to the post-apply pass in migrate-core.mjs / schema-apply.ts)
34
+ -- ---------------------------------------------------------------------------
35
+ do $nb_trg$
36
+ declare r record;
37
+ begin
38
+ for r in
39
+ select p.oid::regprocedure as sig
40
+ from pg_proc p
41
+ join pg_type t on t.oid = p.prorettype
42
+ where p.pronamespace = 'public'::regnamespace and t.typname = 'trigger'
43
+ loop
44
+ execute format('revoke execute on function %s from public, anon, authenticated', r.sig);
45
+ end loop;
46
+ end $nb_trg$;
47
+
48
+ -- The two the advisor names, stated explicitly so the intent survives a grep (02013 parity).
49
+ REVOKE EXECUTE ON FUNCTION public.handle_new_user() FROM PUBLIC, anon, authenticated;
50
+ GRANT EXECUTE ON FUNCTION public.handle_new_user() TO service_role;
51
+
52
+ REVOKE EXECUTE ON FUNCTION public.update_product_ratings() FROM PUBLIC, anon, authenticated;
53
+ GRANT EXECUTE ON FUNCTION public.update_product_ratings() TO service_role;
54
+
55
+ -- ---------------------------------------------------------------------------
56
+ -- 2. The API-role revokes of 02021 / 02022 that the same blanket grant handed back
57
+ -- (identical to API_ROLE_REVOKE_SQL in migrate-core.mjs / schema-apply.ts)
58
+ -- ---------------------------------------------------------------------------
59
+ do $nb_api$
60
+ begin
61
+ revoke truncate on all tables in schema public from anon, authenticated;
62
+ if to_regprocedure('public.generate_order_invoice_number()') is not null then
63
+ revoke execute on function public.generate_order_invoice_number() from public, anon, authenticated;
64
+ end if;
65
+ if to_regprocedure('public.assign_order_invoice_metadata(uuid, timestamp with time zone)') is not null then
66
+ revoke execute on function public.assign_order_invoice_metadata(uuid, timestamp with time zone) from public, anon, authenticated;
67
+ end if;
68
+ if to_regclass('public.order_invoice_number_seq') is not null then
69
+ revoke all on sequence public.order_invoice_number_seq from anon, authenticated;
70
+ end if;
71
+ if to_regprocedure('public.upsert_product_with_variants(jsonb)') is not null then
72
+ revoke execute on function public.upsert_product_with_variants(jsonb) from public, anon;
73
+ end if;
74
+ if to_regprocedure('public.bump_email_2fa_attempts(uuid)') is not null then
75
+ revoke execute on function public.bump_email_2fa_attempts(uuid) from public, anon, authenticated;
76
+ end if;
77
+ if to_regprocedure('public.redeem_coupon_atomically(uuid)') is not null then
78
+ revoke execute on function public.redeem_coupon_atomically(uuid) from public, anon, authenticated;
79
+ end if;
80
+ end $nb_api$;
81
+
82
+ -- ---------------------------------------------------------------------------
83
+ -- 3. pg_net out of `public` (not relocatable: drop + re-create WITH SCHEMA extensions)
84
+ -- ---------------------------------------------------------------------------
85
+ do $nb_pg_net$
86
+ declare
87
+ v_version text;
88
+ begin
89
+ select e.extversion
90
+ into v_version
91
+ from pg_extension e
92
+ where e.extname = 'pg_net'
93
+ and e.extnamespace = 'public'::regnamespace;
94
+
95
+ if v_version is null then
96
+ return; -- not installed, or already registered outside public
97
+ end if;
98
+
99
+ if to_regnamespace('extensions') is null then
100
+ raise notice '02024: pg_net % is registered in schema public and this database has no extensions schema; reinstall it by hand with `create extension pg_net with schema <schema>`', v_version;
101
+ return;
102
+ end if;
103
+
104
+ -- The pg_net worker holds net.http_request_queue while a request is in flight. Fail fast
105
+ -- rather than queue behind it; re-running the migration is cheap.
106
+ perform set_config('lock_timeout', '15s', true);
107
+
108
+ drop extension pg_net;
109
+ create extension pg_net with schema extensions;
110
+
111
+ raise notice '02024: pg_net re-registered in schema extensions (was % in public, now %)',
112
+ v_version, (select extversion from pg_extension where extname = 'pg_net');
113
+ end $nb_pg_net$;