-
Notifications
You must be signed in to change notification settings - Fork 24
Feature/google signin #139
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
f19dff5
e0d3db9
ccf234a
38f65ba
6d75613
19ca52a
5fd5b69
28b1734
f52faac
9cb8ff5
eeed952
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 |
|---|---|---|
|
|
@@ -49,6 +49,7 @@ yarn-error.* | |
|
|
||
| # local env files | ||
| .env*.local | ||
| frontend/.env | ||
|
|
||
| # typescript | ||
| *.tsbuildinfo | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| EXPO_PUBLIC_GOOGLE_EXPO_CLIENT_ID= | ||
| EXPO_PUBLIC_GOOGLE_IOS_CLIENT_ID= | ||
| EXPO_PUBLIC_GOOGLE_ANDROID_CLIENT_ID= | ||
| EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID= |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,6 @@ | ||||||||||||||||||||||||||
| import AsyncStorage from "@react-native-async-storage/async-storage"; | ||||||||||||||||||||||||||
| import { useAuthRequest } from "expo-auth-session/providers/google"; | ||||||||||||||||||||||||||
| import * as WebBrowser from "expo-web-browser"; | ||||||||||||||||||||||||||
| import { createContext, useEffect, useState } from "react"; | ||||||||||||||||||||||||||
| import * as authApi from "../api/auth"; | ||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||
|
|
@@ -7,6 +9,8 @@ import { | |||||||||||||||||||||||||
| setTokenUpdateListener, | ||||||||||||||||||||||||||
| } from "../api/client"; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| WebBrowser.maybeCompleteAuthSession(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const AuthContext = createContext(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| export const AuthProvider = ({ children }) => { | ||||||||||||||||||||||||||
|
|
@@ -15,13 +19,64 @@ export const AuthProvider = ({ children }) => { | |||||||||||||||||||||||||
| const [refresh, setRefresh] = useState(null); | ||||||||||||||||||||||||||
| const [isLoading, setIsLoading] = useState(true); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // For Expo Go, we need to use the web-based auth flow | ||||||||||||||||||||||||||
| // Force all platforms to use web client ID in Expo Go | ||||||||||||||||||||||||||
| const [request, response, promptAsync] = useAuthRequest({ | ||||||||||||||||||||||||||
| expoClientId: process.env.EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID, | ||||||||||||||||||||||||||
| iosClientId: process.env.EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID, // Force web client for iOS in Expo Go | ||||||||||||||||||||||||||
| androidClientId: process.env.EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID, // Force web client for Android in Expo Go | ||||||||||||||||||||||||||
| webClientId: process.env.EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID, | ||||||||||||||||||||||||||
| redirectUri: 'https://auth.expo.io/@devasy23/frontend', | ||||||||||||||||||||||||||
|
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. Avoid hardcoding the redirect URI. The redirect URI is hardcoded as - redirectUri: 'https://auth.expo.io/@devasy23/frontend',
+ redirectUri: process.env.EXPO_PUBLIC_REDIRECT_URI || makeRedirectUri({
+ useProxy: true,
+ }),Also import import { makeRedirectUri } from 'expo-auth-session';🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Debug logging | ||||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||||
| if (request) { | ||||||||||||||||||||||||||
| console.log("Auth request details:", { | ||||||||||||||||||||||||||
| url: request.url, | ||||||||||||||||||||||||||
| params: request.params | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| }, [request]); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||||
| const handleGoogleSignIn = async () => { | ||||||||||||||||||||||||||
| if (response?.type === "success") { | ||||||||||||||||||||||||||
| const { id_token } = response.params; | ||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||
| const res = await authApi.loginWithGoogle(id_token); | ||||||||||||||||||||||||||
| const { access_token, refresh_token, user: userData } = res.data; | ||||||||||||||||||||||||||
| setToken(access_token); | ||||||||||||||||||||||||||
| setRefresh(refresh_token); | ||||||||||||||||||||||||||
| await setAuthTokens({ | ||||||||||||||||||||||||||
| newAccessToken: access_token, | ||||||||||||||||||||||||||
| newRefreshToken: refresh_token, | ||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||
| const normalizedUser = userData?._id | ||||||||||||||||||||||||||
| ? userData | ||||||||||||||||||||||||||
| : userData?.id | ||||||||||||||||||||||||||
| ? { ...userData, _id: userData.id } | ||||||||||||||||||||||||||
| : userData; | ||||||||||||||||||||||||||
| setUser(normalizedUser); | ||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||
| console.error( | ||||||||||||||||||||||||||
| "Google login failed:", | ||||||||||||||||||||||||||
| error.response?.data?.detail || error.message | ||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| handleGoogleSignIn(); | ||||||||||||||||||||||||||
| }, [response]); | ||||||||||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Load token and user data from AsyncStorage on app start | ||||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||||
| const loadStoredAuth = async () => { | ||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||
| const storedToken = await AsyncStorage.getItem("auth_token"); | ||||||||||||||||||||||||||
| const storedRefresh = await AsyncStorage.getItem("refresh_token"); | ||||||||||||||||||||||||||
| const storedUser = await AsyncStorage.getItem("user_data"); | ||||||||||||||||||||||||||
| const storedUser = await AsyncStorage.getItem("user_data"); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if (storedToken && storedUser) { | ||||||||||||||||||||||||||
| setToken(storedToken); | ||||||||||||||||||||||||||
|
|
@@ -146,6 +201,10 @@ export const AuthProvider = ({ children }) => { | |||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| const loginWithGoogle = async () => { | ||||||||||||||||||||||||||
| await promptAsync(); | ||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||
|
Comment on lines
+204
to
+206
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. 🛠️ Refactor suggestion Add error handling to loginWithGoogle The function should handle potential errors from const loginWithGoogle = async () => {
- await promptAsync();
+ try {
+ const result = await promptAsync();
+ return result;
+ } catch (error) {
+ console.error("Failed to initiate Google sign-in:", error);
+ throw error;
+ }
};📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| const logout = async () => { | ||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||
| // Clear stored authentication data | ||||||||||||||||||||||||||
|
|
@@ -182,6 +241,7 @@ export const AuthProvider = ({ children }) => { | |||||||||||||||||||||||||
| signup, | ||||||||||||||||||||||||||
| logout, | ||||||||||||||||||||||||||
| updateUserInContext, | ||||||||||||||||||||||||||
| loginWithGoogle, | ||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||
| {children} | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,8 @@ | |
| "@react-navigation/native-stack": "^7.3.23", | ||
| "axios": "^1.11.0", | ||
| "expo": "~53.0.20", | ||
| "expo-auth-session": "^6.2.1", | ||
| "expo-crypto": "^14.1.5", | ||
| "expo-image-picker": "~16.0.2", | ||
|
Comment on lines
+19
to
21
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. 💡 Verification agent 🧩 Analysis chainVerify SDK compatibility and avoid caret ranges for Expo-managed packages. expo-auth-session and expo-crypto should match Expo SDK 53’s compatible versions. Using ^ can drift to incompatible minor versions; prefer versions installed via “npx expo install …”.
🌐 Web query: Error during web search 🏁 Script executed: #!/bin/bash
# Retrieve the Expo SDK version from app.json (if present)
rg '"sdkVersion"' -n
# Retrieve the Expo package version from frontend/package.json
rg '"expo"' -n frontend/package.json | sed -n '1,20p'Length of output: 103 Pin Expo-managed package versions with • File: frontend/package.json (lines 19–21) npx expo install expo-auth-session expo-crypto• Commit the updated dependency entries (no leading 🤖 Prompt for AI Agents |
||
| "expo-status-bar": "~2.2.3", | ||
| "react": "19.0.0", | ||
|
|
||
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.
🛠️ Refactor suggestion
Prevent duplicate entries in .env file
The current implementation uses
>>which appends to the file. If the file already exists (from a previous run or cache), this could create duplicate entries. Consider clearing the file first:- name: Create .env file working-directory: ./frontend run: | + > .env # Clear the file first echo "EXPO_PUBLIC_GOOGLE_EXPO_CLIENT_ID=${{ secrets.EXPO_PUBLIC_GOOGLE_EXPO_CLIENT_ID }}" >> .env echo "EXPO_PUBLIC_GOOGLE_IOS_CLIENT_ID=${{ secrets.EXPO_PUBLIC_GOOGLE_IOS_CLIENT_ID }}" >> .env echo "EXPO_PUBLIC_GOOGLE_ANDROID_CLIENT_ID=${{ secrets.EXPO_PUBLIC_GOOGLE_ANDROID_CLIENT_ID }}" >> .env echo "EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID=${{ secrets.EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID }}" >> .env📝 Committable suggestion
🤖 Prompt for AI Agents