@imtbl/auth-next-server 2.12.7-alpha.3 → 2.12.7-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -227,22 +227,63 @@ function createAuthConfig(config) {
227
227
  trigger,
228
228
  session: sessionUpdate
229
229
  }) {
230
- if (user) {
231
- return {
232
- ...token,
233
- sub: user.sub,
234
- email: user.email,
235
- nickname: user.nickname,
236
- accessToken: user.accessToken,
237
- refreshToken: user.refreshToken,
238
- idToken: user.idToken,
239
- accessTokenExpires: user.accessTokenExpires,
240
- zkEvm: user.zkEvm
241
- };
242
- }
243
- if (trigger === "update" && sessionUpdate) {
244
- const update = sessionUpdate;
245
- if (update.forceRefresh && token.refreshToken) {
230
+ try {
231
+ if (user) {
232
+ return {
233
+ ...token,
234
+ sub: user.sub,
235
+ email: user.email,
236
+ nickname: user.nickname,
237
+ accessToken: user.accessToken,
238
+ refreshToken: user.refreshToken,
239
+ idToken: user.idToken,
240
+ accessTokenExpires: user.accessTokenExpires,
241
+ zkEvm: user.zkEvm
242
+ };
243
+ }
244
+ if (trigger === "update" && sessionUpdate) {
245
+ const update = sessionUpdate;
246
+ if (update.forceRefresh && token.refreshToken) {
247
+ try {
248
+ const refreshed = await refreshAccessToken(
249
+ token.refreshToken,
250
+ config.clientId,
251
+ authDomain
252
+ );
253
+ const zkEvm = extractZkEvmFromIdToken(refreshed.idToken);
254
+ return {
255
+ ...token,
256
+ accessToken: refreshed.accessToken,
257
+ refreshToken: refreshed.refreshToken,
258
+ idToken: refreshed.idToken,
259
+ accessTokenExpires: refreshed.accessTokenExpires,
260
+ zkEvm: zkEvm ?? token.zkEvm,
261
+ // Keep existing zkEvm if not in new token
262
+ error: void 0
263
+ };
264
+ } catch (error) {
265
+ console.error("[auth-next-server] Force refresh failed:", error);
266
+ return {
267
+ ...token,
268
+ error: "RefreshTokenError"
269
+ };
270
+ }
271
+ }
272
+ return {
273
+ ...token,
274
+ ...update.accessToken ? { accessToken: update.accessToken } : {},
275
+ ...update.refreshToken ? { refreshToken: update.refreshToken } : {},
276
+ ...update.idToken ? { idToken: update.idToken } : {},
277
+ ...update.accessTokenExpires ? { accessTokenExpires: update.accessTokenExpires } : {},
278
+ ...update.zkEvm ? { zkEvm: update.zkEvm } : {},
279
+ // Clear any stale error when valid tokens are synced from client-side
280
+ error: void 0
281
+ };
282
+ }
283
+ if (!isTokenExpired(token.accessTokenExpires)) {
284
+ return token;
285
+ }
286
+ if (token.refreshToken) {
246
287
  try {
247
288
  const refreshed = await refreshAccessToken(
248
289
  token.refreshToken,
@@ -259,9 +300,10 @@ function createAuthConfig(config) {
259
300
  zkEvm: zkEvm ?? token.zkEvm,
260
301
  // Keep existing zkEvm if not in new token
261
302
  error: void 0
303
+ // Clear any previous error
262
304
  };
263
305
  } catch (error) {
264
- console.error("[auth-next-server] Force refresh failed:", error);
306
+ console.error("[auth-next-server] Token refresh failed:", error);
265
307
  return {
266
308
  ...token,
267
309
  error: "RefreshTokenError"
@@ -270,67 +312,35 @@ function createAuthConfig(config) {
270
312
  }
271
313
  return {
272
314
  ...token,
273
- ...update.accessToken ? { accessToken: update.accessToken } : {},
274
- ...update.refreshToken ? { refreshToken: update.refreshToken } : {},
275
- ...update.idToken ? { idToken: update.idToken } : {},
276
- ...update.accessTokenExpires ? { accessTokenExpires: update.accessTokenExpires } : {},
277
- ...update.zkEvm ? { zkEvm: update.zkEvm } : {},
278
- // Clear any stale error when valid tokens are synced from client-side
279
- error: void 0
315
+ error: "TokenExpired"
280
316
  };
317
+ } catch (error) {
318
+ console.error("[auth-next-server] JWT callback error:", error);
319
+ throw error;
281
320
  }
282
- if (!isTokenExpired(token.accessTokenExpires)) {
283
- return token;
284
- }
285
- if (token.refreshToken) {
286
- try {
287
- const refreshed = await refreshAccessToken(
288
- token.refreshToken,
289
- config.clientId,
290
- authDomain
291
- );
292
- const zkEvm = extractZkEvmFromIdToken(refreshed.idToken);
293
- return {
294
- ...token,
295
- accessToken: refreshed.accessToken,
296
- refreshToken: refreshed.refreshToken,
297
- idToken: refreshed.idToken,
298
- accessTokenExpires: refreshed.accessTokenExpires,
299
- zkEvm: zkEvm ?? token.zkEvm,
300
- // Keep existing zkEvm if not in new token
301
- error: void 0
302
- // Clear any previous error
303
- };
304
- } catch (error) {
305
- console.error("[auth-next-server] Token refresh failed:", error);
306
- return {
307
- ...token,
308
- error: "RefreshTokenError"
309
- };
310
- }
311
- }
312
- return {
313
- ...token,
314
- error: "TokenExpired"
315
- };
316
321
  },
317
322
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
318
323
  async session({ session, token }) {
319
- return {
320
- ...session,
321
- user: {
322
- ...session.user,
323
- sub: token.sub,
324
- email: token.email,
325
- nickname: token.nickname
326
- },
327
- accessToken: token.accessToken,
328
- refreshToken: token.refreshToken,
329
- idToken: token.idToken,
330
- accessTokenExpires: token.accessTokenExpires,
331
- zkEvm: token.zkEvm,
332
- ...token.error && { error: token.error }
333
- };
324
+ try {
325
+ return {
326
+ ...session,
327
+ user: {
328
+ ...session.user,
329
+ sub: token.sub,
330
+ email: token.email,
331
+ nickname: token.nickname
332
+ },
333
+ accessToken: token.accessToken,
334
+ refreshToken: token.refreshToken,
335
+ idToken: token.idToken,
336
+ accessTokenExpires: token.accessTokenExpires,
337
+ zkEvm: token.zkEvm,
338
+ ...token.error && { error: token.error }
339
+ };
340
+ } catch (error) {
341
+ console.error("[auth-next-server] Session callback error:", error);
342
+ throw error;
343
+ }
334
344
  }
335
345
  },
336
346
  session: {
@@ -180,22 +180,63 @@ function createAuthConfig(config) {
180
180
  trigger,
181
181
  session: sessionUpdate
182
182
  }) {
183
- if (user) {
184
- return {
185
- ...token,
186
- sub: user.sub,
187
- email: user.email,
188
- nickname: user.nickname,
189
- accessToken: user.accessToken,
190
- refreshToken: user.refreshToken,
191
- idToken: user.idToken,
192
- accessTokenExpires: user.accessTokenExpires,
193
- zkEvm: user.zkEvm
194
- };
195
- }
196
- if (trigger === "update" && sessionUpdate) {
197
- const update = sessionUpdate;
198
- if (update.forceRefresh && token.refreshToken) {
183
+ try {
184
+ if (user) {
185
+ return {
186
+ ...token,
187
+ sub: user.sub,
188
+ email: user.email,
189
+ nickname: user.nickname,
190
+ accessToken: user.accessToken,
191
+ refreshToken: user.refreshToken,
192
+ idToken: user.idToken,
193
+ accessTokenExpires: user.accessTokenExpires,
194
+ zkEvm: user.zkEvm
195
+ };
196
+ }
197
+ if (trigger === "update" && sessionUpdate) {
198
+ const update = sessionUpdate;
199
+ if (update.forceRefresh && token.refreshToken) {
200
+ try {
201
+ const refreshed = await refreshAccessToken(
202
+ token.refreshToken,
203
+ config.clientId,
204
+ authDomain
205
+ );
206
+ const zkEvm = extractZkEvmFromIdToken(refreshed.idToken);
207
+ return {
208
+ ...token,
209
+ accessToken: refreshed.accessToken,
210
+ refreshToken: refreshed.refreshToken,
211
+ idToken: refreshed.idToken,
212
+ accessTokenExpires: refreshed.accessTokenExpires,
213
+ zkEvm: zkEvm ?? token.zkEvm,
214
+ // Keep existing zkEvm if not in new token
215
+ error: void 0
216
+ };
217
+ } catch (error) {
218
+ console.error("[auth-next-server] Force refresh failed:", error);
219
+ return {
220
+ ...token,
221
+ error: "RefreshTokenError"
222
+ };
223
+ }
224
+ }
225
+ return {
226
+ ...token,
227
+ ...update.accessToken ? { accessToken: update.accessToken } : {},
228
+ ...update.refreshToken ? { refreshToken: update.refreshToken } : {},
229
+ ...update.idToken ? { idToken: update.idToken } : {},
230
+ ...update.accessTokenExpires ? { accessTokenExpires: update.accessTokenExpires } : {},
231
+ ...update.zkEvm ? { zkEvm: update.zkEvm } : {},
232
+ // Clear any stale error when valid tokens are synced from client-side
233
+ error: void 0
234
+ };
235
+ }
236
+ if (!isTokenExpired(token.accessTokenExpires)) {
237
+ return token;
238
+ }
239
+ if (token.refreshToken) {
199
240
  try {
200
241
  const refreshed = await refreshAccessToken(
201
242
  token.refreshToken,
@@ -212,9 +253,10 @@ function createAuthConfig(config) {
212
253
  zkEvm: zkEvm ?? token.zkEvm,
213
254
  // Keep existing zkEvm if not in new token
214
255
  error: void 0
256
+ // Clear any previous error
215
257
  };
216
258
  } catch (error) {
217
- console.error("[auth-next-server] Force refresh failed:", error);
259
+ console.error("[auth-next-server] Token refresh failed:", error);
218
260
  return {
219
261
  ...token,
220
262
  error: "RefreshTokenError"
@@ -223,67 +265,35 @@ function createAuthConfig(config) {
223
265
  }
224
266
  return {
225
267
  ...token,
226
- ...update.accessToken ? { accessToken: update.accessToken } : {},
227
- ...update.refreshToken ? { refreshToken: update.refreshToken } : {},
228
- ...update.idToken ? { idToken: update.idToken } : {},
229
- ...update.accessTokenExpires ? { accessTokenExpires: update.accessTokenExpires } : {},
230
- ...update.zkEvm ? { zkEvm: update.zkEvm } : {},
231
- // Clear any stale error when valid tokens are synced from client-side
232
- error: void 0
268
+ error: "TokenExpired"
233
269
  };
270
+ } catch (error) {
271
+ console.error("[auth-next-server] JWT callback error:", error);
272
+ throw error;
234
273
  }
235
- if (!isTokenExpired(token.accessTokenExpires)) {
236
- return token;
237
- }
238
- if (token.refreshToken) {
239
- try {
240
- const refreshed = await refreshAccessToken(
241
- token.refreshToken,
242
- config.clientId,
243
- authDomain
244
- );
245
- const zkEvm = extractZkEvmFromIdToken(refreshed.idToken);
246
- return {
247
- ...token,
248
- accessToken: refreshed.accessToken,
249
- refreshToken: refreshed.refreshToken,
250
- idToken: refreshed.idToken,
251
- accessTokenExpires: refreshed.accessTokenExpires,
252
- zkEvm: zkEvm ?? token.zkEvm,
253
- // Keep existing zkEvm if not in new token
254
- error: void 0
255
- // Clear any previous error
256
- };
257
- } catch (error) {
258
- console.error("[auth-next-server] Token refresh failed:", error);
259
- return {
260
- ...token,
261
- error: "RefreshTokenError"
262
- };
263
- }
264
- }
265
- return {
266
- ...token,
267
- error: "TokenExpired"
268
- };
269
274
  },
270
275
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
271
276
  async session({ session, token }) {
272
- return {
273
- ...session,
274
- user: {
275
- ...session.user,
276
- sub: token.sub,
277
- email: token.email,
278
- nickname: token.nickname
279
- },
280
- accessToken: token.accessToken,
281
- refreshToken: token.refreshToken,
282
- idToken: token.idToken,
283
- accessTokenExpires: token.accessTokenExpires,
284
- zkEvm: token.zkEvm,
285
- ...token.error && { error: token.error }
286
- };
277
+ try {
278
+ return {
279
+ ...session,
280
+ user: {
281
+ ...session.user,
282
+ sub: token.sub,
283
+ email: token.email,
284
+ nickname: token.nickname
285
+ },
286
+ accessToken: token.accessToken,
287
+ refreshToken: token.refreshToken,
288
+ idToken: token.idToken,
289
+ accessTokenExpires: token.accessTokenExpires,
290
+ zkEvm: token.zkEvm,
291
+ ...token.error && { error: token.error }
292
+ };
293
+ } catch (error) {
294
+ console.error("[auth-next-server] Session callback error:", error);
295
+ throw error;
296
+ }
287
297
  }
288
298
  },
289
299
  session: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imtbl/auth-next-server",
3
- "version": "2.12.7-alpha.3",
3
+ "version": "2.12.7-alpha.5",
4
4
  "description": "Immutable Auth.js v5 integration for Next.js - Server-side utilities",
5
5
  "author": "Immutable",
6
6
  "license": "Apache-2.0",
package/src/config.ts CHANGED
@@ -154,31 +154,80 @@ export function createAuthConfig(config: ImmutableAuthConfig): NextAuthConfig {
154
154
  async jwt({
155
155
  token, user, trigger, session: sessionUpdate,
156
156
  }: 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
+ }
171
222
 
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
+ }
178
227
 
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) {
182
231
  try {
183
232
  const refreshed = await refreshAccessToken(
184
233
  token.refreshToken as string,
@@ -194,11 +243,11 @@ export function createAuthConfig(config: ImmutableAuthConfig): NextAuthConfig {
194
243
  idToken: refreshed.idToken,
195
244
  accessTokenExpires: refreshed.accessTokenExpires,
196
245
  zkEvm: zkEvm ?? token.zkEvm, // Keep existing zkEvm if not in new token
197
- error: undefined,
246
+ error: undefined, // Clear any previous error
198
247
  };
199
248
  } 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);
202
251
  return {
203
252
  ...token,
204
253
  error: 'RefreshTokenError',
@@ -206,79 +255,42 @@ export function createAuthConfig(config: ImmutableAuthConfig): NextAuthConfig {
206
255
  }
207
256
  }
208
257
 
209
- // Standard session update - merge provided values
258
+ // No refresh token available
210
259
  return {
211
260
  ...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',
219
262
  };
263
+ } catch (error) {
264
+ // eslint-disable-next-line no-console
265
+ console.error('[auth-next-server] JWT callback error:', error);
266
+ throw error;
220
267
  }
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
- };
262
268
  },
263
269
 
264
270
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
265
271
  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
+ }
282
294
  },
283
295
  },
284
296