J. Jackson
J. Jackson

Reputation: 3774

Supabase third party oAuth providers are returning null?

I'm trying to implement Facebook, Google and Twitter authentication. So far, I've set up the apps within the respective developer platforms, added those keys/secrets to my Supabase console, and created this graphql resolver:

/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import camelcaseKeys from 'camelcase-keys';
import { supabase } from 'lib/supabaseClient';
import { LoginInput, Provider } from 'generated/types';
import { Provider as SupabaseProvider } from '@supabase/supabase-js';
import Context from '../../context';
import { User } from '@supabase/supabase-js';

export default async function login(
  _: any,
  { input }: { input: LoginInput },
  { res, req }: Context
): Promise<any> {
  const { provider } = input;

  // base level error object
  const errorObject = {
    __typename: 'AuthError',
  };

  // return error object if no provider is given
  if (!provider) {
    return {
      ...errorObject,
      message: 'Must include provider',
    };
  }

  try {
    const { user, session, error } = await supabase.auth.signIn({
      // provider can be 'github', 'google', 'gitlab', or 'bitbucket'
      provider: 'facebook',
    });
    console.log({ user });
    console.log({ session });
    console.log({ error });

    if (error) {
      return {
        ...errorObject,
        message: error.message,
      };
    }

    const response = camelcaseKeys(user as User, { deep: true });
    return {
      __typename: 'LoginSuccess',
      accessToken: session?.access_token,
      refreshToken: session?.refresh_token,
      ...response,
    };
  } catch (error) {
    return {
      ...errorObject,
      message: error.message,
    };
  }
}

I have three console logs set up directly underneath the signIn() function, all of which are returning null.

I can also go directly to https://<your-ref>.supabase.co/auth/v1/authorize?provider=<provider> and auth works correctly, so it appears to have been narrowed down specifically to the signIn() function. What would cause the response to return null values?

Upvotes: 5

Views: 2336

Answers (1)

adam-beck
adam-beck

Reputation: 6009

This is happening because these values are not populated until after the redirect from the OAuth server takes place. If you look at the internal code of supabase/gotrue-js you'll see null being returned explicitly.

  private _handleProviderSignIn(
    provider: Provider,
    options: {
      redirectTo?: string
      scopes?: string
    } = {}
  ) {
    const url: string = this.api.getUrlForProvider(provider, {
      redirectTo: options.redirectTo,
      scopes: options.scopes,
    })

    try {
      // try to open on the browser
      if (isBrowser()) {
        window.location.href = url
      }
      return { provider, url, data: null, session: null, user: null, error: null }
    } catch (error) {
      // fallback to returning the URL
      if (!!url) return { provider, url, data: null, session: null, user: null, error: null }
      return { data: null, user: null, session: null, error }
    }
  }

The flow is something like this:

  1. Call `supabase.auth.signIn({ provider: 'github' })
  2. User is sent to Github.com where they will be prompted to allow/deny your app access to their data
  3. If they allow your app access, Github.com redirects back to your app
  4. Now, through some Supabase magic, you will have access to the session, user, etc. data

Upvotes: 1

Related Questions