diff --git a/apps/e2e/playwright.config.ts b/apps/e2e/playwright.config.ts index 17dbdc0b8..f8875d4a3 100644 --- a/apps/e2e/playwright.config.ts +++ b/apps/e2e/playwright.config.ts @@ -26,7 +26,7 @@ export default defineConfig({ baseURL: 'http://localhost:3000', // take a screenshot when a test fails - screenshot: 'on', + screenshot: 'only-on-failure', /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry' @@ -68,10 +68,11 @@ export default defineConfig({ /* Run your local dev server before starting the tests */ webServer: { - command: 'cd ../../ && pnpm run dev', + cwd: '../../', + command: 'pnpm run dev', url: 'http://localhost:3000', reuseExistingServer: !process.env.CI, stdout: 'pipe', - stderr: 'pipe' + stderr: 'pipe', } }); diff --git a/apps/web/package.json b/apps/web/package.json index 56b10b659..6c9f7012b 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -19,14 +19,15 @@ "with-env:test": "dotenv -e ./.env.test --", "supabase:start": "supabase status || supabase start", "supabase:stop": "supabase stop", - "supabase:reset": "supabase db reset || supabase start", + "supabase:reset": "supabase db reset", "supabase:status": "supabase status", "supabase:test": "supabase db test", "supabase:db:lint": "supabase db lint", "supabase:deploy": "supabase link --project-ref $SUPABASE_PROJECT_REF && supabase db push", "supabase:typegen": "pnpm run supabase:typegen:packages && pnpm run supabase:typegen:app", "supabase:typegen:packages": "supabase gen types typescript --local > ../../packages/supabase/src/database.types.ts", - "supabase:typegen:app": "supabase gen types typescript --local > ./lib/database.types.ts" + "supabase:typegen:app": "supabase gen types typescript --local > ./lib/database.types.ts", + "supabase:db:dump:local": "supabase db dump --local --data-only" }, "dependencies": { "@hookform/resolvers": "^3.3.4", diff --git a/apps/web/supabase/migrations/20221215192558_schema.sql b/apps/web/supabase/migrations/20221215192558_schema.sql index e0e43f54d..1eb7ba846 100644 --- a/apps/web/supabase/migrations/20221215192558_schema.sql +++ b/apps/web/supabase/migrations/20221215192558_schema.sql @@ -359,12 +359,7 @@ begin public.accounts_memberships set account_role =( - select - name - from - public.roles - where - hierarchy_level = 1) + kit.get_upper_system_role()) where target_account_id = account_id and user_id = new_owner_id; @@ -421,6 +416,21 @@ create trigger protect_account_fields before update on public.accounts for each row execute function kit.protect_account_fields(); +create or replace function kit.get_upper_system_role() + returns varchar + as $$ +declare + role varchar(50); +begin + select name from public.roles + where account_id is null and + hierarchy_level = 1 into role; + + return role; +end; +$$ +language plpgsql; + create or replace function kit.add_current_user_to_new_account() returns trigger language plpgsql @@ -436,7 +446,7 @@ begin values( new.id, auth.uid(), - 'owner'); + kit.get_upper_system_role()); end if; @@ -490,7 +500,7 @@ create trigger "on_auth_user_updated" -- Account Memberships table create table if not exists public.roles( name varchar(50) not null, - hierarchy_level int not null, + hierarchy_level int not null check (hierarchy_level > 0), account_id uuid references public.accounts(id) on delete cascade, unique(name, account_id), primary key (name) @@ -509,9 +519,13 @@ end; $$ language plpgsql immutable; grant execute on function kit.get_system_role_uuid() to authenticated, service_role; +-- we create a unique index on the roles table to ensure that the +-- can there be a unique hierarchy_level per account (or system role) create unique index idx_unique_hierarchy_per_account on public.roles (hierarchy_level, coalesce(account_id, kit.get_system_role_uuid())); +-- we create a unique index on the roles table to ensure that the +-- can there be a unique name per account (or system role) create unique index idx_unique_name_per_account on public.roles (name, coalesce(account_id, kit.get_system_role_uuid())); @@ -537,22 +551,6 @@ create constraint trigger tr_check_non_personal_account_roles for each row execute procedure kit.check_non_personal_account_roles(); --- Seed the roles table with default roles 'owner' and --- 'member' -insert into public.roles( - name, - hierarchy_level) -values ( - 'owner', - 1); - -insert into public.roles( - name, - hierarchy_level) -values ( - 'member', - 2); - -- RLS alter table public.roles enable row level security; @@ -672,7 +670,7 @@ create policy roles_read on public.roles or public.has_role_on_account(account_id) ); --- Function to check if a user can remove a member from an account +-- Function to check if a user can remove a member from an account create or replace function kit.can_remove_account_member(target_team_account_id uuid, user_id uuid) @@ -882,6 +880,7 @@ begin where id = target_account_id and primary_owner_user_id = target_user_id) into is_primary_owner; + -- If the user is the primary owner, they have the highest role and can -- perform any action if is_primary_owner then @@ -908,9 +907,11 @@ begin from public.roles where - name = role_name; + name = role_name + and account_id = target_account_id or account_id is null; -- If the user's role is higher than the target role, they can perform -- the action + return user_role_hierarchy_level < target_role_hierarchy_level; end; diff --git a/apps/web/supabase/migrations/20240319163440_roles-seed.sql b/apps/web/supabase/migrations/20240319163440_roles-seed.sql index e626cd592..3d6469804 100644 --- a/apps/web/supabase/migrations/20240319163440_roles-seed.sql +++ b/apps/web/supabase/migrations/20240319163440_roles-seed.sql @@ -1,3 +1,18 @@ +-- Seed the roles table with default roles 'owner' and 'member' +insert into public.roles( + name, + hierarchy_level) +values ( + 'owner', + 1); + +insert into public.roles( + name, + hierarchy_level) +values ( + 'member', + 2); + -- We seed the role_permissions table with the default roles and permissions insert into public.role_permissions( role,