@dudousxd/nestjs-durable-dashboard 0.51.1 → 0.52.0

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.
@@ -5,7 +5,7 @@ import * as rxjs from 'rxjs';
5
5
  import { Observable } from 'rxjs';
6
6
  import * as _dudousxd_nestjs_filter from '@dudousxd/nestjs-filter';
7
7
  import { FilterRunner } from '@dudousxd/nestjs-filter';
8
- import { DynamicModule, Type, CanActivate, Provider, InjectionToken, OptionalFactoryDependency, ExecutionContext, StreamableFile } from '@nestjs/common';
8
+ import { CanActivate, ExecutionContext, Provider, Logger, DynamicModule, Type, InjectionToken, OptionalFactoryDependency, StreamableFile } from '@nestjs/common';
9
9
 
10
10
  /** The session user the host `login` hook returns to mint a cookie. */
11
11
  interface DashboardSessionUser {
@@ -416,6 +416,68 @@ declare class DurableAuthController {
416
416
  private runHook;
417
417
  }
418
418
 
419
+ /** The env var the token gate reads when no `token` option is given. */
420
+ declare const DURABLE_DASHBOARD_TOKEN_ENV = "DURABLE_DASHBOARD_TOKEN";
421
+ /** DI token carrying the resolved {@link DashboardGate} (one per dashboard mount). */
422
+ declare const DASHBOARD_GATE: unique symbol;
423
+ /**
424
+ * What the module knows about how the console is protected, captured at `forRoot`/`forRootAsync`
425
+ * time. Everything that can change between module definition and boot (env vars, the async
426
+ * `dashboardAuth` factory) is read later, in {@link resolveDashboardGate}.
427
+ */
428
+ interface DashboardGateOptions {
429
+ /** Host `guards` were passed (non-empty). */
430
+ hasGuards: boolean;
431
+ /** `allowUnauthenticated` as passed. */
432
+ allowUnauthenticated?: boolean;
433
+ /** `token` as passed (else `DURABLE_DASHBOARD_TOKEN` is read at boot). */
434
+ token?: string;
435
+ }
436
+ /**
437
+ * How the gate treats every console request:
438
+ *
439
+ * - `delegated`: `guards` or `dashboardAuth` protect the console; the gate passes everything.
440
+ * - `open`: `allowUnauthenticated: true`; the gate passes everything (warned at boot).
441
+ * - `token`: a request must carry the token (`Authorization: Bearer`, `x-durable-token`, or
442
+ * `?token=` on GET/HEAD).
443
+ * - `unconfigured`: nothing was configured outside production; the gate passes everything
444
+ * (warned at boot, because production will deny).
445
+ * - `deny`: nothing was configured and `NODE_ENV=production`; every request is refused.
446
+ */
447
+ type DashboardGateMode = 'delegated' | 'open' | 'token' | 'unconfigured' | 'deny';
448
+ interface DashboardGate {
449
+ mode: DashboardGateMode;
450
+ /** Set only when `mode === 'token'`. */
451
+ token?: string;
452
+ }
453
+ /**
454
+ * Decide the gate mode. Precedence: `guards`/`dashboardAuth` (they are the gate) > a token > the
455
+ * `allowUnauthenticated` opt-out > the environment default. A token beats `allowUnauthenticated`
456
+ * because a configured secret is never silently ignored.
457
+ */
458
+ declare function resolveDashboardGate(options: DashboardGateOptions, auth: ResolvedDashboardAuth | null): DashboardGate;
459
+ /** Log the one boot line the resolved gate calls for (nothing for a properly configured console). */
460
+ declare function reportDashboardGate(gate: DashboardGate, options: DashboardGateOptions, logger?: Pick<Logger, 'warn' | 'error'>): void;
461
+ /** The `DASHBOARD_GATE` provider: resolves once, after `DASHBOARD_AUTH`, and logs once. */
462
+ declare function dashboardGateProvider(options: DashboardGateOptions): Provider;
463
+ /**
464
+ * Read the token from `Authorization: Bearer <token>`, `x-durable-token`, or (GET/HEAD only) a
465
+ * `token` query param. The query channel is read-only on purpose: a `?token=` URL ends up in access
466
+ * logs, `Referer` headers and browser history, and must never authorize a mutation.
467
+ */
468
+ declare function readDashboardToken(request: unknown): string | undefined;
469
+ /**
470
+ * The fail-closed default gate, stamped on `DurableUiController` and `DurableApiController` (after
471
+ * the built-in session guard, before host `guards`) whenever the module can't prove at definition
472
+ * time that something else protects the console. It never gates `DurableAuthController`, so the
473
+ * login/session/logout routes stay reachable. See {@link DashboardGateMode} for what each mode does.
474
+ */
475
+ declare class DurableDashboardGateGuard implements CanActivate {
476
+ private readonly gate;
477
+ constructor(gate: DashboardGate);
478
+ canActivate(context: ExecutionContext): boolean;
479
+ }
480
+
419
481
  interface DurableDashboardOptions {
420
482
  /**
421
483
  * Where the SPA (UI) is served. Default `/durable`. This is a page route — keep it out of an
@@ -432,8 +494,10 @@ interface DurableDashboardOptions {
432
494
  * Guard classes fronting BOTH dashboard controllers (the SPA at `basePath` and its JSON API at
433
495
  * `apiBasePath`). Stamped onto each controller via `@nestjs/common`'s own `@UseGuards` metadata key
434
496
  * — REPLACE semantics, so a second `forRoot(...)` call overwrites (not appends to) whatever a prior
435
- * call stamped, same as re-applying `@UseGuards` by hand. Omit to leave the routes unguarded (the
436
- * host fronts them another way, e.g. a global guard or reverse-proxy auth).
497
+ * call stamped, same as re-applying `@UseGuards` by hand. A non-empty `guards` counts as the
498
+ * console's authentication, so the fail-closed default gate steps aside (see
499
+ * {@link allowUnauthenticated}). If the host fronts the routes another way (a global guard,
500
+ * reverse-proxy auth), say so with `allowUnauthenticated: true` instead.
437
501
  *
438
502
  * A guard's own DEPENDENCIES resolve from this module's `imports` (see {@link imports}) — the
439
503
  * dashboard module has no application context of its own to pull them from otherwise.
@@ -494,15 +558,36 @@ interface DurableDashboardOptions {
494
558
  *
495
559
  * Composes with {@link guards}: when both are set, a request must pass the built-in session check
496
560
  * AND every guard in `guards` — the SAME logical-AND semantics `@UseGuards` already gives multiple
497
- * guards, since the built-in guard is simply prepended to whatever `guards` you pass. Omit to leave
498
- * the console open (today's behavior, unchanged byte-for-byte) — front it with `guards`, a global
499
- * guard, or a reverse proxy instead.
561
+ * guards, since the built-in guard is simply prepended to whatever `guards` you pass. Setting it
562
+ * counts as the console's authentication (the fail-closed default gate steps aside). Omit it and
563
+ * configure `guards`, a {@link token}, or {@link allowUnauthenticated} instead.
500
564
  *
501
565
  * See {@link DashboardAuthOptions} for the `secret`/`ttl`/`session`/`login`/`revalidate` shape,
502
566
  * and `forRootAsync` / {@link DurableDashboardAsyncOptions.useDashboardAuth} when a hook needs DI
503
567
  * (e.g. an `EntityManager` to look up an admin user).
504
568
  */
505
569
  dashboardAuth?: DashboardAuthOptions;
570
+ /**
571
+ * Explicitly serve the console with NO authentication from this module. Use it only when
572
+ * something outside the module already protects it: a global guard, a reverse proxy / SSO in
573
+ * front of the mount, a private network. Logs a boot warning.
574
+ *
575
+ * Without it, an unconfigured console (no `guards`, no `dashboardAuth`, no token) is DENIED when
576
+ * `NODE_ENV=production` (every UI and API request answers `403`, and one boot error explains how
577
+ * to configure it). Outside production it is still served open, with a boot warning. Ignored when
578
+ * `guards`, `dashboardAuth` or a token is configured.
579
+ */
580
+ allowUnauthenticated?: boolean;
581
+ /**
582
+ * Bearer-token gate for the console. Defaults to `process.env.DURABLE_DASHBOARD_TOKEN` (read at
583
+ * boot). Only applies when neither `guards` nor `dashboardAuth` is configured: every UI and API
584
+ * request must then carry it as `Authorization: Bearer <token>`, an `x-durable-token` header, or
585
+ * (GET/HEAD only) a `?token=` query param, compared in constant time; anything else gets `401`.
586
+ *
587
+ * Meant for scripts and reverse proxies that inject the header: the bundled SPA does not attach
588
+ * the token to its own asset and API requests. Browser operators want `dashboardAuth` or `guards`.
589
+ */
590
+ token?: string;
506
591
  }
507
592
  /**
508
593
  * Async variant of {@link DurableDashboardOptions}. The mount paths and `guards` stay static (the
@@ -510,7 +595,9 @@ interface DurableDashboardOptions {
510
595
  * already has), but `dashboardAuth` is built by an injected factory, so its `session`/`login` hooks
511
596
  * can reach your DB/services — e.g. Mode A's `session` hook calling out to the same auth service
512
597
  * your host app already uses to validate the raw request. Returning `undefined` from
513
- * `useDashboardAuth` leaves the console open, exactly like omitting `dashboardAuth` from `forRoot`.
598
+ * `useDashboardAuth` is exactly like omitting `dashboardAuth` from `forRoot`: the console then
599
+ * falls back to `guards` / the token / `allowUnauthenticated`, and is DENIED in production when
600
+ * none of those is configured.
514
601
  */
515
602
  interface DurableDashboardAsyncOptions {
516
603
  basePath?: string;
@@ -519,8 +606,12 @@ interface DurableDashboardAsyncOptions {
519
606
  imports?: DynamicModule['imports'];
520
607
  /** Providers injected into `useDashboardAuth`, in order. Shared with a `guards` class's own deps. */
521
608
  inject?: Array<InjectionToken | OptionalFactoryDependency>;
522
- /** Build the `dashboardAuth` config from injected deps (or `undefined` to leave the console open). */
609
+ /** Build the `dashboardAuth` config from injected deps (or `undefined` for no session auth). */
523
610
  useDashboardAuth: (...deps: any[]) => DashboardAuthOptions | undefined | Promise<DashboardAuthOptions | undefined>;
611
+ /** See {@link DurableDashboardOptions.allowUnauthenticated}. */
612
+ allowUnauthenticated?: boolean;
613
+ /** See {@link DurableDashboardOptions.token}. */
614
+ token?: string;
524
615
  }
525
616
  /**
526
617
  * Holds the JSON API controller + its read service, mounted on its own path by `forRoot`. Dynamic:
@@ -540,6 +631,10 @@ declare class DurableApiModule {
540
631
  * (true whenever `dashboardAuth` was set, or unconditionally for `forRootAsync`, where it's
541
632
  * resolved at runtime and is a no-op if it ends up unconfigured). */
542
633
  authMayBeConfigured: boolean;
634
+ /** What the fail-closed gate needs; resolved into `DASHBOARD_GATE` at boot (logged once). */
635
+ gate: DashboardGateOptions;
636
+ /** Whether `DurableDashboardGateGuard` is stamped (false when guards/dashboardAuth are static). */
637
+ stampGate: boolean;
543
638
  }): DynamicModule;
