Skip to content

Commit

Permalink
Using current_user endpoint to fetch the authenticated user (#41)
Browse files Browse the repository at this point in the history
* server, betterangels starting commands

* stuck on backend

* initial

* fetch current user

* Added a few things

* adding fetch user

* chagne back to local host

* loop bug fix

* adding fetched user endpoint

* updated session and user fetch

* dev env check

* removed log

---------

Co-authored-by: Davit-BetterAngels <davit@betterangels.la>
Co-authored-by: Davit-BetterAngels <141072810+Davit-BetterAngels@users.noreply.github.com>
  • Loading branch information
3 people authored Oct 9, 2023
1 parent 49f791e commit 44d92fb
Show file tree
Hide file tree
Showing 16 changed files with 115 additions and 74 deletions.
2 changes: 1 addition & 1 deletion apps/betterangels-backend/.env
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ SOCIALACCOUNT_GOOGLE_CLIENT_ID="488261458560-ign54eicotm281qll13vi7gq7ps4ga3h.ap
SOCIALACCOUNT_GOOGLE_SECRET="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"

TRUSTED_ORIGINS=http://localhost:8081
CORS_ALLOW_ALL_ORIGINS=True
CORS_ALLOW_ALL_ORIGINS=True
7 changes: 7 additions & 0 deletions apps/betterangels-backend/accounts/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
SocialLoginSerializer as DjRestAuthSocialLoginSerializer,
)
from django.contrib.auth import get_user_model
from django.contrib.auth.models import User
from django.http import HttpResponseBadRequest
from django.utils.translation import gettext_lazy as _
from requests.exceptions import HTTPError
Expand All @@ -28,6 +29,12 @@
raise ImportError("allauth needs to be added to INSTALLED_APPS.")


class UserSerializer(serializers.ModelSerializer):
class Meta:
model = get_user_model()
fields = ("id", "username", "email")


class SocialLoginSerializer(DjRestAuthSocialLoginSerializer):
code_verifier = serializers.CharField(required=False, allow_blank=True)

Expand Down
3 changes: 2 additions & 1 deletion apps/betterangels-backend/accounts/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django.urls import path

from .views import AuthRedirectView, GoogleLogin, SignUpView
from .views import AuthRedirectView, GoogleLogin, SignUpView, current_user

urlpatterns = [
path("signup/", SignUpView.as_view(), name="signup"),
path("rest-auth/google/", GoogleLogin.as_view(), name="google_login"),
path("auth-redirect", AuthRedirectView.as_view(), name="auth_redirect"),
path("current-user/", current_user, name="current-user"),
]
14 changes: 13 additions & 1 deletion apps/betterangels-backend/accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,28 @@
from django.db import models
from django.urls import reverse_lazy
from django.views.generic.edit import CreateView
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView

from .forms import UserCreationForm
from .serializers import SocialLoginSerializer
from .serializers import SocialLoginSerializer, UserSerializer

T = TypeVar("T")


@api_view(["GET"])
@permission_classes([IsAuthenticated])
def current_user(request):
"""
Return details of the currently authenticated user.
"""
serializer = UserSerializer(request.user)
return Response(serializer.data)


class SignUpView(CreateView[models.Model, UserCreationForm]):
form_class = UserCreationForm
success_url = reverse_lazy("login")
Expand Down
5 changes: 3 additions & 2 deletions apps/betterangels-backend/betterangels_backend/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"corsheaders.middleware.CorsMiddleware",
]


Expand Down Expand Up @@ -228,4 +228,5 @@

