Skip to content

Commit ee9af38

Browse files
committed
auth logs
1 parent 92d3a0a commit ee9af38

File tree

3 files changed

+115
-71
lines changed

3 files changed

+115
-71
lines changed

src/routes/api/auth/callback/$provider.tsx

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ export const Route = createFileRoute('/api/auth/callback/$provider')({
1919
const error = url.searchParams.get('error')
2020

2121
if (error) {
22-
console.error(`[OAuth Callback] OAuth error received: ${error}`)
22+
console.error(`[AUTH:ERROR] OAuth error received from provider: ${error}`)
2323
return Response.redirect(new URL('/login?error=oauth_failed', request.url), 302)
2424
}
2525

2626
if (!code || !state) {
27-
console.error('[OAuth Callback] Missing code or state')
27+
console.error('[AUTH:ERROR] Missing code or state in OAuth callback')
2828
return Response.redirect(new URL('/login?error=oauth_failed', request.url), 302)
2929
}
3030

@@ -35,14 +35,14 @@ export const Route = createFileRoute('/api/auth/callback/$provider')({
3535
.find((c) => c.trim().startsWith('oauth_state='))
3636

3737
if (!stateCookie) {
38-
console.error('[OAuth Callback] No state cookie found')
38+
console.error('[AUTH:ERROR] No state cookie found - possible CSRF or cookie issue')
3939
return Response.redirect(new URL('/login?error=oauth_failed', request.url), 302)
4040
}
4141

4242
const cookieState = decodeURIComponent(stateCookie.split('=').slice(1).join('=').trim())
4343

4444
if (cookieState !== state) {
45-
console.error('[OAuth Callback] State mismatch')
45+
console.error(`[AUTH:ERROR] State mismatch - expected: ${cookieState.substring(0, 10)}..., received: ${state.substring(0, 10)}...`)
4646
return Response.redirect(new URL('/login?error=oauth_failed', request.url), 302)
4747
}
4848

@@ -88,9 +88,15 @@ export const Route = createFileRoute('/api/auth/callback/$provider')({
8888

8989
const tokenData = await tokenResponse.json()
9090
if (tokenData.error) {
91-
console.error('[OAuth Callback] GitHub OAuth error received')
91+
console.error(`[AUTH:ERROR] GitHub token exchange failed: ${tokenData.error}, description: ${tokenData.error_description || 'none'}`)
9292
throw new Error(`GitHub OAuth error: ${tokenData.error}`)
9393
}
94+
95+
if (!tokenData.access_token) {
96+
console.error('[AUTH:ERROR] GitHub token exchange succeeded but no access_token returned')
97+
throw new Error('No access token received from GitHub')
98+
}
99+
94100
accessToken = tokenData.access_token
95101
// Fetch user profile
96102
const profileResponse = await fetch('https://api.github.com/user', {
@@ -121,7 +127,8 @@ export const Route = createFileRoute('/api/auth/callback/$provider')({
121127
}
122128

123129
if (!email) {
124-
throw new Error('No verified email found for GitHub account')
130+
console.error(`[AUTH:ERROR] No verified email found for GitHub user ${profile.id} (${profile.login})`)
131+
throw new Error('No verified email found for GitHub account')
125132
}
126133

127134
userProfile = {
@@ -155,9 +162,15 @@ export const Route = createFileRoute('/api/auth/callback/$provider')({
155162

156163
const tokenData = await tokenResponse.json()
157164
if (tokenData.error) {
158-
console.error('[OAuth Callback] Google OAuth error received')
165+
console.error(`[AUTH:ERROR] Google token exchange failed: ${tokenData.error}, description: ${tokenData.error_description || 'none'}`)
159166
throw new Error(`Google OAuth error: ${tokenData.error}`)
160167
}
168+
169+
if (!tokenData.access_token) {
170+
console.error('[AUTH:ERROR] Google token exchange succeeded but no access_token returned')
171+
throw new Error('No access token received from Google')
172+
}
173+
161174
accessToken = tokenData.access_token
162175

163176
// Fetch user profile
@@ -173,7 +186,8 @@ export const Route = createFileRoute('/api/auth/callback/$provider')({
173186
const profile = await profileResponse.json()
174187

175188
if (!profile.verified_email) {
176-
throw new Error('Google email not verified')
189+
console.error(`[AUTH:ERROR] Google email not verified for user ${profile.id} (${profile.email})`)
190+
throw new Error('Google email not verified')
177191
}
178192

179193
userProfile = {
@@ -193,6 +207,7 @@ export const Route = createFileRoute('/api/auth/callback/$provider')({
193207
})
194208

195209
if (!user) {
210+
console.error(`[AUTH:ERROR] User ${result.userId} not found after OAuth account creation for ${provider}:${userProfile.id} (${userProfile.email})`)
196211
throw new Error('User not found after OAuth account creation')
197212
}
198213

@@ -224,7 +239,11 @@ export const Route = createFileRoute('/api/auth/callback/$provider')({
224239
headers,
225240
})
226241
} catch (err) {
227-
console.error('[API OAuth Callback] Error:', err instanceof Error ? err.message : 'Unknown error')
242+
console.error('[AUTH:ERROR] OAuth callback failed:', {
243+
error: err instanceof Error ? err.message : 'Unknown error',
244+
stack: err instanceof Error ? err.stack : undefined,
245+
provider: params.provider,
246+
})
228247
return Response.redirect(new URL('/login?error=oauth_failed', request.url), 302)
229248
}
230249
},

src/utils/auth.server-helpers.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export async function getCurrentUserFromRequest(request: Request) {
1010
const signedCookie = getSessionCookie(request)
1111

1212
if (!signedCookie) {
13+
// This is normal - user just isn't logged in
1314
return null
1415
}
1516

@@ -18,6 +19,7 @@ export async function getCurrentUserFromRequest(request: Request) {
1819
const cookieData = await verifyCookie(signedCookie)
1920

2021
if (!cookieData) {
22+
console.error('[AUTH:ERROR] Session cookie verification failed - invalid signature or expired')
2123
return null
2224
}
2325

@@ -27,11 +29,13 @@ export async function getCurrentUserFromRequest(request: Request) {
2729
})
2830

2931
if (!user) {
32+
console.error(`[AUTH:ERROR] Session cookie references non-existent user ${cookieData.userId}`)
3033
return null
3134
}
3235

3336
// Verify session version matches (for session revocation)
3437
if (user.sessionVersion !== cookieData.version) {
38+
console.error(`[AUTH:ERROR] Session version mismatch for user ${user.id} - expected ${user.sessionVersion}, got ${cookieData.version}`)
3539
return null
3640
}
3741

@@ -50,10 +54,10 @@ export async function getCurrentUserFromRequest(request: Request) {
5054
interestedInHidingAds: user.interestedInHidingAds,
5155
}
5256
} catch (error) {
53-
console.error(
54-
'[getCurrentUserFromRequest] Failed to get user from session:',
55-
error instanceof Error ? error.message : 'Unknown error',
56-
)
57+
console.error('[AUTH:ERROR] Failed to get user from session:', {
58+
error: error instanceof Error ? error.message : 'Unknown error',
59+
stack: error instanceof Error ? error.stack : undefined,
60+
})
5761
return null
5862
}
5963
}
@@ -65,6 +69,7 @@ export async function getAuthenticatedUser() {
6569
const user = await getCurrentUserFromRequest(request)
6670

6771
if (!user) {
72+
console.error('[AUTH:ERROR] Authentication required but user not authenticated')
6873
throw new Error('Not authenticated')
6974
}
7075

src/utils/oauth.server.ts

Lines changed: 78 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,22 @@ export async function upsertOAuthAccount(
3030
provider: OAuthProvider,
3131
profile: OAuthProfile,
3232
) {
33-
// Check if OAuth account already exists
34-
const existingAccount = await getOAuthAccount(provider, profile.id)
33+
try {
34+
// Check if OAuth account already exists
35+
const existingAccount = await getOAuthAccount(provider, profile.id)
36+
37+
if (existingAccount) {
38+
// Account exists, update user info if needed
39+
const user = await db.query.users.findFirst({
40+
where: eq(users.id, existingAccount.userId),
41+
})
3542

36-
if (existingAccount) {
37-
// Account exists, update user info if needed
38-
const user = await db.query.users.findFirst({
39-
where: eq(users.id, existingAccount.userId),
40-
})
43+
if (!user) {
44+
console.error(`[AUTH:ERROR] OAuth account exists for ${provider}:${profile.id} but user ${existingAccount.userId} not found`)
45+
throw new Error('User not found for existing OAuth account')
46+
}
4147

42-
if (user) {
48+
if (user) {
4349
const updates: {
4450
email?: string
4551
name?: string
@@ -70,64 +76,78 @@ export async function upsertOAuthAccount(
7076
}
7177
}
7278

73-
// Find user by email (for linking multiple OAuth providers)
74-
const existingUser = await db.query.users.findFirst({
75-
where: eq(users.email, profile.email),
76-
})
79+
// Find user by email (for linking multiple OAuth providers)
80+
const existingUser = await db.query.users.findFirst({
81+
where: eq(users.email, profile.email),
82+
})
7783

78-
let userId: string
84+
let userId: string
7985

80-
if (existingUser) {
81-
// Link OAuth account to existing user
82-
userId = existingUser.id
86+
if (existingUser) {
87+
// Link OAuth account to existing user
88+
console.log(`[AUTH:INFO] Linking ${provider} account to existing user ${existingUser.id} (${profile.email})`)
89+
userId = existingUser.id
8390

84-
// Update user info if provided
85-
const updates: {
86-
name?: string
87-
image?: string
88-
} = {}
91+
// Update user info if provided
92+
const updates: {
93+
name?: string
94+
image?: string
95+
} = {}
8996

90-
if (profile.name && !existingUser.name) {
91-
updates.name = profile.name
92-
}
93-
if (profile.image && !existingUser.image) {
94-
updates.image = profile.image
95-
}
97+
if (profile.name && !existingUser.name) {
98+
updates.name = profile.name
99+
}
100+
if (profile.image && !existingUser.image) {
101+
updates.image = profile.image
102+
}
96103

97-
if (Object.keys(updates).length > 0) {
98-
await db
99-
.update(users)
100-
.set({ ...updates, updatedAt: new Date() })
101-
.where(eq(users.id, userId))
102-
}
103-
} else {
104-
// Create new user
105-
const [newUser] = await db
106-
.insert(users)
107-
.values({
108-
email: profile.email,
109-
name: profile.name,
110-
image: profile.image,
111-
capabilities: [],
112-
displayUsername: profile.name,
113-
})
114-
.returning()
104+
if (Object.keys(updates).length > 0) {
105+
await db
106+
.update(users)
107+
.set({ ...updates, updatedAt: new Date() })
108+
.where(eq(users.id, userId))
109+
}
110+
} else {
111+
// Create new user
112+
console.log(`[AUTH:INFO] Creating new user for ${provider} login: ${profile.email}`)
113+
const [newUser] = await db
114+
.insert(users)
115+
.values({
116+
email: profile.email,
117+
name: profile.name,
118+
image: profile.image,
119+
capabilities: [],
120+
displayUsername: profile.name,
121+
})
122+
.returning()
123+
124+
if (!newUser) {
125+
console.error(`[AUTH:ERROR] Failed to create user for ${provider}:${profile.id} (${profile.email})`)
126+
throw new Error('Failed to create user')
127+
}
115128

116-
userId = newUser.id
117-
}
129+
userId = newUser.id
130+
}
118131

119-
// Create OAuth account link
120-
const newOAuthAccount: NewOAuthAccount = {
121-
userId,
122-
provider,
123-
providerAccountId: profile.id,
124-
email: profile.email,
125-
}
132+
// Create OAuth account link
133+
const newOAuthAccount: NewOAuthAccount = {
134+
userId,
135+
provider,
136+
providerAccountId: profile.id,
137+
email: profile.email,
138+
}
126139

127-
await db.insert(oauthAccounts).values(newOAuthAccount)
140+
await db.insert(oauthAccounts).values(newOAuthAccount)
128141

129-
return {
130-
userId,
131-
isNewUser: !existingUser,
142+
return {
143+
userId,
144+
isNewUser: !existingUser,
145+
}
146+
} catch (error) {
147+
console.error(`[AUTH:ERROR] Failed to upsert OAuth account for ${provider}:${profile.id} (${profile.email}):`, {
148+
error: error instanceof Error ? error.message : 'Unknown error',
149+
stack: error instanceof Error ? error.stack : undefined,
150+
})
151+
throw error
132152
}
133153
}

0 commit comments

Comments
 (0)