diff --git a/.github/workflows/run-unit-tests.yml b/.github/workflows/run-unit-tests.yml index 1c4c8fdb..d1b23f98 100644 --- a/.github/workflows/run-unit-tests.yml +++ b/.github/workflows/run-unit-tests.yml @@ -22,5 +22,6 @@ jobs: with: version: latest - run: npm ci + - run: npm run copy-migration-to-test-folder - run: npm run supabase-test:start - run: npm run test:ci diff --git a/.gitignore b/.gitignore index 7a66c531..28af0e1b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /.pnp .pnp.js .yarn/install-state.gz +src/__tests__/supabase/migrations/ # testing diff --git a/README.md b/README.md index aa222a81..6a738e2a 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,9 @@ Replace the values of the variables inside .env with appropriate entries. Values Values for Supabase variables will be displayed in the terminal after running either `npm run supabase-dev:start` or `npm run supabase-test:start`. These values will be the same for both commands, and will be the same each time you run these commands. +Run the script 'npm run create-symlink-supabase-to-src'. This will create a symlink between the supabase/migrations/20240711063356_initial_schema.sql file -> src/__tests__/supabase/migrations/20240711063356_initial_schema.sql file. +Note, if you are a windows user, you may have to run the command prompt as an administrator to run the script. +======= ## Selenium Tests ### Prerequisites @@ -132,8 +135,6 @@ npm run start To run the Selenium tests, navigate into `src/__tests__/e2e` and run `python3 -m pytest`. - - ## Contributing New engineers should review [CONTRIBUTING.md](https://github.com/8by8-org/8by8-challenge/blob/development/CONTRIBUTING.md) for details about the recommended workflow and tools. diff --git a/package.json b/package.json index 4b1fa334..faf1b002 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,9 @@ "lint": "next lint", "format": "prettier --write \"**/*.+(js|ts|tsx|json)\"", "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" + "build-storybook": "storybook build", + "create-symlink-supabase-to-src": "node scripts/create-symlink-supabase-to-src.js", + "copy-migration-to-test-folder": "node scripts/copy-migration-to-test-folder.js" }, "dependencies": { "@paralleldrive/cuid2": "^2.2.2", diff --git a/scripts/copy-migration-to-test-folder.js b/scripts/copy-migration-to-test-folder.js new file mode 100644 index 00000000..fcc10848 --- /dev/null +++ b/scripts/copy-migration-to-test-folder.js @@ -0,0 +1,19 @@ +/** + * copies file from @/supabase/migrations/20240711063356_initial_schema.sql --> src/__tests__/supabase/migrations/20240711063356_initial_schema.sql + */ +const fs = require('fs-extra'); +const path = require('path'); + +let sourcePath = path.join(__dirname, '../supabase/migrations'); +let destPath = path.join(__dirname, '../src/__tests__/supabase/migrations'); + +async function copyDirectory() { + try { + await fs.copy(sourcePath, destPath); + console.log('Directory copied successfully!'); + } catch (err) { + console.error('Error copying directory:', err); + } +} + +copyDirectory(); diff --git a/scripts/create-symlink-supabase-to-src.js b/scripts/create-symlink-supabase-to-src.js new file mode 100644 index 00000000..f4048106 --- /dev/null +++ b/scripts/create-symlink-supabase-to-src.js @@ -0,0 +1,45 @@ +const fs = require('fs'); +const path = require('path'); + +// Define the paths to the directories +const databaseDirPath = path.join(__dirname, '../supabase/migrations'); +const testDirPath = path.join( + __dirname, + '../src/__tests__/supabase/migrations', +); + +// Function to create a symbolic link +function createSymlink(source, destination) { + fs.stat(destination, (err, stats) => { + if (!err) { + console.log(`Existing file or symlink at ${destination}:`); + console.log(`- Is a symlink: ${stats.isSymbolicLink()}`); + console.log(`- Is a file: ${stats.isFile()}`); + console.log(`- Is a directory: ${stats.isDirectory()}`); + console.log(`- Size: ${stats.size} bytes`); + console.log(`- Last modified: ${stats.mtime}\n`); + + if (stats.isSymbolicLink() || stats.isDirectory()) { + console.error( + 'Symlink or Directory already exists. Please remove before running this script.', + ); + } else { + console.error( + `Error: ${destination} exists but is not a directory or symlink.\n`, + ); + } + } else if (err.code === 'ENOENT') { + fs.symlink(source, destination, 'dir', symlinkErr => { + if (symlinkErr) { + console.error(`Error creating symlink: ${symlinkErr.message}\n`); + } else { + console.log(`Symlink created: ${destination} -> ${source}\n`); + } + }); + } else { + console.error(`Error checking destination: ${err.message}\n`); + } + }); +} + +createSymlink(databaseDirPath, testDirPath); diff --git a/src/__tests__/supabase/migrations/20240711063356_initial_schema.sql b/src/__tests__/supabase/migrations/20240711063356_initial_schema.sql deleted file mode 100644 index 41e9ba6d..00000000 --- a/src/__tests__/supabase/migrations/20240711063356_initial_schema.sql +++ /dev/null @@ -1,122 +0,0 @@ --- Create user table, create an index on invite_code, enable row level security, and set a policy -create table public.users ( - id uuid not null references auth.users on delete cascade, - email varchar(320) unique not null, - name varchar(255) not null, - avatar char(1) not null, - type varchar(255) not null, - -- Set the challenge end date to 8 days in the future and save as Unix seconds - challenge_end_timestamp bigint not null default extract(epoch from now() + interval '8 days'), - completed_challenge boolean not null default false, - invite_code varchar(30) unique not null, - primary key (id) -); - -create index invite_code_idx on public.users (invite_code); - -alter table public.users enable row level security; - -create policy "Users can view their own user data." -on public.users for select -using ( (select auth.uid()) = id ); - --- Create completed_actions table, enable row level security, and set a policy -create table public.completed_actions ( - id serial, - election_reminders boolean not null default false, - register_to_vote boolean not null default false, - shared_challenge boolean not null default false, - user_id uuid unique not null references public.users on delete cascade, - primary key (id, user_id) -); - -alter table public.completed_actions enable row level security; - -create policy "Users can view their own completed actions." -on public.completed_actions for select -using ((select auth.uid()) = user_id); - --- Create badges table, enable row level security, and set a policy -create table public.badges ( - id serial, - action varchar(255), - player_name varchar(255), - player_avatar char(1), - challenger_id uuid not null references public.users on delete cascade, - primary key (id, challenger_id) -); - -alter table public.badges enable row level security; - -create policy "Users can view their own badges." -on public.badges for select -using ((select auth.uid()) = challenger_id); - --- Create invited_by table, enable row level security, and set a policy -create table public.invited_by ( - id serial, - player_id uuid unique not null references public.users on delete cascade, - challenger_invite_code varchar(30) not null, - challenger_name varchar(255) not null, - challenger_avatar char(1) not null, - primary key (id, player_id) -); - -alter table public.invited_by enable row level security; - -create policy "Users can view their own invited by data." -on public.invited_by for select -using ((select auth.uid()) = player_id); - --- Create contributed_to table, enable row level security, and set a policy -create table public.contributed_to ( - id serial, - player_id uuid not null references public.users on delete cascade, - challenger_name varchar(255) not null, - challenger_avatar char(1) not null, - primary key (id, player_id) -); - -alter table public.contributed_to enable row level security; - -create policy "Users can view their own contributed to data." -on public.contributed_to for select -using ((select auth.uid()) = player_id); - --- Create a function that creates new rows in public.users and public.completed_actions -create function public.handle_new_user() -returns trigger -language plpgsql -security definer set search_path = '' -as $$ -begin - insert into public.users ( - id, - email, - name, - avatar, - type, - invite_code - ) values ( - new.id, - new.email, - new.raw_user_meta_data ->> 'name', - new.raw_user_meta_data ->> 'avatar', - new.raw_user_meta_data ->> 'type', - new.raw_user_meta_data ->> 'invite_code' - ); - - insert into public.completed_actions ( - user_id - ) values ( - new.id - ); - - return new; -end; -$$; - --- trigger the function every time a user is created -create trigger on_auth_user_created - after insert on auth.users - for each row execute procedure public.handle_new_user(); \ No newline at end of file diff --git a/src/services/server/encryptor/web-crypto-subtle-encryptor.ts b/src/services/server/encryptor/web-crypto-subtle-encryptor.ts index 0f5ec91c..1f78a7e0 100644 --- a/src/services/server/encryptor/web-crypto-subtle-encryptor.ts +++ b/src/services/server/encryptor/web-crypto-subtle-encryptor.ts @@ -15,7 +15,7 @@ export const WebCryptoSubtleEncryptor = inject( * @encryptData * @param data - string to encrypt * @param key - a cryptoKey for encryption and decryption - * @returns A string with the initialization vector concatenated with the encrypted data + * @returns A string with the initialization vector concatenated with the encrypted data. The return value will have length of 12 (length of iv) + X (length of plaintext to encrypt) + 16 (authentication tag) */ async encrypt(data: string, key: CryptoKey): Promise { const encoder = new TextEncoder(); diff --git a/supabase/migrations/20240711063356_initial_schema.sql b/supabase/migrations/20240711063356_initial_schema.sql index 41e9ba6d..e8c4db85 100644 --- a/supabase/migrations/20240711063356_initial_schema.sql +++ b/supabase/migrations/20240711063356_initial_schema.sql @@ -83,6 +83,31 @@ create policy "Users can view their own contributed to data." on public.contributed_to for select using ((select auth.uid()) = player_id); +-- Create registration_information table, enable row level security, and set a policy +create table public.registration_information ( + id serial, + user_id uuid not null references public.users on delete cascade, + us_state varchar(255) not null, + city varchar(255) not null, + street varchar(255) not null, + name_first varchar(255) not null, + name_last varchar(255) not null, + dob varchar(255) not null, + zip varchar(255) not null, + email varchar(255) not null, + citizen varchar(255) not null, + eighteenPlus varchar(255) not null, + party varchar(255) not null, + idNumber varchar(255) not null, + primary key (id, user_id) +); + +alter table public.registration_information enable row level security; + +create policy "Users can view their own registration information." +on public.registration_information for select +using ((select auth.uid()) = user_id); + -- Create a function that creates new rows in public.users and public.completed_actions create function public.handle_new_user() returns trigger