CORS_ALLOW_CREDENTIALS = True
CSRF_TRUSTED_ORIGINS = env("TRUSTED_ORIGINS")
CORS_ALLOW_ALL_ORIGINS = env("CORS_ALLOW_ALL_ORIGINS")
# CORS_ALLOW_ALL_ORIGINS = env("CORS_ALLOW_ALL_ORIGINS")
CORS_ALLOW_ALL_ORIGINS = True
6 changes: 3 additions & 3 deletions apps/betterangels/.env
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
EXPO_PUBLIC_API_URL=http://localhost:8000
EXPO_PUBLIC_CLIENT_ID=488261458560-ign54eicotm281qll13vi7gq7ps4ga3h.apps.googleusercontent.com
EXPO_PUBLIC_REDIRECT_URL=http://localhost:8000/auth-redirect
EXPO_PUBLIC_API_URL=https://api.dev.betterangels.la
EXPO_PUBLIC_CLIENT_ID=488261458560-6j1dksppmk9en8f72dt04jugrvilj4lv.apps.googleusercontent.com
EXPO_PUBLIC_REDIRECT_URL=https://api.dev.betterangels.la/auth-redirect
2 changes: 1 addition & 1 deletion apps/betterangels/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "BetterAngels",
"slug": "betterangels",
"scheme": "betterangels",
"version": "1.0.3",
"version": "1.0.4",
"orientation": "portrait",
"icon": "./src/app/assets/images/icon.png",
"splash": {
Expand Down
2 changes: 1 addition & 1 deletion apps/betterangels/eas.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
},
"env": {
"EXPO_PUBLIC_API_URL": "https://api.dev.betterangels.la",
"EXPO_PUBLIC_CLIENT_ID": "488261458560-ign54eicotm281qll13vi7gq7ps4ga3h.apps.googleusercontent.com",
"EXPO_PUBLIC_CLIENT_ID": "488261458560-6j1dksppmk9en8f72dt04jugrvilj4lv.apps.googleusercontent.com",
"EXPO_PUBLIC_REDIRECT_URL": "https://api.dev.betterangels.la/auth-redirect"
}
},
Expand Down
14 changes: 12 additions & 2 deletions apps/betterangels/src/app/(tabs)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,22 @@ export default function TabOneScreen() {
const { user } = useUser();
const { signOut } = useSignOut();

async function getUser() {
if (!user) return;
console.log(user);
}

return (
<View style={styles.container}>
<Text style={styles.title}>Tab One: user id: {user?.id}</Text>
<Pressable onPress={signOut}>
<Text style={styles.title}>
Tab One: user id: {user?.id} username: {user?.username}
</Text>
<Pressable onPress={() => signOut()}>
<Text>Sign Out</Text>
</Pressable>
<Pressable onPress={() => getUser()}>
<Text>Fetch User</Text>
</Pressable>
<View
style={styles.separator}
lightColor="#eee"
Expand Down
56 changes: 28 additions & 28 deletions apps/betterangels/src/app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,34 +21,34 @@ SplashScreen.preventAutoHideAsync();

export default function RootLayout() {
const [loaded, error] = useFonts({
IBM: require('./fonts/IBMPlexSans-Regular.ttf'),
'IBM-italic': require('./fonts/IBMPlexSans-Italic.ttf'),
'IBM-bold': require('./fonts/IBMPlexSans-Bold.ttf'),
'IBM-bold-italic': require('./fonts/IBMPlexSans-BoldItalic.ttf'),
'IBM-semibold': require('./fonts/IBMPlexSans-SemiBold.ttf'),
'IBM-semibold-italic': require('./fonts/IBMPlexSans-SemiBoldItalic.ttf'),
'IBM-medium': require('./fonts/IBMPlexSans-Medium.ttf'),
'IBM-medium-italic': require('./fonts/IBMPlexSans-MediumItalic.ttf'),
'IBM-light': require('./fonts/IBMPlexSans-Light.ttf'),
'IBM-light-italic': require('./fonts/IBMPlexSans-LightItalic.ttf'),
'IBM-thin': require('./fonts/IBMPlexSans-Thin.ttf'),
'IBM-thin-italic': require('./fonts/IBMPlexSans-ThinItalic.ttf'),
'IBM-extra-light': require('./fonts/IBMPlexSans-ExtraLight.ttf'),
'IBM-extra-light-italic': require('./fonts/IBMPlexSans-ExtraLightItalic.ttf'),
'Pragmatica-bold': require('./fonts/Pragmatica-Bold.ttf'),
'Pragmatica-bold-italic': require('./fonts/Pragmatica-BoldOblique.ttf'),
'Pragmatica-medium': require('./fonts/Pragmatica-Medium.ttf'),
'Pragmatica-medium-italic': require('./fonts/Pragmatica-MediumOblique.ttf'),
'Pragmatica-light': require('./fonts/Pragmatica-Light.ttf'),
'Pragmatica-light-italic': require('./fonts/Pragmatica-LightOblique.ttf'),
'Pragmatica-extra-light': require('./fonts/Pragmatica-ExtraLight.ttf'),
'Pragmatica-extra-light-italic': require('./fonts/Pragmatica-ExtraLightOblique.ttf'),
'Pragmatica-black': require('./fonts/Pragmatica-Black.ttf'),
'Pragmatica-black-italic': require('./fonts/Pragmatica-BlackOblique.ttf'),
'Pragmatica-book': require('./fonts/Pragmatica-Book.ttf'),
'Pragmatica-book-italic': require('./fonts/Pragmatica-BookOblique.ttf'),
'Pragmatica-extra-bold': require('./fonts/Pragmatica-ExtraBold.ttf'),
'Pragmatica-extra-bold-italic': require('./fonts/Pragmatica-ExtraBoldOblique.ttf'),
IBM: require('./assets/fonts/IBMPlexSans-Regular.ttf'),
'IBM-italic': require('./assets/fonts/IBMPlexSans-Italic.ttf'),
'IBM-bold': require('./assets/fonts/IBMPlexSans-Bold.ttf'),
'IBM-bold-italic': require('./assets/fonts/IBMPlexSans-BoldItalic.ttf'),
'IBM-semibold': require('./assets/fonts/IBMPlexSans-SemiBold.ttf'),
'IBM-semibold-italic': require('./assets/fonts/IBMPlexSans-SemiBoldItalic.ttf'),
'IBM-medium': require('./assets/fonts/IBMPlexSans-Medium.ttf'),
'IBM-medium-italic': require('./assets/fonts/IBMPlexSans-MediumItalic.ttf'),
'IBM-light': require('./assets/fonts/IBMPlexSans-Light.ttf'),
'IBM-light-italic': require('./assets/fonts/IBMPlexSans-LightItalic.ttf'),
'IBM-thin': require('./assets/fonts/IBMPlexSans-Thin.ttf'),
'IBM-thin-italic': require('./assets/fonts/IBMPlexSans-ThinItalic.ttf'),
'IBM-extra-light': require('./assets/fonts/IBMPlexSans-ExtraLight.ttf'),
'IBM-extra-light-italic': require('./assets/fonts/IBMPlexSans-ExtraLightItalic.ttf'),
'Pragmatica-bold': require('./assets/fonts/Pragmatica-Bold.ttf'),
'Pragmatica-bold-italic': require('./assets/fonts/Pragmatica-BoldOblique.ttf'),
'Pragmatica-medium': require('./assets/fonts/Pragmatica-Medium.ttf'),
'Pragmatica-medium-italic': require('./assets/fonts/Pragmatica-MediumOblique.ttf'),
'Pragmatica-light': require('./assets/fonts/Pragmatica-Light.ttf'),
'Pragmatica-light-italic': require('./assets/fonts/Pragmatica-LightOblique.ttf'),
'Pragmatica-extra-light': require('./assets/fonts/Pragmatica-ExtraLight.ttf'),
'Pragmatica-extra-light-italic': require('./assets/fonts/Pragmatica-ExtraLightOblique.ttf'),
'Pragmatica-black': require('./assets/fonts/Pragmatica-Black.ttf'),
'Pragmatica-black-italic': require('./assets/fonts/Pragmatica-BlackOblique.ttf'),
'Pragmatica-book': require('./assets/fonts/Pragmatica-Book.ttf'),
'Pragmatica-book-italic': require('./assets/fonts/Pragmatica-BookOblique.ttf'),
'Pragmatica-extra-bold': require('./assets/fonts/Pragmatica-ExtraBold.ttf'),
'Pragmatica-extra-bold-italic': require('./assets/fonts/Pragmatica-ExtraBoldOblique.ttf'),
});

// Expo Router uses Error Boundaries to catch errors in the navigation tree.
Expand Down
41 changes: 13 additions & 28 deletions apps/betterangels/src/app/sign-in.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { getSessionId, useStore, useUser } from '@monorepo/expo/betterangels';
import { fetchUser, useStore, useUser } from '@monorepo/expo/betterangels';
import { HouseIcon } from '@monorepo/expo/shared/icons';
import { Buffer } from 'buffer';
import * as AuthSession from 'expo-auth-session';
import { useAutoDiscovery } from 'expo-auth-session';
import * as Crypto from 'expo-crypto';
import { router } from 'expo-router';
import * as WebBrowser from 'expo-web-browser';
import React, { useCallback, useEffect, useState } from 'react';
import { Button, Linking, Platform, SafeAreaView, Text } from 'react-native';
import { Button, Linking, SafeAreaView, Text } from 'react-native';
import { apiUrl, clientId, redirectUri } from '../../config';

WebBrowser.maybeCompleteAuthSession();
Expand All @@ -34,10 +33,9 @@ export default function SignIn() {
const [generatedState, setGeneratedState] = useState<string | undefined>(
undefined
);
const discovery = useAutoDiscovery(discoveryUrl);
const discovery = AuthSession.useAutoDiscovery(discoveryUrl);
const { saveStore } = useStore();
const { setUser } = useUser();
const [authKey, setAuthKey] = useState<string | null>(null);

useEffect(() => {
setGeneratedState(generateStatePayload());
Expand Down Expand Up @@ -98,7 +96,7 @@ export default function SignIn() {
}

try {
const tokenResponse = await fetch(
await fetch(
`${apiUrl}/rest-auth/google/?redirect_uri=${encodeURIComponent(
redirectUri
)}`,
Expand All @@ -116,16 +114,10 @@ export default function SignIn() {
}
);

if (Platform.OS === 'ios' || Platform.OS === 'android') {
const setCookieHeader = tokenResponse.headers.get('set-cookie');
if (setCookieHeader) {
const { sessionId } = getSessionId(setCookieHeader);
setAuthKey(sessionId);
saveStore('sessionid', sessionId);
setUser({ id: sessionId });
router.replace('/');
}
}
const userData = await fetchUser();
console.log('user data: ', userData);
setUser(userData);
router.replace('/');
} catch (error) {
console.error('Error fetching access token', error);
}
Expand Down Expand Up @@ -163,18 +155,11 @@ export default function SignIn() {
style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}
>
<HouseIcon color="#ffffff" size="md" />
{authKey ? (
<>
<Text>Token: {authKey}</Text>
<Button title="Logout" onPress={() => setAuthKey(null)} />
</>
) : (
<Button
title="Login with Google"
onPress={() => promptAsync({ showInRecents: false })}
disabled={!generatedState && !request}
/>
)}
<Button
title="Login with Google"
onPress={() => promptAsync({ showInRecents: false })}
disabled={!generatedState && !request}
/>
</SafeAreaView>
);
}
20 changes: 20 additions & 0 deletions libs/expo/betterangels/src/lib/helpers/fetchUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export default async function fetchUser() {
try {
const response = await fetch(
`${process.env['EXPO_PUBLIC_API_URL']}/current-user/`,
{
credentials: 'include',
}
);

const data = await response.json();

if (response.ok) {
return data;
} else {
console.log('Failed to fetch user data:', response);
}
} catch (e) {
console.log('Error getting user:', e);
}
}
1 change: 1 addition & 0 deletions libs/expo/betterangels/src/lib/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default as fetchUser } from './fetchUser';
export { default as getSessionId } from './getSessionId';
2 changes: 2 additions & 0 deletions libs/expo/betterangels/src/lib/providers/user/UserContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { createContext, Dispatch, SetStateAction } from 'react';

export type TUser = {
id: string;
username?: string;
email?: string;
};

export interface IUserProviderValue {
Expand Down
10 changes: 5 additions & 5 deletions libs/expo/betterangels/src/lib/providers/user/UserProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ReactNode, useEffect, useMemo, useState } from 'react';

import { useStore } from '../../hooks';
import { fetchUser } from '../../helpers';
import UserContext, { TUser } from './UserContext';

interface UserProviderProps {
Expand All @@ -10,13 +10,13 @@ interface UserProviderProps {
function useProtectedRoute() {
const [user, setUser] = useState<TUser | undefined>();
const [isLoading, setIsLoading] = useState<boolean>(true);
const { getStore } = useStore();

useEffect(() => {
async function getUserAndNavigate() {
try {
const sessionId = await getStore('sessionid');
setUser({ id: sessionId });
const user = await fetchUser();
console.log('fetched user: ', user);
setUser(user);
} catch (e) {
console.log(e);
} finally {
Expand All @@ -25,7 +25,7 @@ function useProtectedRoute() {
}

getUserAndNavigate();
}, [getStore]);
}, []);

return { user, setUser, isLoading };
}
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"private": true,
"scripts": {
"storybook": "nx run expo-shared-ui-components:storybook",
"storybook:build": "nx build-storybook expo-shared-ui-components"
"storybook:build": "nx build-storybook expo-shared-ui-components",
"server": "nx start betterangels-backend",
"ba": "nx start betterangels"
},
"dependencies": {
"@expo/metro-config": "~0.10.6",
Expand Down

0 comments on commit 44d92fb

Please sign in to comment.