544
639
  }
545
640
  /**
@@ -549,6 +644,8 @@ declare class DurableApiModule {
549
644
  * so it resolves the engine and store. Front the routes with the first-class `guards` option
550
645
  * (plus `imports` for the guards' own dependencies) — see {@link DurableDashboardOptions.guards} —
551
646
  * or with the built-in `dashboardAuth` cookie login, or both.
647
+ * With none of those (and no `token` / `allowUnauthenticated`), the console fails closed when
648
+ * `NODE_ENV=production` — see {@link DurableDashboardOptions.allowUnauthenticated}.
552
649
  */
553
650
  declare class DurableDashboardModule {
554
651
  static forRoot(options?: DurableDashboardOptions): DynamicModule;
@@ -635,4 +732,4 @@ declare class DurableUiController {
635
732
  asset(file: string): StreamableFile;
636
733
  }
637
734
 
638
- export { DASHBOARD_API_PATH, DASHBOARD_BASE_PATH, type DashboardAuthOptions, DashboardService, type DashboardSessionUser, DurableApiController, DurableApiModule, DurableApiSessionGuard, DurableAuthController, type DurableDashboardAsyncOptions, DurableDashboardModule, type DurableDashboardOptions, DurableUiController, DurableUiSessionGuard, type UnauthenticatedPageContext, type UnauthenticatedPageHook };
735
+ export { DASHBOARD_API_PATH, DASHBOARD_BASE_PATH, DASHBOARD_GATE, DURABLE_DASHBOARD_TOKEN_ENV, type DashboardAuthOptions, type DashboardGate, type DashboardGateMode, type DashboardGateOptions, DashboardService, type DashboardSessionUser, DurableApiController, DurableApiModule, DurableApiSessionGuard, DurableAuthController, type DurableDashboardAsyncOptions, DurableDashboardGateGuard, DurableDashboardModule, type DurableDashboardOptions, DurableUiController, DurableUiSessionGuard, type UnauthenticatedPageContext, type UnauthenticatedPageHook, dashboardGateProvider, readDashboardToken, reportDashboardGate, resolveDashboardGate };
@@ -5,7 +5,7 @@ import * as rxjs from 'rxjs';
5
5
  import { Observable } from 'rxjs';
6
6
  import * as _dudousxd_nestjs_filter from '@dudousxd/nestjs-filter';
7
7
  import { FilterRunner } from '@dudousxd/nestjs-filter';
8
- import { DynamicModule, Type, CanActivate, Provider, InjectionToken, OptionalFactoryDependency, ExecutionContext, StreamableFile } from '@nestjs/common';
8
+ import { CanActivate, ExecutionContext, Provider, Logger, DynamicModule, Type, InjectionToken, OptionalFactoryDependency, StreamableFile } from '@nestjs/common';
9
9
 
10
10
  /** The session user the host `login` hook returns to mint a cookie. */
11
11
  interface DashboardSessionUser {
@@ -416,6 +416,68 @@ declare class DurableAuthController {
416
416
  private runHook;
417
417
  }
418
418
 
419
+ /** The env var the token gate reads when no `token` option is given. */
420
+ declare const DURABLE_DASHBOARD_TOKEN_ENV = "DURABLE_DASHBOARD_TOKEN";
421
+ /** DI token carrying the resolved {@link DashboardGate} (one per dashboard mount). */
422
+ declare const DASHBOARD_GATE: unique symbol;
423
+ /**
424
+ * What the module knows about how the console is protected, captured at `forRoot`/`forRootAsync`
425
+ * time. Everything that can change between module definition and boot (env vars, the async
426
+ * `dashboardAuth` factory) is read later, in {@link resolveDashboardGate}.
427
+ */
428
+ interface DashboardGateOptions {
429
+ /** Host `guards` were passed (non-empty). */
430
+ hasGuards: boolean;
431
+ /** `allowUnauthenticated` as passed. */
432
+ allowUnauthenticated?: boolean;
433
+ /** `token` as passed (else `DURABLE_DASHBOARD_TOKEN` is read at boot). */
434
+ token?: string;
435
+ }
436
+ /**
437
+ * How the gate treats every console request:
438
+ *
439
+ * - `delegated`: `guards` or `dashboardAuth` protect the console; the gate passes everything.
440
+ * - `open`: `allowUnauthenticated: true`; the gate passes everything (warned at boot).
441
+ * - `token`: a request must carry the token (`Authorization: Bearer`, `x-durable-token`, or
442
+ * `?token=` on GET/HEAD).
443
+ * - `unconfigured`: nothing was configured outside production; the gate passes everything
444
+ * (warned at boot, because production will deny).
445
+ * - `deny`: nothing was configured and `NODE_ENV=production`; every request is refused.
446
+ */
447
+ type DashboardGateMode = 'delegated' | 'open' | 'token' | 'unconfigured' | 'deny';
448
+ interface DashboardGate {
449
+ mode: DashboardGateMode;
450
+ /** Set only when `mode === 'token'`. */
451
+ token?: string;
452
+ }
453
+ /**
454
+ * Decide the gate mode. Precedence: `guards`/`dashboardAuth` (they are the gate) > a token > the
455
+ * `allowUnauthenticated` opt-out > the environment default. A token beats `allowUnauthenticated`
456
+ * because a configured secret is never silently ignored.
457
+ */
458
+ declare function resolveDashboardGate(options: DashboardGateOptions, auth: ResolvedDashboardAuth | null): DashboardGate;
459
+ /** Log the one boot line the resolved gate calls for (nothing for a properly configured console). */
460
+ declare function reportDashboardGate(gate: DashboardGate, options: DashboardGateOptions, logger?: Pick<Logger, 'warn' | 'error'>): void;
461
+ /** The `DASHBOARD_GATE` provider: resolves once, after `DASHBOARD_AUTH`, and logs once. */
462
+ declare function dashboardGateProvider(options: DashboardGateOptions): Provider;
463
+ /**
464
+ * Read the token from `Authorization: Bearer <token>`, `x-durable-token`, or (GET/HEAD only) a
465
+ * `token` query param. The query channel is read-only on purpose: a `?token=` URL ends up in access
466
+ * logs, `Referer` headers and browser history, and must never authorize a mutation.
467
+ */
468
+ declare function readDashboardToken(request: unknown): string | undefined;
469
+ /**
470
+ * The fail-closed default gate, stamped on `DurableUiController` and `DurableApiController` (after
471
+ * the built-in session guard, before host `guards`) whenever the module can't prove at definition
472
+ * time that something else protects the console. It never gates `DurableAuthController`, so the
473
+ * login/session/logout routes stay reachable. See {@link DashboardGateMode} for what each mode does.
474
+ */
475
+ declare class DurableDashboardGateGuard implements CanActivate {
476
+ private readonly gate;
477
+ constructor(gate: DashboardGate);
478
+ canActivate(context: ExecutionContext): boolean;
479
+ }
480
+
419
481
  interface DurableDashboardOptions {
420
482
  /**
421
483
  * Where the SPA (UI) is served. Default `/durable`. This is a page route — keep it out of an
@@ -432,8 +494,10 @@ interface DurableDashboardOptions {
432
494
  * Guard classes fronting BOTH dashboard controllers (the SPA at `basePath` and its JSON API at
433
495
  * `apiBasePath`). Stamped onto each controller via `@nestjs/common`'s own `@UseGuards` metadata key
434
496
  * — REPLACE semantics, so a second `forRoot(...)` call overwrites (not appends to) whatever a prior
435
- * call stamped, same as re-applying `@UseGuards` by hand. Omit to leave the routes unguarded (the
436
- * host fronts them another way, e.g. a global guard or reverse-proxy auth).
497
+ * call stamped, same as re-applying `@UseGuards` by hand. A non-empty `guards` counts as the
498
+ * console's authentication, so the fail-closed default gate steps aside (see
499
+ * {@link allowUnauthenticated}). If the host fronts the routes another way (a global guard,
500
+ * reverse-proxy auth), say so with `allowUnauthenticated: true` instead.
437
501
  *
438
502
  * A guard's own DEPENDENCIES resolve from this module's `imports` (see {@link imports}) — the
439
503
  * dashboard module has no application context of its own to pull them from otherwise.
@@ -494,15 +558,36 @@ interface DurableDashboardOptions {
494
558
  *
495
559
  * Composes with {@link guards}: when both are set, a request must pass the built-in session check
496
560
  * AND every guard in `guards` — the SAME logical-AND semantics `@UseGuards` already gives multiple
497
- * guards, since the built-in guard is simply prepended to whatever `guards` you pass. Omit to leave
498
- * the console open (today's behavior, unchanged byte-for-byte) — front it with `guards`, a global
499
- * guard, or a reverse proxy instead.
561
+ * guards, since the built-in guard is simply prepended to whatever `guards` you pass. Setting it
562
+ * counts as the console's authentication (the fail-closed default gate steps aside). Omit it and
563
+ * configure `guards`, a {@link token}, or {@link allowUnauthenticated} instead.
500
564
  *
501
565
  * See {@link DashboardAuthOptions} for the `secret`/`ttl`/`session`/`login`/`revalidate` shape,
502
566
  * and `forRootAsync` / {@link DurableDashboardAsyncOptions.useDashboardAuth} when a hook needs DI
503
567
  * (e.g. an `EntityManager` to look up an admin user).
504
568
  */
505
569
  dashboardAuth?: DashboardAuthOptions;
570
+ /**
571
+ * Explicitly serve the console with NO authentication from this module. Use it only when
572
+ * something outside the module already protects it: a global guard, a reverse proxy / SSO in
573
+ * front of the mount, a private network. Logs a boot warning.
574
+ *
575
+ * Without it, an unconfigured console (no `guards`, no `dashboardAuth`, no token) is DENIED when
576
+ * `NODE_ENV=production` (every UI and API request answers `403`, and one boot error explains how
577
+ * to configure it). Outside production it is still served open, with a boot warning. Ignored when
578
+ * `guards`, `dashboardAuth` or a token is configured.
579
+ */
580
+ allowUnauthenticated?: boolean;
581
+ /**
582
+ * Bearer-token gate for the console. Defaults to `process.env.DURABLE_DASHBOARD_TOKEN` (read at
583
+ * boot). Only applies when neither `guards` nor `dashboardAuth` is configured: every UI and API
584
+ * request must then carry it as `Authorization: Bearer <token>`, an `x-durable-token` header, or
585
+ * (GET/HEAD only) a `?token=` query param, compared in constant time; anything else gets `401`.
586
+ *
587
+ * Meant for scripts and reverse proxies that inject the header: the bundled SPA does not attach
588
+ * the token to its own asset and API requests. Browser operators want `dashboardAuth` or `guards`.
589
+ */
590
+ token?: string;
506
591
  }
507
592
  /**
508
593
  * Async variant of {@link DurableDashboardOptions}. The mount paths and `guards` stay static (the
@@ -510,7 +595,9 @@ interface DurableDashboardOptions {
510
595
  * already has), but `dashboardAuth` is built by an injected factory, so its `session`/`login` hooks
511
596
  * can reach your DB/services — e.g. Mode A's `session` hook calling out to the same auth service
512
597
  * your host app already uses to validate the raw request. Returning `undefined` from
513
- * `useDashboardAuth` leaves the console open, exactly like omitting `dashboardAuth` from `forRoot`.
598
+ * `useDashboardAuth` is exactly like omitting `dashboardAuth` from `forRoot`: the console then
599
+ * falls back to `guards` / the token / `allowUnauthenticated`, and is DENIED in production when
600
+ * none of those is configured.
514
601
  */
515
602
  interface DurableDashboardAsyncOptions {
516
603
  basePath?: string;
@@ -519,8 +606,12 @@ interface DurableDashboardAsyncOptions {
519
606
  imports?: DynamicModule['imports'];
520
607
  /** Providers injected into `useDashboardAuth`, in order. Shared with a `guards` class's own deps. */
521
608
  inject?: Array<InjectionToken | OptionalFactoryDependency>;
522
- /** Build the `dashboardAuth` config from injected deps (or `undefined` to leave the console open). */
609
+ /** Build the `dashboardAuth` config from injected deps (or `undefined` for no session auth). */
523
610
  useDashboardAuth: (...deps: any[]) => DashboardAuthOptions | undefined | Promise<DashboardAuthOptions | undefined>;
611
+ /** See {@link DurableDashboardOptions.allowUnauthenticated}. */
612
+ allowUnauthenticated?: boolean;
613
+ /** See {@link DurableDashboardOptions.token}. */
614
+ token?: string;
524
615
  }
525
616
  /**
526
617
  * Holds the JSON API controller + its read service, mounted on its own path by `forRoot`. Dynamic:
@@ -540,6 +631,10 @@ declare class DurableApiModule {
540
631
  * (true whenever `dashboardAuth` was set, or unconditionally for `forRootAsync`, where it's
541
632
  * resolved at runtime and is a no-op if it ends up unconfigured). */
542
633
  authMayBeConfigured: boolean;
634
+ /** What the fail-closed gate needs; resolved into `DASHBOARD_GATE` at boot (logged once). */
635
+ gate: DashboardGateOptions;
636
+ /** Whether `DurableDashboardGateGuard` is stamped (false when guards/dashboardAuth are static). */
637
+ stampGate: boolean;
543
638
  }): DynamicModule;
544
639
  }
