Repository navigation
Refactor AuthContext to use Better Auth session as source of truth #38
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
Changes from all commits
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 | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -12,7 +12,7 @@ const Signin = () => { | |||||||||||||||||
| const navigate = useNavigate(); | ||||||||||||||||||
| const [loading, setLoading] = useState(false); | ||||||||||||||||||
| const [tab, setTab] = useState<"password" | "passkey">("password"); | ||||||||||||||||||
| const { setUser } = useAuth(); | ||||||||||||||||||
| const { fetchUser } = useAuth(); | ||||||||||||||||||
|
|
||||||||||||||||||
| const schema = z.object({ | ||||||||||||||||||
| email: z.string().email({ message: "Invalid email address" }), | ||||||||||||||||||
|
|
@@ -55,11 +55,7 @@ const Signin = () => { | |||||||||||||||||
| }); | ||||||||||||||||||
|
|
||||||||||||||||||
| if (!res.ok) throw new Error("Invalid credentials"); | ||||||||||||||||||
| const profileRes = await fetch(`${BASE_URL}/profile`, { | ||||||||||||||||||
| credentials: "include", | ||||||||||||||||||
| }); | ||||||||||||||||||
| const profileData: any = await profileRes.json(); | ||||||||||||||||||
| setUser(profileData); | ||||||||||||||||||
| await fetchUser(); | ||||||||||||||||||
|
||||||||||||||||||
| await fetchUser(); | |
| await fetchUser().catch((error: unknown) => { | |
| // Ensure auth refresh failures are treated as login failures. | |
| if (error instanceof Error) { | |
| throw error; | |
| } | |
| throw new Error("Failed to refresh user session after sign-in"); | |
| }); |
Copilot
AI
Mar 7, 2026
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.
Same as the password flow: after passkey verification, the code proceeds to success toast + navigation regardless of whether fetchUser() actually hydrated auth state (it currently swallows failures). Consider having fetchUser signal refresh failures so this flow doesn’t navigate with a null auth context.
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,6 +5,7 @@ import { toast } from "react-hot-toast"; | |||||||||||
| import { useNavigate } from "react-router-dom"; | ||||||||||||
| import { z } from "zod"; | ||||||||||||
| import { BASE_URL } from "../config"; | ||||||||||||
| import { useAuth } from "../context/AuthContext"; | ||||||||||||
| import { base64urlToUint8Array, bufferToBase64 } from "../utils/webauthn"; | ||||||||||||
|
|
||||||||||||
| const schema = z.object({ | ||||||||||||
|
|
@@ -17,6 +18,7 @@ type SignupFormData = z.infer<typeof schema>; | |||||||||||
| const Signup = () => { | ||||||||||||
| const resolver = zodResolver(schema); | ||||||||||||
| const navigate = useNavigate(); | ||||||||||||
| const { fetchUser } = useAuth(); | ||||||||||||
|
|
||||||||||||
| const { | ||||||||||||
| register, | ||||||||||||
|
|
@@ -39,6 +41,7 @@ const Signup = () => { | |||||||||||
| }); | ||||||||||||
| if (!res.ok) throw new Error("Signup failed"); | ||||||||||||
|
|
||||||||||||
| await fetchUser(); | ||||||||||||
|
||||||||||||
| await fetchUser(); | |
| const fetchedUser = await fetchUser(); | |
| if (!fetchedUser) { | |
| throw new Error("Failed to load user session after signup"); | |
| } |
Copilot
AI
Mar 7, 2026
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.
Same concern for the passkey-only signup flow: navigation/success messaging happens even if fetchUser() didn’t successfully hydrate auth state (it currently catches errors internally). Consider making fetchUser signal refresh failure so this path can stop and display an error instead of navigating with a null auth context.
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.
fetchUsertreats any non-2xx response from/api/auth/get-sessionas “no session” by settingsessionDatato null, which will clearusereven on transient server/network errors (e.g., 500) and can desync UI from a still-valid cookie session. Consider distinguishing “no session” (e.g., 200 with{ session: null }or a 401) from unexpected failures (throw / keep prior user and surface an error).