-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding app metadata to setup and claims (#15)
* Adding app metadata to setup and claims - raw_app_meta_data column should have a value on creation - app_metadata is populated in the jwt.claims setting * Fix authenticate-as test Update get_supabase_user function
- Loading branch information
1 parent
4ffec5e
commit 75bd67e
Showing
5 changed files
with
432 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/** | ||
* ### tests.create_supabase_user(identifier text, email text, phone text) | ||
* | ||
* Creates a new user in the `auth.users` table. | ||
* You can recall a user's info by using `tests.get_supabase_user(identifier text)`. | ||
* | ||
* Parameters: | ||
* - `identifier` - A unique identifier for the user. We recommend you keep it memorable like "test_owner" or "test_member" | ||
* - `email` - (Optional) The email address of the user | ||
* - `phone` - (Optional) The phone number of the user | ||
* - `metadata` - (Optional) Additional user metadata to be added to the user | ||
* | ||
* Returns: | ||
* - `user_id` - The UUID of the user in the `auth.users` table | ||
* | ||
* Example: | ||
* ```sql | ||
* SELECT tests.create_supabase_user('test_owner'); | ||
* SELECT tests.create_supabase_user('test_member', '[email protected]', '555-555-5555'); | ||
* SELECT tests.create_supabase_user('test_member', '[email protected]', '555-555-5555', '{"key": "value"}'::jsonb); | ||
* ``` | ||
*/ | ||
CREATE OR REPLACE FUNCTION tests.create_supabase_user(identifier text, email text default null, phone text default null, metadata jsonb default null) | ||
RETURNS uuid | ||
SECURITY DEFINER | ||
SET search_path = auth, pg_temp | ||
AS $$ | ||
DECLARE | ||
user_id uuid; | ||
BEGIN | ||
|
||
-- create the user | ||
user_id := extensions.uuid_generate_v4(); | ||
INSERT INTO auth.users (id, email, phone, raw_user_meta_data, raw_app_meta_data) | ||
VALUES (user_id, coalesce(email, concat(user_id, '@test.com')), phone, jsonb_build_object('test_identifier', identifier) || coalesce(metadata, '{}'::jsonb), '{}'::jsonb) | ||
RETURNING id INTO user_id; | ||
|
||
RETURN user_id; | ||
END; | ||
$$ LANGUAGE plpgsql; | ||
|
||
|
||
/** | ||
* ### tests.authenticate_as(identifier text) | ||
* Authenticates as a user created with `tests.create_supabase_user`. | ||
* | ||
* Parameters: | ||
* - `identifier` - The unique identifier for the user | ||
* | ||
* Returns: | ||
* - `void` | ||
* | ||
* Example: | ||
* ```sql | ||
* SELECT tests.create_supabase_user('test_owner'); | ||
* SELECT tests.authenticate_as('test_owner'); | ||
* ``` | ||
*/ | ||
CREATE OR REPLACE FUNCTION tests.authenticate_as (identifier text) | ||
RETURNS void | ||
AS $$ | ||
DECLARE | ||
user_data json; | ||
original_auth_data text; | ||
BEGIN | ||
-- store the request.jwt.claims in a variable in case we need it | ||
original_auth_data := current_setting('request.jwt.claims', true); | ||
user_data := tests.get_supabase_user(identifier); | ||
|
||
if user_data is null OR user_data ->> 'id' IS NULL then | ||
RAISE EXCEPTION 'User with identifier % not found', identifier; | ||
end if; | ||
|
||
|
||
perform set_config('role', 'authenticated', true); | ||
perform set_config('request.jwt.claims', json_build_object( | ||
'sub', user_data ->> 'id', | ||
'email', user_data ->> 'email', | ||
'phone', user_data ->> 'phone', | ||
'user_metadata', user_data -> 'raw_user_meta_data', | ||
'app_metadata', user_data -> 'raw_app_meta_data' | ||
)::text, true); | ||
|
||
EXCEPTION | ||
-- revert back to original auth data | ||
WHEN OTHERS THEN | ||
set local role authenticated; | ||
set local "request.jwt.claims" to original_auth_data; | ||
RAISE; | ||
END | ||
$$ LANGUAGE plpgsql; | ||
|
||
|
||
/** | ||
* ### tests.get_supabase_user(identifier text) | ||
* | ||
* Returns the user info for a user created with `tests.create_supabase_user`. | ||
* | ||
* Parameters: | ||
* - `identifier` - The unique identifier for the user | ||
* | ||
* Returns: | ||
* - `user_id` - The UUID of the user in the `auth.users` table | ||
* | ||
* Example: | ||
* ```sql | ||
* SELECT posts where posts.user_id = tests.get_supabase_user('test_owner') -> 'id'; | ||
* ``` | ||
*/ | ||
CREATE OR REPLACE FUNCTION tests.get_supabase_user(identifier text) | ||
RETURNS json | ||
SECURITY DEFINER | ||
SET search_path = auth, pg_temp | ||
AS $$ | ||
DECLARE | ||
supabase_user json; | ||
BEGIN | ||
SELECT json_build_object( | ||
'id', id, | ||
'email', email, | ||
'phone', phone, | ||
'raw_user_meta_data', raw_user_meta_data, | ||
'raw_app_meta_data', raw_app_meta_data | ||
) into supabase_user | ||
FROM auth.users | ||
WHERE raw_user_meta_data ->> 'test_identifier' = identifier limit 1; | ||
|
||
if supabase_user is null OR supabase_user -> 'id' IS NULL then | ||
RAISE EXCEPTION 'User with identifier % not found', identifier; | ||
end if; | ||
RETURN supabase_user; | ||
END; | ||
$$ LANGUAGE plpgsql; |
Oops, something went wrong.