@nextblock-cms/db 0.17.6 → 0.17.8
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.
|
@@ -1 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache tag for every cached activation read. Activation and deactivation call
|
|
3
|
+
* `updateTag(PACKAGE_ACTIVATION_CACHE_TAG)` so a purchase unlocks the CMS on the very
|
|
4
|
+
* next request instead of after the 60 s window.
|
|
5
|
+
*/
|
|
6
|
+
export declare const PACKAGE_ACTIVATION_CACHE_TAG = "package-activation";
|
|
7
|
+
/**
|
|
8
|
+
* The moment a stored activation stops being valid, from what the row knows:
|
|
9
|
+
* the license expiration (recorded from the vendor at checkout, from Freemius at
|
|
10
|
+
* activation, and refreshed by the background re-validation) or the trial end. Null
|
|
11
|
+
* when the row carries no date, which is the case for keys activated before these
|
|
12
|
+
* fields existed and for lifetime licenses.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolvePackageActivationExpiry(meta: unknown): number | null;
|
|
15
|
+
/** A row counts only while its status is active AND any known expiry is in the future. */
|
|
16
|
+
export declare function isPackageActivationRowValid(row: {
|
|
17
|
+
meta?: unknown;
|
|
18
|
+
status?: unknown;
|
|
19
|
+
}, now?: number): boolean;
|
|
1
20
|
export declare function verifyPackageOnline(packageId: string, customClient?: any): Promise<boolean>;
|
package/package.json
CHANGED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
-- 02013: clear the Supabase Advisor warnings on RLS policies and trigger-function grants.
|
|
2
|
+
--
|
|
3
|
+
-- Performance advisor
|
|
4
|
+
-- * auth_rls_initplan: cms_interactions_insert_policy called auth.uid() per candidate row.
|
|
5
|
+
-- Wrapped as (select auth.uid()) it becomes an InitPlan evaluated once per statement.
|
|
6
|
+
-- * multiple_permissive_policies: cms_redirects and site_scripts each had two SELECT
|
|
7
|
+
-- policies for `authenticated` ("Admins read all …" and "Public read active …"), and
|
|
8
|
+
-- form_endpoints had an admin FOR ALL policy overlapping the editor SELECT policy. Every
|
|
9
|
+
-- permissive policy that matches a role + command is evaluated for every row, so the
|
|
10
|
+
-- policies are re-cut so exactly one applies per role + command. Who can read or write
|
|
11
|
+
-- what is unchanged:
|
|
12
|
+
-- - anon reads active redirects / scripts;
|
|
13
|
+
-- - authenticated reads active rows, ADMIN reads all;
|
|
14
|
+
-- - form_endpoints: ADMIN + WRITER read, ADMIN writes (now three command-scoped
|
|
15
|
+
-- policies instead of FOR ALL), service_role unchanged.
|
|
16
|
+
--
|
|
17
|
+
-- Security advisor
|
|
18
|
+
-- * anon_/authenticated_security_definer_function_executable: handle_new_user() and
|
|
19
|
+
-- update_product_ratings() are SECURITY DEFINER trigger functions. Postgres checks
|
|
20
|
+
-- EXECUTE on a trigger function only at CREATE TRIGGER time, never when the trigger
|
|
21
|
+
-- fires (and PostgREST cannot call a `RETURNS trigger` function via /rpc anyway), so
|
|
22
|
+
-- anon and authenticated never needed the privilege. 02003 already revokes it on
|
|
23
|
+
-- handle_new_user() for fresh installs, but production recorded the baseline as applied
|
|
24
|
+
-- without running it (docs/04 → "How a squash crosses live databases"), so the
|
|
25
|
+
-- generation-1 grants were still live there. Idempotent: safe on a fresh install too.
|
|
26
|
+
--
|
|
27
|
+
-- The two Auth-dashboard warnings (leaked password protection, MFA options) are project
|
|
28
|
+
-- settings, not schema, and are not addressed here.
|
|
29
|
+
|
|
30
|
+
-- ---------------------------------------------------------------------------
|
|
31
|
+
-- cms_interactions: InitPlan-friendly auth.uid()
|
|
32
|
+
-- ---------------------------------------------------------------------------
|
|
33
|
+
DROP POLICY IF EXISTS cms_interactions_insert_policy ON public.cms_interactions;
|
|
34
|
+
CREATE POLICY cms_interactions_insert_policy ON public.cms_interactions
|
|
35
|
+
FOR INSERT TO authenticated
|
|
36
|
+
WITH CHECK (
|
|
37
|
+
((SELECT auth.uid()) = user_id)
|
|
38
|
+
AND (
|
|
39
|
+
status = 'pending'::public.approval_status
|
|
40
|
+
OR (SELECT public.get_current_user_role()) = ANY (ARRAY['ADMIN'::public.user_role, 'WRITER'::public.user_role])
|
|
41
|
+
)
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
-- ---------------------------------------------------------------------------
|
|
45
|
+
-- cms_redirects: one SELECT policy per role
|
|
46
|
+
-- ---------------------------------------------------------------------------
|
|
47
|
+
DROP POLICY IF EXISTS "Admins read all redirects" ON public.cms_redirects;
|
|
48
|
+
DROP POLICY IF EXISTS "Public read active redirects" ON public.cms_redirects;
|
|
49
|
+
DROP POLICY IF EXISTS "Authenticated read redirects" ON public.cms_redirects;
|
|
50
|
+
|
|
51
|
+
CREATE POLICY "Public read active redirects" ON public.cms_redirects
|
|
52
|
+
FOR SELECT TO anon
|
|
53
|
+
USING (is_active);
|
|
54
|
+
|
|
55
|
+
CREATE POLICY "Authenticated read redirects" ON public.cms_redirects
|
|
56
|
+
FOR SELECT TO authenticated
|
|
57
|
+
USING (is_active OR (SELECT public.get_current_user_role()) = 'ADMIN'::public.user_role);
|
|
58
|
+
|
|
59
|
+
-- ---------------------------------------------------------------------------
|
|
60
|
+
-- site_scripts: one SELECT policy per role
|
|
61
|
+
-- ---------------------------------------------------------------------------
|
|
62
|
+
DROP POLICY IF EXISTS "Admins read all site scripts" ON public.site_scripts;
|
|
63
|
+
DROP POLICY IF EXISTS "Public read active site scripts" ON public.site_scripts;
|
|
64
|
+
DROP POLICY IF EXISTS "Authenticated read site scripts" ON public.site_scripts;
|
|
65
|
+
|
|
66
|
+
CREATE POLICY "Public read active site scripts" ON public.site_scripts
|
|
67
|
+
FOR SELECT TO anon
|
|
68
|
+
USING (is_active);
|
|
69
|
+
|
|
70
|
+
CREATE POLICY "Authenticated read site scripts" ON public.site_scripts
|
|
71
|
+
FOR SELECT TO authenticated
|
|
72
|
+
USING (is_active OR (SELECT public.get_current_user_role()) = 'ADMIN'::public.user_role);
|
|
73
|
+
|
|
74
|
+
-- ---------------------------------------------------------------------------
|
|
75
|
+
-- form_endpoints: admin FOR ALL -> INSERT / UPDATE / DELETE, editor SELECT stays the only read
|
|
76
|
+
-- ---------------------------------------------------------------------------
|
|
77
|
+
DROP POLICY IF EXISTS form_endpoints_admin_write_policy ON public.form_endpoints;
|
|
78
|
+
DROP POLICY IF EXISTS form_endpoints_admin_insert_policy ON public.form_endpoints;
|
|
79
|
+
DROP POLICY IF EXISTS form_endpoints_admin_update_policy ON public.form_endpoints;
|
|
80
|
+
DROP POLICY IF EXISTS form_endpoints_admin_delete_policy ON public.form_endpoints;
|
|
81
|
+
|
|
82
|
+
CREATE POLICY form_endpoints_admin_insert_policy ON public.form_endpoints
|
|
83
|
+
FOR INSERT TO authenticated
|
|
84
|
+
WITH CHECK ((SELECT public.get_current_user_role()) = 'ADMIN'::public.user_role);
|
|
85
|
+
|
|
86
|
+
CREATE POLICY form_endpoints_admin_update_policy ON public.form_endpoints
|
|
87
|
+
FOR UPDATE TO authenticated
|
|
88
|
+
USING ((SELECT public.get_current_user_role()) = 'ADMIN'::public.user_role)
|
|
89
|
+
WITH CHECK ((SELECT public.get_current_user_role()) = 'ADMIN'::public.user_role);
|
|
90
|
+
|
|
91
|
+
CREATE POLICY form_endpoints_admin_delete_policy ON public.form_endpoints
|
|
92
|
+
FOR DELETE TO authenticated
|
|
93
|
+
USING ((SELECT public.get_current_user_role()) = 'ADMIN'::public.user_role);
|
|
94
|
+
|
|
95
|
+
-- ---------------------------------------------------------------------------
|
|
96
|
+
-- SECURITY DEFINER trigger functions: not callable by API roles
|
|
97
|
+
-- ---------------------------------------------------------------------------
|
|
98
|
+
REVOKE EXECUTE ON FUNCTION public.handle_new_user() FROM PUBLIC, anon, authenticated;
|
|
99
|
+
GRANT EXECUTE ON FUNCTION public.handle_new_user() TO service_role;
|
|
100
|
+
|
|
101
|
+
REVOKE EXECUTE ON FUNCTION public.update_product_ratings() FROM PUBLIC, anon, authenticated;
|
|
102
|
+
GRANT EXECUTE ON FUNCTION public.update_product_ratings() TO service_role;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
-- 02014: package_activations is readable by staff only.
|
|
2
|
+
--
|
|
3
|
+
-- The baseline granted SELECT on package_activations to every authenticated user
|
|
4
|
+
-- ("Allow authenticated read access" USING (true)). Public sign-up creates USER-role
|
|
5
|
+
-- accounts, so any storefront customer could read the plaintext license keys and the
|
|
6
|
+
-- Freemius install handles (meta.fm_uid / meta.fm_install_id) of the premium packages —
|
|
7
|
+
-- and the dashboard now buys and stores those keys itself. Only staff surfaces read
|
|
8
|
+
-- this table with the cookie client (the dashboard stats for ADMIN and WRITER, the
|
|
9
|
+
-- packages page for ADMIN); everything else goes through the service role, which is
|
|
10
|
+
-- unaffected. Writes were never allowed to authenticated users and stay that way.
|
|
11
|
+
|
|
12
|
+
DROP POLICY IF EXISTS "Allow authenticated read access" ON public.package_activations;
|
|
13
|
+
|
|
14
|
+
CREATE POLICY "Staff read package activations" ON public.package_activations
|
|
15
|
+
FOR SELECT TO authenticated
|
|
16
|
+
USING (
|
|
17
|
+
(SELECT public.get_current_user_role()) = ANY (ARRAY['ADMIN'::public.user_role, 'WRITER'::public.user_role])
|
|
18
|
+
);
|