-
Notifications
You must be signed in to change notification settings - Fork 2
Google oauth #7
base: main
Are you sure you want to change the base?
Google oauth #7
Changes from all commits
164d5a6
8100ae3
3016678
5107290
b22f369
89f2cfa
e413c24
34fbfa7
47d5636
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,3 +35,6 @@ yarn-error.log* | |
| # Ignore cache files | ||
| /.changelog | ||
| /.cache | ||
|
|
||
| # Environment files | ||
| .env | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| import React, { useState, useEffect } from "react"; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why call this Also I believe the convention is to use capital letters for the file name, |
||
| import axios from "axios"; | ||
| import { createClient } from "@supabase/supabase-js"; | ||
|
|
||
| const supabase = createClient(process.env.REACT_APP_SUPABASE_URL, process.env.REACT_APP_SUPABASE_PUBLIC_ANON_KEY, { | ||
| auth: { | ||
|
Comment on lines
+5
to
+6
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add instructions to the README about what env vars are necessary, where to find them, and where to set them like an
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also this seems to duplicate code from supabaseSetup.tsx? |
||
| autoRefreshToken: true, | ||
| persistSession: true, | ||
| detectSessionInUrl: true | ||
| } | ||
| }); | ||
|
|
||
| ... | ||
| declare global { | ||
| interface Window { | ||
| handleSignInWithGoogle?: any; | ||
| } | ||
| } | ||
|
|
||
| function Login() { | ||
| const [session, setSession] = useState(null); | ||
| const [user, setUser] = useState(null); | ||
|
|
||
| useEffect(() => { | ||
| const script = document.createElement('script'); | ||
|
|
||
| script.src = "https://accounts.google.com/gsi/client"; | ||
| script.async = true; | ||
| script.defer = true; | ||
|
|
||
| document.body.appendChild(script); | ||
|
|
||
| return () => { | ||
| document.body.removeChild(script); | ||
| } | ||
| }, []); | ||
|
|
||
| window.handleSignInWithGoogle = async(response) => { | ||
| try { | ||
| const { data, error } = await supabase.auth.signInWithOAuth({ | ||
| provider: 'google', | ||
| options: { | ||
| redirectTo: 'http://localhost:3000/logged-in' | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This shouldn't redirect |
||
| }, | ||
| }) | ||
|
|
||
| } catch (error) { | ||
| console.log("Error:", error); | ||
| } | ||
| } | ||
|
|
||
| return ( | ||
| <> | ||
| <div className="google-login-button"> | ||
| <div id="g_id_onload" | ||
| data-client_id="757897629512-3ltcl0q206uancd3h7jbi63aaj3levud.apps.googleusercontent.com" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Normally client IDs are risky to leak in source code and should be set via env vars. What is this client ID corresponding to? Google API client ID? |
||
| data-context="signin" | ||
| data-ux_mode="popup" | ||
| data-callback="handleSignInWithGoogle" | ||
| data-auto_prompt="false"> | ||
| </div> | ||
|
|
||
| <div className="g_id_signin" | ||
| data-type="standard" | ||
| data-shape="rectangular" | ||
| data-theme="outline" | ||
| data-text="signin_with" | ||
| data-size="large" | ||
| data-logo_alignment="left"> | ||
| </div> | ||
| </div> | ||
| </> | ||
| ); | ||
| } | ||
|
|
||
| export default Login; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| /* eslint-disable @typescript-eslint/no-explicit-any */ | ||
| import React, { createContext, useState, useEffect, useContext, ReactNode } from "react"; | ||
| import { createClient, Session, AuthChangeEvent } from "@supabase/supabase-js"; | ||
|
|
||
| const supabase = createClient(process.env.REACT_APP_SUPABASE_URL, process.env.REACT_APP_SUPABASE_PUBLIC_ANON_KEY, { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is duplicated |
||
| auth: { | ||
| autoRefreshToken: true, | ||
| persistSession: true, | ||
| detectSessionInUrl: true | ||
| } | ||
| }); | ||
|
|
||
| interface AuthContextProps { | ||
| session: Session | null; | ||
| user: any; | ||
| } | ||
| const AuthContext = createContext<AuthContextProps>({session: null, user: null}); | ||
|
|
||
| export const useAuth = () => useContext(AuthContext) | ||
|
|
||
| export const AuthProvider: React.FC<{ children: ReactNode }> = ({children}) => { | ||
| const [session, setSession] = useState<Session | null>(null); | ||
| const [user, setUser] = useState<any>(null); | ||
|
|
||
| useEffect(() => { | ||
| const sessionListener = supabase.auth.onAuthStateChange((event: AuthChangeEvent, session: Session | null) => { | ||
| setSession(session); | ||
| setUser(session?.user ?? null); | ||
| }); | ||
|
|
||
| const fetchSession = async() => { | ||
| try { | ||
| const { data, error } = await supabase.auth.getSession(); | ||
|
|
||
| if(error) { | ||
| // Handle error if any | ||
| console.error("Error fetching session: ", error) | ||
| } else if (data && data.session) { | ||
| // session exists | ||
| setSession(data.session); | ||
| setUser(data.session.user ?? null); | ||
| } else { | ||
| // no session exists, set seesion state to null | ||
| setSession(null); | ||
| setUser(null); | ||
| } | ||
| } catch (error) { | ||
| console.error("Unexpected error fetching session: ", error) | ||
| } | ||
| }; | ||
|
|
||
| fetchSession(); | ||
|
|
||
| return () => { | ||
| if(sessionListener.data.subscription) { | ||
| sessionListener.data.subscription.unsubscribe(); | ||
| } | ||
| }; | ||
| }, []); | ||
|
|
||
| return ( | ||
| <AuthContext.Provider value={{ session, user }}> | ||
| {children} | ||
| </AuthContext.Provider> | ||
| ); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,5 +7,6 @@ | |
| <body> | ||
| <div id="app"></div> | ||
| <script type="module" src="index.tsx"></script> | ||
| <script src="https://accounts.google.com/gsi/client" async></script> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You auto-inject this via the JS code. What approach did you intend to do? |
||
| </body> | ||
| </html> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| import React from "react"; | ||
| import { useAuth } from "../../contexts/AuthContext"; | ||
| import { supabase } from "../../setup/supabaseSetup"; | ||
| import { useNavigate } from "react-router-dom"; | ||
|
|
||
|
|
||
| export default function LoggedIn() { | ||
| const {session, user} = useAuth(); | ||
|
|
||
| const navigate = useNavigate(); | ||
|
|
||
| const signOut = async() => { | ||
| try { | ||
| const { error } = await supabase.auth.signOut(); | ||
| if(error) { | ||
| console.error("Error signing out: ", error.message) | ||
| } else { | ||
| console.log("User signed out successfully"); | ||
| navigate("/"); | ||
| } | ||
| } catch (error) { | ||
| console.error("Error while signing out: ", error) | ||
| } | ||
| } | ||
|
|
||
| return ( | ||
| <div> | ||
| {session ? <h1>User is logged in</h1> : <h1>User is not logged in</h1>} | ||
| {user ? <h2>User {user.email} is logged in</h2> : <h2>User has no name</h2>} | ||
| <button onClick={signOut}>Sign Out</button> | ||
| </div> | ||
| ) | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| import { createClient } from '@supabase/supabase-js'; | ||
|
|
||
| const supabaseUrl = process.env.REACT_APP_SUPABASE_URL; | ||
| const supabaseKey = process.env.REACT_APP_SUPABASE_PUBLIC_ANON_KEY; | ||
|
|
||
| if (!supabaseUrl || !supabaseKey) { | ||
| throw new Error("Supabase URL or Supabase Key is missing. Make sure to set them in your environment variables."); | ||
| } | ||
|
|
||
| export const supabase = createClient(supabaseUrl, supabaseKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normally the URL wouldn't change when you're logged in to a value like this. Was this for experimentation, or you intend to keep it?