@dudousxd/nestjs-agent-dashboard 0.10.1 → 0.12.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/README.md +24 -0
- package/dist/client/agent-client.d.ts +1 -0
- package/dist/client/agent-client.d.ts.map +1 -1
- package/dist/client/agent-client.js +4 -0
- package/dist/client/agent-client.js.map +1 -1
- package/dist/client/console-session.d.ts +63 -0
- package/dist/client/console-session.d.ts.map +1 -0
- package/dist/client/console-session.js +107 -0
- package/dist/client/console-session.js.map +1 -0
- package/dist/server/index.cjs +60 -10
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +49 -2
- package/dist/server/index.d.ts +49 -2
- package/dist/server/index.js +60 -10
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/server/index.d.cts
CHANGED
|
@@ -214,6 +214,44 @@ type LoginHook = (username: string, password: string) => Promise<DashboardSessio
|
|
|
214
214
|
* receives the already-minted session.
|
|
215
215
|
*/
|
|
216
216
|
type RevalidateHook = (session: DashboardSessionUser) => Promise<boolean> | boolean;
|
|
217
|
+
/** What `unauthenticatedPage` receives. An object (not positional args) so fields can be added later. */
|
|
218
|
+
interface UnauthenticatedPageContext {
|
|
219
|
+
/**
|
|
220
|
+
* The platform-native request — Express' `Request`, Fastify's `FastifyRequest`. Typed `unknown`
|
|
221
|
+
* for the same reason `SessionHook`'s is: this package refuses to depend on either platform.
|
|
222
|
+
* Cast it to whatever your app actually runs on.
|
|
223
|
+
*/
|
|
224
|
+
request: unknown;
|
|
225
|
+
/**
|
|
226
|
+
* The platform-native response. The hook OWNS it: it must write AND end it (`res.render(...)`,
|
|
227
|
+
* `res.status(401).send(...)`, an Inertia render, ...). If the hook returns without writing, the
|
|
228
|
+
* library falls back to its own built-in page rather than leaving the request hanging.
|
|
229
|
+
*/
|
|
230
|
+
response: unknown;
|
|
231
|
+
/** Where this console is mounted (e.g. `/ai-gateway`) — useful for a "back to the console" link. */
|
|
232
|
+
basePath: string;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Host-owned page for an unauthenticated navigation to the console.
|
|
236
|
+
*
|
|
237
|
+
* The built-in page cannot know who hosts the console, so it can only say "open this console from
|
|
238
|
+
* your application" in the abstract — it can't name the launcher, link to it, or look like the rest
|
|
239
|
+
* of the host's product. This hook hands the whole response to the host instead: render through
|
|
240
|
+
* your own template engine, your own Inertia page, whatever.
|
|
241
|
+
*
|
|
242
|
+
* Served at `<basePath>/auth/session-required`, which is where `DashboardAuthPageGuard` already
|
|
243
|
+
* redirects a denied Mode-A navigation today — this hook changes what that page CONTAINS, not the
|
|
244
|
+
* flow that reaches it.
|
|
245
|
+
*
|
|
246
|
+
* Deliberately NOT a replacement for Mode B's built-in login form. A host that wants its own login
|
|
247
|
+
* UI uses Mode A plus this hook, and posts to `<basePath>/auth/session` from its own page — the
|
|
248
|
+
* mint endpoint is the supported primitive for that.
|
|
249
|
+
*
|
|
250
|
+
* Fail-closed by construction: it only ever runs on a request that has ALREADY been denied. A hook
|
|
251
|
+
* that throws, or that returns without writing, falls back to the built-in page — it cannot let
|
|
252
|
+
* anyone in.
|
|
253
|
+
*/
|
|
254
|
+
type UnauthenticatedPageHook = (context: UnauthenticatedPageContext) => void | Promise<void>;
|
|
217
255
|
/** Which `dashboardAuth` hook(s) a resolved config was given — see `resolveDashboardAuth`. */
|
|
218
256
|
type AuthMode = 'session' | 'login';
|
|
219
257
|
/**
|
|
@@ -245,6 +283,9 @@ interface DashboardAuthOptions {
|
|
|
245
283
|
/** Re-checks a live session on sliding renewal; see `RevalidateHook`. Not a mode — it cannot
|
|
246
284
|
* mint a session, only revoke one already minted by `session`/`login`. */
|
|
247
285
|
revalidate?: RevalidateHook;
|
|
286
|
+
/** Renders the host's own page for an unauthenticated navigation, in place of the built-in
|
|
287
|
+
* "open this console from your application" card; see `UnauthenticatedPageHook`. */
|
|
288
|
+
unauthenticatedPage?: UnauthenticatedPageHook;
|
|
248
289
|
}
|
|
249
290
|
/** Resolved, validated `dashboardAuth` config used by the guards/controller. */
|
|
250
291
|
interface ResolvedDashboardAuth {
|
|
@@ -254,6 +295,7 @@ interface ResolvedDashboardAuth {
|
|
|
254
295
|
session?: SessionHook;
|
|
255
296
|
login?: LoginHook;
|
|
256
297
|
revalidate?: RevalidateHook;
|
|
298
|
+
unauthenticatedPage?: UnauthenticatedPageHook;
|
|
257
299
|
}
|
|
258
300
|
/**
|
|
259
301
|
* Validate + resolve `dashboardAuth`. Returns `null` when unconfigured (behavior unchanged — the
|
|
@@ -306,7 +348,7 @@ declare class AgentDashboardAuthController {
|
|
|
306
348
|
login(body: LoginFormBody, req: unknown, res: AuthPageResponse): Promise<string>;
|
|
307
349
|
logout(req: unknown, res: AuthPageResponse): string;
|
|
308
350
|
session(request: unknown, response: unknown): Promise<void>;
|
|
309
|
-
sessionRequiredPage():
|
|
351
|
+
sessionRequiredPage(req: AuthPageRequest, res: unknown): Promise<void>;
|
|
310
352
|
/** Uniform failure: same redirect (generic error flag) whether the user is unknown or the password is wrong. */
|
|
311
353
|
private redirectToLoginError;
|
|
312
354
|
private currentSession;
|
|
@@ -316,6 +358,11 @@ declare class AgentDashboardAuthController {
|
|
|
316
358
|
* endpoint into a stack-trace leak nor floods the logs on repeated bad attempts.
|
|
317
359
|
*/
|
|
318
360
|
private runHook;
|
|
361
|
+
/**
|
|
362
|
+
* Warn once per hook kind for the life of the process, not once per request: a broken hook fires
|
|
363
|
+
* on every denied navigation and would otherwise flood the logs.
|
|
364
|
+
*/
|
|
365
|
+
private warnHookOnce;
|
|
319
366
|
private requireAuth;
|
|
320
367
|
}
|
|
321
368
|
|
|
@@ -589,4 +636,4 @@ declare const DASHBOARD_APPROVAL_ACTOR_REF: unique symbol;
|
|
|
589
636
|
*/
|
|
590
637
|
declare const DASHBOARD_AUTH: unique symbol;
|
|
591
638
|
|
|
592
|
-
export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_GOVERNANCE_QUERIES, AGENT_PRICING_STORE, type ActorSpendRowWithLabel, AgentApiController, AgentApiModule, type AgentDashboardAsyncOptions, AgentDashboardAuthController, AgentDashboardModule, type AgentDashboardMountPathsOptions, type AgentDashboardOptions, AgentUiController, type AuthMode, DASHBOARD_API_PATH, DASHBOARD_APPROVAL_ACTOR_REF, DASHBOARD_AUTH, DASHBOARD_BASE_PATH, type DashboardAuthOptions, DashboardService, type LiveAgentEvent, type LoginHook, type ReliabilityOverview, type ResolvedDashboardAuth, type RevalidateHook, type SessionHook, type SpendOverview, type ThreadActivityRowWithLabel, type ThreadSpendRowWithLabel, type WithActorLabel, agentDashboardMountPaths, parsePriceInput, resolveDashboardAuth };
|
|
639
|
+
export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_GOVERNANCE_QUERIES, AGENT_PRICING_STORE, type ActorSpendRowWithLabel, AgentApiController, AgentApiModule, type AgentDashboardAsyncOptions, AgentDashboardAuthController, AgentDashboardModule, type AgentDashboardMountPathsOptions, type AgentDashboardOptions, AgentUiController, type AuthMode, DASHBOARD_API_PATH, DASHBOARD_APPROVAL_ACTOR_REF, DASHBOARD_AUTH, DASHBOARD_BASE_PATH, type DashboardAuthOptions, DashboardService, type LiveAgentEvent, type LoginHook, type ReliabilityOverview, type ResolvedDashboardAuth, type RevalidateHook, type SessionHook, type SpendOverview, type ThreadActivityRowWithLabel, type ThreadSpendRowWithLabel, type UnauthenticatedPageContext, type UnauthenticatedPageHook, type WithActorLabel, agentDashboardMountPaths, parsePriceInput, resolveDashboardAuth };
|
package/dist/server/index.d.ts
CHANGED
|
@@ -214,6 +214,44 @@ type LoginHook = (username: string, password: string) => Promise<DashboardSessio
|
|
|
214
214
|
* receives the already-minted session.
|
|
215
215
|
*/
|
|
216
216
|
type RevalidateHook = (session: DashboardSessionUser) => Promise<boolean> | boolean;
|
|
217
|
+
/** What `unauthenticatedPage` receives. An object (not positional args) so fields can be added later. */
|
|
218
|
+
interface UnauthenticatedPageContext {
|
|
219
|
+
/**
|
|
220
|
+
* The platform-native request — Express' `Request`, Fastify's `FastifyRequest`. Typed `unknown`
|
|
221
|
+
* for the same reason `SessionHook`'s is: this package refuses to depend on either platform.
|
|
222
|
+
* Cast it to whatever your app actually runs on.
|
|
223
|
+
*/
|
|
224
|
+
request: unknown;
|
|
225
|
+
/**
|
|
226
|
+
* The platform-native response. The hook OWNS it: it must write AND end it (`res.render(...)`,
|
|
227
|
+
* `res.status(401).send(...)`, an Inertia render, ...). If the hook returns without writing, the
|
|
228
|
+
* library falls back to its own built-in page rather than leaving the request hanging.
|
|
229
|
+
*/
|
|
230
|
+
response: unknown;
|
|
231
|
+
/** Where this console is mounted (e.g. `/ai-gateway`) — useful for a "back to the console" link. */
|
|
232
|
+
basePath: string;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Host-owned page for an unauthenticated navigation to the console.
|
|
236
|
+
*
|
|
237
|
+
* The built-in page cannot know who hosts the console, so it can only say "open this console from
|
|
238
|
+
* your application" in the abstract — it can't name the launcher, link to it, or look like the rest
|
|
239
|
+
* of the host's product. This hook hands the whole response to the host instead: render through
|
|
240
|
+
* your own template engine, your own Inertia page, whatever.
|
|
241
|
+
*
|
|
242
|
+
* Served at `<basePath>/auth/session-required`, which is where `DashboardAuthPageGuard` already
|
|
243
|
+
* redirects a denied Mode-A navigation today — this hook changes what that page CONTAINS, not the
|
|
244
|
+
* flow that reaches it.
|
|
245
|
+
*
|
|
246
|
+
* Deliberately NOT a replacement for Mode B's built-in login form. A host that wants its own login
|
|
247
|
+
* UI uses Mode A plus this hook, and posts to `<basePath>/auth/session` from its own page — the
|
|
248
|
+
* mint endpoint is the supported primitive for that.
|
|
249
|
+
*
|
|
250
|
+
* Fail-closed by construction: it only ever runs on a request that has ALREADY been denied. A hook
|
|
251
|
+
* that throws, or that returns without writing, falls back to the built-in page — it cannot let
|
|
252
|
+
* anyone in.
|
|
253
|
+
*/
|
|
254
|
+
type UnauthenticatedPageHook = (context: UnauthenticatedPageContext) => void | Promise<void>;
|
|
217
255
|
/** Which `dashboardAuth` hook(s) a resolved config was given — see `resolveDashboardAuth`. */
|
|
218
256
|
type AuthMode = 'session' | 'login';
|
|
219
257
|
/**
|
|
@@ -245,6 +283,9 @@ interface DashboardAuthOptions {
|
|
|
245
283
|
/** Re-checks a live session on sliding renewal; see `RevalidateHook`. Not a mode — it cannot
|
|
246
284
|
* mint a session, only revoke one already minted by `session`/`login`. */
|
|
247
285
|
revalidate?: RevalidateHook;
|
|
286
|
+
/** Renders the host's own page for an unauthenticated navigation, in place of the built-in
|
|
287
|
+
* "open this console from your application" card; see `UnauthenticatedPageHook`. */
|
|
288
|
+
unauthenticatedPage?: UnauthenticatedPageHook;
|
|
248
289
|
}
|
|
249
290
|
/** Resolved, validated `dashboardAuth` config used by the guards/controller. */
|
|
250
291
|
interface ResolvedDashboardAuth {
|
|
@@ -254,6 +295,7 @@ interface ResolvedDashboardAuth {
|
|
|
254
295
|
session?: SessionHook;
|
|
255
296
|
login?: LoginHook;
|
|
256
297
|
revalidate?: RevalidateHook;
|
|
298
|
+
unauthenticatedPage?: UnauthenticatedPageHook;
|
|
257
299
|
}
|
|
258
300
|
/**
|
|
259
301
|
* Validate + resolve `dashboardAuth`. Returns `null` when unconfigured (behavior unchanged — the
|
|
@@ -306,7 +348,7 @@ declare class AgentDashboardAuthController {
|
|
|
306
348
|
login(body: LoginFormBody, req: unknown, res: AuthPageResponse): Promise<string>;
|
|
307
349
|
logout(req: unknown, res: AuthPageResponse): string;
|
|
308
350
|
session(request: unknown, response: unknown): Promise<void>;
|
|
309
|
-
sessionRequiredPage():
|
|
351
|
+
sessionRequiredPage(req: AuthPageRequest, res: unknown): Promise<void>;
|
|
310
352
|
/** Uniform failure: same redirect (generic error flag) whether the user is unknown or the password is wrong. */
|
|
311
353
|
private redirectToLoginError;
|
|
312
354
|
private currentSession;
|
|
@@ -316,6 +358,11 @@ declare class AgentDashboardAuthController {
|
|
|
316
358
|
* endpoint into a stack-trace leak nor floods the logs on repeated bad attempts.
|
|
317
359
|
*/
|
|
318
360
|
private runHook;
|
|
361
|
+
/**
|
|
362
|
+
* Warn once per hook kind for the life of the process, not once per request: a broken hook fires
|
|
363
|
+
* on every denied navigation and would otherwise flood the logs.
|
|
364
|
+
*/
|
|
365
|
+
private warnHookOnce;
|
|
319
366
|
private requireAuth;
|
|
320
367
|
}
|
|
321
368
|
|
|
@@ -589,4 +636,4 @@ declare const DASHBOARD_APPROVAL_ACTOR_REF: unique symbol;
|
|
|
589
636
|
*/
|
|
590
637
|
declare const DASHBOARD_AUTH: unique symbol;
|
|
591
638
|
|
|
592
|
-
export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_GOVERNANCE_QUERIES, AGENT_PRICING_STORE, type ActorSpendRowWithLabel, AgentApiController, AgentApiModule, type AgentDashboardAsyncOptions, AgentDashboardAuthController, AgentDashboardModule, type AgentDashboardMountPathsOptions, type AgentDashboardOptions, AgentUiController, type AuthMode, DASHBOARD_API_PATH, DASHBOARD_APPROVAL_ACTOR_REF, DASHBOARD_AUTH, DASHBOARD_BASE_PATH, type DashboardAuthOptions, DashboardService, type LiveAgentEvent, type LoginHook, type ReliabilityOverview, type ResolvedDashboardAuth, type RevalidateHook, type SessionHook, type SpendOverview, type ThreadActivityRowWithLabel, type ThreadSpendRowWithLabel, type WithActorLabel, agentDashboardMountPaths, parsePriceInput, resolveDashboardAuth };
|
|
639
|
+
export { AGENT_ACTOR_DIRECTORY, AGENT_ACTOR_RESOLVER, AGENT_APPROVAL_PORT, AGENT_GOVERNANCE_QUERIES, AGENT_PRICING_STORE, type ActorSpendRowWithLabel, AgentApiController, AgentApiModule, type AgentDashboardAsyncOptions, AgentDashboardAuthController, AgentDashboardModule, type AgentDashboardMountPathsOptions, type AgentDashboardOptions, AgentUiController, type AuthMode, DASHBOARD_API_PATH, DASHBOARD_APPROVAL_ACTOR_REF, DASHBOARD_AUTH, DASHBOARD_BASE_PATH, type DashboardAuthOptions, DashboardService, type LiveAgentEvent, type LoginHook, type ReliabilityOverview, type ResolvedDashboardAuth, type RevalidateHook, type SessionHook, type SpendOverview, type ThreadActivityRowWithLabel, type ThreadSpendRowWithLabel, type UnauthenticatedPageContext, type UnauthenticatedPageHook, type WithActorLabel, agentDashboardMountPaths, parsePriceInput, resolveDashboardAuth };
|
package/dist/server/index.js
CHANGED
|
@@ -147,6 +147,20 @@ function resolveRawResponse(response) {
|
|
|
147
147
|
return null;
|
|
148
148
|
}
|
|
149
149
|
__name(resolveRawResponse, "resolveRawResponse");
|
|
150
|
+
function responseAlreadyWritten(response) {
|
|
151
|
+
const raw = resolveRawResponse(response);
|
|
152
|
+
return raw?.headersSent === true;
|
|
153
|
+
}
|
|
154
|
+
__name(responseAlreadyWritten, "responseAlreadyWritten");
|
|
155
|
+
function sendHtml(response, status, html) {
|
|
156
|
+
const raw = resolveRawResponse(response);
|
|
157
|
+
if (!raw) return;
|
|
158
|
+
raw.statusCode = status;
|
|
159
|
+
raw.setHeader("content-type", "text/html; charset=utf-8");
|
|
160
|
+
raw.setHeader("cache-control", "no-store, must-revalidate");
|
|
161
|
+
raw.end(html);
|
|
162
|
+
}
|
|
163
|
+
__name(sendHtml, "sendHtml");
|
|
150
164
|
function sendRedirect(response, status, location) {
|
|
151
165
|
const raw = resolveRawResponse(response);
|
|
152
166
|
if (!raw) return;
|
|
@@ -1384,10 +1398,31 @@ var AgentDashboardAuthController = class _AgentDashboardAuthController {
|
|
|
1384
1398
|
// Mode-A-only landing: the host mints the session, so there is nothing to submit here. Serves
|
|
1385
1399
|
// as the redirect target `DashboardAuthPageGuard` bounces to instead of `/auth/login`, which
|
|
1386
1400
|
// 404s under Mode A (see `loginPage` above).
|
|
1387
|
-
|
|
1401
|
+
//
|
|
1402
|
+
// Non-passthrough `@Res()` (unlike its sibling routes) because `dashboardAuth.unauthenticatedPage`
|
|
1403
|
+
// hands the response to the HOST, which writes and ends it itself — there is no return value for
|
|
1404
|
+
// Nest to send, and letting Nest also send one would double-write. The `Content-Type` /
|
|
1405
|
+
// `Cache-Control` this route used to carry as decorators move into `sendHtml` for the built-in
|
|
1406
|
+
// path; the host owns its own headers on the hook path.
|
|
1407
|
+
async sessionRequiredPage(req, res) {
|
|
1388
1408
|
const auth = this.requireAuth();
|
|
1389
1409
|
if (auth.modes.includes("login")) throw new NotFoundException();
|
|
1390
|
-
|
|
1410
|
+
const hook = auth.unauthenticatedPage;
|
|
1411
|
+
if (hook) {
|
|
1412
|
+
try {
|
|
1413
|
+
await hook({
|
|
1414
|
+
request: req,
|
|
1415
|
+
response: res,
|
|
1416
|
+
basePath: this.basePath
|
|
1417
|
+
});
|
|
1418
|
+
if (responseAlreadyWritten(res)) return;
|
|
1419
|
+
this.warnHookOnce("unauthenticatedPage", "dashboardAuth.unauthenticatedPage returned without writing a response; falling back to the built-in page. The hook must write AND end the response it is given.");
|
|
1420
|
+
} catch (error) {
|
|
1421
|
+
this.warnHookOnce("unauthenticatedPage", `dashboardAuth.unauthenticatedPage threw; falling back to the built-in page. ${String(error)}`);
|
|
1422
|
+
if (responseAlreadyWritten(res)) return;
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
sendHtml(res, 200, renderSessionRequiredPage());
|
|
1391
1426
|
}
|
|
1392
1427
|
/** Uniform failure: same redirect (generic error flag) whether the user is unknown or the password is wrong. */
|
|
1393
1428
|
redirectToLoginError(res, returnTo) {
|
|
@@ -1412,13 +1447,19 @@ var AgentDashboardAuthController = class _AgentDashboardAuthController {
|
|
|
1412
1447
|
try {
|
|
1413
1448
|
return await run() ?? null;
|
|
1414
1449
|
} catch (error) {
|
|
1415
|
-
|
|
1416
|
-
this.warnedHooks.add(kind);
|
|
1417
|
-
this.logger.warn(`AgentDashboardModule dashboardAuth ${kind} hook threw; treating as denial. ${error instanceof Error ? error.message : String(error)}`);
|
|
1418
|
-
}
|
|
1450
|
+
this.warnHookOnce(kind, `AgentDashboardModule dashboardAuth ${kind} hook threw; treating as denial. ${error instanceof Error ? error.message : String(error)}`);
|
|
1419
1451
|
return null;
|
|
1420
1452
|
}
|
|
1421
1453
|
}
|
|
1454
|
+
/**
|
|
1455
|
+
* Warn once per hook kind for the life of the process, not once per request: a broken hook fires
|
|
1456
|
+
* on every denied navigation and would otherwise flood the logs.
|
|
1457
|
+
*/
|
|
1458
|
+
warnHookOnce(kind, message) {
|
|
1459
|
+
if (this.warnedHooks.has(kind)) return;
|
|
1460
|
+
this.warnedHooks.add(kind);
|
|
1461
|
+
this.logger.warn(message);
|
|
1462
|
+
}
|
|
1422
1463
|
requireAuth() {
|
|
1423
1464
|
if (!this.auth) throw new NotFoundException();
|
|
1424
1465
|
return this.auth;
|
|
@@ -1487,11 +1528,14 @@ _ts_decorate4([
|
|
|
1487
1528
|
], AgentDashboardAuthController.prototype, "session", null);
|
|
1488
1529
|
_ts_decorate4([
|
|
1489
1530
|
Get2("session-required"),
|
|
1490
|
-
|
|
1491
|
-
|
|
1531
|
+
_ts_param4(0, Req2()),
|
|
1532
|
+
_ts_param4(1, Res()),
|
|
1492
1533
|
_ts_metadata4("design:type", Function),
|
|
1493
|
-
_ts_metadata4("design:paramtypes", [
|
|
1494
|
-
|
|
1534
|
+
_ts_metadata4("design:paramtypes", [
|
|
1535
|
+
typeof AuthPageRequest === "undefined" ? Object : AuthPageRequest,
|
|
1536
|
+
Object
|
|
1537
|
+
]),
|
|
1538
|
+
_ts_metadata4("design:returntype", Promise)
|
|
1495
1539
|
], AgentDashboardAuthController.prototype, "sessionRequiredPage", null);
|
|
1496
1540
|
AgentDashboardAuthController = _ts_decorate4([
|
|
1497
1541
|
Controller2("auth"),
|
|
@@ -1821,6 +1865,9 @@ function resolveDashboardAuth(options) {
|
|
|
1821
1865
|
if (options.revalidate !== void 0 && typeof options.revalidate !== "function") {
|
|
1822
1866
|
throw new Error("AgentDashboardModule dashboardAuth: `revalidate` must be a function.");
|
|
1823
1867
|
}
|
|
1868
|
+
if (options.unauthenticatedPage !== void 0 && typeof options.unauthenticatedPage !== "function") {
|
|
1869
|
+
throw new Error("AgentDashboardModule dashboardAuth: `unauthenticatedPage` must be a function.");
|
|
1870
|
+
}
|
|
1824
1871
|
if (modes.length === 0) {
|
|
1825
1872
|
throw new Error("AgentDashboardModule dashboardAuth: at least one of `session` (the host mints the session from its own auth) or `login` (the built-in login screen) is required \u2014 otherwise the cookie can never be minted. Failing closed.");
|
|
1826
1873
|
}
|
|
@@ -1836,6 +1883,9 @@ function resolveDashboardAuth(options) {
|
|
|
1836
1883
|
} : {},
|
|
1837
1884
|
...options.revalidate !== void 0 ? {
|
|
1838
1885
|
revalidate: options.revalidate
|
|
1886
|
+
} : {},
|
|
1887
|
+
...options.unauthenticatedPage !== void 0 ? {
|
|
1888
|
+
unauthenticatedPage: options.unauthenticatedPage
|
|
1839
1889
|
} : {}
|
|
1840
1890
|
};
|
|
1841
1891
|
}
|