edelacruz
07/20/2022, 7:34 AMcreate or replace function test_function()
RETURNS text
LANGUAGE plpgsql
security definer set search_path = auth
as $$
declare user_role text;
begin
select raw_user_meta_data->>'role'
from auth.users
into user_role
where id = auth.uid()
return user_role;
end
$$;
When I call this function from within my js app it returns null
const {data, error} = await supabase.rpc('test_function')
When I replace auth.uid() with the id of an existing user it still returns null in my code
but when I run select * from test_function() in Supabase Studio's SQL Editor I do get the role I assigned to my user
Why is there a difference between calling a function from code and calling it from the SQL Editor?
And why is auth.uid() not working?
To be clear; there is an authenticated user in the code that I'm calling from.Scott P
07/20/2022, 1:17 PMsecurity invoker instead of security definer.
If you're creating the function via the SQL editor in the dashboard, security definer means it will be running as the dashboard user (e.g. supabase_admin I think), whereas security invoker will run it as the user which calls the function.Waldemar
07/20/2022, 6:22 PMauth.uid() is changed to just uid().
Maybe it is somehow related.jaitaiwan
07/21/2022, 6:10 AMselect raw_user_meta_data->>'role'
from auth.users
into user_role
where id = auth.uid()
return user_role; in the sql editor (replacing auth.uid() with the uid that your user has?jaitaiwan
07/21/2022, 6:10 AMWaldemar
07/21/2022, 8:57 AMjaitaiwan
07/21/2022, 10:09 AMjaitaiwan
07/21/2022, 10:10 AMedelacruz
07/21/2022, 10:48 AMcreate or replace function test_function()
RETURNS text
LANGUAGE plpgsql
security definer set search_path = auth
as $$
declare user_role text;
begin
select raw_user_meta_data->>'role'
from auth.users
into user_role
where id = 'f32fc3d5-b9a5-4b62-a5d1-d4e59ed6e6ea';
return user_role;
end
$$;
I will see the correct role in both the SQL Editor when running select * from test_function()
But when I change to security invoker I will still get a correct answer in the SQL editor but null in my Javacript.edelacruz
07/21/2022, 10:49 AMjaitaiwan
07/21/2022, 10:53 AMedelacruz
07/21/2022, 10:55 AMjaitaiwan
07/21/2022, 10:55 AMedelacruz
07/21/2022, 10:56 AMjaitaiwan
07/21/2022, 10:56 AMjaitaiwan
07/21/2022, 10:58 AMedelacruz
07/21/2022, 10:58 AMjaitaiwan
07/21/2022, 10:59 AMedelacruz
07/21/2022, 10:59 AMedelacruz
07/21/2022, 10:59 AMjaitaiwan
07/21/2022, 10:59 AMedelacruz
07/21/2022, 11:00 AMedelacruz
07/21/2022, 11:00 AMjaitaiwan
07/21/2022, 11:00 AMedelacruz
07/21/2022, 11:01 AMcreate or replace function test_function()
RETURNS text
LANGUAGE plpgsql
security definer set search_path = auth
as $$
declare user_role text;
begin
select raw_user_meta_data->>'role'
from auth.users
into user_role
where id = auth.uid()
return user_role;
end
$$;jaitaiwan
07/21/2022, 11:02 AMedelacruz
07/21/2022, 11:02 AMedelacruz
07/21/2022, 11:03 AMjaitaiwan
07/21/2022, 11:04 AMedelacruz
07/21/2022, 11:04 AMedelacruz
07/21/2022, 11:04 AMedelacruz
07/21/2022, 11:05 AMjaitaiwan
07/21/2022, 11:05 AMjaitaiwan
07/21/2022, 11:05 AMjaitaiwan
07/21/2022, 11:05 AMedelacruz
07/21/2022, 11:06 AMjaitaiwan
07/21/2022, 11:06 AMedelacruz
07/21/2022, 11:08 AMedelacruz
07/21/2022, 11:08 AMjaitaiwan
07/21/2022, 11:09 AMjaitaiwan
07/21/2022, 11:09 AMjaitaiwan
07/21/2022, 11:10 AMedelacruz
07/21/2022, 11:13 AMedelacruz
07/21/2022, 11:14 AMedelacruz
07/21/2022, 11:15 AMcreate or replace function users_by_tenant_id(tenant_id_input text) RETURNS TABLE (
user_id uuid,
user_email varchar,
user_name text,
user_role text,
user_alias text,
user_tenant_id text
) LANGUAGE plpgsql security definer
set search_path = auth as $$
declare user_role text;
begin
select raw_user_meta_data->>'role'
from auth.users into user_role
where id = auth.uid();
if user_role != 'admin' then raise notice 'Not allowed';
else return query
select u.id,
u.email,
u.raw_user_meta_data->>'name' as name,
u.raw_user_meta_data->>'role' as role,
u.raw_user_meta_data->>'alias' as alias,
u.raw_user_meta_data->>'tenant_id' as tenant_id
from auth.users u
where u.raw_user_meta_data->>'tenant_id' = $1;
end if;
end $$;edelacruz
07/21/2022, 11:16 AMjaitaiwan
07/21/2022, 1:44 PMjaitaiwan
07/21/2022, 1:44 PMjaitaiwan
07/21/2022, 1:48 PMselect proname,prosrc from pg_proc where proname= 'uid';
Do you get:
select
coalesce(
nullif(current_setting('request.jwt.claim.sub', true), ''),
(nullif(current_setting('request.jwt.claims', true), '')::jsonb ->> 'sub')
)::uuid ?garyaustin
07/21/2022, 2:11 PMgaryaustin
07/21/2022, 2:29 PMdeclare myid uuid;
begin
select id from auth.users where id = auth.uid() into myid;
return myid;
end
And works fine, returning the user's id to the client.Waldemar
07/22/2022, 6:48 AMedelacruz
07/22/2022, 8:01 AM-- A function to return all users from the auth.users table
-- but only if the requestor has an admin role in raw_user_meta_data.role
create or replace function get_all_users()
returns table (
user_email varchar,
user_name text,
user_role text
)
language plpgsql
security definer set search_path = auth
as $$
declare user_role text;
begin
select raw_user_meta_data->>'role'
from auth.users
into user_role
where id = auth.uid();
if user_role <> 'admin' then
return;
else
return query
select
email,
raw_user_meta_data->>'name',
raw_user_meta_data->>'role'
from auth.users;
end if;
end $$;edelacruz
07/22/2022, 8:06 AMjaitaiwan
07/22/2022, 8:49 AMedelacruz
07/22/2022, 8:53 AM