545
640
  /**
@@ -549,6 +644,8 @@ declare class DurableApiModule {
549
644
  * so it resolves the engine and store. Front the routes with the first-class `guards` option
550
645
  * (plus `imports` for the guards' own dependencies) — see {@link DurableDashboardOptions.guards} —
551
646
  * or with the built-in `dashboardAuth` cookie login, or both.
647
+ * With none of those (and no `token` / `allowUnauthenticated`), the console fails closed when
648
+ * `NODE_ENV=production` — see {@link DurableDashboardOptions.allowUnauthenticated}.
552
649
  */
553
650
  declare class DurableDashboardModule {
554
651
  static forRoot(options?: DurableDashboardOptions): DynamicModule;
@@ -635,4 +732,4 @@ declare class DurableUiController {
635
732
  asset(file: string): StreamableFile;
636
733
  }
637
734
 
638
- export { DASHBOARD_API_PATH, DASHBOARD_BASE_PATH, type DashboardAuthOptions, DashboardService, type DashboardSessionUser, DurableApiController, DurableApiModule, DurableApiSessionGuard, DurableAuthController, type DurableDashboardAsyncOptions, DurableDashboardModule, type DurableDashboardOptions, DurableUiController, DurableUiSessionGuard, type UnauthenticatedPageContext, type UnauthenticatedPageHook };
735
+ export { DASHBOARD_API_PATH, DASHBOARD_BASE_PATH, DASHBOARD_GATE, DURABLE_DASHBOARD_TOKEN_ENV, type DashboardAuthOptions, type DashboardGate, type DashboardGateMode, type DashboardGateOptions, DashboardService, type DashboardSessionUser, DurableApiController, DurableApiModule, DurableApiSessionGuard, DurableAuthController, type DurableDashboardAsyncOptions, DurableDashboardGateGuard, DurableDashboardModule, type DurableDashboardOptions, DurableUiController, DurableUiSessionGuard, type UnauthenticatedPageContext, type UnauthenticatedPageHook, dashboardGateProvider, readDashboardToken, reportDashboardGate, resolveDashboardGate };