supabase / cli

Supabase CLI. Manage postgres migrations, run Supabase locally, deploy edge functions. Postgres backups. Generating types from your database schema.
https://supabase.com/docs/reference/cli/about
MIT License
954 stars 178 forks source link

Support for auth.phone in the config file #180

Closed wladpaiva closed 1 year ago

wladpaiva commented 2 years ago

Feature request

Is your feature request related to a problem? Please describe.

Yes, supabase cli doens't allow to config the phone authentication

Describe the solution you'd like

Currently the config.toml allows the configuration of many things related to email auth but none for the phone auth although the docker gotrue has those env vars

GOTRUE_SMS_AUTOCONFIRM="false"
GOTRUE_SMS_MAX_FREQUENCY="5s"
GOTRUE_SMS_OTP_EXP="6000"
GOTRUE_SMS_OTP_LENGTH="6"
GOTRUE_SMS_PROVIDER="twilio"
GOTRUE_SMS_TWILIO_ACCOUNT_SID=""
GOTRUE_SMS_TWILIO_AUTH_TOKEN=""
GOTRUE_SMS_TWILIO_MESSAGE_SERVICE_SID=""
GOTRUE_SMS_TEMPLATE="This is from supabase. Your code is {{ .Code }} ."
GOTRUE_SMS_MESSAGEBIRD_ACCESS_KEY=""
GOTRUE_SMS_MESSAGEBIRD_ORIGINATOR=""
GOTRUE_SMS_TEXTLOCAL_API_KEY=""
GOTRUE_SMS_TEXTLOCAL_SENDER=""
GOTRUE_SMS_VONAGE_API_KEY=""
GOTRUE_SMS_VONAGE_API_SECRET=""
GOTRUE_SMS_VONAGE_FROM=""

Describe alternatives you've considered

You can run a docker-compose file shared in the supabase/supabase repository with all those settings but it is heavily overwhelming configure everything. The supabase cli makes it soooo much faster to init a supabase dev environment.

Additional context

Add any other context or screenshots about the feature request here.

darlanjunior commented 2 years ago

Just to let you know, what we did to solve this is to force the OTP (confirmation_token) to be 123456 and the confirmation_sent_at to be now() in a trigger. Of course we're not testing the integration with the sms provider but that's better to keep costs low.

sdaoud commented 1 year ago

Is there any update here? We'd like to be able to integrate with our SMS provider locally, to test the entire auth journey

MoaathAlattas commented 1 year ago

@darlanjunior could you share the trigger? Also, how did you bypass the error Error sending sms: sms Provider could not be found

darlanjunior commented 1 year ago
CREATE OR REPLACE FUNCTION auth.force_otp()
 RETURNS trigger
 LANGUAGE plpgsql
AS $function$BEGIN
  NEW.confirmation_token := 123456;
  NEW.confirmation_sent_at := now();
  return new;
END;$function$
;

create trigger force_otp before
update
    on
    auth.users for each row execute function auth.force_otp();

You can safely ignore the error and just attempt to sign in. It only works once per user, unfortunately.

MoaathAlattas commented 1 year ago

You can safely ignore the error and just attempt to sign in. It only works once per user, unfortunately.

thanks @darlanjunior! after some digging I created a db function that I call manually on sign in only on dev mode. Still not the nicest but does the job for now.

CREATE OR REPLACE FUNCTION public.mock_phone_otp(phone text)
 RETURNS void
 LANGUAGE plpgsql
 SECURITY DEFINER
AS $function$begin
  UPDATE auth.users
      SET confirmation_token = encode(sha224(concat(mock_phone_otp.phone,'123456')::bytea), 'hex'),
          confirmation_sent_at = now()
    WHERE users.phone = mock_phone_otp.phone;
  end;
$function$
;

in code it would be something like:


const { error } = await sdk.auth.signInWithOtp({
    phone: phoneNumber,
});

if (DEV) {
    await sdk.rpc("mock_phone_otp", {
        phone: phoneNumber,
    });
} else if (error) {
    console.error(error);
    return redirect(`/sign-in`);
}

References: https://github.com/supabase/gotrue/blob/ed7b2dc5001a95d96f7a56bb463cfd265279ac2e/internal/api/verify_test.go#L633

janbaykara commented 1 year ago

Here's a fleshed out version of @MoaathAlattas's code:

const code = "123456"

function mockOtp() {
   const normalisedPhone = phone.replace(/^0/, '').replace(/\+/, '')
   await supabase.rpc("mock_phone_otp", { code, phone: normalisedPhone })
}

// Then later, use the same arbitrary code you defined earlier:

await supabase.auth.verifyOtp({
   phone: phone,
   token: code,
   type: 'sms'
});

Pass in your own OTP code in the SQL function:

+CREATE OR REPLACE FUNCTION public.mock_phone_otp(phone text,code text)
 RETURNS void
 LANGUAGE plpgsql
 SECURITY DEFINER
AS $function$begin
  UPDATE auth.users
      SET confirmation_token = encode(sha224(concat(mock_phone_otp.phone,mock_phone_otp.code)::bytea), 'hex'),
          confirmation_sent_at = now()
    WHERE users.phone = mock_phone_otp.phone;
  end;
$function$