diff --git a/FastNotes/app/login.tsx b/FastNotes/app/login.tsx
index b8c419d..833eb41 100644
--- a/FastNotes/app/login.tsx
+++ b/FastNotes/app/login.tsx
@@ -1,6 +1,6 @@
import { useState } from 'react'
import { Link, Stack } from 'expo-router'
-import { Pressable, Text, TextInput, View } from 'react-native'
+import { Keyboard, KeyboardAvoidingView, Platform, Pressable, ScrollView, Text, TextInput, View } from 'react-native'
import { supabase } from '@/libs/supabase'
import { useAppTheme } from '@/src/theme/AppThemeProvider'
import { loginScreenStyles as styles } from '@/src/styles/app-styles'
@@ -36,55 +36,69 @@ export default function LoginScreen() {
return (
<>
-
- Login
-
- E-mail
-
-
- Password
-
-
- {errorMessage ? (
- {errorMessage}
- ) : null}
-
- [
- styles.loginButton,
- pressed && !isSubmitting ? styles.loginButtonPressed : null,
- isSubmitting ? styles.loginButtonDisabled : null,
- ]}
+
+
-
- {isSubmitting ? 'Logging in...' : 'Log in'}
-
-
+
+
+ Login
-
- Create a new account
-
-
+ E-mail
+
+
+ Password
+
+
+ {errorMessage ? (
+ {errorMessage}
+ ) : null}
+
+ [
+ styles.loginButton,
+ pressed && !isSubmitting ? styles.loginButtonPressed : null,
+ isSubmitting ? styles.loginButtonDisabled : null,
+ ]}
+ >
+
+ {isSubmitting ? 'Logging in...' : 'Log in'}
+
+
+
+
+ Create a new account
+
+
+
+
+
>
)
}
diff --git a/FastNotes/app/newNote.tsx b/FastNotes/app/newNote.tsx
index a995bff..99c48e6 100644
--- a/FastNotes/app/newNote.tsx
+++ b/FastNotes/app/newNote.tsx
@@ -88,7 +88,7 @@ export default function NewNoteScreen() {
return
}
- router.replace("/index")
+ router.replace("/")
}
}
diff --git a/FastNotes/app/signup.tsx b/FastNotes/app/signup.tsx
index e243dbc..afcf518 100644
--- a/FastNotes/app/signup.tsx
+++ b/FastNotes/app/signup.tsx
@@ -1,7 +1,7 @@
import { supabase } from "@/libs/supabase"
-import { Link, Stack } from "expo-router"
+import { Link, Stack, router } from "expo-router"
import { useState } from "react"
-import { Pressable, Text, TextInput, View } from 'react-native'
+import { Keyboard, KeyboardAvoidingView, Platform, Pressable, ScrollView, Text, TextInput, View } from 'react-native'
import { useAppTheme } from "@/src/theme/AppThemeProvider"
import { signupScreenStyles as styles } from "@/src/styles/app-styles"
@@ -59,60 +59,80 @@ export default function SignupScreen(){
return (
<>
-
- Sign up
-
- E-mail
-
-
- Password
-
-
- {errorMessage ? (
- {errorMessage}
- ) : null}
-
- {successMessage ? (
- {successMessage}
- ) : null}
-
- [
- styles.actionButton,
- pressed && !isSubmitting ? styles.actionButtonPressed : null,
- isSubmitting ? styles.actionButtonDisabled : null,
- ]}
+
+
-
- {isSubmitting ? 'Creating account...' : 'Sign up'}
-
-
+
+
+ router.replace("/login")}
+ style={styles.backButton}
+ >
+ Back to login
+
-
- Already have an account? Log in
-
+ Sign up
-
+ E-mail
+
+
+ Password
+
+
+ {errorMessage ? (
+ {errorMessage}
+ ) : null}
+
+ {successMessage ? (
+ {successMessage}
+ ) : null}
+
+ [
+ styles.actionButton,
+ pressed && !isSubmitting ? styles.actionButtonPressed : null,
+ isSubmitting ? styles.actionButtonDisabled : null,
+ ]}
+ >
+
+ {isSubmitting ? 'Creating account...' : 'Sign up'}
+
+
+
+
+ Already have an account? Log in
+
+
+
+
+
>
)
}
diff --git a/FastNotes/providers/auth-provider.tsx b/FastNotes/providers/auth-provider.tsx
index 3abc1a0..cccf199 100644
--- a/FastNotes/providers/auth-provider.tsx
+++ b/FastNotes/providers/auth-provider.tsx
@@ -10,12 +10,37 @@ const buildClaims = (user?: { id: string; email?: string | null } | null) =>
}
: null
+const isInvalidRefreshTokenError = (error: { message?: string; status?: number } | null) => {
+ if (!error) {
+ return false
+ }
+
+ const message = error.message?.toLowerCase() ?? ''
+
+ return error.status === 401 && (
+ message.includes('invalid refresh token') ||
+ message.includes('refresh token not found')
+ )
+}
+
export default function AuthProvider({ children }: PropsWithChildren) {
const [claims, setClaims] = useState | undefined | null>()
const [profile, setProfile] = useState()
const [isLoading, setIsLoading] = useState(true)
useEffect(() => {
+ const clearInvalidSession = async () => {
+ const { error } = await supabase.auth.signOut({ scope: 'local' })
+
+ if (error) {
+ console.error('Error clearing invalid local session:', error)
+ }
+
+ setClaims(null)
+ setProfile(null)
+ setIsLoading(false)
+ }
+
const hydrateSession = async () => {
const {
data: { session },
@@ -23,6 +48,12 @@ export default function AuthProvider({ children }: PropsWithChildren) {
} = await supabase.auth.getSession()
if (error) {
+ if (isInvalidRefreshTokenError(error)) {
+ console.warn('Clearing expired auth session:', error.message)
+ await clearInvalidSession()
+ return
+ }
+
console.error('Error hydrating session:', error)
}
diff --git a/FastNotes/src/styles/app-styles.ts b/FastNotes/src/styles/app-styles.ts
index 429271c..bd1a42a 100644
--- a/FastNotes/src/styles/app-styles.ts
+++ b/FastNotes/src/styles/app-styles.ts
@@ -72,10 +72,23 @@ export const themedTextStyles = StyleSheet.create({
})
export const loginScreenStyles = StyleSheet.create({
- container: {
+ keyboardAvoider: {
+ flex: 1,
+ },
+ scrollView: {
+ flex: 1,
+ },
+ scrollContent: {
+ flexGrow: 1,
+ justifyContent: "center",
+ paddingHorizontal: 24,
+ paddingVertical: 32,
+ },
+ dismissArea: {
flex: 1,
justifyContent: "center",
- padding: 24,
+ },
+ form: {
gap: 12,
},
title: {
@@ -125,12 +138,33 @@ export const loginScreenStyles = StyleSheet.create({
})
export const signupScreenStyles = StyleSheet.create({
- container: {
+ keyboardAvoider: {
+ flex: 1,
+ },
+ scrollView: {
+ flex: 1,
+ },
+ scrollContent: {
+ flexGrow: 1,
+ justifyContent: "center",
+ paddingHorizontal: 24,
+ paddingVertical: 32,
+ },
+ dismissArea: {
flex: 1,
justifyContent: "center",
- padding: 24,
+ },
+ form: {
gap: 12,
},
+ backButton: {
+ alignSelf: "flex-start",
+ paddingVertical: 8,
+ },
+ backButtonText: {
+ fontSize: 16,
+ fontWeight: "600",
+ },
title: {
fontSize: 28,
fontWeight: "700",