@dudousxd/nestjs-durable-dashboard 0.51.0 → 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.
@@ -24,14 +24,21 @@ var index_exports = {};
24
24
  __export(index_exports, {
25
25
  DASHBOARD_API_PATH: () => DASHBOARD_API_PATH,
26
26
  DASHBOARD_BASE_PATH: () => DASHBOARD_BASE_PATH,
27
+ DASHBOARD_GATE: () => DASHBOARD_GATE,
28
+ DURABLE_DASHBOARD_TOKEN_ENV: () => DURABLE_DASHBOARD_TOKEN_ENV,
27
29
  DashboardService: () => DashboardService,
28
30
  DurableApiController: () => DurableApiController,
29
31
  DurableApiModule: () => DurableApiModule,
30
32
  DurableApiSessionGuard: () => DurableApiSessionGuard,
31
33
  DurableAuthController: () => DurableAuthController,
34
+ DurableDashboardGateGuard: () => DurableDashboardGateGuard,
32
35
  DurableDashboardModule: () => DurableDashboardModule,
33
36
  DurableUiController: () => DurableUiController,
34
- DurableUiSessionGuard: () => DurableUiSessionGuard
37
+ DurableUiSessionGuard: () => DurableUiSessionGuard,
38
+ dashboardGateProvider: () => dashboardGateProvider,
39
+ readDashboardToken: () => readDashboardToken,
40
+ reportDashboardGate: () => reportDashboardGate,
41
+ resolveDashboardGate: () => resolveDashboardGate
35
42
  });
36
43
  module.exports = __toCommonJS(index_exports);
37
44
 
@@ -245,11 +252,30 @@ var DashboardService = class {
245
252
  }
246
253
  /**
247
254
  * Deliver a `ctx.webhook()` callback: turn an inbound POST (token + body) into the signal the
248
- * waiting run is parked on. Returns the run result, or `null` if no run waits on that token (a
249
- * stale/duplicate callback) — a safe no-op the controller maps to 404. Control-plane-only.
255
+ * run is (or will be) parked on. A callback that arrives BEFORE the run reaches `wait()` (the url
256
+ * was handed out and the run is still busy or sleeping) is buffered, and `wait()` consumes it, so
257
+ * the result is the run's current status. Returns `null` — mapped to 404 by the controller — for a
258
+ * token that is not a webhook token, whose run doesn't exist or is terminal, or whose wait already
259
+ * resolved (a duplicate): nothing is buffered for those, so a public endpoint can't leave junk
260
+ * rows behind or signal non-webhook tokens. Control-plane-only.
250
261
  */
251
262
  async deliverWebhook(token, body) {
252
- return this.controlPlane().engine.signal(token, body);
263
+ const { store, engine } = this.controlPlane();
264
+ const parsed = (0, import_nestjs_durable_core.parseWebhookToken)(token);
265
+ if (!parsed) return null;
266
+ const run = await store.getRun(parsed.runId);
267
+ if (!run || import_nestjs_durable_core.TERMINAL_RUN_STATUSES.includes(run.status)) return null;
268
+ const resolved = await store.getCheckpoint(parsed.runId, parsed.seq);
269
+ if (resolved?.status === "completed") return null;
270
+ const delivered = await engine.signal(token, body);
271
+ if (delivered) return delivered;
272
+ const now = await store.getCheckpoint(parsed.runId, parsed.seq);
273
+ if (now?.status === "completed" && await store.takeBufferedSignal(token)) return null;
274
+ const fresh = await store.getRun(parsed.runId);
275
+ return {
276
+ runId: run.id,
277
+ status: fresh?.status ?? run.status
278
+ };
253
279
  }
254
280
  /** Side-effect-free read of a value a run published via `ctx.setEvent` (a live query). Control-plane-only. */
255
281
  async getEvent(runId, key) {
@@ -1311,7 +1337,7 @@ var DurableApiController = class {
1311
1337
  */
1312
1338
  async webhook(token, body) {
1313
1339
  const result = await this.dashboard.deliverWebhook(token, body);
1314
- if (!result) throw new import_common5.NotFoundException(`no run is waiting on webhook ${token}`);
1340
+ if (!result) throw new import_common5.NotFoundException(`no live run is waiting for webhook ${token}`);
1315
1341
  return result;
1316
1342
  }
1317
1343
  /** Live query: the latest value a run published for `key` via `ctx.setEvent` (no side effect). */
@@ -2484,13 +2510,8 @@ DurableAuthController = _ts_decorate9([
2484
2510
  ])
2485
2511
  ], DurableAuthController);
