diff --git a/src/server/docker/.env.example b/src/server/docker/.env.example index 26fa370..96e8034 100644 --- a/src/server/docker/.env.example +++ b/src/server/docker/.env.example @@ -110,6 +110,10 @@ AZURE_REDIRECT_URI= AZURE_TENANT_ID= AZURE_TENANT_URL= +# Gib's Auth (Trying to set up Authentik) +#SAML_ENABLED=false +#SAML_PRIVATE_KEY= + ############ # Studio - Configuration for the Dashboard diff --git a/src/server/docker/docker-compose.yml b/src/server/docker/docker-compose.yml index 2a78f6e..76bcfe8 100644 --- a/src/server/docker/docker-compose.yml +++ b/src/server/docker/docker-compose.yml @@ -5,22 +5,22 @@ # Destroy: docker compose -f docker-compose.yml -f ./dev/docker-compose.dev.yml down -v --remove-orphans # Reset everything: ./reset.sh -name: supabase +name: techtracker networks: - supabase-network: - name: supabase-network + techtracker: + name: techtracker driver: bridge ipam: config: - - subnet: 172.20.0.0/16 + - subnet: 172.19.0.0/16 services: studio: container_name: supabase-studio image: supabase/studio:2025.05.19-sha-3487831 - networks: [supabase-network] + networks: [techtracker] restart: unless-stopped healthcheck: test: @@ -61,7 +61,7 @@ services: kong: container_name: supabase-kong image: kong:2.8.1 - networks: [supabase-network] + networks: [techtracker] restart: unless-stopped ports: - ${KONG_HTTP_PORT}:8000/tcp @@ -90,7 +90,7 @@ services: auth: container_name: supabase-auth image: supabase/gotrue:v2.172.1 - networks: [supabase-network] + networks: [techtracker] restart: unless-stopped healthcheck: test: @@ -173,7 +173,7 @@ services: GOTRUE_EXTERNAL_AZURE_CLIENT_ID: ${AZURE_CLIENT_ID} GOTRUE_EXTERNAL_AZURE_SECRET: ${AZURE_SECRET} GOTRUE_EXTERNAL_AZURE_TENANT_ID: ${AZURE_TENANT_ID} - GOTRUE_EXTERNAL_AZURE_TENANT_URL: ${AZURE_TENANT_URL} + GOTRUE_EXTERNAL_AZURE_URL: ${AZURE_TENANT_URL} GOTRUE_EXTERNAL_AZURE_REDIRECT_URI: ${AZURE_REDIRECT_URI} # Uncomment to enable custom access token hook. Please see: https://supabase.com/docs/guides/auth/auth-hooks for full list of hooks and additional details about custom_access_token_hook @@ -199,7 +199,7 @@ services: rest: container_name: supabase-rest image: postgrest/postgrest:v12.2.12 - networks: [supabase-network] + networks: [techtracker] restart: unless-stopped depends_on: db: @@ -224,7 +224,7 @@ services: # This container name looks inconsistent but is correct because realtime constructs tenant id by parsing the subdomain container_name: realtime-dev.supabase-realtime image: supabase/realtime:v2.34.47 - networks: [supabase-network] + networks: [techtracker] restart: unless-stopped depends_on: db: @@ -270,7 +270,7 @@ services: storage: container_name: supabase-storage image: supabase/storage-api:v1.22.17 - networks: [supabase-network] + networks: [techtracker] restart: unless-stopped volumes: - ./volumes/storage:/var/lib/storage:z @@ -314,7 +314,7 @@ services: imgproxy: container_name: supabase-imgproxy image: darthsim/imgproxy:v3.8.0 - networks: [supabase-network] + networks: [techtracker] restart: unless-stopped volumes: - ./volumes/storage:/var/lib/storage:z @@ -337,7 +337,7 @@ services: meta: container_name: supabase-meta image: supabase/postgres-meta:v0.89.0 - networks: [supabase-network] + networks: [techtracker] restart: unless-stopped depends_on: db: @@ -356,7 +356,7 @@ services: functions: container_name: supabase-edge-functions image: supabase/edge-runtime:v1.67.4 - networks: [supabase-network] + networks: [techtracker] restart: unless-stopped volumes: - ./volumes/functions:/home/deno/functions:Z @@ -381,7 +381,7 @@ services: analytics: container_name: supabase-analytics image: supabase/logflare:1.12.0 - networks: [supabase-network] + networks: [techtracker] restart: unless-stopped ports: - 4000:4000 @@ -430,7 +430,7 @@ services: db: container_name: supabase-db image: supabase/postgres:15.8.1.060 - networks: [supabase-network] + networks: [techtracker] ports: - ${POSTGRES_PORT}:${POSTGRES_PORT} restart: unless-stopped @@ -490,7 +490,7 @@ services: vector: container_name: supabase-vector image: timberio/vector:0.28.1-alpine - networks: [supabase-network] + networks: [techtracker] restart: unless-stopped volumes: - ./volumes/logs/vector.yml:/etc/vector/vector.yml:ro,z @@ -522,7 +522,7 @@ services: supavisor: container_name: supabase-pooler image: supabase/supavisor:2.5.1 - networks: [supabase-network] + networks: [techtracker] restart: unless-stopped ports: #- ${POSTGRES_PORT}:5432 @@ -574,3 +574,4 @@ services: volumes: db-config: + name: techtracker-db-config diff --git a/src/server/docker/volumes/db/init/data.sql b/src/server/docker/volumes/db/init/data.sql index e69de29..d67a532 100755 --- a/src/server/docker/volumes/db/init/data.sql +++ b/src/server/docker/volumes/db/init/data.sql @@ -0,0 +1,126 @@ +-- Create a table for public profiles +create table profiles ( + id uuid references auth.users on delete cascade not null primary key, + updated_at timestamp with time zone, + email text unique, + full_name text, + avatar_url text, + provider text, + + constraint full_name_length check (char_length(full_name) >= 3 and char_length(full_name) <= 50) +); +-- Set up Row Level Security (RLS) +-- See https://supabase.com/docs/guides/auth/row-level-security for more details. +alter table profiles + enable row level security; + +create policy "Public profiles are viewable by everyone." on profiles + for select using (true); + +create policy "Users can insert their own profile." on profiles + for insert with check ((select auth.uid()) = id); + +create policy "Users can update own profile." on profiles + for update using ((select auth.uid()) = id); + +-- This trigger automatically creates a profile entry when a new user signs up via Supabase Auth. +-- See https://supabase.com/docs/guides/auth/managing-user-data#using-triggers for more details. +create function public.handle_new_user() +returns trigger +set search_path = '' +as $$ +begin + insert into public.profiles (id, email, full_name, avatar_url, provider, updated_at) + values ( + new.id, + new.email, + new.raw_user_meta_data->>'full_name', + new.raw_user_meta_data->>'avatar_url', + new.raw_user_meta_data->>'provider', + now() + ); + return new; +end; +$$ language plpgsql security definer; +create trigger on_auth_user_created + after insert on auth.users + for each row execute procedure public.handle_new_user(); + +-- Set up Storage! +insert into storage.buckets (id, name) + values ('avatars', 'avatars'); + +-- Set up access controls for storage. +-- See https://supabase.com/docs/guides/storage#policy-examples for more details. +create policy "Avatar images are publicly accessible." on storage.objects + for select using (bucket_id = 'avatars'); + +create policy "Anyone can upload an avatar." on storage.objects + for insert with check (bucket_id = 'avatars'); + +create policy "Anyone can update an avatar." on storage.objects + for update using (bucket_id = 'avatars'); + +create policy "Anyone can delete an avatar." on storage.objects + for delete using (bucket_id = 'avatars'); + +-- Create a table for public statuses +CREATE TABLE statuses ( + id uuid DEFAULT gen_random_uuid() PRIMARY KEY, + user_id uuid REFERENCES public.profiles ON DELETE CASCADE NOT NULL, + updated_by_id uuid REFERENCES public.profiles ON DELETE SET NULL DEFAULT auth.uid(), + created_at timestamp with time zone DEFAULT now() NOT NULL, + status text NOT NULL, + CONSTRAINT status_length CHECK (char_length(status) >= 3 AND char_length(status) <= 80) +); + +-- Set up Row Level Security (RLS) +ALTER TABLE statuses + ENABLE ROW LEVEL SECURITY; + +-- Policies +CREATE POLICY "Public statuses are viewable by everyone." ON statuses + FOR SELECT USING (true); + +-- RECREATE it using the recommended sub-select form +CREATE POLICY "Authenticated users can insert statuses for any user." + ON public.statuses + FOR INSERT + WITH CHECK ( + (SELECT auth.role()) = 'authenticated' + ); + +-- ADD an UPDATE policy so anyone signed-in can update *any* status +CREATE POLICY "Authenticated users can update statuses for any user." + ON public.statuses + FOR UPDATE + USING ( + (SELECT auth.role()) = 'authenticated' + ) + WITH CHECK ( + (SELECT auth.role()) = 'authenticated' + ); + +-- Function to add first status +CREATE FUNCTION public.handle_first_status() +RETURNS TRIGGER +SET search_path = '' +AS $$ +BEGIN + INSERT INTO public.statuses (user_id, updated_by_id, status) + VALUES ( + NEW.id, + NEW.id, + 'Just joined!' + ); + RETURN NEW; +END; +$$ LANGUAGE plpgsql SECURITY DEFINER; + +-- Create a separate trigger for the status +CREATE TRIGGER on_auth_user_created_add_status + AFTER INSERT ON auth.users + FOR EACH ROW EXECUTE PROCEDURE public.handle_first_status(); + +alter publication supabase_realtime add table profiles; +alter publication supabase_realtime add table statuses;