1- import { and , eq } from 'drizzle-orm'
1+ import { and , desc , eq } from 'drizzle-orm'
22import { getSession } from '@/lib/auth'
33import { createLogger } from '@/lib/logs/console/logger'
44import { refreshOAuthToken } from '@/lib/oauth/oauth'
@@ -70,7 +70,8 @@ export async function getOAuthToken(userId: string, providerId: string): Promise
7070 } )
7171 . from ( account )
7272 . where ( and ( eq ( account . userId , userId ) , eq ( account . providerId , providerId ) ) )
73- . orderBy ( account . createdAt )
73+ // Always use the most recently updated credential for this provider
74+ . orderBy ( desc ( account . updatedAt ) )
7475 . limit ( 1 )
7576
7677 if ( connections . length === 0 ) {
@@ -80,19 +81,13 @@ export async function getOAuthToken(userId: string, providerId: string): Promise
8081
8182 const credential = connections [ 0 ]
8283
83- // Check if we have a valid access token
84- if ( ! credential . accessToken ) {
85- logger . warn ( `Access token is null for user ${ userId } , provider ${ providerId } ` )
86- return null
87- }
88-
89- // Check if the token is expired and needs refreshing
84+ // Determine whether we should refresh: missing token OR expired token
9085 const now = new Date ( )
9186 const tokenExpiry = credential . accessTokenExpiresAt
92- // Only refresh if we have an expiration time AND it's expired AND we have a refresh token
93- const needsRefresh = tokenExpiry && tokenExpiry < now && ! ! credential . refreshToken
87+ const shouldAttemptRefresh =
88+ ! ! credential . refreshToken && ( ! credential . accessToken || ( tokenExpiry && tokenExpiry < now ) )
9489
95- if ( needsRefresh ) {
90+ if ( shouldAttemptRefresh ) {
9691 logger . info (
9792 `Access token expired for user ${ userId } , provider ${ providerId } . Attempting to refresh.`
9893 )
@@ -141,6 +136,13 @@ export async function getOAuthToken(userId: string, providerId: string): Promise
141136 }
142137 }
143138
139+ if ( ! credential . accessToken ) {
140+ logger . warn (
141+ `Access token is null and no refresh attempted or available for user ${ userId } , provider ${ providerId } `
142+ )
143+ return null
144+ }
145+
144146 logger . info ( `Found valid OAuth token for user ${ userId } , provider ${ providerId } ` )
145147 return credential . accessToken
146148}
@@ -164,19 +166,21 @@ export async function refreshAccessTokenIfNeeded(
164166 return null
165167 }
166168
167- // Check if we need to refresh the token
169+ // Decide if we should refresh: token missing OR expired
168170 const expiresAt = credential . accessTokenExpiresAt
169171 const now = new Date ( )
170- // Only refresh if we have an expiration time AND it's expired
171- // If no expiration time is set (newly created credentials), assume token is valid
172- const needsRefresh = expiresAt && expiresAt <= now
172+ const shouldRefresh =
173+ ! ! credential . refreshToken && ( ! credential . accessToken || ( expiresAt && expiresAt <= now ) )
173174
174175 const accessToken = credential . accessToken
175176
176- if ( needsRefresh && credential . refreshToken ) {
177+ if ( shouldRefresh ) {
177178 logger . info ( `[${ requestId } ] Token expired, attempting to refresh for credential` )
178179 try {
179- const refreshedToken = await refreshOAuthToken ( credential . providerId , credential . refreshToken )
180+ const refreshedToken = await refreshOAuthToken (
181+ credential . providerId ,
182+ credential . refreshToken !
183+ )
180184
181185 if ( ! refreshedToken ) {
182186 logger . error ( `[${ requestId } ] Failed to refresh token for credential: ${ credentialId } ` , {
@@ -217,6 +221,7 @@ export async function refreshAccessTokenIfNeeded(
217221 return null
218222 }
219223 } else if ( ! accessToken ) {
224+ // We have no access token and either no refresh token or not eligible to refresh
220225 logger . error ( `[${ requestId } ] Missing access token for credential` )
221226 return null
222227 }
@@ -233,21 +238,20 @@ export async function refreshTokenIfNeeded(
233238 credential : any ,
234239 credentialId : string
235240) : Promise < { accessToken : string ; refreshed : boolean } > {
236- // Check if we need to refresh the token
241+ // Decide if we should refresh: token missing OR expired
237242 const expiresAt = credential . accessTokenExpiresAt
238243 const now = new Date ( )
239- // Only refresh if we have an expiration time AND it's expired
240- // If no expiration time is set (newly created credentials), assume token is valid
241- const needsRefresh = expiresAt && expiresAt <= now
244+ const shouldRefresh =
245+ ! ! credential . refreshToken && ( ! credential . accessToken || ( expiresAt && expiresAt <= now ) )
242246
243- // If token is still valid, return it directly
244- if ( ! needsRefresh || ! credential . refreshToken ) {
247+ // If token appears valid and present , return it directly
248+ if ( ! shouldRefresh ) {
245249 logger . info ( `[${ requestId } ] Access token is valid` )
246250 return { accessToken : credential . accessToken , refreshed : false }
247251 }
248252
249253 try {
250- const refreshResult = await refreshOAuthToken ( credential . providerId , credential . refreshToken )
254+ const refreshResult = await refreshOAuthToken ( credential . providerId , credential . refreshToken ! )
251255
252256 if ( ! refreshResult ) {
253257 logger . error ( `[${ requestId } ] Failed to refresh token for credential` )
0 commit comments