Check if the user exists in Auth #1282
|
Is there a way to check if a user exists in Auth by checking the email address? |
Replies: 17 comments 44 replies
|
If you try to create an account with the same email you will be notified that the email is already in use. You could also create a stored procedure to copy the |
|
I'm using |
|
I have a work around:
|
|
In the response there's So we should be able to do something like: if (user.identities.length) {
// please confirm your email, or send again
} else {
// already signed up, sign in instead?
}I'd kinda like supabase to do this for us though and return an error. |
|
I'm having the same issue here, I would like to query the The reason I would like to do this is that I don't think I guess the solutions at the moment are:
|
|
This is what I do. I created the function: create or replace function get_user_id_by_email(user_email text) returns uuid
as $$
declare
user_id uuid;
begin
select id
from auth.users
where email = user_email
into user_id;
return user_id;
end;
$$ language plpgsql security invoker;then I revoked all roles' privileges except for service_role using the following query: do
$$
declare
pg_role record;
begin
for pg_role in select rolname from pg_roles
loop
execute 'revoke all on function "public"."get_user_id_by_email" from ' || quote_ident(pg_role.rolname);
end loop;
grant EXECUTE ON function "public"."get_user_id_by_email" to service_role;
end;
$$finally, I call it on the server with a supabase admin client (created with service role key) to call the function, like so: const {data, error} = await supabase.rpc('get_user_id_by_email', {user_email: 'user@email.com'});if the user exists, you'll get an id, otherwise, the user does not exist. P.S. I noticed that the "supabase_admin" role is also is able to bypass and invoke the function after revoking it from all roles except for service_role. I tested it on anon and authenticated, and they're both unable to invoke it as expected. I figured since supabase_admin is supposed to be granted only for admins, there's no harm. To check the privileges for a specific function, i used the following query: SELECT proacl,proname FROM pg_proc WHERE proname = 'get_user_id_by_email';and as expected, it shows that the only role who has permission to invoke it is indeed just the service_role; I'm still trying to figure things out, but so far, this is what I have. I hope it helps. |
|
OK,it's better to grant least permission.
many thanks for your help
…On Sun, Mar 12, 2023 at 20:37 ofeenee ***@***.***> wrote:
@halofe <https://github.com/halofe> I'd like to add one more note if I
may:
the grant ALL ON auth.users to service_role; is a bit "too much" to get
the function to work. The function requires "read access" only, and "grant
ALL" gives service_role the permission to do all operations "select insert
update delete". It's a good "safety switch" to have to prevent accidental
data mutation.
I personally use my service_role client as admin to do certain operations
on auth.users, that's why I grant all. However, if all you need is the
necessary permissions to allow service_role to invoke and use the
function, the following should be enough:
grant select ON auth.users to service_role;
My bad, as I should've mentioned that earlier; I apologize for that.
—
Reply to this email directly, view it on GitHub
<#1282 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A2TS3SS75WRVZMN6PAESYZLW3W7OZANCNFSM43S7LFZQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
|
I started using supabase recently, and I realized I could leverage the identities array inside the Example code: |
|
Hi there! After some testing, I've realized that new users do not have the properties |
|
hey, |
|
What should we do if the account is pending email verification? Currently, by default, it just sends the confirmation email again and again. Anyone got a clue? |
|
This is my user invitation logic: Call it on the server like this: Use it in your app like this: preExistingUser is handy when there is other logic in your post invite flow that is dependent on whether or not the invited user was already a user of another tenant/company/etc. This is from a multi-tentant app obviously. update: comments |
|
Is there not any example for a real app using supabase to check the auth flow implementation ? |
|
I've just changed an alert message to: Please check your inbox for email verification! if Email is not arrived shortly, please check if you already registered via Google or Apple! and in settings I've added identity synchronization buttons https://supabase.com/docs/guides/auth/auth-identity-linking. Hacking over this user flow is not safe. |
|
Best solution, without breaking any logic or crafting not reliable method, is to create a specific function in supabase to return a confirmation It can be designed like this create or replace function public.email_exists(p_email text) grant execute on function public.email_exists(text) to anon; Callable from your app, locked by your supabase security access, fastly check if the email is used or not, easy to reproduce. I couldn't find any better way to do this, as supabase do not provide a default build in function for it. |
|
I've read all the answers, and while I think creating a specific function in Supabase to return a confirmation is a good idea, why not just doing this? I am interested in knowing what are the pro and cons of this. |
|
I see a lot of answers about changing access to auth tables or using functions (e.g., security definer/edge) to determine if an account exists. Each of these are a security risk. The solution I find that works is to allow the dummy data to return and present the user with a message that a confirmation link will be sent to their email if an account does not already exist. You can then provide both a resend and password reset link (simplest solution). Or, what I prefer for a cleaner interface is to create an edge function using a maintenance key (service role) to check if the email is present and email has been confirmed. From the edge function you can then resend the email confirmation email as usual (if email is not confirmed) or send a custom email from the edge function notifying the user an account already exists. On the front end do not tell the user which email was sent. This protects the privacy of users and from bad actors trying to determine which emails have registered. If you do not like the user not getting an initial email you can just build in the sign up functionality from the edge function. That said, if you do use edge functions with CAPTCHA and will need to confirm the tokens manually. As well as be mindful when using a service role. You may need two clients. 1 for service role calls (email/confirmation status) and one for the authenticated user (user inserts/updates). Providing brief snippet from an edge function for sending email. Your SMTP provider should have instructions you can follow for additional information. Below was for zepto. |
If you try to create an account with the same email you will be notified that the email is already in use. You could also create a stored procedure to copy the
auth.useremail into your ownuserstable and you would be able to query that easily. You could probably also create a stored procedure to check if the email already exists in theauth.usertable.