@monocloud/auth-nextjs 0.1.5 → 0.1.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.
package/dist/index.mjs CHANGED
@@ -1,9 +1,8 @@
1
1
  import { MonoCloudAuthBaseError, MonoCloudCoreClient, MonoCloudHttpError, MonoCloudOPError, MonoCloudTokenError, MonoCloudValidationError, MonoCloudValidationError as MonoCloudValidationError$1 } from "@monocloud/auth-node-core";
2
2
  import { NextRequest, NextResponse } from "next/server.js";
3
3
  import { ensureLeadingSlash, isAbsoluteUrl, isPresent } from "@monocloud/auth-node-core/internal";
4
- import { isUserInGroup } from "@monocloud/auth-node-core/utils";
4
+ import { isUserInGroup as isUserInGroup$1 } from "@monocloud/auth-node-core/utils";
5
5
  import { serialize } from "cookie";
6
- import { IncomingMessage, ServerResponse } from "node:http";
7
6
 
8
7
  //#region src/requests/monocloud-app-router-request.ts
9
8
  var MonoCloudAppRouterRequest = class {
@@ -219,6 +218,12 @@ var MonoCloudCookieRequest = class {
219
218
  const isMonoCloudRequest = (req) => req instanceof MonoCloudAppRouterRequest || req instanceof MonoCloudPageRouterRequest || req instanceof MonoCloudCookieRequest;
220
219
  const isMonoCloudResponse = (res) => res instanceof MonoCloudAppRouterResponse || res instanceof MonoCloudPageRouterResponse || res instanceof MonoCloudCookieResponse;
221
220
  const isAppRouter = (req) => req instanceof Request || req.headers instanceof Headers || typeof req.bodyUsed === "boolean";
221
+ const isNodeRequest = (req) => {
222
+ return !!(req && typeof req === "object" && "headers" in req && !("bodyUsed" in req) && typeof req.on === "function");
223
+ };
224
+ const isNodeResponse = (res) => {
225
+ return !!(res && typeof res === "object" && "setHeader" in res && typeof res.setHeader === "function" && "end" in res && typeof res.end === "function");
226
+ };
222
227
  const getNextRequest = (req) => {
223
228
  if (req instanceof NextRequest) return req;
224
229
  return new NextRequest(req.url, {
@@ -252,7 +257,7 @@ const getMonoCloudCookieReqRes = (req, resOrCtx) => {
252
257
  request = new MonoCloudAppRouterRequest(getNextRequest(req));
253
258
  response = resOrCtx instanceof Response ? new MonoCloudAppRouterResponse(getNextResponse(resOrCtx)) : new MonoCloudCookieResponse();
254
259
  } else {
255
- if (!(req instanceof IncomingMessage) || !(resOrCtx instanceof ServerResponse)) throw new MonoCloudValidationError$1("Invalid pages router request and response");
260
+ if (!isNodeRequest(req) || !isNodeResponse(resOrCtx)) throw new MonoCloudValidationError$1("Invalid pages router request and response");
256
261
  request = new MonoCloudPageRouterRequest(req);
257
262
  response = new MonoCloudPageRouterResponse(resOrCtx);
258
263
  }
@@ -279,35 +284,32 @@ const mergeResponse = (responses) => {
279
284
  //#endregion
280
285
  //#region src/monocloud-next-client.ts
281
286
  /**
282
- * The MonoCloud Next.js Client.
287
+ * `MonoCloudNextClient` is the core SDK entry point for integrating MonoCloud authentication into a Next.js application.
283
288
  *
284
- * @example Using Environment Variables (Recommended)
289
+ * It provides:
290
+ * - Authentication middleware
291
+ * - Route protection helpers
292
+ * - Session and token access
293
+ * - Redirect utilities
294
+ * - Server-side enforcement helpers
285
295
  *
286
- * 1. Add following variables to your `.env`.
296
+ * ## 1. Add environment variables
287
297
  *
288
- * ```bash
298
+ * ```bash:.env.local
289
299
  * MONOCLOUD_AUTH_TENANT_DOMAIN=<tenant-domain>
290
300
  * MONOCLOUD_AUTH_CLIENT_ID=<client-id>
291
301
  * MONOCLOUD_AUTH_CLIENT_SECRET=<client-secret>
292
- * MONOCLOUD_AUTH_SCOPES=openid profile email # Default
302
+ * MONOCLOUD_AUTH_SCOPES=openid profile email
293
303
  * MONOCLOUD_AUTH_APP_URL=http://localhost:3000
294
304
  * MONOCLOUD_AUTH_COOKIE_SECRET=<cookie-secret>
295
305
  * ```
296
306
  *
297
- * 2. Instantiate the client in a shared file (e.g., lib/monocloud.ts)
298
- *
299
- * ```typescript
300
- * import { MonoCloudNextClient } from '@monocloud/auth-nextjs';
301
- *
302
- * export const monoCloud = new MonoCloudNextClient();
303
- * ```
304
- *
305
- * 3. Add MonoCloud middleware/proxy
307
+ * ## 2. Register middleware
306
308
  *
307
- * ```typescript
308
- * import { monoCloud } from "@/lib/monocloud";
309
+ * ```typescript:src/proxy.ts
310
+ * import { authMiddleware } from "@monocloud/auth-nextjs";
309
311
  *
310
- * export default monoCloud.authMiddleware();
312
+ * export default authMiddleware();
311
313
  *
312
314
  * export const config = {
313
315
  * matcher: [
@@ -316,218 +318,115 @@ const mergeResponse = (responses) => {
316
318
  * };
317
319
  * ```
318
320
  *
319
- * @example Using Constructor Options
321
+ * ## Advanced usage
320
322
  *
321
- * ⚠️ Security Note: Never commit your credentials to version control. Load them from environment variables.
323
+ * ### Create a shared client instance
324
+ *
325
+ * By default, the SDK exposes function exports (for example, `authMiddleware()`, `getSession()`, `getTokens()`) that internally use a shared singleton `MonoCloudNextClient`.
326
+ *
327
+ * Create your own `MonoCloudNextClient` instance when you need multiple configurations, dependency injection, or explicit control over initialization.
328
+ *
329
+ * ```ts:src/monocloud.ts
330
+ * import { MonoCloudNextClient } from "@monocloud/auth-nextjs";
331
+ *
332
+ * export const monoCloud = new MonoCloudNextClient();
333
+ * ```
322
334
  *
323
- * 1. Instantiate the client in a shared file (e.g., lib/monocloud.ts)
335
+ * ### Using instance methods
324
336
  *
325
- * ```typescript
326
- * import { MonoCloudNextClient } from '@monocloud/auth-nextjs';
337
+ * Once you create a client instance, call methods directly on it instead of using the default function exports.
338
+ *
339
+ * ```ts:src/app/page.tsx
340
+ * import { monoCloud } from "@/monocloud";
341
+ *
342
+ * export default async function Page() {
343
+ * const session = await monoCloud.getSession();
344
+ *
345
+ * if (!session) {
346
+ * return <>Not signed in</>;
347
+ * }
348
+ *
349
+ * return <>Hello {session.user.name}</>;
350
+ * }
351
+ * ```
352
+ *
353
+ * #### Using constructor options
354
+ *
355
+ * When configuration is provided through both constructor options and environment variables, the values passed to the constructor take precedence. Environment variables are used only for options that are not explicitly supplied.
356
+ *
357
+ * ```ts:src/monocloud.ts
358
+ * import { MonoCloudNextClient } from "@monocloud/auth-nextjs";
327
359
  *
328
360
  * export const monoCloud = new MonoCloudNextClient({
329
- * tenantDomain: '<tenant-domain>',
330
- * clientId: '<client-id>',
331
- * clientSecret: '<client-secret>',
332
- * scopes: 'openid profile email', // Default
333
- * appUrl: 'http://localhost:3000',
334
- * cookieSecret: '<cookie-secret>'
361
+ * tenantDomain: "<tenant-domain>",
362
+ * clientId: "<client-id>",
363
+ * clientSecret: "<client-secret>",
364
+ * appUrl: "http://localhost:3000",
365
+ * cookieSecret: "<cookie-secret>",
366
+ * defaultAuthParams: {
367
+ * scopes: "openid profile email",
368
+ * },
335
369
  * });
336
370
  * ```
337
- * 2. Add MonoCloud middleware/proxy
338
371
  *
339
- * ```typescript
340
- * import { monoCloud } from "@/lib/monocloud";
372
+ * ### Modifying default routes
341
373
  *
342
- * export default monoCloud.authMiddleware();
374
+ * If you customize any of the default auth route paths:
343
375
  *
344
- * export const config = {
345
- * matcher: [
346
- * "/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
347
- * ],
348
- * };
376
+ * - Also set the corresponding `NEXT_PUBLIC_` environment variables so client-side helpers
377
+ * (for example `<SignIn />`, `<SignOut />`, and `useAuth()`) can discover the correct URLs.
378
+ * - Update the **Application URLs** in your MonoCloud Dashboard to match the new paths.
379
+ *
380
+ * Example:
381
+ *
382
+ * ```bash:.env.local
383
+ * MONOCLOUD_AUTH_CALLBACK_URL=/api/custom_callback
384
+ * NEXT_PUBLIC_MONOCLOUD_AUTH_CALLBACK_URL=/api/custom_callback
349
385
  * ```
350
386
  *
351
- * <details>
352
- * <summary>All Environment Variables</summary>
353
- * <h4>Core Configuration (Required)</h4>
354
- *
355
- * <ul>
356
- * <li><strong>MONOCLOUD_AUTH_CLIENT_ID : </strong>Unique identifier for your application/client.</li>
357
- * <li><strong>MONOCLOUD_AUTH_CLIENT_SECRET : </strong>Application/client secret.</li>
358
- * <li><strong>MONOCLOUD_AUTH_TENANT_DOMAIN : </strong>The domain of your MonoCloud tenant (e.g., https://your-tenant.us.monocloud.com).</li>
359
- * <li><strong>MONOCLOUD_AUTH_APP_URL : </strong>The base URL where your application is hosted.</li>
360
- * <li><strong>MONOCLOUD_AUTH_COOKIE_SECRET : </strong>A long, random string used to encrypt and sign session cookies.</li>
361
- * </ul>
362
- *
363
- * <h4>Authentication &amp; Security</h4>
364
- *
365
- * <ul>
366
- * <li><strong>MONOCLOUD_AUTH_SCOPES : </strong>A space-separated list of OIDC scopes to request (e.g., openid profile email).</li>
367
- * <li><strong>MONOCLOUD_AUTH_RESOURCE : </strong>The default resource/audience identifier for access tokens.</li>
368
- * <li><strong>MONOCLOUD_AUTH_USE_PAR : </strong>Enables Pushed Authorization Requests.</li>
369
- * <li><strong>MONOCLOUD_AUTH_CLOCK_SKEW : </strong>The allowed clock drift in seconds when validating token timestamps.</li>
370
- * <li><strong>MONOCLOUD_AUTH_FEDERATED_SIGNOUT : </strong>If true, signs the user out of MonoCloud (SSO sign-out) when they sign out of the app.</li>
371
- * <li><strong>MONOCLOUD_AUTH_RESPONSE_TIMEOUT : </strong>The maximum time in milliseconds to wait for a response.</li>
372
- * <li><strong>MONOCLOUD_AUTH_ALLOW_QUERY_PARAM_OVERRIDES : </strong>Allows dynamic overrides of auth parameters via URL query strings.</li>
373
- * <li><strong>MONOCLOUD_AUTH_POST_LOGOUT_REDIRECT_URI : </strong>The URL users are sent to after a successful logout.</li>
374
- * <li><strong>MONOCLOUD_AUTH_USER_INFO : </strong>Determines if user profile data from the UserInfo endpoint should be fetched after authorization code exchange.</li>
375
- * <li><strong>MONOCLOUD_AUTH_REFETCH_USER_INFO : </strong>If true, re-fetches user information on every request to userinfo endpoint or when calling getTokens()</li>
376
- * <li><strong>MONOCLOUD_AUTH_ID_TOKEN_SIGNING_ALG : </strong>The expected algorithm for signing ID tokens (e.g., RS256).</li>
377
- * <li><strong>MONOCLOUD_AUTH_FILTERED_ID_TOKEN_CLAIMS : </strong>A space-separated list of claims to exclude from the session object.</li>
378
- * </ul>
379
- *
380
- * <h4>Routes</h4>
381
- *
382
- * <aside>
383
- * <strong>⚠️ Important: Modifying Default Routes</strong>
384
- * <p>If you choose to customize any of the default route paths, you must adhere to the following requirements:</p>
385
- * <ul>
386
- * <li>
387
- * <strong>Client-Side Synchronization:</strong> You must also define a corresponding <code>NEXT_PUBLIC_</code> version of the environment variable (e.g., <code>NEXT_PUBLIC_MONOCLOUD_AUTH_CALLBACK_URL</code>). This ensures that client-side components like <code>&lt;SignIn /&gt;</code>, <code>&lt;SignOut /&gt;</code>, and the <code>useAuth()</code> hook can correctly identify your custom endpoints.
388
- * </li>
389
- * <li>
390
- * <strong>Dashboard Configuration:</strong> Changing these URLs will alter the endpoints required by MonoCloud. You must update the <strong>Application URLs</strong> section in your MonoCloud Dashboard to match these new paths.
391
- * </li>
392
- * </ul>
393
- * <p><em>Example:</em></p>
394
- * <code>
395
- * MONOCLOUD_AUTH_CALLBACK_URL=/api/custom_callback<br />
396
- * NEXT_PUBLIC_MONOCLOUD_AUTH_CALLBACK_URL=/api/custom_callback
397
- * </code>
398
- * <p>In this case, the Redirect URI in your dashboard should be set to: <code>http://localhost:3000/api/custom_callback</code> (assuming local development).</p>
399
- * </aside>
400
- *
401
- * <ul>
402
- * <li><strong>MONOCLOUD_AUTH_CALLBACK_URL : </strong>The application path where MonoCloud sends the user after authentication.</li>
403
- * <li><strong>MONOCLOUD_AUTH_SIGNIN_URL : </strong>The internal route path to trigger the sign-in.</li>
404
- * <li><strong>MONOCLOUD_AUTH_SIGNOUT_URL : </strong>The internal route path to trigger the sign-out.</li>
405
- * <li><strong>MONOCLOUD_AUTH_USER_INFO_URL : </strong>The route that exposes the current user's profile from userinfo endpoint.</li>
406
- * </ul>
407
- *
408
- * <h4>Session Cookie Settings</h4>
409
- *
410
- * <ul>
411
- * <li><strong>MONOCLOUD_AUTH_SESSION_COOKIE_NAME : </strong>The name of the cookie used to store the user session.</li>
412
- * <li><strong>MONOCLOUD_AUTH_SESSION_COOKIE_PATH : </strong>The scope path for the session cookie.</li>
413
- * <li><strong>MONOCLOUD_AUTH_SESSION_COOKIE_DOMAIN : </strong>The domain scope for the session cookie.</li>
414
- * <li><strong>MONOCLOUD_AUTH_SESSION_COOKIE_HTTP_ONLY : </strong>Prevents client-side scripts from accessing the session cookie.</li>
415
- * <li><strong>MONOCLOUD_AUTH_SESSION_COOKIE_SECURE : </strong>Ensures the session cookie is only sent over HTTPS.</li>
416
- * <li><strong>MONOCLOUD_AUTH_SESSION_COOKIE_SAME_SITE : </strong>The SameSite policy for the session cookie (Lax, Strict, or None).</li>
417
- * <li><strong>MONOCLOUD_AUTH_SESSION_COOKIE_PERSISTENT : </strong>If true, the session survives browser restarts.</li>
418
- * <li><strong>MONOCLOUD_AUTH_SESSION_SLIDING : </strong>If true, the session will be a sliding session instead of absolute.</li>
419
- * <li><strong>MONOCLOUD_AUTH_SESSION_DURATION : </strong>The session lifetime in seconds.</li>
420
- * <li><strong>MONOCLOUD_AUTH_SESSION_MAX_DURATION : </strong>The absolute maximum lifetime of a session in seconds.</li>
421
- * </ul>
422
- *
423
- * <h4>State Cookie Settings</h4>
424
- *
425
- * <ul>
426
- * <li><strong>MONOCLOUD_AUTH_STATE_COOKIE_NAME : </strong>The name of the cookie used to store OpenID state/nonce.</li>
427
- * <li><strong>MONOCLOUD_AUTH_STATE_COOKIE_PATH : </strong>The scope path for the state cookie.</li>
428
- * <li><strong>MONOCLOUD_AUTH_STATE_COOKIE_DOMAIN : </strong>The domain scope for the state cookie.</li>
429
- * <li><strong>MONOCLOUD_AUTH_STATE_COOKIE_SECURE : </strong>Ensures the state cookie is only sent over HTTPS</li>
430
- * <li><strong>MONOCLOUD_AUTH_STATE_COOKIE_SAME_SITE : </strong>The SameSite policy for the state cookie.</li>
431
- * <li><strong>MONOCLOUD_AUTH_STATE_COOKIE_PERSISTENT : </strong>Whether the state cookie is persistent.</li>
432
- * </ul>
433
- *
434
- * <h4>Caching</h4>
435
- *
436
- * <ul>
437
- * <li><strong>MONOCLOUD_AUTH_JWKS_CACHE_DURATION : </strong>Duration in seconds to cache the JSON Web Key Set.</li>
438
- * <li><strong>MONOCLOUD_AUTH_METADATA_CACHE_DURATION : </strong>Duration in seconds to cache the OpenID discovery metadata.</li>
439
- * </ul>
440
- * </details>
387
+ * When routes are overridden, the Redirect URI configured in the dashboard
388
+ * must reflect the new path. For example, during local development:
441
389
  *
390
+ * `http://localhost:3000/api/custom_callback`
442
391
  *
392
+ * @category Classes
443
393
  */
444
394
  var MonoCloudNextClient = class {
445
395
  /**
446
- * The underlying OIDC client instance used for low-level OpenID Connect operations.
396
+ * This exposes the framework-agnostic MonoCloud client used internally by the Next.js SDK.
397
+ * Use it if you need access to lower-level functionality not directly exposed by MonoCloudNextClient.
398
+ *
399
+ * @returns Returns the underlying **Node client** instance.
400
+ */
401
+ get coreClient() {
402
+ return this._coreClient;
403
+ }
404
+ /**
405
+ * This is intended for advanced scenarios requiring direct control over the authorization or token flow.
447
406
  *
448
- * @example
449
- * // Manually revoke an access token
450
- * await client.oidcClient.revokeToken(accessToken, 'access_token');
407
+ * @returns Returns the underlying **OIDC client** used for OpenID Connect operations.
451
408
  */
452
409
  get oidcClient() {
453
410
  return this.coreClient.oidcClient;
454
411
  }
455
412
  /**
456
- * @param options Configuration options including domain, client ID, and secret.
413
+ * Creates a new client instance.
414
+ *
415
+ * @param options Optional configuration for initializing the MonoCloud client. If not provided, settings are automatically resolved from environment variables.
457
416
  */
458
417
  constructor(options) {
459
418
  const opt = {
460
419
  ...options ?? {},
461
- userAgent: (options === null || options === void 0 ? void 0 : options.userAgent) ?? `@monocloud/auth-nextjs@0.1.5`,
420
+ userAgent: (options === null || options === void 0 ? void 0 : options.userAgent) ?? `@monocloud/auth-nextjs@0.1.7`,
462
421
  debugger: (options === null || options === void 0 ? void 0 : options.debugger) ?? "@monocloud:auth-nextjs"
463
422
  };
464
423
  this.registerPublicEnvVariables();
465
- this.coreClient = new MonoCloudCoreClient(opt);
424
+ this._coreClient = new MonoCloudCoreClient(opt);
466
425
  }
467
426
  /**
468
- * Creates a **Next.js API route handler** (for both Pages Router and App Router)
469
- * that processes all MonoCloud authentication endpoints
470
- * (`/signin`, `/callback`, `/userinfo`, `/signout`).
471
- *
472
- * @param options Authentication configuration routes.
473
- *
474
- * **Note:** If you are already using `authMiddleware()`, you typically do **not**
475
- * need this API route handler. This function is intended for applications where
476
- * middleware cannot be used—such as statically generated (SSG) deployments that still
477
- * require server-side authentication flows.
478
- *
479
- * @example App Router
480
- *
481
- * ```typescript
482
- * // app/api/auth/[...monocloud]/route.ts
483
- *
484
- * import { monoCloud } from "@/lib/monocloud";
485
- *
486
- * export const GET = monoCloud.monoCloudAuth();
487
- *```
488
- *
489
- * @example App Router with Response
490
- *
491
- * ```typescript
492
- * import { monoCloud } from "@/lib/monocloud";
493
- * import { NextRequest, NextResponse } from "next/server";
494
- *
495
- * export const GET = (req: NextRequest) => {
496
- * const authHandler = monoCloud.monoCloudAuth();
497
- *
498
- * const res = new NextResponse();
499
- *
500
- * res.cookies.set("last_auth_requested", `${Date.now()}`);
501
- *
502
- * return authHandler(req, res);
503
- * };
504
- * ```
505
- *
506
- * @example Pages Router
507
- *
508
- * ```typescript
509
- * // pages/api/auth/[...monocloud].ts
510
- *
511
- * import { monoCloud } from "@/lib/monocloud";
512
- *
513
- * export default monoCloud.monoCloudAuth();
514
- *```
515
- *
516
- * @example Page Router with Response
517
- *
518
- * ```typescript
519
- * import { monoCloud } from "@/lib/monocloud";
520
- * import { NextApiRequest, NextApiResponse } from "next";
521
- *
522
- * export default function handler(req: NextApiRequest, res: NextApiResponse) {
523
- * const authHandler = monoCloud.monoCloudAuth();
524
- *
525
- * res.setHeader("last_auth_requested", `${Date.now()}`);
526
- *
527
- * return authHandler(req, res);
528
- * }
529
- * ```
530
- *
427
+ * @see {@link monoCloudAuth} for full docs and examples.
428
+ * @param options Optional configuration for the auth handler.
429
+ * @returns Returns a Next.js-compatible handler for App Router route handlers or Pages Router API routes.
531
430
  */
532
431
  monoCloudAuth(options) {
533
432
  return (req, resOrCtx) => {
@@ -576,7 +475,7 @@ var MonoCloudNextClient = class {
576
475
  const { redirect } = await import("next/navigation");
577
476
  return redirect(signInRoute.toString());
578
477
  }
579
- if ((options === null || options === void 0 ? void 0 : options.groups) && !isUserInGroup(session.user, options.groups, options.groupsClaim ?? process.env.MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) {
478
+ if ((options === null || options === void 0 ? void 0 : options.groups) && !isUserInGroup$1(session.user, options.groups, options.groupsClaim ?? process.env.MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) {
580
479
  if (options.onGroupAccessDenied) return options.onGroupAccessDenied({
581
480
  ...params,
582
481
  user: session.user
@@ -595,10 +494,10 @@ var MonoCloudNextClient = class {
595
494
  if (!session) {
596
495
  var _options$authParams10, _options$authParams11, _options$authParams12, _options$authParams13, _options$authParams14, _options$authParams15, _options$authParams16, _options$authParams17, _options$authParams18;
597
496
  if (options === null || options === void 0 ? void 0 : options.onAccessDenied) {
598
- const customProps$1 = await options.onAccessDenied({ ...context });
497
+ const customProps = await options.onAccessDenied({ ...context });
599
498
  return {
600
- ...customProps$1 ?? {},
601
- props: { ...(customProps$1 === null || customProps$1 === void 0 ? void 0 : customProps$1.props) ?? {} }
499
+ ...customProps ?? {},
500
+ props: { ...(customProps === null || customProps === void 0 ? void 0 : customProps.props) ?? {} }
602
501
  };
603
502
  }
604
503
  const { routes, appUrl } = this.getOptions();
@@ -618,15 +517,15 @@ var MonoCloudNextClient = class {
618
517
  permanent: false
619
518
  } };
620
519
  }
621
- if ((options === null || options === void 0 ? void 0 : options.groups) && !isUserInGroup(session.user, options.groups, options.groupsClaim ?? process.env.MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) {
520
+ if ((options === null || options === void 0 ? void 0 : options.groups) && !isUserInGroup$1(session.user, options.groups, options.groupsClaim ?? process.env.MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) {
622
521
  var _options$onGroupAcces;
623
- const customProps$1 = await ((_options$onGroupAcces = options.onGroupAccessDenied) === null || _options$onGroupAcces === void 0 ? void 0 : _options$onGroupAcces.call(options, {
522
+ const customProps = await ((_options$onGroupAcces = options.onGroupAccessDenied) === null || _options$onGroupAcces === void 0 ? void 0 : _options$onGroupAcces.call(options, {
624
523
  ...context,
625
524
  user: session.user
626
525
  })) ?? { props: { groupAccessDenied: true } };
627
526
  return {
628
- ...customProps$1,
629
- props: { ...customProps$1.props ?? {} }
527
+ ...customProps,
528
+ props: { ...customProps.props ?? {} }
630
529
  };
631
530
  }
632
531
  const customProps = (options === null || options === void 0 ? void 0 : options.getServerSideProps) ? await options.getServerSideProps(context) : {};
@@ -664,7 +563,7 @@ var MonoCloudNextClient = class {
664
563
  }
665
564
  return mergeResponse([res, NextResponse.json({ message: "unauthorized" }, { status: 401 })]);
666
565
  }
667
- if ((options === null || options === void 0 ? void 0 : options.groups) && !isUserInGroup(session.user, options.groups, options.groupsClaim ?? process.env.MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) {
566
+ if ((options === null || options === void 0 ? void 0 : options.groups) && !isUserInGroup$1(session.user, options.groups, options.groupsClaim ?? process.env.MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) {
668
567
  if (options.onGroupAccessDenied) {
669
568
  const result = await options.onGroupAccessDenied(req, ctx, session.user);
670
569
  if (result instanceof NextResponse) return mergeResponse([res, result]);
@@ -682,7 +581,7 @@ var MonoCloudNextClient = class {
682
581
  if (options === null || options === void 0 ? void 0 : options.onAccessDenied) return options.onAccessDenied(req, res);
683
582
  return res.status(401).json({ message: "unauthorized" });
684
583
  }
685
- if ((options === null || options === void 0 ? void 0 : options.groups) && !isUserInGroup(session.user, options.groups, options.groupsClaim ?? process.env.MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) {
584
+ if ((options === null || options === void 0 ? void 0 : options.groups) && !isUserInGroup$1(session.user, options.groups, options.groupsClaim ?? process.env.MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) {
686
585
  if (options.onGroupAccessDenied) return options.onGroupAccessDenied(req, res, session.user);
687
586
  return res.status(403).json({ message: "forbidden" });
688
587
  }
@@ -747,7 +646,7 @@ var MonoCloudNextClient = class {
747
646
  return mergeResponse([nxtResp, NextResponse.redirect(signInRoute)]);
748
647
  }
749
648
  const groupsClaim = (options === null || options === void 0 ? void 0 : options.groupsClaim) ?? process.env.MONOCLOUD_AUTH_GROUPS_CLAIM;
750
- if (allowedGroups && !isUserInGroup(session.user, allowedGroups, groupsClaim)) {
649
+ if (allowedGroups && !isUserInGroup$1(session.user, allowedGroups, groupsClaim)) {
751
650
  if (options === null || options === void 0 ? void 0 : options.onGroupAccessDenied) {
752
651
  const result = await options.onGroupAccessDenied(req, evt, session.user);
753
652
  if (result instanceof NextResponse) return mergeResponse([nxtResp, result]);
@@ -799,7 +698,7 @@ var MonoCloudNextClient = class {
799
698
  ({request, response} = getMonoCloudCookieReqRes(args[0], void 0));
800
699
  options = args[1];
801
700
  }
802
- else if (args.length === 2 && args[0] instanceof IncomingMessage && args[1] instanceof ServerResponse) ({request, response} = getMonoCloudCookieReqRes(args[0], args[1]));
701
+ else if (args.length === 2 && isNodeRequest(args[0]) && isNodeResponse(args[1])) ({request, response} = getMonoCloudCookieReqRes(args[0], args[1]));
803
702
  else {
804
703
  ({request, response} = getMonoCloudCookieReqRes(args[0], args[1]));
805
704
  options = args[2];
@@ -819,52 +718,9 @@ var MonoCloudNextClient = class {
819
718
  return await this.coreClient.isAuthenticated(request, response);
820
719
  }
821
720
  /**
822
- * Redirects the user to the sign-in flow if they are not authenticated.
823
- *
824
- * **This helper is App Router only and is designed for server environments (server components, route handlers, and server actions).**
825
- *
826
- * @param options Options to customize the sign-in.
827
- *
828
- * @returns
829
- *
830
- * @example React Server Component
831
- *
832
- * ```tsx
833
- * import { monoCloud } from "@/lib/monocloud";
834
- *
835
- * export default async function Home() {
836
- * await monoCloud.protect();
837
- *
838
- * return <>You are signed in.</>;
839
- * }
840
- * ```
841
- *
842
- * @example API Handler
843
- *
844
- * ```typescript
845
- * import { NextResponse } from "next/server";
846
- * import { monoCloud } from "@/lib/monocloud";
847
- *
848
- * export const GET = async () => {
849
- * await monoCloud.protect();
850
- *
851
- * return NextResponse.json({ secret: "ssshhhh!!!" });
852
- * };
853
- * ```
854
- *
855
- * @example Server Action
856
- *
857
- * ```typescript
858
- * "use server";
859
- *
860
- * import { monoCloud } from "@/lib/monocloud";
861
- *
862
- * export async function getMessage() {
863
- * await monoCloud.protect();
864
- *
865
- * return { secret: "sssshhhhh!!!" };
866
- * }
867
- * ```
721
+ * @see {@link protect} for full docs and examples.
722
+ * @param options Optional configuration for redirect behavior (for example, return URL or sign-in parameters).
723
+ * @returns Resolves if the user is authenticated; otherwise triggers a redirect.
868
724
  */
869
725
  async protect(options) {
870
726
  var _options$authParams19, _options$authParams20, _options$authParams21, _options$authParams22, _options$authParams23, _options$authParams24, _options$authParams25, _options$authParams26, _options$authParams27;
@@ -873,7 +729,7 @@ var MonoCloudNextClient = class {
873
729
  try {
874
730
  const session = await this.getSession();
875
731
  if (session && !(options === null || options === void 0 ? void 0 : options.groups)) return;
876
- if (session && options && options.groups && isUserInGroup(session.user, options.groups, options.groupsClaim ?? process.env.MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) return;
732
+ if (session && (options === null || options === void 0 ? void 0 : options.groups) && isUserInGroup$1(session.user, options.groups, options.groupsClaim ?? process.env.MONOCLOUD_AUTH_GROUPS_CLAIM, options.matchAll)) return;
877
733
  const { headers } = await import("next/headers");
878
734
  path = (await headers()).get("x-monocloud-path") ?? "/";
879
735
  } catch {
@@ -912,7 +768,7 @@ var MonoCloudNextClient = class {
912
768
  groups = args[1];
913
769
  options = args[2];
914
770
  }
915
- if (args[0] instanceof IncomingMessage && args[1] instanceof ServerResponse) {
771
+ if (isNodeRequest(args[0]) && isNodeResponse(args[1])) {
916
772
  ({request, response} = getMonoCloudCookieReqRes(args[0], args[1]));
917
773
  groups = args[2];
918
774
  }
@@ -938,66 +794,9 @@ var MonoCloudNextClient = class {
938
794
  return await this.coreClient.isUserInGroup(request, response, groups, (options === null || options === void 0 ? void 0 : options.groupsClaim) ?? process.env.MONOCLOUD_AUTH_GROUPS_CLAIM, options === null || options === void 0 ? void 0 : options.matchAll);
939
795
  }
940
796
  /**
941
- * Redirects the user to the sign-in flow.
942
- *
943
- * **This helper is App Router only and is designed for server environments (server components, route handlers, and server actions).**
944
- *
945
- * @param options Options to customize the sign-in.
946
- *
947
- * @returns
948
- *
949
- * @example React Server Component
950
- *
951
- * ```tsx
952
- * import { monoCloud } from "@/lib/monocloud";
953
- *
954
- * export default async function Home() {
955
- * const allowed = await monoCloud.isUserInGroup(["admin"]);
956
- *
957
- * if (!allowed) {
958
- * await monoCloud.redirectToSignIn({ returnUrl: "/home" });
959
- * }
960
- *
961
- * return <>You are signed in.</>;
962
- * }
963
- * ```
964
- *
965
- * @example Server Action
966
- *
967
- * ```typescript
968
- * "use server";
969
- *
970
- * import { monoCloud } from "@/lib/monocloud";
971
- *
972
- * export async function protectedAction() {
973
- * const session = await monoCloud.getSession();
974
- *
975
- * if (!session) {
976
- * await monoCloud.redirectToSignIn();
977
- * }
978
- *
979
- * return { data: "Sensitive Data" };
980
- * }
981
- * ```
982
- *
983
- * @example API Handler
984
- *
985
- * ```typescript
986
- * import { NextResponse } from "next/server";
987
- * import { monoCloud } from "@/lib/monocloud";
988
- *
989
- * export const GET = async () => {
990
- * const session = await monoCloud.getSession();
991
- *
992
- * if (!session) {
993
- * await monoCloud.redirectToSignIn({
994
- * returnUrl: "/dashboard",
995
- * });
996
- * }
997
- *
998
- * return NextResponse.json({ data: "Protected content" });
999
- * };
1000
- * ```
797
+ * @see {@link redirectToSignIn} for full docs and examples.
798
+ * @param options Optional configuration for the redirect, such as `returnUrl` or additional sign-in parameters.
799
+ * @returns Never resolves. Triggers a redirect to the sign-in flow.
1001
800
  */
1002
801
  async redirectToSignIn(options) {
1003
802
  const { routes, appUrl } = this.coreClient.getOptions();
@@ -1022,65 +821,9 @@ var MonoCloudNextClient = class {
1022
821
  redirect(signInRoute.toString());
1023
822
  }
1024
823
  /**
1025
- * Redirects the user to the sign-out flow.
1026
- *
1027
- * **This helper is App Router only and is designed for server environments (server components, route handlers, and server actions).**
1028
- *
1029
- * @param options Options to customize the sign out.
1030
- *
1031
- * @returns
1032
- *
1033
- * @example React Server Component
1034
- *
1035
- * ```tsx
1036
- * import { monoCloud } from "@/lib/monocloud";
1037
- *
1038
- * export default async function Page() {
1039
- * const session = await monoCloud.getSession();
1040
- *
1041
- * // Example: Force sign-out if a specific condition is met (e.g., account suspended)
1042
- * if (session?.user.isSuspended) {
1043
- * await monoCloud.redirectToSignOut();
1044
- * }
1045
- *
1046
- * return <>Welcome User</>;
1047
- * }
1048
- * ```
1049
- *
1050
- * @example Server Action
1051
- *
1052
- * ```typescript
1053
- * "use server";
1054
- *
1055
- * import { monoCloud } from "@/lib/monocloud";
1056
- *
1057
- * export async function signOutAction() {
1058
- * const session = await monoCloud.getSession();
1059
- *
1060
- * if (session) {
1061
- * await monoCloud.redirectToSignOut();
1062
- * }
1063
- * }
1064
- * ```
1065
- *
1066
- * @example API Handler
1067
- *
1068
- * ```typescript
1069
- * import { monoCloud } from "@/lib/monocloud";
1070
- * import { NextResponse } from "next/server";
1071
- *
1072
- * export const GET = async () => {
1073
- * const session = await monoCloud.getSession();
1074
- *
1075
- * if (session) {
1076
- * await monoCloud.redirectToSignOut({
1077
- * postLogoutRedirectUri: "/goodbye",
1078
- * });
1079
- * }
1080
- *
1081
- * return NextResponse.json({ status: "already_signed_out" });
1082
- * };
1083
- * ```
824
+ * @see {@link redirectToSignOut} for full docs and examples.
825
+ * @param options Optional configuration for the redirect, such as `postLogoutRedirectUri` or additional sign-out parameters.
826
+ * @returns Never resolves. Triggers a redirect to the sign-out flow.
1084
827
  */
1085
828
  async redirectToSignOut(options) {
1086
829
  var _options$postLogoutRe;
@@ -1109,5 +852,275 @@ var MonoCloudNextClient = class {
1109
852
  };
1110
853
 
1111
854
  //#endregion
1112
- export { MonoCloudAuthBaseError, MonoCloudHttpError, MonoCloudNextClient, MonoCloudOPError, MonoCloudTokenError, MonoCloudValidationError };
855
+ //#region src/initialize.ts
856
+ let instance;
857
+ /**
858
+ * Retrieves the singleton instance of the MonoCloudNextClient.
859
+ * Initializes it lazily on the first call.
860
+ */
861
+ const getInstance = () => {
862
+ instance ??= new MonoCloudNextClient();
863
+ return instance;
864
+ };
865
+ /**
866
+ * Creates a Next.js catch-all auth route handler (Pages Router and App Router) for the built-in routes (`/signin`, `/callback`, `/userinfo`, `/signout`).
867
+ *
868
+ * Mount this handler on a catch-all route (e.g. `/api/auth/[...monocloud]`).
869
+ *
870
+ * > If you already use `authMiddleware()`, you typically don’t need this handler. Use `monoCloudAuth()` when middleware cannot be used or when auth routes need customization.
871
+ *
872
+ * @example App Router
873
+ * ```tsx:src/app/api/auth/[...monocloud]/route.ts tab="App Router" tab-group="monoCloudAuth"
874
+ * import { monoCloudAuth } from "@monocloud/auth-nextjs";
875
+ *
876
+ * export const GET = monoCloudAuth();
877
+ *```
878
+ *
879
+ * @example App Router (Response)
880
+ * ```tsx:src/app/api/auth/[...monocloud]/route.ts tab="App Router (Response)" tab-group="monoCloudAuth"
881
+ * import { monoCloudAuth } from "@monocloud/auth-nextjs";
882
+ * import { NextRequest, NextResponse } from "next/server";
883
+ *
884
+ * export const GET = (req: NextRequest) => {
885
+ * const authHandler = monoCloudAuth();
886
+ *
887
+ * const res = new NextResponse();
888
+ *
889
+ * res.cookies.set("last_auth_requested", `${Date.now()}`);
890
+ *
891
+ * return authHandler(req, res);
892
+ * };
893
+ * ```
894
+ *
895
+ * @example Pages Router
896
+ * ```tsx:src/pages/api/auth/[...monocloud].ts tab="Pages Router" tab-group="monoCloudAuth"
897
+ * import { monoCloudAuth } from "@monocloud/auth-nextjs";
898
+ *
899
+ * export default monoCloudAuth();
900
+ *```
901
+ *
902
+ * @example Pages Router (Response)
903
+ * ```tsx:src/pages/api/auth/[...monocloud].ts tab="Pages Router (Response)" tab-group="monoCloudAuth"
904
+ * import { monoCloudAuth } from "@monocloud/auth-nextjs";
905
+ * import { NextApiRequest, NextApiResponse } from "next";
906
+ *
907
+ * export default function handler(req: NextApiRequest, res: NextApiResponse) {
908
+ * const authHandler = monoCloudAuth();
909
+ *
910
+ * res.setHeader("last_auth_requested", `${Date.now()}`);
911
+ *
912
+ * return authHandler(req, res);
913
+ * }
914
+ * ```
915
+ *
916
+ * @param options Optional configuration for the auth handler.
917
+ * @returns Returns a Next.js-compatible handler for App Router route handlers or Pages Router API routes.
918
+ *
919
+ * @category Functions
920
+ */
921
+ function monoCloudAuth(options) {
922
+ return getInstance().monoCloudAuth(options);
923
+ }
924
+ function authMiddleware(...args) {
925
+ return getInstance().authMiddleware(...args);
926
+ }
927
+ function getSession(...args) {
928
+ return getInstance().getSession(...args);
929
+ }
930
+ function getTokens(...args) {
931
+ return getInstance().getTokens(...args);
932
+ }
933
+ function isAuthenticated(...args) {
934
+ return getInstance().isAuthenticated(...args);
935
+ }
936
+ /**
937
+ * Ensures the current user is authenticated. If not, redirects to the sign-in flow.
938
+ *
939
+ * > **App Router only.** Intended for Server Components, Route Handlers, and Server Actions.
940
+ *
941
+ * @example Server Component
942
+ * ```tsx:src/app/page.tsx tab="Server Component" tab-group="protect"
943
+ * import { protect } from "@monocloud/auth-nextjs";
944
+ *
945
+ * export default async function Home() {
946
+ * await protect();
947
+ *
948
+ * return <>You are signed in.</>;
949
+ * }
950
+ * ```
951
+ *
952
+ * @example Server Action
953
+ * ```tsx:src/action.ts tab="Server Action" tab-group="protect"
954
+ * "use server";
955
+ *
956
+ * import { protect } from "@monocloud/auth-nextjs";
957
+ *
958
+ * export async function getMessage() {
959
+ * await protect();
960
+ *
961
+ * return { secret: "sssshhhhh!!!" };
962
+ * }
963
+ * ```
964
+ *
965
+ * @example API Handler
966
+ * ```tsx:src/app/api/protected/route.ts tab="API Handler" tab-group="protect"
967
+ * import { protect } from "@monocloud/auth-nextjs";
968
+ * import { NextResponse } from "next/server";
969
+ *
970
+ * export const GET = async () => {
971
+ * await protect();
972
+ *
973
+ * return NextResponse.json({ secret: "ssshhhh!!!" });
974
+ * };
975
+ * ```
976
+ *
977
+ * @param options Optional configuration for redirect behavior (for example, return URL or sign-in parameters).
978
+ * @returns Resolves if the user is authenticated; otherwise triggers a redirect.
979
+ *
980
+ * @category Functions
981
+ */
982
+ function protect(options) {
983
+ return getInstance().protect(options);
984
+ }
985
+ function protectApi(handler, options) {
986
+ return getInstance().protectApi(handler, options);
987
+ }
988
+ function protectPage(...args) {
989
+ return getInstance().protectPage(...args);
990
+ }
991
+ function isUserInGroup(...args) {
992
+ return getInstance().isUserInGroup(...args);
993
+ }
994
+ /**
995
+ * Redirects the user to the sign-in flow.
996
+ *
997
+ * > **App Router only**. Intended for use in Server Components, Route Handlers, and Server Actions.
998
+ *
999
+ * This helper performs a server-side redirect to the configured sign-in route. Execution does not continue after the redirect is triggered.
1000
+ *
1001
+ * @example Server Component
1002
+ * ```tsx:src/app/page.tsx tab="Server Component" tab-group="redirect-to-sign-in"
1003
+ * import { isUserInGroup, redirectToSignIn } from "@monocloud/auth-nextjs";
1004
+ *
1005
+ * export default async function Home() {
1006
+ * const allowed = await isUserInGroup(["admin"]);
1007
+ *
1008
+ * if (!allowed) {
1009
+ * await redirectToSignIn({ returnUrl: "/home" });
1010
+ * }
1011
+ *
1012
+ * return <>You are signed in.</>;
1013
+ * }
1014
+ * ```
1015
+ *
1016
+ * @example Server Action
1017
+ * ```tsx:src/action.ts tab="Server Action" tab-group="redirect-to-sign-in"
1018
+ * "use server";
1019
+ *
1020
+ * import { getSession, redirectToSignIn } from "@monocloud/auth-nextjs";
1021
+ *
1022
+ * export async function protectedAction() {
1023
+ * const session = await getSession();
1024
+ *
1025
+ * if (!session) {
1026
+ * await redirectToSignIn();
1027
+ * }
1028
+ *
1029
+ * return { data: "Sensitive Data" };
1030
+ * }
1031
+ * ```
1032
+ *
1033
+ * @example API Handler
1034
+ * ```tsx:src/app/api/protected/route.ts tab="API Handler" tab-group="redirect-to-sign-in"
1035
+ * import { getSession, redirectToSignIn } from "@monocloud/auth-nextjs";
1036
+ * import { NextResponse } from "next/server";
1037
+ *
1038
+ * export const GET = async () => {
1039
+ * const session = await getSession();
1040
+ *
1041
+ * if (!session) {
1042
+ * await redirectToSignIn({
1043
+ * returnUrl: "/dashboard",
1044
+ * });
1045
+ * }
1046
+ *
1047
+ * return NextResponse.json({ data: "Protected content" });
1048
+ * };
1049
+ * ```
1050
+ *
1051
+ * @param options Optional configuration for the redirect, such as `returnUrl` or additional sign-in parameters.
1052
+ * @returns Never resolves. Triggers a redirect to the sign-in flow.
1053
+ *
1054
+ * @category Functions
1055
+ */
1056
+ function redirectToSignIn(options) {
1057
+ return getInstance().redirectToSignIn(options);
1058
+ }
1059
+ /**
1060
+ * Redirects the user to the sign-out flow.
1061
+ *
1062
+ * > **App Router only**. Intended for use in Server Components, Route Handlers, and Server Actions.
1063
+ *
1064
+ * This helper performs a server-side redirect to the configured sign-out route. Execution does not continue after the redirect is triggered.
1065
+ *
1066
+ * @example Server Component
1067
+ * ```tsx:src/app/page.tsx tab="Server Component" tab-group="redirect-to-sign-out"
1068
+ * import { getSession, redirectToSignOut } from "@monocloud/auth-nextjs";
1069
+ *
1070
+ * export default async function Page() {
1071
+ * const session = await getSession();
1072
+ *
1073
+ * // Example: Force sign-out if a specific condition is met (e.g., account suspended)
1074
+ * if (session?.user.isSuspended) {
1075
+ * await redirectToSignOut();
1076
+ * }
1077
+ *
1078
+ * return <>Welcome User</>;
1079
+ * }
1080
+ * ```
1081
+ *
1082
+ * @example Server Action
1083
+ * ```tsx:src/action.ts tab="Server Action" tab-group="redirect-to-sign-out"
1084
+ * "use server";
1085
+ *
1086
+ * import { getSession, redirectToSignOut } from "@monocloud/auth-nextjs";
1087
+ *
1088
+ * export async function signOutAction() {
1089
+ * const session = await getSession();
1090
+ *
1091
+ * if (session) {
1092
+ * await redirectToSignOut();
1093
+ * }
1094
+ * }
1095
+ * ```
1096
+ *
1097
+ * @example API Handler
1098
+ * ```tsx:src/app/api/signout/route.ts tab="API Handler" tab-group="redirect-to-sign-out"
1099
+ * import { getSession, redirectToSignOut } from "@monocloud/auth-nextjs";
1100
+ * import { NextResponse } from "next/server";
1101
+ *
1102
+ * export const GET = async () => {
1103
+ * const session = await getSession();
1104
+ *
1105
+ * if (session) {
1106
+ * await redirectToSignOut({
1107
+ * postLogoutRedirectUri: "/goodbye",
1108
+ * });
1109
+ * }
1110
+ *
1111
+ * return NextResponse.json({ status: "already_signed_out" });
1112
+ * };
1113
+ * ```
1114
+ *
1115
+ * @param options Optional configuration for the redirect, such as `postLogoutRedirectUri` or additional sign-out parameters.
1116
+ * @returns Never resolves. Triggers a redirect to the sign-out flow.
1117
+ *
1118
+ * @category Functions
1119
+ */
1120
+ function redirectToSignOut(options) {
1121
+ return getInstance().redirectToSignOut(options);
1122
+ }
1123
+
1124
+ //#endregion
1125
+ export { MonoCloudAuthBaseError, MonoCloudHttpError, MonoCloudNextClient, MonoCloudOPError, MonoCloudTokenError, MonoCloudValidationError, authMiddleware, getSession, getTokens, isAuthenticated, isUserInGroup, monoCloudAuth, protect, protectApi, protectPage, redirectToSignIn, redirectToSignOut };
1113
1126
  //# sourceMappingURL=index.mjs.map