2486
2512
 
2487
- // src/server/durable-dashboard.module.ts
2488
- var import_reflect_metadata = require("reflect-metadata");
2489
- var import_nestjs_filter3 = require("@dudousxd/nestjs-filter");
2490
- var import_common11 = require("@nestjs/common");
2491
- var import_core = require("@nestjs/core");
2492
-
2493
- // src/server/durable-session.guard.ts
2513
+ // src/server/durable-dashboard-gate.guard.ts
2514
+ var import_node_crypto2 = require("crypto");
2494
2515
  var import_common10 = require("@nestjs/common");
2495
2516
  function _ts_decorate10(decorators, target, key, desc) {
2496
2517
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -2518,6 +2539,191 @@ function _ts_param6(paramIndex, decorator) {
2518
2539
  };
2519
2540
  }
2520
2541
  __name(_ts_param6, "_ts_param");
2542
+ var DURABLE_DASHBOARD_TOKEN_ENV = "DURABLE_DASHBOARD_TOKEN";
2543
+ var DASHBOARD_GATE = Symbol("DASHBOARD_GATE");
2544
+ var LOG_CONTEXT = "DurableDashboard";
2545
+ var HOW_TO_CONFIGURE = [
2546
+ "Configure one of: `guards: [YourAuthGuard]`, `dashboardAuth: { secret, session | login }`",
2547
+ "(or `useDashboardAuth` in forRootAsync), a bearer token via the `token` option or the",
2548
+ `${DURABLE_DASHBOARD_TOKEN_ENV} env var, or \`allowUnauthenticated: true\` when the console is`,
2549
+ "already protected outside this module (a global guard, a reverse proxy, a private network)."
2550
+ ].join(" ");
2551
+ function isProduction() {
2552
+ return (process.env.NODE_ENV ?? "").trim().toLowerCase() === "production";
2553
+ }
2554
+ __name(isProduction, "isProduction");
2555
+ function resolveDashboardGate(options, auth) {
2556
+ if (options.hasGuards || auth !== null) return {
2557
+ mode: "delegated"
2558
+ };
2559
+ const token = options.token ?? process.env[DURABLE_DASHBOARD_TOKEN_ENV];
2560
+ if (typeof token === "string" && token !== "") return {
2561
+ mode: "token",
2562
+ token
2563
+ };
2564
+ if (options.allowUnauthenticated === true) return {
2565
+ mode: "open"
2566
+ };
2567
+ return {
2568
+ mode: isProduction() ? "deny" : "unconfigured"
2569
+ };
2570
+ }
2571
+ __name(resolveDashboardGate, "resolveDashboardGate");
2572
+ function reportDashboardGate(gate, options, logger = new import_common10.Logger(LOG_CONTEXT)) {
2573
+ switch (gate.mode) {
2574
+ case "open":
2575
+ logger.warn("allowUnauthenticated: true. The durable console (including retry/cancel and other mutating endpoints) is served with NO authentication from this module. Only do this when a global guard or reverse proxy already protects it.");
2576
+ return;
2577
+ case "token":
2578
+ if (options.allowUnauthenticated === true) {
2579
+ logger.warn("allowUnauthenticated: true is ignored because a dashboard token is configured; requests must carry the token.");
2580
+ }
2581
+ return;
2582
+ case "unconfigured":
2583
+ logger.warn([
2584
+ "The durable console is UNAUTHENTICATED: no guards, dashboardAuth, token or",
2585
+ "allowUnauthenticated were configured. It is served open because NODE_ENV is not",
2586
+ '"production", but it WILL deny every request when NODE_ENV=production.',
2587
+ HOW_TO_CONFIGURE
2588
+ ].join(" "));
2589
+ return;
2590
+ case "deny":
2591
+ logger.error([
2592
+ "The durable console has no authentication configured and NODE_ENV=production, so it",
2593
+ "is failing closed: every console request (UI and API) is denied.",
2594
+ HOW_TO_CONFIGURE
2595
+ ].join(" "));
2596
+ return;
2597
+ case "delegated":
2598
+ return;
2599
+ }
2600
+ }
2601
+ __name(reportDashboardGate, "reportDashboardGate");
2602
+ function dashboardGateProvider(options) {
2603
+ return {
2604
+ provide: DASHBOARD_GATE,
2605
+ inject: [
2606
+ DASHBOARD_AUTH
2607
+ ],
2608
+ useFactory: /* @__PURE__ */ __name((auth) => {
2609
+ const gate = resolveDashboardGate(options, auth);
2610
+ reportDashboardGate(gate, options);
2611
+ return gate;
2612
+ }, "useFactory")
2613
+ };
2614
+ }
2615
+ __name(dashboardGateProvider, "dashboardGateProvider");
2616
+ function isRecord3(value) {
2617
+ return typeof value === "object" && value !== null;
2618
+ }
2619
+ __name(isRecord3, "isRecord");
2620
+ function headerValue(request, name) {
2621
+ const headers = request.headers;
2622
+ if (!isRecord3(headers)) return void 0;
2623
+ const value = headers[name];
2624
+ if (typeof value === "string") return value;
2625
+ if (Array.isArray(value) && typeof value[0] === "string") return value[0];
2626
+ return void 0;
2627
+ }
2628
+ __name(headerValue, "headerValue");
2629
+ function readDashboardToken(request) {
2630
+ if (!isRecord3(request)) return void 0;
2631
+ const authorization = headerValue(request, "authorization");
2632
+ if (authorization) {
2633
+ const match = /^Bearer\s+(.+)$/i.exec(authorization);
2634
+ if (match?.[1]) return match[1].trim();
2635
+ }
2636
+ const header = headerValue(request, "x-durable-token");
2637
+ if (header) return header.trim();
2638
+ const method = typeof request.method === "string" ? request.method.toUpperCase() : "";
2639
+ if (method === "GET" || method === "HEAD") {
2640
+ const query = request.query;
2641
+ if (isRecord3(query)) {
2642
+ const value = query.token;
2643
+ if (typeof value === "string" && value !== "") return value;
2644
+ }
2645
+ }
2646
+ return void 0;
2647
+ }
2648
+ __name(readDashboardToken, "readDashboardToken");
2649
+ function secretsMatch(provided, expected) {
2650
+ const a = Buffer.from(provided);
2651
+ const b = Buffer.from(expected);
2652
+ if (a.length !== b.length) return false;
2653
+ return (0, import_node_crypto2.timingSafeEqual)(a, b);
2654
+ }
2655
+ __name(secretsMatch, "secretsMatch");
2656
+ var DurableDashboardGateGuard = class {
2657
+ static {
2658
+ __name(this, "DurableDashboardGateGuard");
2659
+ }
2660
+ gate;
2661
+ constructor(gate) {
2662
+ this.gate = gate;
2663
+ }
2664
+ canActivate(context) {
2665
+ switch (this.gate.mode) {
2666
+ case "delegated":
2667
+ case "open":
2668
+ case "unconfigured":
2669
+ return true;
2670
+ case "deny":
2671
+ throw new import_common10.ForbiddenException([
2672
+ "Durable dashboard authentication is not configured, and NODE_ENV=production denies",
2673
+ "an unauthenticated console.",
2674
+ HOW_TO_CONFIGURE
2675
+ ].join(" "));
2676
+ case "token": {
2677
+ const provided = readDashboardToken(context.switchToHttp().getRequest());
2678
+ if (provided !== void 0 && secretsMatch(provided, this.gate.token ?? "")) return true;
2679
+ throw new import_common10.UnauthorizedException("A valid durable dashboard token is required (Authorization: Bearer <token>, x-durable-token, or ?token= on GET).");
2680
+ }
2681
+ }
2682
+ }
2683
+ };
2684
+ DurableDashboardGateGuard = _ts_decorate10([
2685
+ (0, import_common10.Injectable)(),
2686
+ _ts_param6(0, (0, import_common10.Inject)(DASHBOARD_GATE)),
2687
+ _ts_metadata8("design:type", Function),
2688
+ _ts_metadata8("design:paramtypes", [
2689
+ typeof DashboardGate === "undefined" ? Object : DashboardGate
2690
+ ])
2691
+ ], DurableDashboardGateGuard);
2692
+
2693
+ // src/server/durable-dashboard.module.ts
2694
+ var import_reflect_metadata = require("reflect-metadata");
2695
+ var import_nestjs_filter3 = require("@dudousxd/nestjs-filter");
2696
+ var import_common12 = require("@nestjs/common");
2697
+ var import_core = require("@nestjs/core");
2698
+
2699
+ // src/server/durable-session.guard.ts
2700
+ var import_common11 = require("@nestjs/common");
2701
+ function _ts_decorate11(decorators, target, key, desc) {
2702
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2703
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
2704
+ r = Reflect.decorate(decorators, target, key, desc);
2705
+ } else {
2706
+ for (var i = decorators.length - 1; i >= 0; i--) {
2707
+ if (d = decorators[i]) {
2708
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2709
+ }
2710
+ }
2711
+ }
2712
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2713
+ }
2714
+ __name(_ts_decorate11, "_ts_decorate");
2715
+ function _ts_metadata9(metadataKey, metadataValue) {
2716
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
2717
+ return Reflect.metadata(metadataKey, metadataValue);
2718
+ }
2719
+ }
2720
+ __name(_ts_metadata9, "_ts_metadata");
2721
+ function _ts_param7(paramIndex, decorator) {
2722
+ return function(target, key) {
2723
+ decorator(target, key, paramIndex);
2724
+ };
2725
+ }
2726
+ __name(_ts_param7, "_ts_param");
2521
2727
  var DurableUiSessionGuard = class {
2522
2728
  static {
2523
2729
  __name(this, "DurableUiSessionGuard");
@@ -2558,12 +2764,12 @@ var DurableUiSessionGuard = class {
2558
2764
  throw new DashboardLoginRedirectException(`${this.basePath}/login?returnTo=${returnTo}`);
2559
2765
  }
2560
2766
  };
2561
- DurableUiSessionGuard = _ts_decorate10([
2562
- (0, import_common10.Injectable)(),
2563
- _ts_param6(0, (0, import_common10.Inject)(DASHBOARD_AUTH)),
2564
- _ts_param6(1, (0, import_common10.Inject)(DASHBOARD_BASE_PATH)),
2565
- _ts_metadata8("design:type", Function),
2566
- _ts_metadata8("design:paramtypes", [
2767
+ DurableUiSessionGuard = _ts_decorate11([
2768
+ (0, import_common11.Injectable)(),
2769
+ _ts_param7(0, (0, import_common11.Inject)(DASHBOARD_AUTH)),
2770
+ _ts_param7(1, (0, import_common11.Inject)(DASHBOARD_BASE_PATH)),
2771
+ _ts_metadata9("design:type", Function),
2772
+ _ts_metadata9("design:paramtypes", [
2567
2773
  Object,
2568
2774
  String
2569
2775
  ])
@@ -2595,24 +2801,24 @@ var DurableApiSessionGuard = class {
2595
2801
  * 401; `DurableUiSessionGuard`'s redirect/session-required exceptions above don't reach it.
2596
2802
  */
2597
2803
  unauthorized(auth) {
2598
- return new import_common10.UnauthorizedException({
2804
+ return new import_common11.UnauthorizedException({
2599
2805
  auth: {
2600
2806
  modes: auth.modes
2601
2807
  }
2602
2808
  });
2603
2809
  }
2604
2810
  };
2605
- DurableApiSessionGuard = _ts_decorate10([
2606
- (0, import_common10.Injectable)(),
2607
- _ts_param6(0, (0, import_common10.Inject)(DASHBOARD_AUTH)),
2608
- _ts_metadata8("design:type", Function),
2609
- _ts_metadata8("design:paramtypes", [
2811
+ DurableApiSessionGuard = _ts_decorate11([
2812
+ (0, import_common11.Injectable)(),
2813
+ _ts_param7(0, (0, import_common11.Inject)(DASHBOARD_AUTH)),
2814
+ _ts_metadata9("design:type", Function),
2815
+ _ts_metadata9("design:paramtypes", [
2610
2816
  Object
2611
2817
  ])
2612
2818
  ], DurableApiSessionGuard);
2613
2819
 
2614
2820
  // src/server/durable-dashboard.module.ts
2615
- function _ts_decorate11(decorators, target, key, desc) {
2821
+ function _ts_decorate12(decorators, target, key, desc) {
2616
2822
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2617
2823
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
2618
2824
  r = Reflect.decorate(decorators, target, key, desc);
@@ -2625,7 +2831,7 @@ function _ts_decorate11(decorators, target, key, desc) {
2625
2831
  }
2626
2832
  return c > 3 && r && Object.defineProperty(target, key, r), r;
2627
2833
  }
2628
- __name(_ts_decorate11, "_ts_decorate");
2834
+ __name(_ts_decorate12, "_ts_decorate");
2629
2835
  var GUARDS_METADATA = "__guards__";
2630
2836
  function normalize(path) {
2631
2837
  return `/${path.replace(/^\/+|\/+$/g, "")}`;
@@ -2633,9 +2839,7 @@ function normalize(path) {
2633
2839
  __name(normalize, "normalize");
2634
2840
  function stampGuards(hostGuards, builtIn, controller) {
2635
2841
  const merged = [
2636
- ...builtIn ? [
2637
- builtIn
2638
- ] : [],
2842
+ ...builtIn.filter((guard) => guard !== void 0),
2639
2843
  ...hostGuards ?? []
2640
2844
  ];
2641
2845
  Reflect.defineMetadata(GUARDS_METADATA, merged, controller);
@@ -2646,7 +2850,10 @@ var DurableApiModule = class _DurableApiModule {
2646
2850
  __name(this, "DurableApiModule");
2647
2851
  }
2648
2852
  static register(options) {
2649
- stampGuards(options.guards, options.authMayBeConfigured ? DurableApiSessionGuard : void 0, DurableApiController);
2853
+ stampGuards(options.guards, [
2854
+ options.authMayBeConfigured ? DurableApiSessionGuard : void 0,
2855
+ options.stampGate ? DurableDashboardGateGuard : void 0
2856
+ ], DurableApiController);
2650
2857
  return {
2651
2858
  module: _DurableApiModule,
2652
2859
  imports: [
@@ -2690,16 +2897,21 @@ var DurableApiModule = class _DurableApiModule {
2690
2897
  RunFilter,
2691
2898
  options.authProvider,
2692
2899
  DurableApiSessionGuard,
2900
+ // Resolved ONCE here (this module is imported by the UI module, which reuses it via the
2901
+ // export below), so the boot report is logged once per mount.
2902
+ dashboardGateProvider(options.gate),
2903
+ DurableDashboardGateGuard,
2693
2904
  ...options.guards ?? []
2694
2905
  ],
2695
2906
  exports: [
2696
- DashboardService
2907
+ DashboardService,
2908
+ DASHBOARD_GATE
2697
2909
  ]
2698
2910
  };
2699
2911
  }
2700
2912
  };
2701
- DurableApiModule = _ts_decorate11([
2702
- (0, import_common11.Module)({})
2913
+ DurableApiModule = _ts_decorate12([
2914
+ (0, import_common12.Module)({})
2703
2915
  ], DurableApiModule);
2704
2916
  var DurableDashboardModule = class _DurableDashboardModule {
2705
2917
  static {
@@ -2710,7 +2922,8 @@ var DurableDashboardModule = class _DurableDashboardModule {
2710
2922
  provide: DASHBOARD_AUTH,
2711
2923
  useValue: resolveDashboardAuth(options.dashboardAuth)
2712
2924
  };
2713
- return _DurableDashboardModule.build(options, authProvider, options.dashboardAuth !== void 0);
2925
+ const authConfigured = options.dashboardAuth !== void 0;
2926
+ return _DurableDashboardModule.build(options, authProvider, authConfigured, authConfigured);
2714
2927
  }
2715
2928
  static forRootAsync(options) {
2716
2929
  const authProvider = {
@@ -2718,13 +2931,27 @@ var DurableDashboardModule = class _DurableDashboardModule {
2718
2931
  inject: options.inject ?? [],
2719
2932
  useFactory: /* @__PURE__ */ __name(async (...deps) => resolveDashboardAuth(await options.useDashboardAuth(...deps)), "useFactory")
2720
2933
  };
2721
- return _DurableDashboardModule.build(options, authProvider, true);
2934
+ return _DurableDashboardModule.build(options, authProvider, true, false);
2722
2935
  }
2723
2936
  /** Shared wiring: static routing + the API module, with `dashboardAuth` supplied by `authProvider`. */
2724
- static build(options, authProvider, authMayBeConfigured) {
2937
+ static build(options, authProvider, authMayBeConfigured, authStaticallyConfigured) {
2725
2938
  const basePath = normalize(options.basePath ?? "/durable");
2726
2939
  const apiBasePath = normalize(options.apiBasePath ?? `${basePath}/api`);
2727
- stampGuards(options.guards, authMayBeConfigured ? DurableUiSessionGuard : void 0, DurableUiController);
2940
+ const hasGuards = (options.guards?.length ?? 0) > 0;
2941
+ const gate = {
2942
+ hasGuards,
2943
+ ...options.allowUnauthenticated !== void 0 ? {
2944
+ allowUnauthenticated: options.allowUnauthenticated
2945
+ } : {},
2946
+ ...options.token !== void 0 ? {
2947
+ token: options.token
2948
+ } : {}
2949
+ };
2950
+ const stampGate = !hasGuards && !authStaticallyConfigured;
2951
+ stampGuards(options.guards, [
2952
+ authMayBeConfigured ? DurableUiSessionGuard : void 0,
2953
+ stampGate ? DurableDashboardGateGuard : void 0
2954
+ ], DurableUiController);
2728
2955
  return {
2729
2956
  module: _DurableDashboardModule,
2730
2957
  imports: [
@@ -2740,7 +2967,9 @@ var DurableDashboardModule = class _DurableDashboardModule {
2740
2967
  guards: options.guards
2741
2968
  } : {},
2742
2969
  authProvider,
2743
- authMayBeConfigured
2970
+ authMayBeConfigured,
2971
+ gate,
2972
+ stampGate
2744
2973
  }),
2745
2974
  import_core.RouterModule.register([
2746
2975
  {
@@ -2773,6 +3002,8 @@ var DurableDashboardModule = class _DurableDashboardModule {
2773
3002
  },
2774
3003
  authProvider,
2775
3004
  DurableUiSessionGuard,
3005
+ // `DASHBOARD_GATE` itself comes from the imported DurableApiModule (resolved once there).
3006
+ DurableDashboardGateGuard,
2776
3007
  // DurableUiController (and DurableAuthController, when present) are hosted HERE, so their
2777
3008
  // guards DI-instantiate from this module.
2778
3009
  ...options.guards ?? []
@@ -2784,20 +3015,27 @@ var DurableDashboardModule = class _DurableDashboardModule {
2784
3015
  };
2785
3016
  }
2786
3017
  };
2787
- DurableDashboardModule = _ts_decorate11([
2788
- (0, import_common11.Module)({})
3018
+ DurableDashboardModule = _ts_decorate12([
3019
+ (0, import_common12.Module)({})
2789
3020
  ], DurableDashboardModule);
2790
3021
  // Annotate the CommonJS export names for ESM import in node:
2791
3022
  0 && (module.exports = {
2792
3023
  DASHBOARD_API_PATH,
2793
3024
  DASHBOARD_BASE_PATH,
3025
+ DASHBOARD_GATE,
3026
+ DURABLE_DASHBOARD_TOKEN_ENV,
2794
3027
  DashboardService,
2795
3028
  DurableApiController,
2796
3029
  DurableApiModule,
2797
3030
  DurableApiSessionGuard,
2798
3031
  DurableAuthController,
3032
+ DurableDashboardGateGuard,
2799
3033
  DurableDashboardModule,
2800
3034
  DurableUiController,
2801
- DurableUiSessionGuard
3035
+ DurableUiSessionGuard,
3036
+ dashboardGateProvider,
3037
+ readDashboardToken,
3038
+ reportDashboardGate,
3039
+ resolveDashboardGate
2802
3040
  });
2803
3041
  //# sourceMappingURL=index.cjs.map