@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.
- package/dist/server/index.cjs +256 -37
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +106 -9
- package/dist/server/index.d.ts +106 -9
- package/dist/server/index.js +246 -34
- package/dist/server/index.js.map +1 -1
- package/package.json +2 -2
package/dist/server/index.d.cts
CHANGED
|
@@ -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 {
|
|
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.
|
|
436
|
-
*
|
|
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.
|
|
498
|
-
* the console
|
|
499
|
-
*
|
|
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`
|
|
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`
|
|
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 };
|
package/dist/server/index.d.ts
CHANGED
|
@@ -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 {
|
|
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.
|
|
436
|
-
*
|
|
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.
|
|
498
|
-
* the console
|
|
499
|
-
*
|
|
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`
|
|
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`
|
|
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 };
|