This commit is contained in:
Jordi Enric
2024-03-13 23:44:46 +01:00
parent b48d3bb72d
commit 6f3a973051
9 changed files with 230 additions and 954 deletions
+5 -5
View File
@@ -20,11 +20,11 @@ export const CodeBlock = ({
});
return (
<div className="rounded-lg bg-slate-900 font-mono text-white">
<div className="flex items-center justify-between px-2">
<h2 className="text-xs text-slate-300">{title || language}</h2>
<button onClick={copy} className="p-2 text-slate-300">
{isCopied ? <Check size="18" /> : <Clipboard size="18" />}
<div className="rounded-lg bg-zinc-900 font-mono text-white">
<div className="flex items-center justify-between pl-2">
<h2 className="text-xs text-zinc-300">{title || language}</h2>
<button onClick={copy} className="p-2 text-zinc-400">
{isCopied ? <Check size="15" /> : <Clipboard size="15" />}
</button>
</div>
<SyntaxHighlighter
@@ -5,11 +5,10 @@ import Spinner from "@/components/Spinner";
import { ZendoEditor } from "@/components/Editor/ZendoEditor";
import { toast } from "sonner";
import { useBlogTags } from "@/components/Editor/Editor.queries";
import { usePostQuery, useUpdatePostTagsMutation } from "@/queries/posts";
import { usePostQuery } from "@/queries/posts";
import { getSupabaseBrowserClient } from "@/lib/supabase";
export default function Post() {
const api = createAPIClient();
const router = useRouter();
const queryClient = useQueryClient();
@@ -18,11 +17,11 @@ export default function Post() {
const sb = getSupabaseBrowserClient();
const { data: post, isLoading } = usePostQuery(postSlug);
const { data: post, isLoading, isRefetching } = usePostQuery(postSlug);
const tags = useBlogTags({ blogId });
if (isLoading || tags.isLoading) {
if (isLoading || tags.isLoading || isRefetching) {
return (
<div className="flex-center p-12">
<Spinner />
@@ -63,7 +62,9 @@ export default function Post() {
}));
if (newTags) {
await sb.from("post_tags").upsert(newTags);
await sb.from("post_tags").upsert(newTags, {
onConflict: "tag_id, post_id, blog_id",
});
}
queryClient.invalidateQueries([
@@ -74,6 +75,8 @@ export default function Post() {
"tags",
]);
queryClient.refetchQueries(["posts", "post", blogId, postSlug]);
toast.success("Post saved!");
} catch (error: any) {
console.error(error);
@@ -1,511 +0,0 @@
drop policy "delete_categories_policy" on "public"."categories";
drop policy "insert_categories_policy" on "public"."categories";
drop policy "select_categories_policy" on "public"."categories";
drop policy "update_categories_policy" on "public"."categories";
drop policy "Allow AUTHED users to query ALL their POSTS" on "public"."posts";
drop policy "Enable delete for users based on user_id" on "public"."posts";
drop policy "Enable insert for authenticated users only" on "public"."posts";
drop policy "Enable read access for all users if published" on "public"."posts";
drop policy "Enable update for users based on user_id" on "public"."posts";
revoke delete on table "public"."admin_users" from "anon";
revoke insert on table "public"."admin_users" from "anon";
revoke references on table "public"."admin_users" from "anon";
revoke select on table "public"."admin_users" from "anon";
revoke trigger on table "public"."admin_users" from "anon";
revoke truncate on table "public"."admin_users" from "anon";
revoke update on table "public"."admin_users" from "anon";
revoke delete on table "public"."admin_users" from "authenticated";
revoke insert on table "public"."admin_users" from "authenticated";
revoke references on table "public"."admin_users" from "authenticated";
revoke select on table "public"."admin_users" from "authenticated";
revoke trigger on table "public"."admin_users" from "authenticated";
revoke truncate on table "public"."admin_users" from "authenticated";
revoke update on table "public"."admin_users" from "authenticated";
revoke delete on table "public"."admin_users" from "service_role";
revoke insert on table "public"."admin_users" from "service_role";
revoke references on table "public"."admin_users" from "service_role";
revoke select on table "public"."admin_users" from "service_role";
revoke trigger on table "public"."admin_users" from "service_role";
revoke truncate on table "public"."admin_users" from "service_role";
revoke update on table "public"."admin_users" from "service_role";
revoke delete on table "public"."categories" from "anon";
revoke insert on table "public"."categories" from "anon";
revoke references on table "public"."categories" from "anon";
revoke select on table "public"."categories" from "anon";
revoke trigger on table "public"."categories" from "anon";
revoke truncate on table "public"."categories" from "anon";
revoke update on table "public"."categories" from "anon";
revoke delete on table "public"."categories" from "authenticated";
revoke insert on table "public"."categories" from "authenticated";
revoke references on table "public"."categories" from "authenticated";
revoke select on table "public"."categories" from "authenticated";
revoke trigger on table "public"."categories" from "authenticated";
revoke truncate on table "public"."categories" from "authenticated";
revoke update on table "public"."categories" from "authenticated";
revoke delete on table "public"."categories" from "service_role";
revoke insert on table "public"."categories" from "service_role";
revoke references on table "public"."categories" from "service_role";
revoke select on table "public"."categories" from "service_role";
revoke trigger on table "public"."categories" from "service_role";
revoke truncate on table "public"."categories" from "service_role";
revoke update on table "public"."categories" from "service_role";
alter table "public"."admin_users" drop constraint "admin_users_user_id_fkey";
alter table "public"."categories" drop constraint "categories_blog_id_fkey";
alter table "public"."categories" drop constraint "categories_blog_id_slug_key";
alter table "public"."posts" drop constraint "unique_slug_per_user_post_constraint";
alter table "public"."admin_users" drop constraint "admin_users_pkey";
alter table "public"."categories" drop constraint "categories_pkey";
alter table "public"."products" drop constraint "products_pkey";
alter table "public"."subscriptions" drop constraint "subscriptions_pkey";
drop index if exists "public"."admin_users_pkey";
drop index if exists "public"."categories_blog_id_slug_key";
drop index if exists "public"."categories_pkey";
drop index if exists "public"."products_pkey";
drop index if exists "public"."subscriptions_pkey";
drop index if exists "public"."unique_slug_per_user_post_constraint";
drop table "public"."admin_users";
drop table "public"."categories";
create table "public"."blog_tags" (
"id" uuid not null default gen_random_uuid(),
"blog_id" uuid not null,
"name" text not null,
"slug" text not null,
"created_at" timestamp with time zone not null default now(),
"updated_at" timestamp with time zone not null default now(),
"description" text
);
alter table "public"."blog_tags" enable row level security;
create table "public"."post_tags" (
"id" bigint generated by default as identity not null,
"created_at" timestamp with time zone not null default now(),
"post_id" uuid not null,
"tag_id" uuid not null,
"blog_id" uuid not null
);
alter table "public"."post_tags" enable row level security;
create table "public"."prices" (
"id" bigint generated by default as identity not null,
"created_at" timestamp with time zone not null default now(),
"price" jsonb not null,
"stripe_price_id" text not null
);
alter table "public"."prices" enable row level security;
alter table "public"."posts" add column "deleted" boolean not null default false;
alter table "public"."posts" add column "deprecated_user_id" text default 'default'::text;
alter table "public"."posts" alter column "user_id" set default auth.uid();
alter table "public"."posts" alter column "user_id" set data type uuid using "user_id"::uuid;
alter table "public"."products" alter column "stripe_product_id" set not null;
alter table "public"."subscriptions" add column "stripe_subscription_id" text not null;
alter table "public"."subscriptions" add column "subscription" jsonb not null;
CREATE UNIQUE INDEX post_categories_pkey ON public.post_tags USING btree (id);
CREATE UNIQUE INDEX prices_pkey ON public.prices USING btree (id, stripe_price_id);
CREATE UNIQUE INDEX prices_stripe_price_id_key ON public.prices USING btree (stripe_price_id);
CREATE UNIQUE INDEX products_stripe_product_id_key ON public.products USING btree (stripe_product_id);
CREATE UNIQUE INDEX subscriptions_stripe_subscription_id_key ON public.subscriptions USING btree (stripe_subscription_id);
CREATE UNIQUE INDEX unique_post_tag_blog_combination ON public.post_tags USING btree (post_id, tag_id, blog_id);
CREATE UNIQUE INDEX categories_blog_id_slug_key ON public.blog_tags USING btree (blog_id, slug);
CREATE UNIQUE INDEX categories_pkey ON public.blog_tags USING btree (id);
CREATE UNIQUE INDEX products_pkey ON public.products USING btree (id, stripe_product_id);
CREATE UNIQUE INDEX subscriptions_pkey ON public.subscriptions USING btree (stripe_subscription_id);
CREATE UNIQUE INDEX unique_slug_per_user_post_constraint ON public.posts USING btree (slug, deprecated_user_id, blog_id);
alter table "public"."blog_tags" add constraint "categories_pkey" PRIMARY KEY using index "categories_pkey";
alter table "public"."post_tags" add constraint "post_categories_pkey" PRIMARY KEY using index "post_categories_pkey";
alter table "public"."prices" add constraint "prices_pkey" PRIMARY KEY using index "prices_pkey";
alter table "public"."products" add constraint "products_pkey" PRIMARY KEY using index "products_pkey";
alter table "public"."subscriptions" add constraint "subscriptions_pkey" PRIMARY KEY using index "subscriptions_pkey";
alter table "public"."blog_tags" add constraint "blog_tags_blog_id_fkey" FOREIGN KEY (blog_id) REFERENCES blogs(id) ON DELETE CASCADE not valid;
alter table "public"."blog_tags" validate constraint "blog_tags_blog_id_fkey";
alter table "public"."blog_tags" add constraint "categories_blog_id_slug_key" UNIQUE using index "categories_blog_id_slug_key";
alter table "public"."post_tags" add constraint "post_tags_blog_id_fkey" FOREIGN KEY (blog_id) REFERENCES blogs(id) not valid;
alter table "public"."post_tags" validate constraint "post_tags_blog_id_fkey";
alter table "public"."post_tags" add constraint "post_tags_post_id_fkey" FOREIGN KEY (post_id) REFERENCES posts(id) not valid;
alter table "public"."post_tags" validate constraint "post_tags_post_id_fkey";
alter table "public"."post_tags" add constraint "post_tags_tag_id_fkey" FOREIGN KEY (tag_id) REFERENCES blog_tags(id) not valid;
alter table "public"."post_tags" validate constraint "post_tags_tag_id_fkey";
alter table "public"."post_tags" add constraint "unique_post_tag_blog_combination" UNIQUE using index "unique_post_tag_blog_combination";
alter table "public"."prices" add constraint "prices_stripe_price_id_key" UNIQUE using index "prices_stripe_price_id_key";
alter table "public"."products" add constraint "products_stripe_product_id_key" UNIQUE using index "products_stripe_product_id_key";
alter table "public"."subscriptions" add constraint "subscriptions_stripe_subscription_id_key" UNIQUE using index "subscriptions_stripe_subscription_id_key";
alter table "public"."posts" add constraint "unique_slug_per_user_post_constraint" UNIQUE using index "unique_slug_per_user_post_constraint";
create or replace view "public"."posts_with_tags" as SELECT p.created_at,
p.deprecated_user_id,
p.blog_id,
p.title,
p.published,
p.content,
p.updated_at,
p.slug,
p.id AS post_id,
p.cover_image,
p.metadata,
p.deleted,
p.user_id,
COALESCE(array_agg(bt.name) FILTER (WHERE (bt.id IS NOT NULL)), '{}'::text[]) AS tags
FROM ((posts p
LEFT JOIN post_tags pt ON ((p.id = pt.post_id)))
LEFT JOIN blog_tags bt ON ((pt.tag_id = bt.id)))
GROUP BY p.created_at, p.deprecated_user_id, p.blog_id, p.title, p.published, p.content, p.updated_at, p.slug, p.id, p.cover_image, p.metadata, p.deleted, p.user_id
ORDER BY p.created_at DESC;
grant delete on table "public"."blog_tags" to "anon";
grant insert on table "public"."blog_tags" to "anon";
grant references on table "public"."blog_tags" to "anon";
grant select on table "public"."blog_tags" to "anon";
grant trigger on table "public"."blog_tags" to "anon";
grant truncate on table "public"."blog_tags" to "anon";
grant update on table "public"."blog_tags" to "anon";
grant delete on table "public"."blog_tags" to "authenticated";
grant insert on table "public"."blog_tags" to "authenticated";
grant references on table "public"."blog_tags" to "authenticated";
grant select on table "public"."blog_tags" to "authenticated";
grant trigger on table "public"."blog_tags" to "authenticated";
grant truncate on table "public"."blog_tags" to "authenticated";
grant update on table "public"."blog_tags" to "authenticated";
grant delete on table "public"."blog_tags" to "service_role";
grant insert on table "public"."blog_tags" to "service_role";
grant references on table "public"."blog_tags" to "service_role";
grant select on table "public"."blog_tags" to "service_role";
grant trigger on table "public"."blog_tags" to "service_role";
grant truncate on table "public"."blog_tags" to "service_role";
grant update on table "public"."blog_tags" to "service_role";
grant delete on table "public"."post_tags" to "anon";
grant insert on table "public"."post_tags" to "anon";
grant references on table "public"."post_tags" to "anon";
grant select on table "public"."post_tags" to "anon";
grant trigger on table "public"."post_tags" to "anon";
grant truncate on table "public"."post_tags" to "anon";
grant update on table "public"."post_tags" to "anon";
grant delete on table "public"."post_tags" to "authenticated";
grant insert on table "public"."post_tags" to "authenticated";
grant references on table "public"."post_tags" to "authenticated";
grant select on table "public"."post_tags" to "authenticated";
grant trigger on table "public"."post_tags" to "authenticated";
grant truncate on table "public"."post_tags" to "authenticated";
grant update on table "public"."post_tags" to "authenticated";
grant delete on table "public"."post_tags" to "service_role";
grant insert on table "public"."post_tags" to "service_role";
grant references on table "public"."post_tags" to "service_role";
grant select on table "public"."post_tags" to "service_role";
grant trigger on table "public"."post_tags" to "service_role";
grant truncate on table "public"."post_tags" to "service_role";
grant update on table "public"."post_tags" to "service_role";
grant delete on table "public"."prices" to "anon";
grant insert on table "public"."prices" to "anon";
grant references on table "public"."prices" to "anon";
grant select on table "public"."prices" to "anon";
grant trigger on table "public"."prices" to "anon";
grant truncate on table "public"."prices" to "anon";
grant update on table "public"."prices" to "anon";
grant delete on table "public"."prices" to "authenticated";
grant insert on table "public"."prices" to "authenticated";
grant references on table "public"."prices" to "authenticated";
grant select on table "public"."prices" to "authenticated";
grant trigger on table "public"."prices" to "authenticated";
grant truncate on table "public"."prices" to "authenticated";
grant update on table "public"."prices" to "authenticated";
grant delete on table "public"."prices" to "service_role";
grant insert on table "public"."prices" to "service_role";
grant references on table "public"."prices" to "service_role";
grant select on table "public"."prices" to "service_role";
grant trigger on table "public"."prices" to "service_role";
grant truncate on table "public"."prices" to "service_role";
grant update on table "public"."prices" to "service_role";
create policy "delete_categories_policy"
on "public"."blog_tags"
as permissive
for delete
to public
using ((EXISTS ( SELECT 1
FROM blogs
WHERE ((blogs.id = blog_tags.blog_id) AND (blogs.user_id = CURRENT_USER)))));
create policy "insert_categories_policy"
on "public"."blog_tags"
as permissive
for insert
to public
with check ((EXISTS ( SELECT 1
FROM blogs
WHERE ((blogs.id = blog_tags.blog_id) AND (blogs.user_id = (auth.uid())::text)))));
create policy "select_categories_policy"
on "public"."blog_tags"
as permissive
for select
to public
using (true);
create policy "update_categories_policy"
on "public"."blog_tags"
as permissive
for update
to public
using ((EXISTS ( SELECT 1
FROM blogs
WHERE ((blogs.id = blog_tags.blog_id) AND (blogs.user_id = CURRENT_USER)))));
create policy "Enable insert for authenticated users only"
on "public"."post_tags"
as permissive
for insert
to authenticated
with check ((EXISTS ( SELECT 1
FROM blogs
WHERE ((blogs.id = post_tags.blog_id) AND (blogs.user_id = (auth.uid())::text)))));
create policy "Enable read access for all users"
on "public"."post_tags"
as permissive
for select
to public
using (true);
create policy "delete_policy"
on "public"."post_tags"
as permissive
for delete
to authenticated
using ((EXISTS ( SELECT 1
FROM blogs
WHERE ((blogs.id = post_tags.blog_id) AND (blogs.user_id = (auth.uid())::text)))));
create policy "update_post_tags"
on "public"."post_tags"
as permissive
for update
to authenticated
using ((EXISTS ( SELECT 1
FROM blogs
WHERE ((blogs.id = post_tags.blog_id) AND (blogs.user_id = (auth.uid())::text)))))
with check (true);
create policy "insert_posts"
on "public"."posts"
as permissive
for insert
to authenticated
with check ((EXISTS ( SELECT 1
FROM blogs
WHERE ((blogs.id = posts.blog_id) AND (blogs.user_id = (auth.uid())::text)))));
create policy "read_posts"
on "public"."posts"
as permissive
for select
to anon
using (((published = true) AND (deleted = false)));
create policy "update_posts"
on "public"."posts"
as permissive
for update
to authenticated
using ((EXISTS ( SELECT 1
FROM blogs
WHERE ((blogs.id = posts.blog_id) AND (blogs.user_id = (auth.uid())::text)))));
create policy "Enable read access for all users"
on "public"."prices"
as permissive
for select
to public
using (true);
create policy "Enable read access for all users"
on "public"."products"
as permissive
for select
to public
using (true);
@@ -1,35 +0,0 @@
drop policy "insert_posts" on "public"."posts";
set check_function_bodies = off;
CREATE OR REPLACE FUNCTION public.is_blog_owner(blog_id uuid, given_user_id uuid)
RETURNS boolean
LANGUAGE plpgsql
AS $function$
BEGIN
RETURN EXISTS (
SELECT 1
FROM public.blogs
WHERE id = blog_id AND user_id = given_user_id::text
);
END;
$function$
;
create policy "authed_read_posts"
on "public"."posts"
as permissive
for select
to authenticated
using (is_blog_owner(blog_id, auth.uid()));
create policy "insert_posts"
on "public"."posts"
as permissive
for insert
to authenticated
with check (is_blog_owner(blog_id, auth.uid()));
@@ -1,205 +0,0 @@
drop policy "delete_categories_policy" on "public"."blog_tags";
drop policy "insert_categories_policy" on "public"."blog_tags";
drop policy "update_categories_policy" on "public"."blog_tags";
drop policy "owners of a blog can create invitations" on "public"."invitations";
drop policy "owners of a blog can delete invitations" on "public"."invitations";
drop policy "owners of the blog can see invitations" on "public"."invitations";
drop policy "Enable insert for authenticated users only" on "public"."post_tags";
drop policy "Enable read access for all users" on "public"."post_tags";
drop policy "delete_policy" on "public"."post_tags";
drop policy "users can crud their blogs" on "public"."blogs";
drop policy "update_post_tags" on "public"."post_tags";
drop policy "update_posts" on "public"."posts";
revoke delete on table "public"."invitations" from "anon";
revoke insert on table "public"."invitations" from "anon";
revoke references on table "public"."invitations" from "anon";
revoke select on table "public"."invitations" from "anon";
revoke trigger on table "public"."invitations" from "anon";
revoke truncate on table "public"."invitations" from "anon";
revoke update on table "public"."invitations" from "anon";
revoke delete on table "public"."invitations" from "authenticated";
revoke insert on table "public"."invitations" from "authenticated";
revoke references on table "public"."invitations" from "authenticated";
revoke select on table "public"."invitations" from "authenticated";
revoke trigger on table "public"."invitations" from "authenticated";
revoke truncate on table "public"."invitations" from "authenticated";
revoke update on table "public"."invitations" from "authenticated";
revoke delete on table "public"."invitations" from "service_role";
revoke insert on table "public"."invitations" from "service_role";
revoke references on table "public"."invitations" from "service_role";
revoke select on table "public"."invitations" from "service_role";
revoke trigger on table "public"."invitations" from "service_role";
revoke truncate on table "public"."invitations" from "service_role";
revoke update on table "public"."invitations" from "service_role";
alter table "public"."invitations" drop constraint "invitations_blog_id_fkey";
alter table "public"."posts" drop constraint "unique_slug_per_user_post_constraint";
drop view if exists "public"."posts_with_tags";
alter table "public"."invitations" drop constraint "invitations_pkey";
drop index if exists "public"."invitations_pkey";
drop index if exists "public"."unique_slug_per_user_post_constraint";
drop table "public"."invitations";
alter table "public"."blogs" alter column "user_id" drop default;
alter table "public"."blogs" alter column "user_id" set data type uuid using "user_id"::uuid;
alter table "public"."posts" drop column "deprecated_user_id";
CREATE UNIQUE INDEX unique_slug_per_user_blog_constraint ON public.posts USING btree (slug, user_id, blog_id);
alter table "public"."blogs" add constraint "fk_blogs_users" FOREIGN KEY (user_id) REFERENCES auth.users(id) not valid;
alter table "public"."blogs" validate constraint "fk_blogs_users";
alter table "public"."posts" add constraint "public_posts_user_id_fkey" FOREIGN KEY (user_id) REFERENCES auth.users(id) not valid;
alter table "public"."posts" validate constraint "public_posts_user_id_fkey";
set check_function_bodies = off;
CREATE OR REPLACE FUNCTION public.is_blog_owner(blog_id uuid, given_user_id uuid)
RETURNS boolean
LANGUAGE plpgsql
AS $function$
BEGIN
RETURN EXISTS (
SELECT 1
FROM public.blogs
WHERE id = blog_id AND user_id = given_user_id
);
END;
$function$
;
create or replace view "public"."posts_with_tags" as SELECT p.created_at,
p.blog_id,
p.title,
p.published,
p.content,
p.updated_at,
p.slug,
p.id AS post_id,
p.cover_image,
p.metadata,
p.deleted,
COALESCE(array_agg(bt.name) FILTER (WHERE (bt.id IS NOT NULL)), '{}'::text[]) AS tags
FROM ((posts p
LEFT JOIN post_tags pt ON ((p.id = pt.post_id)))
LEFT JOIN blog_tags bt ON ((pt.tag_id = bt.id)))
GROUP BY p.created_at, p.blog_id, p.title, p.published, p.content, p.updated_at, p.slug, p.id, p.cover_image, p.metadata, p.deleted, p.user_id
ORDER BY p.created_at DESC;
create policy "delete_tags"
on "public"."blog_tags"
as permissive
for delete
to public
using (is_blog_owner(blog_id, auth.uid()));
create policy "insert_tags"
on "public"."blog_tags"
as permissive
for insert
to public
with check (is_blog_owner(blog_id, auth.uid()));
create policy "update_tags"
on "public"."blog_tags"
as permissive
for update
to public
using (is_blog_owner(blog_id, auth.uid()));
create policy "delete_post_tag"
on "public"."post_tags"
as permissive
for delete
to authenticated
using (is_blog_owner(blog_id, auth.uid()));
create policy "insert_post_tag"
on "public"."post_tags"
as permissive
for insert
to authenticated
with check (is_blog_owner(blog_id, auth.uid()));
create policy "read_post_tags"
on "public"."post_tags"
as permissive
for select
to public
using (true);
create policy "users can crud their blogs"
on "public"."blogs"
as permissive
for all
to authenticated
using ((auth.uid() = user_id));
create policy "update_post_tags"
on "public"."post_tags"
as permissive
for update
to authenticated
using (is_blog_owner(blog_id, auth.uid()))
with check (true);
create policy "update_posts"
on "public"."posts"
as permissive
for update
to authenticated
using (is_blog_owner(blog_id, auth.uid()));
@@ -1,25 +0,0 @@
create or replace view "public"."posts_with_blog_and_subscription_status" as SELECT p.created_at,
p.blog_id,
p.title,
p.published,
p.content,
p.updated_at,
p.slug,
p.id AS post_id,
p.cover_image,
p.metadata,
p.deleted,
COALESCE(array_agg(bt.name) FILTER (WHERE (bt.id IS NOT NULL)), '{}'::text[]) AS tags,
t.owner_id,
s.status AS subscription_status
FROM (((((posts p
LEFT JOIN blogs b ON ((p.blog_id = b.id)))
LEFT JOIN teams t ON ((b.user_id = t.owner_id)))
LEFT JOIN subscriptions s ON ((t.owner_id = s.user_id)))
LEFT JOIN post_tags pt ON ((p.id = pt.post_id)))
LEFT JOIN blog_tags bt ON ((pt.tag_id = bt.id)))
GROUP BY p.created_at, p.blog_id, p.title, p.published, p.content, p.updated_at, p.slug, p.id, p.cover_image, p.metadata, p.deleted, p.user_id, t.owner_id, s.status
ORDER BY p.created_at DESC;
@@ -1,33 +0,0 @@
alter table "public"."blogs" drop constraint "fk_blogs_users";
drop view if exists "public"."posts_with_blog_and_subscription_status";
alter table "public"."blogs" alter column "user_id" set default auth.uid();
alter table "public"."blogs" add constraint "blogs_user_id_fkey" FOREIGN KEY (user_id) REFERENCES auth.users(id) not valid;
alter table "public"."blogs" validate constraint "blogs_user_id_fkey";
create or replace view "public"."posts_with_blog_and_subscription_status" as SELECT p.created_at,
p.blog_id,
p.title,
p.published,
p.content,
p.updated_at,
p.slug,
p.id AS post_id,
p.cover_image,
p.metadata,
p.deleted,
COALESCE(array_agg(bt.name) FILTER (WHERE (bt.id IS NOT NULL)), '{}'::text[]) AS tags,
s.status AS subscription_status
FROM ((((posts p
LEFT JOIN blogs b ON ((p.blog_id = b.id)))
LEFT JOIN subscriptions s ON ((b.user_id = s.user_id)))
LEFT JOIN post_tags pt ON ((p.id = pt.post_id)))
LEFT JOIN blog_tags bt ON ((pt.tag_id = bt.id)))
GROUP BY p.created_at, p.blog_id, p.title, p.published, p.content, p.updated_at, p.slug, p.id, p.cover_image, p.metadata, p.deleted, p.user_id, s.status
ORDER BY p.created_at DESC;
@@ -10,28 +10,14 @@ SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
CREATE EXTENSION IF NOT EXISTS "timescaledb" WITH SCHEMA "extensions";
CREATE SCHEMA IF NOT EXISTS "public";
CREATE EXTENSION IF NOT EXISTS "pg_net" WITH SCHEMA "extensions";
CREATE EXTENSION IF NOT EXISTS "pgsodium" WITH SCHEMA "pgsodium";
ALTER SCHEMA "public" OWNER TO "pg_database_owner";
CREATE SCHEMA IF NOT EXISTS "stripe";
ALTER SCHEMA "stripe" OWNER TO "postgres";
CREATE EXTENSION IF NOT EXISTS "pg_graphql" WITH SCHEMA "graphql";
CREATE EXTENSION IF NOT EXISTS "pg_stat_statements" WITH SCHEMA "extensions";
CREATE EXTENSION IF NOT EXISTS "pgcrypto" WITH SCHEMA "extensions";
CREATE EXTENSION IF NOT EXISTS "pgjwt" WITH SCHEMA "extensions";
CREATE EXTENSION IF NOT EXISTS "supabase_vault" WITH SCHEMA "vault";
CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA "extensions";
CREATE OR REPLACE FUNCTION "public"."generate_random_string"("length" integer) RETURNS "text"
LANGUAGE "plpgsql"
AS $$
@@ -73,6 +59,20 @@ $$;
ALTER FUNCTION "public"."generate_slug"("title" "text") OWNER TO "postgres";
CREATE OR REPLACE FUNCTION "public"."is_blog_owner"("blog_id" "uuid", "given_user_id" "uuid") RETURNS boolean
LANGUAGE "plpgsql"
AS $$
BEGIN
RETURN EXISTS (
SELECT 1
FROM public.blogs
WHERE id = blog_id AND user_id = given_user_id
);
END;
$$;
ALTER FUNCTION "public"."is_blog_owner"("blog_id" "uuid", "given_user_id" "uuid") OWNER TO "postgres";
CREATE OR REPLACE FUNCTION "public"."requesting_user_id"() RETURNS "text"
LANGUAGE "sql" STABLE
AS $$
@@ -85,46 +85,30 @@ SET default_tablespace = '';
SET default_table_access_method = "heap";
CREATE TABLE IF NOT EXISTS "public"."admin_users" (
"id" bigint NOT NULL,
CREATE TABLE IF NOT EXISTS "public"."blog_tags" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"blog_id" "uuid" NOT NULL,
"name" "text" NOT NULL,
"slug" "text" NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"user_id" "uuid"
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"description" "text"
);
ALTER TABLE "public"."admin_users" OWNER TO "postgres";
ALTER TABLE "public"."admin_users" ALTER COLUMN "id" ADD GENERATED BY DEFAULT AS IDENTITY (
SEQUENCE NAME "public"."admin_users_id_seq"
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1
);
ALTER TABLE "public"."blog_tags" OWNER TO "postgres";
CREATE TABLE IF NOT EXISTS "public"."blogs" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"title" "text" NOT NULL,
"emoji" "text" NOT NULL,
"user_id" "text" DEFAULT "public"."requesting_user_id"() NOT NULL,
"user_id" "uuid" DEFAULT "auth"."uid"() NOT NULL,
"description" "text",
"public_id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL
);
ALTER TABLE "public"."blogs" OWNER TO "postgres";
CREATE TABLE IF NOT EXISTS "public"."categories" (
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"blog_id" "uuid" NOT NULL,
"name" "text" NOT NULL,
"slug" "text" NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"updated_at" timestamp with time zone DEFAULT "now"() NOT NULL
);
ALTER TABLE "public"."categories" OWNER TO "postgres";
CREATE TABLE IF NOT EXISTS "public"."feedback" (
"id" bigint NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
@@ -161,19 +145,28 @@ ALTER TABLE "public"."homepage_signup" ALTER COLUMN "id" ADD GENERATED BY DEFAUL
CACHE 1
);
CREATE TABLE IF NOT EXISTS "public"."invitations" (
CREATE TABLE IF NOT EXISTS "public"."post_tags" (
"id" bigint NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"blog_id" "uuid" NOT NULL,
"email" "text" NOT NULL,
"name" "text" NOT NULL,
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL
"post_id" "uuid" NOT NULL,
"tag_id" "uuid" NOT NULL,
"blog_id" "uuid" NOT NULL
);
ALTER TABLE "public"."invitations" OWNER TO "postgres";
ALTER TABLE "public"."post_tags" OWNER TO "postgres";
ALTER TABLE "public"."post_tags" ALTER COLUMN "id" ADD GENERATED BY DEFAULT AS IDENTITY (
SEQUENCE NAME "public"."post_tags_id_seq"
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1
);
CREATE TABLE IF NOT EXISTS "public"."posts" (
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"user_id" "text" DEFAULT "public"."requesting_user_id"() NOT NULL,
"user_id" "uuid" DEFAULT "auth"."uid"() NOT NULL,
"blog_id" "uuid" NOT NULL,
"title" "text" NOT NULL,
"published" boolean DEFAULT false NOT NULL,
@@ -182,16 +175,91 @@ CREATE TABLE IF NOT EXISTS "public"."posts" (
"slug" "text" NOT NULL,
"id" "uuid" DEFAULT "gen_random_uuid"() NOT NULL,
"cover_image" "text",
"metadata" "jsonb"[]
"metadata" "jsonb"[],
"deleted" boolean DEFAULT false NOT NULL,
"published_at" timestamp with time zone DEFAULT "now"()
);
ALTER TABLE "public"."posts" OWNER TO "postgres";
CREATE TABLE IF NOT EXISTS "public"."subscriptions" (
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"user_id" "uuid" NOT NULL,
"status" "text" NOT NULL,
"stripe_subscription_id" "text" NOT NULL,
"subscription" "jsonb" NOT NULL
);
ALTER TABLE "public"."subscriptions" OWNER TO "postgres";
CREATE OR REPLACE VIEW "public"."posts_with_blog_and_subscription_status" AS
SELECT "p"."created_at",
"p"."blog_id",
"p"."title",
"p"."published",
"p"."content",
"p"."updated_at",
"p"."slug",
"p"."id" AS "post_id",
"p"."cover_image",
"p"."metadata",
"p"."deleted",
COALESCE("array_agg"("bt"."name") FILTER (WHERE ("bt"."id" IS NOT NULL)), '{}'::"text"[]) AS "tags",
"s"."status" AS "subscription_status"
FROM (((("public"."posts" "p"
LEFT JOIN "public"."blogs" "b" ON (("p"."blog_id" = "b"."id")))
LEFT JOIN "public"."subscriptions" "s" ON (("b"."user_id" = "s"."user_id")))
LEFT JOIN "public"."post_tags" "pt" ON (("p"."id" = "pt"."post_id")))
LEFT JOIN "public"."blog_tags" "bt" ON (("pt"."tag_id" = "bt"."id")))
GROUP BY "p"."created_at", "p"."blog_id", "p"."title", "p"."published", "p"."content", "p"."updated_at", "p"."slug", "p"."id", "p"."cover_image", "p"."metadata", "p"."deleted", "p"."user_id", "s"."status"
ORDER BY "p"."created_at" DESC;
ALTER TABLE "public"."posts_with_blog_and_subscription_status" OWNER TO "postgres";
CREATE OR REPLACE VIEW "public"."posts_with_tags" AS
SELECT "p"."created_at",
"p"."blog_id",
"p"."title",
"p"."published",
"p"."content",
"p"."updated_at",
"p"."slug",
"p"."id" AS "post_id",
"p"."cover_image",
"p"."metadata",
"p"."deleted",
COALESCE("array_agg"("bt"."name") FILTER (WHERE ("bt"."id" IS NOT NULL)), '{}'::"text"[]) AS "tags"
FROM (("public"."posts" "p"
LEFT JOIN "public"."post_tags" "pt" ON (("p"."id" = "pt"."post_id")))
LEFT JOIN "public"."blog_tags" "bt" ON (("pt"."tag_id" = "bt"."id")))
GROUP BY "p"."created_at", "p"."blog_id", "p"."title", "p"."published", "p"."content", "p"."updated_at", "p"."slug", "p"."id", "p"."cover_image", "p"."metadata", "p"."deleted", "p"."user_id"
ORDER BY "p"."created_at" DESC;
ALTER TABLE "public"."posts_with_tags" OWNER TO "postgres";
CREATE TABLE IF NOT EXISTS "public"."prices" (
"id" bigint NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"price" "jsonb" NOT NULL,
"stripe_price_id" "text" NOT NULL
);
ALTER TABLE "public"."prices" OWNER TO "postgres";
ALTER TABLE "public"."prices" ALTER COLUMN "id" ADD GENERATED BY DEFAULT AS IDENTITY (
SEQUENCE NAME "public"."prices_id_seq"
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1
);
CREATE TABLE IF NOT EXISTS "public"."products" (
"id" bigint NOT NULL,
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"product" "jsonb" NOT NULL,
"stripe_product_id" "text"
"stripe_product_id" "text" NOT NULL
);
ALTER TABLE "public"."products" OWNER TO "postgres";
@@ -205,14 +273,6 @@ ALTER TABLE "public"."products" ALTER COLUMN "id" ADD GENERATED BY DEFAULT AS ID
CACHE 1
);
CREATE TABLE IF NOT EXISTS "public"."subscriptions" (
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"user_id" "uuid" NOT NULL,
"status" "text" NOT NULL
);
ALTER TABLE "public"."subscriptions" OWNER TO "postgres";
CREATE TABLE IF NOT EXISTS "public"."teams" (
"created_at" timestamp with time zone DEFAULT "now"() NOT NULL,
"owner_id" "uuid",
@@ -271,16 +331,13 @@ CREATE OR REPLACE VIEW "public"."users" AS
ALTER TABLE "public"."users" OWNER TO "postgres";
ALTER TABLE ONLY "public"."admin_users"
ADD CONSTRAINT "admin_users_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."blogs"
ADD CONSTRAINT "blogs_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."categories"
ALTER TABLE ONLY "public"."blog_tags"
ADD CONSTRAINT "categories_blog_id_slug_key" UNIQUE ("blog_id", "slug");
ALTER TABLE ONLY "public"."categories"
ALTER TABLE ONLY "public"."blog_tags"
ADD CONSTRAINT "categories_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."feedback"
@@ -289,17 +346,29 @@ ALTER TABLE ONLY "public"."feedback"
ALTER TABLE ONLY "public"."homepage_signup"
ADD CONSTRAINT "homepage_signup_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."invitations"
ADD CONSTRAINT "invitations_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."post_tags"
ADD CONSTRAINT "post_categories_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."posts"
ADD CONSTRAINT "posts_pkey" PRIMARY KEY ("id");
ALTER TABLE ONLY "public"."prices"
ADD CONSTRAINT "prices_pkey" PRIMARY KEY ("id", "stripe_price_id");
ALTER TABLE ONLY "public"."prices"
ADD CONSTRAINT "prices_stripe_price_id_key" UNIQUE ("stripe_price_id");
ALTER TABLE ONLY "public"."products"
ADD CONSTRAINT "products_pkey" PRIMARY KEY ("id");
ADD CONSTRAINT "products_pkey" PRIMARY KEY ("id", "stripe_product_id");
ALTER TABLE ONLY "public"."products"
ADD CONSTRAINT "products_stripe_product_id_key" UNIQUE ("stripe_product_id");
ALTER TABLE ONLY "public"."subscriptions"
ADD CONSTRAINT "subscriptions_pkey" PRIMARY KEY ("user_id");
ADD CONSTRAINT "subscriptions_pkey" PRIMARY KEY ("stripe_subscription_id");
ALTER TABLE ONLY "public"."subscriptions"
ADD CONSTRAINT "subscriptions_stripe_subscription_id_key" UNIQUE ("stripe_subscription_id");
ALTER TABLE ONLY "public"."subscriptions"
ADD CONSTRAINT "subscriptions_user_id_key" UNIQUE ("user_id");
@@ -313,106 +382,101 @@ ALTER TABLE ONLY "public"."teams"
ALTER TABLE ONLY "public"."teams"
ADD CONSTRAINT "teams_ref_key" UNIQUE ("ref");
ALTER TABLE ONLY "public"."posts"
ADD CONSTRAINT "unique_slug_per_user_post_constraint" UNIQUE ("slug", "user_id", "blog_id");
ALTER TABLE ONLY "public"."post_tags"
ADD CONSTRAINT "unique_post_tag_blog_combination" UNIQUE ("post_id", "tag_id", "blog_id");
CREATE INDEX "posts_slug_blog_id_idx" ON "public"."posts" USING "btree" ("slug", "blog_id");
CREATE INDEX "posts_slug_idx" ON "public"."posts" USING "btree" ("slug");
ALTER TABLE ONLY "public"."admin_users"
ADD CONSTRAINT "admin_users_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id");
CREATE UNIQUE INDEX "unique_slug_per_user_blog_constraint" ON "public"."posts" USING "btree" ("slug", "user_id", "blog_id");
ALTER TABLE ONLY "public"."categories"
ADD CONSTRAINT "categories_blog_id_fkey" FOREIGN KEY ("blog_id") REFERENCES "public"."blogs"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."blog_tags"
ADD CONSTRAINT "blog_tags_blog_id_fkey" FOREIGN KEY ("blog_id") REFERENCES "public"."blogs"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."invitations"
ADD CONSTRAINT "invitations_blog_id_fkey" FOREIGN KEY ("blog_id") REFERENCES "public"."blogs"("id");
ALTER TABLE ONLY "public"."blogs"
ADD CONSTRAINT "blogs_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id");
ALTER TABLE ONLY "public"."post_tags"
ADD CONSTRAINT "post_tags_blog_id_fkey" FOREIGN KEY ("blog_id") REFERENCES "public"."blogs"("id");
ALTER TABLE ONLY "public"."post_tags"
ADD CONSTRAINT "post_tags_post_id_fkey" FOREIGN KEY ("post_id") REFERENCES "public"."posts"("id");
ALTER TABLE ONLY "public"."post_tags"
ADD CONSTRAINT "post_tags_tag_id_fkey" FOREIGN KEY ("tag_id") REFERENCES "public"."blog_tags"("id");
ALTER TABLE ONLY "public"."posts"
ADD CONSTRAINT "posts_blog_id_fkey" FOREIGN KEY ("blog_id") REFERENCES "public"."blogs"("id") ON DELETE CASCADE;
ALTER TABLE ONLY "public"."posts"
ADD CONSTRAINT "public_posts_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id");
ALTER TABLE ONLY "public"."teams"
ADD CONSTRAINT "public_teams_owner_id_fkey" FOREIGN KEY ("owner_id") REFERENCES "auth"."users"("id");
ALTER TABLE ONLY "public"."subscriptions"
ADD CONSTRAINT "subscriptions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id");
CREATE POLICY "Allow AUTHED users to query ALL their POSTS" ON "public"."posts" FOR SELECT TO "authenticated" USING ((("auth"."uid"())::"text" = "user_id"));
CREATE POLICY "Enable INSERT access for all users" ON "public"."homepage_signup" FOR INSERT TO "anon" WITH CHECK (true);
CREATE POLICY "Enable delete for users based on user_id" ON "public"."posts" FOR DELETE USING ((("auth"."uid"())::"text" = "user_id"));
CREATE POLICY "Enable insert for authenticated users only" ON "public"."feedback" FOR INSERT TO "authenticated" WITH CHECK (true);
CREATE POLICY "Enable insert for authenticated users only" ON "public"."posts" FOR INSERT TO "authenticated" WITH CHECK ((("auth"."uid"())::"text" = "user_id"));
CREATE POLICY "Enable insert for owners" ON "public"."teams" FOR INSERT TO "authenticated" WITH CHECK (("auth"."uid"() = "owner_id"));
CREATE POLICY "Enable read access for all users" ON "public"."prices" FOR SELECT USING (true);
CREATE POLICY "Enable read access for all users" ON "public"."products" FOR SELECT USING (true);
CREATE POLICY "Enable read access for all users" ON "public"."teams" FOR SELECT USING (true);
CREATE POLICY "Enable read access for all users if published" ON "public"."posts" FOR SELECT TO "anon" USING (("published" = true));
CREATE POLICY "authed_read_posts" ON "public"."posts" FOR SELECT TO "authenticated" USING ("public"."is_blog_owner"("blog_id", "auth"."uid"()));
CREATE POLICY "Enable update for users based on user_id" ON "public"."posts" FOR UPDATE USING ((("auth"."uid"())::"text" = "user_id"));
ALTER TABLE "public"."admin_users" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."blog_tags" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."blogs" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."categories" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "delete_post_tag" ON "public"."post_tags" FOR DELETE TO "authenticated" USING ("public"."is_blog_owner"("blog_id", "auth"."uid"()));
CREATE POLICY "delete_categories_policy" ON "public"."categories" FOR DELETE USING ((EXISTS ( SELECT 1
FROM "public"."blogs"
WHERE (("blogs"."id" = "categories"."blog_id") AND ("blogs"."user_id" = CURRENT_USER)))));
CREATE POLICY "delete_tags" ON "public"."blog_tags" FOR DELETE USING ("public"."is_blog_owner"("blog_id", "auth"."uid"()));
ALTER TABLE "public"."feedback" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."homepage_signup" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "insert_categories_policy" ON "public"."categories" FOR INSERT WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."blogs"
WHERE (("blogs"."id" = "categories"."blog_id") AND ("blogs"."user_id" = CURRENT_USER)))));
CREATE POLICY "insert_post_tag" ON "public"."post_tags" FOR INSERT TO "authenticated" WITH CHECK ("public"."is_blog_owner"("blog_id", "auth"."uid"()));
ALTER TABLE "public"."invitations" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "insert_posts" ON "public"."posts" FOR INSERT TO "authenticated" WITH CHECK ("public"."is_blog_owner"("blog_id", "auth"."uid"()));
CREATE POLICY "owners of a blog can create invitations" ON "public"."invitations" FOR INSERT TO "authenticated" WITH CHECK ((EXISTS ( SELECT 1
FROM "public"."blogs"
WHERE (("blogs"."id" = "invitations"."blog_id") AND ("blogs"."user_id" = "public"."requesting_user_id"())))));
CREATE POLICY "insert_tags" ON "public"."blog_tags" FOR INSERT WITH CHECK ("public"."is_blog_owner"("blog_id", "auth"."uid"()));
CREATE POLICY "owners of a blog can delete invitations" ON "public"."invitations" FOR DELETE TO "authenticated" USING ((EXISTS ( SELECT 1
FROM "public"."blogs"
WHERE (("blogs"."id" = "invitations"."blog_id") AND ("blogs"."user_id" = "public"."requesting_user_id"())))));
CREATE POLICY "owners of the blog can see invitations" ON "public"."invitations" FOR SELECT TO "authenticated" USING ((EXISTS ( SELECT "blogs"."id",
"blogs"."created_at",
"blogs"."title",
"blogs"."emoji",
"blogs"."user_id",
"blogs"."description",
"blogs"."public_id"
FROM "public"."blogs"
WHERE (("blogs"."id" = "invitations"."blog_id") AND ("blogs"."user_id" = "public"."requesting_user_id"())))));
ALTER TABLE "public"."post_tags" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."posts" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."prices" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."products" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "read_post_tags" ON "public"."post_tags" FOR SELECT USING (true);
CREATE POLICY "read_posts" ON "public"."posts" FOR SELECT TO "anon" USING ((("published" = true) AND ("deleted" = false)));
CREATE POLICY "select subscription" ON "public"."subscriptions" FOR SELECT TO "authenticated" USING (("auth"."uid"() = "user_id"));
CREATE POLICY "select_categories_policy" ON "public"."categories" FOR SELECT USING ((EXISTS ( SELECT 1
FROM "public"."blogs"
WHERE (("blogs"."id" = "categories"."blog_id") AND ("blogs"."user_id" = CURRENT_USER)))));
CREATE POLICY "select_categories_policy" ON "public"."blog_tags" FOR SELECT USING (true);
ALTER TABLE "public"."subscriptions" ENABLE ROW LEVEL SECURITY;
ALTER TABLE "public"."teams" ENABLE ROW LEVEL SECURITY;
CREATE POLICY "update_categories_policy" ON "public"."categories" FOR UPDATE USING ((EXISTS ( SELECT 1
FROM "public"."blogs"
WHERE (("blogs"."id" = "categories"."blog_id") AND ("blogs"."user_id" = CURRENT_USER)))));
CREATE POLICY "update_post_tags" ON "public"."post_tags" FOR UPDATE TO "authenticated" USING ("public"."is_blog_owner"("blog_id", "auth"."uid"())) WITH CHECK (true);
CREATE POLICY "users can crud their blogs" ON "public"."blogs" TO "authenticated" USING ((("auth"."uid"())::"text" = "user_id"));
CREATE POLICY "update_posts" ON "public"."posts" FOR UPDATE TO "authenticated" USING ("public"."is_blog_owner"("blog_id", "auth"."uid"()));
CREATE POLICY "update_tags" ON "public"."blog_tags" FOR UPDATE USING ("public"."is_blog_owner"("blog_id", "auth"."uid"()));
CREATE POLICY "users can crud their blogs" ON "public"."blogs" TO "authenticated" USING (("auth"."uid"() = "user_id"));
REVOKE USAGE ON SCHEMA "public" FROM PUBLIC;
GRANT USAGE ON SCHEMA "public" TO "postgres";
@@ -428,26 +492,22 @@ GRANT ALL ON FUNCTION "public"."generate_slug"("title" "text") TO "anon";
GRANT ALL ON FUNCTION "public"."generate_slug"("title" "text") TO "authenticated";
GRANT ALL ON FUNCTION "public"."generate_slug"("title" "text") TO "service_role";
GRANT ALL ON FUNCTION "public"."is_blog_owner"("blog_id" "uuid", "given_user_id" "uuid") TO "anon";
GRANT ALL ON FUNCTION "public"."is_blog_owner"("blog_id" "uuid", "given_user_id" "uuid") TO "authenticated";
GRANT ALL ON FUNCTION "public"."is_blog_owner"("blog_id" "uuid", "given_user_id" "uuid") TO "service_role";
GRANT ALL ON FUNCTION "public"."requesting_user_id"() TO "anon";
GRANT ALL ON FUNCTION "public"."requesting_user_id"() TO "authenticated";
GRANT ALL ON FUNCTION "public"."requesting_user_id"() TO "service_role";
GRANT ALL ON TABLE "public"."admin_users" TO "anon";
GRANT ALL ON TABLE "public"."admin_users" TO "authenticated";
GRANT ALL ON TABLE "public"."admin_users" TO "service_role";
GRANT ALL ON SEQUENCE "public"."admin_users_id_seq" TO "anon";
GRANT ALL ON SEQUENCE "public"."admin_users_id_seq" TO "authenticated";
GRANT ALL ON SEQUENCE "public"."admin_users_id_seq" TO "service_role";
GRANT ALL ON TABLE "public"."blog_tags" TO "anon";
GRANT ALL ON TABLE "public"."blog_tags" TO "authenticated";
GRANT ALL ON TABLE "public"."blog_tags" TO "service_role";
GRANT ALL ON TABLE "public"."blogs" TO "anon";
GRANT ALL ON TABLE "public"."blogs" TO "authenticated";
GRANT ALL ON TABLE "public"."blogs" TO "service_role";
GRANT ALL ON TABLE "public"."categories" TO "anon";
GRANT ALL ON TABLE "public"."categories" TO "authenticated";
GRANT ALL ON TABLE "public"."categories" TO "service_role";
GRANT ALL ON TABLE "public"."feedback" TO "anon";
GRANT ALL ON TABLE "public"."feedback" TO "authenticated";
GRANT ALL ON TABLE "public"."feedback" TO "service_role";
@@ -464,14 +524,38 @@ GRANT ALL ON SEQUENCE "public"."homepage_signup_id_seq" TO "anon";
GRANT ALL ON SEQUENCE "public"."homepage_signup_id_seq" TO "authenticated";
GRANT ALL ON SEQUENCE "public"."homepage_signup_id_seq" TO "service_role";
GRANT ALL ON TABLE "public"."invitations" TO "anon";
GRANT ALL ON TABLE "public"."invitations" TO "authenticated";
GRANT ALL ON TABLE "public"."invitations" TO "service_role";
GRANT ALL ON TABLE "public"."post_tags" TO "anon";
GRANT ALL ON TABLE "public"."post_tags" TO "authenticated";
GRANT ALL ON TABLE "public"."post_tags" TO "service_role";
GRANT ALL ON SEQUENCE "public"."post_tags_id_seq" TO "anon";
GRANT ALL ON SEQUENCE "public"."post_tags_id_seq" TO "authenticated";
GRANT ALL ON SEQUENCE "public"."post_tags_id_seq" TO "service_role";
GRANT ALL ON TABLE "public"."posts" TO "anon";
GRANT ALL ON TABLE "public"."posts" TO "authenticated";
GRANT ALL ON TABLE "public"."posts" TO "service_role";
GRANT ALL ON TABLE "public"."subscriptions" TO "anon";
GRANT ALL ON TABLE "public"."subscriptions" TO "authenticated";
GRANT ALL ON TABLE "public"."subscriptions" TO "service_role";
GRANT ALL ON TABLE "public"."posts_with_blog_and_subscription_status" TO "anon";
GRANT ALL ON TABLE "public"."posts_with_blog_and_subscription_status" TO "authenticated";
GRANT ALL ON TABLE "public"."posts_with_blog_and_subscription_status" TO "service_role";
GRANT ALL ON TABLE "public"."posts_with_tags" TO "anon";
GRANT ALL ON TABLE "public"."posts_with_tags" TO "authenticated";
GRANT ALL ON TABLE "public"."posts_with_tags" TO "service_role";
GRANT ALL ON TABLE "public"."prices" TO "anon";
GRANT ALL ON TABLE "public"."prices" TO "authenticated";
GRANT ALL ON TABLE "public"."prices" TO "service_role";
GRANT ALL ON SEQUENCE "public"."prices_id_seq" TO "anon";
GRANT ALL ON SEQUENCE "public"."prices_id_seq" TO "authenticated";
GRANT ALL ON SEQUENCE "public"."prices_id_seq" TO "service_role";
GRANT ALL ON TABLE "public"."products" TO "anon";
GRANT ALL ON TABLE "public"."products" TO "authenticated";
GRANT ALL ON TABLE "public"."products" TO "service_role";
@@ -480,10 +564,6 @@ GRANT ALL ON SEQUENCE "public"."products_id_seq" TO "anon";
GRANT ALL ON SEQUENCE "public"."products_id_seq" TO "authenticated";
GRANT ALL ON SEQUENCE "public"."products_id_seq" TO "service_role";
GRANT ALL ON TABLE "public"."subscriptions" TO "anon";
GRANT ALL ON TABLE "public"."subscriptions" TO "authenticated";
GRANT ALL ON TABLE "public"."subscriptions" TO "service_role";
GRANT ALL ON TABLE "public"."teams" TO "anon";
GRANT ALL ON TABLE "public"."teams" TO "authenticated";
GRANT ALL ON TABLE "public"."teams" TO "service_role";
+3 -1
View File
@@ -2,8 +2,9 @@
## General
- [] bug when adding a second tag to a post
- [x] License
- [] FAQ on homepage
- [] FAQ on homepage?
- [] Update README
- [] Homepage use cases examples: personal blog, docs, careers page, product listing pages, help center, changelogs, directory websites, etc.
- [] email provider
@@ -45,6 +46,7 @@
## Posts
- [] When uploading an image, it would be nice if you could rename it before uploading.
- [] See "published at" and "updated at" dates in post list
- [] change published date in post settings
- [x] View all posts