@imtbl/auth-nextjs 2.12.4-alpha.5 → 2.12.4-alpha.7

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.
@@ -254,7 +254,7 @@ function useAccessToken() {
254
254
 
255
255
  // src/client/callback.tsx
256
256
  var import_react3 = require("react");
257
- var import_router = require("next/router");
257
+ var import_navigation = require("next/navigation");
258
258
  var import_react4 = require("next-auth/react");
259
259
  var import_auth3 = require("@imtbl/auth");
260
260
  var import_jsx_runtime2 = require("react/jsx-runtime");
@@ -262,9 +262,12 @@ function CallbackPage({
262
262
  config,
263
263
  redirectTo = "/",
264
264
  loadingComponent = null,
265
- errorComponent
265
+ errorComponent,
266
+ onSuccess,
267
+ onError
266
268
  }) {
267
- const router = (0, import_router.useRouter)();
269
+ const router = (0, import_navigation.useRouter)();
270
+ const searchParams = (0, import_navigation.useSearchParams)();
268
271
  const [error, setError] = (0, import_react3.useState)(null);
269
272
  const callbackProcessedRef = (0, import_react3.useRef)(false);
270
273
  (0, import_react3.useEffect)(() => {
@@ -283,6 +286,14 @@ function CallbackPage({
283
286
  if (!authUser) {
284
287
  throw new Error("Authentication failed: no user data received from login callback");
285
288
  }
289
+ const user = {
290
+ sub: authUser.profile.sub,
291
+ email: authUser.profile.email,
292
+ nickname: authUser.profile.nickname
293
+ };
294
+ if (onSuccess) {
295
+ await onSuccess(user);
296
+ }
286
297
  window.close();
287
298
  } else if (authUser) {
288
299
  const tokenData = {
@@ -307,40 +318,45 @@ function CallbackPage({
307
318
  if (!result?.ok) {
308
319
  throw new Error("NextAuth sign-in failed: unknown error");
309
320
  }
310
- router.replace(redirectTo);
321
+ const user = {
322
+ sub: authUser.profile.sub,
323
+ email: authUser.profile.email,
324
+ nickname: authUser.profile.nickname
325
+ };
326
+ if (onSuccess) {
327
+ await onSuccess(user);
328
+ }
329
+ const resolvedRedirectTo = typeof redirectTo === "function" ? redirectTo(user) || "/" : redirectTo;
330
+ router.replace(resolvedRedirectTo);
311
331
  } else {
312
332
  throw new Error("Authentication failed: no user data received from login callback");
313
333
  }
314
334
  } catch (err) {
315
- setError(err instanceof Error ? err.message : "Authentication failed");
335
+ const errorMessage = err instanceof Error ? err.message : "Authentication failed";
336
+ if (onError) {
337
+ onError(errorMessage);
338
+ }
339
+ setError(errorMessage);
316
340
  }
317
341
  };
318
342
  const handleOAuthError = () => {
319
- const errorCode = router.query.error;
320
- const errorDescription = router.query.error_description;
343
+ const errorCode = searchParams.get("error");
344
+ const errorDescription = searchParams.get("error_description");
321
345
  const errorMessage = errorDescription || errorCode || "Authentication failed";
346
+ if (onError) {
347
+ onError(errorMessage);
348
+ }
322
349
  setError(errorMessage);
323
350
  };
324
- if (!router.isReady) {
325
- return;
326
- }
327
- if (router.query.error) {
351
+ if (searchParams.get("error")) {
328
352
  handleOAuthError();
329
353
  return;
330
354
  }
331
- if (router.query.code && !callbackProcessedRef.current) {
355
+ if (searchParams.get("code") && !callbackProcessedRef.current) {
332
356
  callbackProcessedRef.current = true;
333
357
  handleCallback();
334
358
  }
335
- }, [
336
- router.isReady,
337
- router.query.code,
338
- router.query.error,
339
- router.query.error_description,
340
- router,
341
- config,
342
- redirectTo
343
- ]);
359
+ }, [searchParams, router, config, redirectTo, onSuccess, onError]);
344
360
  if (error) {
345
361
  if (errorComponent) {
346
362
  return errorComponent(error);
@@ -352,6 +368,7 @@ function CallbackPage({
352
368
  "button",
353
369
  {
354
370
  onClick: () => router.push("/"),
371
+ type: "button",
355
372
  style: {
356
373
  padding: "0.5rem 1rem",
357
374
  marginTop: "1rem",
@@ -240,7 +240,7 @@ function useAccessToken() {
240
240
 
241
241
  // src/client/callback.tsx
242
242
  import { useEffect as useEffect2, useState as useState2, useRef as useRef2 } from "react";
243
- import { useRouter } from "next/router";
243
+ import { useRouter, useSearchParams } from "next/navigation";
244
244
  import { signIn as signIn2 } from "next-auth/react";
245
245
  import { Auth as Auth2 } from "@imtbl/auth";
246
246
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
@@ -248,9 +248,12 @@ function CallbackPage({
248
248
  config,
249
249
  redirectTo = "/",
250
250
  loadingComponent = null,
251
- errorComponent
251
+ errorComponent,
252
+ onSuccess,
253
+ onError
252
254
  }) {
253
255
  const router = useRouter();
256
+ const searchParams = useSearchParams();
254
257
  const [error, setError] = useState2(null);
255
258
  const callbackProcessedRef = useRef2(false);
256
259
  useEffect2(() => {
@@ -269,6 +272,14 @@ function CallbackPage({
269
272
  if (!authUser) {
270
273
  throw new Error("Authentication failed: no user data received from login callback");
271
274
  }
275
+ const user = {
276
+ sub: authUser.profile.sub,
277
+ email: authUser.profile.email,
278
+ nickname: authUser.profile.nickname
279
+ };
280
+ if (onSuccess) {
281
+ await onSuccess(user);
282
+ }
272
283
  window.close();
273
284
  } else if (authUser) {
274
285
  const tokenData = {
@@ -293,40 +304,45 @@ function CallbackPage({
293
304
  if (!result?.ok) {
294
305
  throw new Error("NextAuth sign-in failed: unknown error");
295
306
  }
296
- router.replace(redirectTo);
307
+ const user = {
308
+ sub: authUser.profile.sub,
309
+ email: authUser.profile.email,
310
+ nickname: authUser.profile.nickname
311
+ };
312
+ if (onSuccess) {
313
+ await onSuccess(user);
314
+ }
315
+ const resolvedRedirectTo = typeof redirectTo === "function" ? redirectTo(user) || "/" : redirectTo;
316
+ router.replace(resolvedRedirectTo);
297
317
  } else {
298
318
  throw new Error("Authentication failed: no user data received from login callback");
299
319
  }
300
320
  } catch (err) {
301
- setError(err instanceof Error ? err.message : "Authentication failed");
321
+ const errorMessage = err instanceof Error ? err.message : "Authentication failed";
322
+ if (onError) {
323
+ onError(errorMessage);
324
+ }
325
+ setError(errorMessage);
302
326
  }
303
327
  };
304
328
  const handleOAuthError = () => {
305
- const errorCode = router.query.error;
306
- const errorDescription = router.query.error_description;
329
+ const errorCode = searchParams.get("error");
330
+ const errorDescription = searchParams.get("error_description");
307
331
  const errorMessage = errorDescription || errorCode || "Authentication failed";
332
+ if (onError) {
333
+ onError(errorMessage);
334
+ }
308
335
  setError(errorMessage);
309
336
  };
310
- if (!router.isReady) {
311
- return;
312
- }
313
- if (router.query.error) {
337
+ if (searchParams.get("error")) {
314
338
  handleOAuthError();
315
339
  return;
316
340
  }
317
- if (router.query.code && !callbackProcessedRef.current) {
341
+ if (searchParams.get("code") && !callbackProcessedRef.current) {
318
342
  callbackProcessedRef.current = true;
319
343
  handleCallback();
320
344
  }
321
- }, [
322
- router.isReady,
323
- router.query.code,
324
- router.query.error,
325
- router.query.error_description,
326
- router,
327
- config,
328
- redirectTo
329
- ]);
345
+ }, [searchParams, router, config, redirectTo, onSuccess, onError]);
330
346
  if (error) {
331
347
  if (errorComponent) {
332
348
  return errorComponent(error);
@@ -338,6 +354,7 @@ function CallbackPage({
338
354
  "button",
339
355
  {
340
356
  onClick: () => router.push("/"),
357
+ type: "button",
341
358
  style: {
342
359
  padding: "0.5rem 1rem",
343
360
  marginTop: "1rem",
@@ -30,8 +30,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
+ DEFAULT_AUDIENCE: () => DEFAULT_AUDIENCE,
34
+ DEFAULT_AUTH_DOMAIN: () => DEFAULT_AUTH_DOMAIN,
35
+ DEFAULT_NEXTAUTH_BASE_PATH: () => DEFAULT_NEXTAUTH_BASE_PATH,
36
+ DEFAULT_SCOPE: () => DEFAULT_SCOPE,
33
37
  ImmutableAuth: () => ImmutableAuth,
34
38
  MarketingConsentStatus: () => import_auth.MarketingConsentStatus,
39
+ createAuthConfig: () => createAuthConfig,
40
+ createImmutableAuth: () => createImmutableAuth,
35
41
  isTokenExpired: () => isTokenExpired,
36
42
  refreshAccessToken: () => refreshAccessToken
37
43
  });
@@ -43,7 +49,10 @@ var import_credentials = __toESM(require("next-auth/providers/credentials"), 1);
43
49
 
44
50
  // src/constants.ts
45
51
  var DEFAULT_AUTH_DOMAIN = "https://auth.immutable.com";
52
+ var DEFAULT_AUDIENCE = "platform_api";
53
+ var DEFAULT_SCOPE = "openid profile email offline_access transact";
46
54
  var IMMUTABLE_PROVIDER_ID = "immutable";
55
+ var DEFAULT_NEXTAUTH_BASE_PATH = "/api/auth";
47
56
  var DEFAULT_TOKEN_EXPIRY_SECONDS = 900;
48
57
  var DEFAULT_TOKEN_EXPIRY_MS = DEFAULT_TOKEN_EXPIRY_SECONDS * 1e3;
49
58
  var TOKEN_EXPIRY_BUFFER_SECONDS = 60;
@@ -111,7 +120,7 @@ function isTokenExpired(accessTokenExpires, bufferSeconds = TOKEN_EXPIRY_BUFFER_
111
120
  }
112
121
 
113
122
  // src/config.ts
114
- var CredentialsProvider = import_credentials.default.default || import_credentials.default;
123
+ var Credentials = import_credentials.default.default || import_credentials.default;
115
124
  async function validateTokens(accessToken, authDomain) {
116
125
  try {
117
126
  const response = await fetch(`${authDomain}/userinfo`, {
@@ -130,18 +139,18 @@ async function validateTokens(accessToken, authDomain) {
130
139
  return null;
131
140
  }
132
141
  }
133
- function createAuthOptions(config) {
142
+ function createAuthConfig(config) {
134
143
  const authDomain = config.authenticationDomain || DEFAULT_AUTH_DOMAIN;
135
144
  return {
136
145
  providers: [
137
- CredentialsProvider({
146
+ Credentials({
138
147
  id: IMMUTABLE_PROVIDER_ID,
139
148
  name: "Immutable",
140
149
  credentials: {
141
150
  tokens: { label: "Tokens", type: "text" }
142
151
  },
143
152
  async authorize(credentials) {
144
- if (!credentials?.tokens) {
153
+ if (!credentials?.tokens || typeof credentials.tokens !== "string") {
145
154
  return null;
146
155
  }
147
156
  let tokenData;
@@ -184,6 +193,7 @@ function createAuthOptions(config) {
184
193
  })
185
194
  ],
186
195
  callbacks: {
196
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
187
197
  async jwt({
188
198
  token,
189
199
  user,
@@ -204,13 +214,14 @@ function createAuthOptions(config) {
204
214
  };
205
215
  }
206
216
  if (trigger === "update" && sessionUpdate) {
217
+ const update = sessionUpdate;
207
218
  return {
208
219
  ...token,
209
- ...sessionUpdate.accessToken && { accessToken: sessionUpdate.accessToken },
210
- ...sessionUpdate.refreshToken && { refreshToken: sessionUpdate.refreshToken },
211
- ...sessionUpdate.idToken && { idToken: sessionUpdate.idToken },
212
- ...sessionUpdate.accessTokenExpires && { accessTokenExpires: sessionUpdate.accessTokenExpires },
213
- ...sessionUpdate.zkEvm && { zkEvm: sessionUpdate.zkEvm }
220
+ ...update.accessToken ? { accessToken: update.accessToken } : {},
221
+ ...update.refreshToken ? { refreshToken: update.refreshToken } : {},
222
+ ...update.idToken ? { idToken: update.idToken } : {},
223
+ ...update.accessTokenExpires ? { accessTokenExpires: update.accessTokenExpires } : {},
224
+ ...update.zkEvm ? { zkEvm: update.zkEvm } : {}
214
225
  };
215
226
  }
216
227
  if (!isTokenExpired(token.accessTokenExpires)) {
@@ -218,10 +229,12 @@ function createAuthOptions(config) {
218
229
  }
219
230
  return refreshAccessToken(token, config);
220
231
  },
232
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
221
233
  async session({ session, token }) {
222
234
  return {
223
235
  ...session,
224
236
  user: {
237
+ ...session.user,
225
238
  sub: token.sub,
226
239
  email: token.email,
227
240
  nickname: token.nickname
@@ -239,26 +252,24 @@ function createAuthOptions(config) {
239
252
  strategy: "jwt",
240
253
  // Session max age in seconds (30 days default)
241
254
  maxAge: DEFAULT_SESSION_MAX_AGE_SECONDS
242
- },
243
- // Use NEXTAUTH_SECRET from environment
244
- secret: process.env.NEXTAUTH_SECRET
255
+ }
245
256
  };
246
257
  }
247
258
 
248
259
  // src/index.ts
249
260
  var import_auth = require("@imtbl/auth");
250
261
  var NextAuth = import_next_auth.default.default || import_next_auth.default;
251
- function ImmutableAuth(config, overrides) {
252
- const authOptions = createAuthOptions(config);
262
+ function createImmutableAuth(config, overrides) {
263
+ const authConfig = createAuthConfig(config);
253
264
  if (!overrides) {
254
- return NextAuth(authOptions);
265
+ return NextAuth(authConfig);
255
266
  }
256
267
  const composedCallbacks = {
257
- ...authOptions.callbacks
268
+ ...authConfig.callbacks
258
269
  };
259
270
  if (overrides.callbacks) {
260
271
  if (overrides.callbacks.jwt) {
261
- const internalJwt = authOptions.callbacks?.jwt;
272
+ const internalJwt = authConfig.callbacks?.jwt;
262
273
  const userJwt = overrides.callbacks.jwt;
263
274
  composedCallbacks.jwt = async (params) => {
264
275
  const token = internalJwt ? await internalJwt(params) : params.token;
@@ -266,7 +277,7 @@ function ImmutableAuth(config, overrides) {
266
277
  };
267
278
  }
268
279
  if (overrides.callbacks.session) {
269
- const internalSession = authOptions.callbacks?.session;
280
+ const internalSession = authConfig.callbacks?.session;
270
281
  const userSession = overrides.callbacks.session;
271
282
  composedCallbacks.session = async (params) => {
272
283
  const session = internalSession ? await internalSession(params) : params.session;
@@ -280,17 +291,24 @@ function ImmutableAuth(config, overrides) {
280
291
  composedCallbacks.redirect = overrides.callbacks.redirect;
281
292
  }
282
293
  }
283
- const mergedOptions = {
284
- ...authOptions,
294
+ const mergedConfig = {
295
+ ...authConfig,
285
296
  ...overrides,
286
297
  callbacks: composedCallbacks
287
298
  };
288
- return NextAuth(mergedOptions);
299
+ return NextAuth(mergedConfig);
289
300
  }
301
+ var ImmutableAuth = createImmutableAuth;
290
302
  // Annotate the CommonJS export names for ESM import in node:
291
303
  0 && (module.exports = {
304
+ DEFAULT_AUDIENCE,
305
+ DEFAULT_AUTH_DOMAIN,
306
+ DEFAULT_NEXTAUTH_BASE_PATH,
307
+ DEFAULT_SCOPE,
292
308
  ImmutableAuth,
293
309
  MarketingConsentStatus,
310
+ createAuthConfig,
311
+ createImmutableAuth,
294
312
  isTokenExpired,
295
313
  refreshAccessToken
296
314
  });
@@ -1,55 +1,24 @@
1
1
  import {
2
- createAuthOptions,
2
+ DEFAULT_AUDIENCE,
3
+ DEFAULT_AUTH_DOMAIN,
4
+ DEFAULT_NEXTAUTH_BASE_PATH,
5
+ DEFAULT_SCOPE,
6
+ ImmutableAuth,
7
+ MarketingConsentStatus,
8
+ createAuthConfig,
9
+ createImmutableAuth,
3
10
  isTokenExpired,
4
11
  refreshAccessToken
5
- } from "./chunk-OPPMGNFZ.js";
6
-
7
- // src/index.ts
8
- import NextAuthDefault from "next-auth";
9
- import { MarketingConsentStatus } from "@imtbl/auth";
10
- var NextAuth = NextAuthDefault.default || NextAuthDefault;
11
- function ImmutableAuth(config, overrides) {
12
- const authOptions = createAuthOptions(config);
13
- if (!overrides) {
14
- return NextAuth(authOptions);
15
- }
16
- const composedCallbacks = {
17
- ...authOptions.callbacks
18
- };
19
- if (overrides.callbacks) {
20
- if (overrides.callbacks.jwt) {
21
- const internalJwt = authOptions.callbacks?.jwt;
22
- const userJwt = overrides.callbacks.jwt;
23
- composedCallbacks.jwt = async (params) => {
24
- const token = internalJwt ? await internalJwt(params) : params.token;
25
- return userJwt({ ...params, token });
26
- };
27
- }
28
- if (overrides.callbacks.session) {
29
- const internalSession = authOptions.callbacks?.session;
30
- const userSession = overrides.callbacks.session;
31
- composedCallbacks.session = async (params) => {
32
- const session = internalSession ? await internalSession(params) : params.session;
33
- return userSession({ ...params, session });
34
- };
35
- }
36
- if (overrides.callbacks.signIn) {
37
- composedCallbacks.signIn = overrides.callbacks.signIn;
38
- }
39
- if (overrides.callbacks.redirect) {
40
- composedCallbacks.redirect = overrides.callbacks.redirect;
41
- }
42
- }
43
- const mergedOptions = {
44
- ...authOptions,
45
- ...overrides,
46
- callbacks: composedCallbacks
47
- };
48
- return NextAuth(mergedOptions);
49
- }
12
+ } from "./chunk-BRDI4KXS.js";
50
13
  export {
14
+ DEFAULT_AUDIENCE,
15
+ DEFAULT_AUTH_DOMAIN,
16
+ DEFAULT_NEXTAUTH_BASE_PATH,
17
+ DEFAULT_SCOPE,
51
18
  ImmutableAuth,
52
19
  MarketingConsentStatus,
20
+ createAuthConfig,
21
+ createImmutableAuth,
53
22
  isTokenExpired,
54
23
  refreshAccessToken
55
24
  };