Skip to content

Commit 4e0956c

Browse files
authored
feat(passport): add logging to auth callbacks (#2791)
1 parent a384921 commit 4e0956c

1 file changed

Lines changed: 103 additions & 91 deletions

File tree

packages/auth-next-server/src/config.ts

Lines changed: 103 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -154,31 +154,80 @@ export function createAuthConfig(config: ImmutableAuthConfig): NextAuthConfig {
154154
async jwt({
155155
token, user, trigger, session: sessionUpdate,
156156
}: any) {
157-
// Initial sign in - store all token data
158-
if (user) {
159-
return {
160-
...token,
161-
sub: user.sub,
162-
email: user.email,
163-
nickname: user.nickname,
164-
accessToken: user.accessToken,
165-
refreshToken: user.refreshToken,
166-
idToken: user.idToken,
167-
accessTokenExpires: user.accessTokenExpires,
168-
zkEvm: user.zkEvm,
169-
};
170-
}
157+
try {
158+
// Initial sign in - store all token data
159+
if (user) {
160+
return {
161+
...token,
162+
sub: user.sub,
163+
email: user.email,
164+
nickname: user.nickname,
165+
accessToken: user.accessToken,
166+
refreshToken: user.refreshToken,
167+
idToken: user.idToken,
168+
accessTokenExpires: user.accessTokenExpires,
169+
zkEvm: user.zkEvm,
170+
};
171+
}
172+
173+
// Handle session update (for client-side token sync or forceRefresh)
174+
// When client-side Auth refreshes tokens via TOKEN_REFRESHED event,
175+
// it calls updateSession() which triggers this callback with the new tokens.
176+
// We clear any stale error (e.g., TokenExpired) on successful update.
177+
if (trigger === 'update' && sessionUpdate) {
178+
const update = sessionUpdate as Record<string, unknown>;
179+
180+
// If forceRefresh is requested, perform server-side token refresh
181+
// This is used after zkEVM registration to get updated claims from IDP
182+
if (update.forceRefresh && token.refreshToken) {
183+
try {
184+
const refreshed = await refreshAccessToken(
185+
token.refreshToken as string,
186+
config.clientId,
187+
authDomain,
188+
);
189+
// Extract zkEvm claims from the refreshed idToken
190+
const zkEvm = extractZkEvmFromIdToken(refreshed.idToken);
191+
return {
192+
...token,
193+
accessToken: refreshed.accessToken,
194+
refreshToken: refreshed.refreshToken,
195+
idToken: refreshed.idToken,
196+
accessTokenExpires: refreshed.accessTokenExpires,
197+
zkEvm: zkEvm ?? token.zkEvm, // Keep existing zkEvm if not in new token
198+
error: undefined,
199+
};
200+
} catch (error) {
201+
// eslint-disable-next-line no-console
202+
console.error('[auth-next-server] Force refresh failed:', error);
203+
return {
204+
...token,
205+
error: 'RefreshTokenError',
206+
};
207+
}
208+
}
209+
210+
// Standard session update - merge provided values
211+
return {
212+
...token,
213+
...(update.accessToken ? { accessToken: update.accessToken } : {}),
214+
...(update.refreshToken ? { refreshToken: update.refreshToken } : {}),
215+
...(update.idToken ? { idToken: update.idToken } : {}),
216+
...(update.accessTokenExpires ? { accessTokenExpires: update.accessTokenExpires } : {}),
217+
...(update.zkEvm ? { zkEvm: update.zkEvm } : {}),
218+
// Clear any stale error when valid tokens are synced from client-side
219+
error: undefined,
220+
};
221+
}
171222

172-
// Handle session update (for client-side token sync or forceRefresh)
173-
// When client-side Auth refreshes tokens via TOKEN_REFRESHED event,
174-
// it calls updateSession() which triggers this callback with the new tokens.
175-
// We clear any stale error (e.g., TokenExpired) on successful update.
176-
if (trigger === 'update' && sessionUpdate) {
177-
const update = sessionUpdate as Record<string, unknown>;
223+
// Return token if not expired
224+
if (!isTokenExpired(token.accessTokenExpires as number)) {
225+
return token;
226+
}
178227

179-
// If forceRefresh is requested, perform server-side token refresh
180-
// This is used after zkEVM registration to get updated claims from IDP
181-
if (update.forceRefresh && token.refreshToken) {
228+
// Token expired - attempt server-side refresh
229+
// This ensures clients always get fresh tokens from session callbacks
230+
if (token.refreshToken) {
182231
try {
183232
const refreshed = await refreshAccessToken(
184233
token.refreshToken as string,
@@ -194,91 +243,54 @@ export function createAuthConfig(config: ImmutableAuthConfig): NextAuthConfig {
194243
idToken: refreshed.idToken,
195244
accessTokenExpires: refreshed.accessTokenExpires,
196245
zkEvm: zkEvm ?? token.zkEvm, // Keep existing zkEvm if not in new token
197-
error: undefined,
246+
error: undefined, // Clear any previous error
198247
};
199248
} catch (error) {
200-
// eslint-disable-next-line no-console
201-
console.error('[auth-next-server] Force refresh failed:', error);
249+
// eslint-disable-next-line no-console
250+
console.error('[auth-next-server] Token refresh failed:', error);
202251
return {
203252
...token,
204253
error: 'RefreshTokenError',
205254
};
206255
}
207256
}
208257

209-
// Standard session update - merge provided values
258+
// No refresh token available
210259
return {
211260
...token,
212-
...(update.accessToken ? { accessToken: update.accessToken } : {}),
213-
...(update.refreshToken ? { refreshToken: update.refreshToken } : {}),
214-
...(update.idToken ? { idToken: update.idToken } : {}),
215-
...(update.accessTokenExpires ? { accessTokenExpires: update.accessTokenExpires } : {}),
216-
...(update.zkEvm ? { zkEvm: update.zkEvm } : {}),
217-
// Clear any stale error when valid tokens are synced from client-side
218-
error: undefined,
261+
error: 'TokenExpired',
219262
};
263+
} catch (error) {
264+
// eslint-disable-next-line no-console
265+
console.error('[auth-next-server] JWT callback error:', error);
266+
throw error;
220267
}
221-
222-
// Return token if not expired
223-
if (!isTokenExpired(token.accessTokenExpires as number)) {
224-
return token;
225-
}
226-
227-
// Token expired - attempt server-side refresh
228-
// This ensures clients always get fresh tokens from session callbacks
229-
if (token.refreshToken) {
230-
try {
231-
const refreshed = await refreshAccessToken(
232-
token.refreshToken as string,
233-
config.clientId,
234-
authDomain,
235-
);
236-
// Extract zkEvm claims from the refreshed idToken
237-
const zkEvm = extractZkEvmFromIdToken(refreshed.idToken);
238-
return {
239-
...token,
240-
accessToken: refreshed.accessToken,
241-
refreshToken: refreshed.refreshToken,
242-
idToken: refreshed.idToken,
243-
accessTokenExpires: refreshed.accessTokenExpires,
244-
zkEvm: zkEvm ?? token.zkEvm, // Keep existing zkEvm if not in new token
245-
error: undefined, // Clear any previous error
246-
};
247-
} catch (error) {
248-
// eslint-disable-next-line no-console
249-
console.error('[auth-next-server] Token refresh failed:', error);
250-
return {
251-
...token,
252-
error: 'RefreshTokenError',
253-
};
254-
}
255-
}
256-
257-
// No refresh token available
258-
return {
259-
...token,
260-
error: 'TokenExpired',
261-
};
262268
},
263269

264270
// eslint-disable-next-line @typescript-eslint/no-explicit-any
265271
async session({ session, token }: any) {
266-
// Expose token data to the session
267-
return {
268-
...session,
269-
user: {
270-
...session.user,
271-
sub: token.sub as string,
272-
email: token.email as string | undefined,
273-
nickname: token.nickname as string | undefined,
274-
},
275-
accessToken: token.accessToken as string,
276-
refreshToken: token.refreshToken as string | undefined,
277-
idToken: token.idToken as string | undefined,
278-
accessTokenExpires: token.accessTokenExpires as number,
279-
zkEvm: token.zkEvm,
280-
...(token.error && { error: token.error as string }),
281-
};
272+
try {
273+
// Expose token data to the session
274+
return {
275+
...session,
276+
user: {
277+
...session.user,
278+
sub: token.sub as string,
279+
email: token.email as string | undefined,
280+
nickname: token.nickname as string | undefined,
281+
},
282+
accessToken: token.accessToken as string,
283+
refreshToken: token.refreshToken as string | undefined,
284+
idToken: token.idToken as string | undefined,
285+
accessTokenExpires: token.accessTokenExpires as number,
286+
zkEvm: token.zkEvm,
287+
...(token.error && { error: token.error as string }),
288+
};
289+
} catch (error) {
290+
// eslint-disable-next-line no-console
291+
console.error('[auth-next-server] Session callback error:', error);
292+
throw error;
293+
}
282294
},
283295
},
284296

0 commit comments

Comments
 (0)