@dudousxd/nestjs-agent-dashboard 0.9.1 → 0.10.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 +41 -5
- package/dist/server/index.cjs +176 -78
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +94 -37
- package/dist/server/index.d.ts +94 -37
- package/dist/server/index.js +177 -79
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -261,6 +261,39 @@ function clearSessionCookie(context) {
|
|
|
261
261
|
appendSetCookie(context.response, cookie);
|
|
262
262
|
}
|
|
263
263
|
__name(clearSessionCookie, "clearSessionCookie");
|
|
264
|
+
async function maybeRenewSession(auth, session, request, response, now = Date.now()) {
|
|
265
|
+
if (now - session.iat <= auth.ttlMs / 2) return true;
|
|
266
|
+
const user = {
|
|
267
|
+
id: session.sub,
|
|
268
|
+
...session.name !== void 0 ? {
|
|
269
|
+
name: session.name
|
|
270
|
+
} : {},
|
|
271
|
+
roles: session.roles
|
|
272
|
+
};
|
|
273
|
+
if (auth.revalidate) {
|
|
274
|
+
let allowed;
|
|
275
|
+
try {
|
|
276
|
+
allowed = await auth.revalidate(user);
|
|
277
|
+
} catch {
|
|
278
|
+
allowed = false;
|
|
279
|
+
}
|
|
280
|
+
if (!allowed) {
|
|
281
|
+
clearSessionCookie({
|
|
282
|
+
request,
|
|
283
|
+
response
|
|
284
|
+
});
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
issueSessionCookie(user, {
|
|
289
|
+
auth,
|
|
290
|
+
request,
|
|
291
|
+
response,
|
|
292
|
+
now
|
|
293
|
+
});
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
__name(maybeRenewSession, "maybeRenewSession");
|
|
264
297
|
|
|
265
298
|
// src/server/auth/dashboard-auth.guard.ts
|
|
266
299
|
function _ts_decorate(decorators, target, key, desc) {
|
|
@@ -288,14 +321,16 @@ var DashboardAuthGuard = class {
|
|
|
288
321
|
constructor(auth) {
|
|
289
322
|
this.auth = auth;
|
|
290
323
|
}
|
|
291
|
-
canActivate(context) {
|
|
324
|
+
async canActivate(context) {
|
|
292
325
|
if (!this.auth) return true;
|
|
293
326
|
const http = context.switchToHttp();
|
|
294
327
|
const request = http.getRequest();
|
|
295
328
|
const session = this.verifyRequestSession(request);
|
|
296
329
|
if (!session) throw new UnauthorizedException();
|
|
297
330
|
attachSession(request, session);
|
|
298
|
-
this.
|
|
331
|
+
if (!await maybeRenewSession(this.auth, session, request, http.getResponse())) {
|
|
332
|
+
throw new UnauthorizedException();
|
|
333
|
+
}
|
|
299
334
|
return true;
|
|
300
335
|
}
|
|
301
336
|
verifyRequestSession(request) {
|
|
@@ -307,28 +342,6 @@ var DashboardAuthGuard = class {
|
|
|
307
342
|
secret: auth.secret
|
|
308
343
|
});
|
|
309
344
|
}
|
|
310
|
-
/**
|
|
311
|
-
* Sliding renewal: a valid cookie past 50% of its TTL is transparently re-issued on the
|
|
312
|
-
* response, so an active user never gets logged out mid-session.
|
|
313
|
-
*/
|
|
314
|
-
maybeRenew(response, request, session) {
|
|
315
|
-
const auth = this.auth;
|
|
316
|
-
if (!auth) return;
|
|
317
|
-
const now = Date.now();
|
|
318
|
-
if (now - session.iat <= auth.ttlMs / 2) return;
|
|
319
|
-
issueSessionCookie({
|
|
320
|
-
id: session.sub,
|
|
321
|
-
...session.name !== void 0 ? {
|
|
322
|
-
name: session.name
|
|
323
|
-
} : {},
|
|
324
|
-
roles: session.roles
|
|
325
|
-
}, {
|
|
326
|
-
auth,
|
|
327
|
-
request,
|
|
328
|
-
response,
|
|
329
|
-
now
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
345
|
};
|
|
333
346
|
DashboardAuthGuard = _ts_decorate([
|
|
334
347
|
Injectable(),
|
|
@@ -1117,24 +1130,21 @@ AgentApiController = _ts_decorate3([
|
|
|
1117
1130
|
], AgentApiController);
|
|
1118
1131
|
|
|
1119
1132
|
// src/server/agent-dashboard-auth.controller.ts
|
|
1120
|
-
import { Body as Body2, Controller as Controller2, Get as Get2, Header, Inject as Inject4, Logger, NotFoundException, Optional as Optional4, Post as Post2, Query as Query2, Req as Req2, Res } from "@nestjs/common";
|
|
1133
|
+
import { Body as Body2, Controller as Controller2, Get as Get2, Header, HttpCode as HttpCode2, Inject as Inject4, Logger, NotFoundException, Optional as Optional4, Post as Post2, Query as Query2, Req as Req2, Res, UnauthorizedException as UnauthorizedException2 } from "@nestjs/common";
|
|
1121
1134
|
|
|
1122
1135
|
// src/server/auth/login-page.ts
|
|
1123
1136
|
function escapeHtml(value) {
|
|
1124
1137
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1125
1138
|
}
|
|
1126
1139
|
__name(escapeHtml, "escapeHtml");
|
|
1127
|
-
function
|
|
1128
|
-
const action = escapeHtml(options.actionUrl);
|
|
1129
|
-
const returnTo = escapeHtml(options.returnTo);
|
|
1130
|
-
const errorBanner = options.error === true ? '<p role="alert" class="error">Invalid username or password.</p>' : "";
|
|
1140
|
+
function pageShell(content, title) {
|
|
1131
1141
|
return `<!doctype html>
|
|
1132
1142
|
<html lang="en">
|
|
1133
1143
|
<head>
|
|
1134
1144
|
<meta charset="utf-8" />
|
|
1135
1145
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
1136
1146
|
<meta name="robots" content="noindex, nofollow" />
|
|
1137
|
-
<title
|
|
1147
|
+
<title>${title}</title>
|
|
1138
1148
|
<style>
|
|
1139
1149
|
:root { color-scheme: dark; }
|
|
1140
1150
|
* { box-sizing: border-box; }
|
|
@@ -1165,6 +1175,13 @@ function renderLoginPage(options) {
|
|
|
1165
1175
|
font-weight: 600;
|
|
1166
1176
|
color: #34d399;
|
|
1167
1177
|
}
|
|
1178
|
+
h1 {
|
|
1179
|
+
margin: 0 0 12px;
|
|
1180
|
+
font-size: 16px;
|
|
1181
|
+
font-weight: 600;
|
|
1182
|
+
color: #f4f4f5;
|
|
1183
|
+
}
|
|
1184
|
+
p { margin: 0 0 16px; color: #a1a1aa; }
|
|
1168
1185
|
form { display: flex; flex-direction: column; gap: 16px; }
|
|
1169
1186
|
label { display: flex; flex-direction: column; gap: 6px; }
|
|
1170
1187
|
.field-label {
|
|
@@ -1203,7 +1220,17 @@ function renderLoginPage(options) {
|
|
|
1203
1220
|
</head>
|
|
1204
1221
|
<body>
|
|
1205
1222
|
<div class="card">
|
|
1206
|
-
|
|
1223
|
+
${content}
|
|
1224
|
+
</div>
|
|
1225
|
+
</body>
|
|
1226
|
+
</html>`;
|
|
1227
|
+
}
|
|
1228
|
+
__name(pageShell, "pageShell");
|
|
1229
|
+
function renderLoginPage(options) {
|
|
1230
|
+
const action = escapeHtml(options.actionUrl);
|
|
1231
|
+
const returnTo = escapeHtml(options.returnTo);
|
|
1232
|
+
const errorBanner = options.error === true ? '<p role="alert" class="error">Invalid username or password.</p>' : "";
|
|
1233
|
+
return pageShell(`<p class="brand">AI Gateway</p>
|
|
1207
1234
|
<form method="post" action="${action}">
|
|
1208
1235
|
<input type="hidden" name="returnTo" value="${returnTo}" />
|
|
1209
1236
|
<label>
|
|
@@ -1216,12 +1243,15 @@ function renderLoginPage(options) {
|
|
|
1216
1243
|
</label>
|
|
1217
1244
|
${errorBanner}
|
|
1218
1245
|
<button type="submit">Sign in</button>
|
|
1219
|
-
</form
|
|
1220
|
-
</div>
|
|
1221
|
-
</body>
|
|
1222
|
-
</html>`;
|
|
1246
|
+
</form>`, "Sign in \u2014 AI Gateway");
|
|
1223
1247
|
}
|
|
1224
1248
|
__name(renderLoginPage, "renderLoginPage");
|
|
1249
|
+
function renderSessionRequiredPage() {
|
|
1250
|
+
return pageShell(`<p class="brand">AI Gateway</p>
|
|
1251
|
+
<h1>Open this console from your application</h1>
|
|
1252
|
+
<p>Your session is minted by the host app. Use its console launcher to sign in, then reload.</p>`, "Sign in \u2014 AI Gateway");
|
|
1253
|
+
}
|
|
1254
|
+
__name(renderSessionRequiredPage, "renderSessionRequiredPage");
|
|
1225
1255
|
|
|
1226
1256
|
// src/server/auth/sanitize-return-to.ts
|
|
1227
1257
|
function sanitizeReturnTo(basePath, returnTo) {
|
|
@@ -1267,14 +1297,15 @@ var AgentDashboardAuthController = class _AgentDashboardAuthController {
|
|
|
1267
1297
|
auth;
|
|
1268
1298
|
basePath;
|
|
1269
1299
|
logger = new Logger(_AgentDashboardAuthController.name);
|
|
1270
|
-
/** Warn once (not per request) so a broken hook can't be used to flood the logs. */
|
|
1271
|
-
|
|
1300
|
+
/** Warn once PER HOOK KIND (not per request) so a broken hook can't be used to flood the logs. */
|
|
1301
|
+
warnedHooks = /* @__PURE__ */ new Set();
|
|
1272
1302
|
constructor(auth, basePath) {
|
|
1273
1303
|
this.auth = auth;
|
|
1274
1304
|
this.basePath = basePath;
|
|
1275
1305
|
}
|
|
1276
1306
|
loginPage(req, res, returnToQuery, error) {
|
|
1277
|
-
this.requireAuth();
|
|
1307
|
+
const auth = this.requireAuth();
|
|
1308
|
+
if (!auth.login) throw new NotFoundException();
|
|
1278
1309
|
const returnTo = sanitizeReturnTo(this.basePath, returnToQuery);
|
|
1279
1310
|
if (this.currentSession(req)) {
|
|
1280
1311
|
res.status(302);
|
|
@@ -1289,6 +1320,7 @@ var AgentDashboardAuthController = class _AgentDashboardAuthController {
|
|
|
1289
1320
|
}
|
|
1290
1321
|
async login(body, req, res) {
|
|
1291
1322
|
const auth = this.requireAuth();
|
|
1323
|
+
if (!auth.login) throw new NotFoundException();
|
|
1292
1324
|
const returnTo = sanitizeReturnTo(this.basePath, body?.returnTo);
|
|
1293
1325
|
const username = body?.username;
|
|
1294
1326
|
const password = body?.password;
|
|
@@ -1296,7 +1328,7 @@ var AgentDashboardAuthController = class _AgentDashboardAuthController {
|
|
|
1296
1328
|
this.redirectToLoginError(res, returnTo);
|
|
1297
1329
|
return "";
|
|
1298
1330
|
}
|
|
1299
|
-
const user = await this.
|
|
1331
|
+
const user = await this.runHook("login", () => auth.login?.(username.trim(), isString(password) ? password : "") ?? null);
|
|
1300
1332
|
if (!user) {
|
|
1301
1333
|
this.redirectToLoginError(res, returnTo);
|
|
1302
1334
|
return "";
|
|
@@ -1316,9 +1348,30 @@ var AgentDashboardAuthController = class _AgentDashboardAuthController {
|
|
|
1316
1348
|
response: res
|
|
1317
1349
|
});
|
|
1318
1350
|
res.status(302);
|
|
1319
|
-
res.setHeader("Location", `${this.basePath}/auth/login`);
|
|
1351
|
+
res.setHeader("Location", this.auth && !this.auth.login ? `${this.basePath}/auth/session-required` : `${this.basePath}/auth/login`);
|
|
1320
1352
|
return "";
|
|
1321
1353
|
}
|
|
1354
|
+
// Mode A: the host frontend (carrying its own auth) POSTs here; the host hook validates the raw
|
|
1355
|
+
// request and returns the session user, or `null` to deny. No credential reaches this library.
|
|
1356
|
+
async session(request, response) {
|
|
1357
|
+
const auth = this.requireAuth();
|
|
1358
|
+
if (!auth.session) throw new NotFoundException();
|
|
1359
|
+
const user = await this.runHook("session", () => auth.session?.(request) ?? null);
|
|
1360
|
+
if (!user) throw new UnauthorizedException2();
|
|
1361
|
+
issueSessionCookie(user, {
|
|
1362
|
+
auth,
|
|
1363
|
+
request,
|
|
1364
|
+
response
|
|
1365
|
+
});
|
|
1366
|
+
}
|
|
1367
|
+
// Mode-A-only landing: the host mints the session, so there is nothing to submit here. Serves
|
|
1368
|
+
// as the redirect target `DashboardAuthPageGuard` bounces to instead of `/auth/login`, which
|
|
1369
|
+
// 404s under Mode A (see `loginPage` above).
|
|
1370
|
+
sessionRequiredPage() {
|
|
1371
|
+
const auth = this.requireAuth();
|
|
1372
|
+
if (auth.login) throw new NotFoundException();
|
|
1373
|
+
return renderSessionRequiredPage();
|
|
1374
|
+
}
|
|
1322
1375
|
/** Uniform failure: same redirect (generic error flag) whether the user is unknown or the password is wrong. */
|
|
1323
1376
|
redirectToLoginError(res, returnTo) {
|
|
1324
1377
|
res.status(303);
|
|
@@ -1334,17 +1387,17 @@ var AgentDashboardAuthController = class _AgentDashboardAuthController {
|
|
|
1334
1387
|
}) !== null;
|
|
1335
1388
|
}
|
|
1336
1389
|
/**
|
|
1337
|
-
* Run
|
|
1338
|
-
* (`null`) and warn-logged ONCE, so a buggy/unreachable hook never 500s the
|
|
1339
|
-
* stack-trace leak nor floods the logs.
|
|
1390
|
+
* Run a host hook (`login` or `session`) defensively: a throw (sync or async) is treated as a
|
|
1391
|
+
* denial (`null`) and warn-logged ONCE PER KIND, so a buggy/unreachable hook never 500s the
|
|
1392
|
+
* endpoint into a stack-trace leak nor floods the logs on repeated bad attempts.
|
|
1340
1393
|
*/
|
|
1341
|
-
async
|
|
1394
|
+
async runHook(kind, run) {
|
|
1342
1395
|
try {
|
|
1343
|
-
return await
|
|
1396
|
+
return await run() ?? null;
|
|
1344
1397
|
} catch (error) {
|
|
1345
|
-
if (!this.
|
|
1346
|
-
this.
|
|
1347
|
-
this.logger.warn(`AgentDashboardModule dashboardAuth
|
|
1398
|
+
if (!this.warnedHooks.has(kind)) {
|
|
1399
|
+
this.warnedHooks.add(kind);
|
|
1400
|
+
this.logger.warn(`AgentDashboardModule dashboardAuth ${kind} hook threw; treating as denial. ${error instanceof Error ? error.message : String(error)}`);
|
|
1348
1401
|
}
|
|
1349
1402
|
return null;
|
|
1350
1403
|
}
|
|
@@ -1401,6 +1454,28 @@ _ts_decorate4([
|
|
|
1401
1454
|
]),
|
|
1402
1455
|
_ts_metadata4("design:returntype", String)
|
|
1403
1456
|
], AgentDashboardAuthController.prototype, "logout", null);
|
|
1457
|
+
_ts_decorate4([
|
|
1458
|
+
Post2("session"),
|
|
1459
|
+
HttpCode2(204),
|
|
1460
|
+
_ts_param4(0, Req2()),
|
|
1461
|
+
_ts_param4(1, Res({
|
|
1462
|
+
passthrough: true
|
|
1463
|
+
})),
|
|
1464
|
+
_ts_metadata4("design:type", Function),
|
|
1465
|
+
_ts_metadata4("design:paramtypes", [
|
|
1466
|
+
Object,
|
|
1467
|
+
Object
|
|
1468
|
+
]),
|
|
1469
|
+
_ts_metadata4("design:returntype", Promise)
|
|
1470
|
+
], AgentDashboardAuthController.prototype, "session", null);
|
|
1471
|
+
_ts_decorate4([
|
|
1472
|
+
Get2("session-required"),
|
|
1473
|
+
Header("Content-Type", "text/html; charset=utf-8"),
|
|
1474
|
+
Header("Cache-Control", "no-store, must-revalidate"),
|
|
1475
|
+
_ts_metadata4("design:type", Function),
|
|
1476
|
+
_ts_metadata4("design:paramtypes", []),
|
|
1477
|
+
_ts_metadata4("design:returntype", String)
|
|
1478
|
+
], AgentDashboardAuthController.prototype, "sessionRequiredPage", null);
|
|
1404
1479
|
AgentDashboardAuthController = _ts_decorate4([
|
|
1405
1480
|
Controller2("auth"),
|
|
1406
1481
|
_ts_param4(0, Optional4()),
|
|
@@ -1513,19 +1588,39 @@ var DashboardAuthPageGuard = class {
|
|
|
1513
1588
|
this.auth = auth;
|
|
1514
1589
|
this.basePath = basePath;
|
|
1515
1590
|
}
|
|
1516
|
-
canActivate(context) {
|
|
1591
|
+
async canActivate(context) {
|
|
1517
1592
|
if (!this.auth) return true;
|
|
1593
|
+
const auth = this.auth;
|
|
1518
1594
|
const http = context.switchToHttp();
|
|
1519
1595
|
const request = http.getRequest();
|
|
1520
1596
|
const session = this.verifyRequestSession(request);
|
|
1521
|
-
if (!session)
|
|
1522
|
-
const returnTo = readOriginalUrl(request);
|
|
1523
|
-
throw new DashboardAuthRedirect(`${this.basePath}/auth/login?returnTo=${encodeURIComponent(returnTo)}`);
|
|
1524
|
-
}
|
|
1597
|
+
if (!session) this.deny(auth, request);
|
|
1525
1598
|
attachSession(request, session);
|
|
1526
|
-
|
|
1599
|
+
if (!await maybeRenewSession(auth, session, request, http.getResponse())) {
|
|
1600
|
+
this.deny(auth, request);
|
|
1601
|
+
}
|
|
1527
1602
|
return true;
|
|
1528
1603
|
}
|
|
1604
|
+
/**
|
|
1605
|
+
* No valid session: bounce the browser navigation onward. Under Mode B (`login` configured)
|
|
1606
|
+
* that's the built-in login screen, carrying `returnTo` back to the page that was requested.
|
|
1607
|
+
* Under Mode-A-only there is no login screen to redirect to — the host mints the session
|
|
1608
|
+
* itself — so this instead serves the instruction page rather than redirecting into a 404.
|
|
1609
|
+
* Pulled out of `canActivate` so both the "no session at all" and the "revalidate revoked a
|
|
1610
|
+
* renewable session" paths reuse the exact same mode-aware deny logic.
|
|
1611
|
+
*
|
|
1612
|
+
* Takes `auth` explicitly rather than reading `this.auth`: `canActivate`'s `!this.auth` early
|
|
1613
|
+
* return narrows the field within that method only — TS doesn't carry it across a method call —
|
|
1614
|
+
* so the caller passes the already-narrowed value instead of this method re-deriving (or
|
|
1615
|
+
* asserting away) the nullability.
|
|
1616
|
+
*/
|
|
1617
|
+
deny(auth, request) {
|
|
1618
|
+
if (!auth.login) {
|
|
1619
|
+
throw new DashboardAuthRedirect(`${this.basePath}/auth/session-required`);
|
|
1620
|
+
}
|
|
1621
|
+
const returnTo = readOriginalUrl(request);
|
|
1622
|
+
throw new DashboardAuthRedirect(`${this.basePath}/auth/login?returnTo=${encodeURIComponent(returnTo)}`);
|
|
1623
|
+
}
|
|
1529
1624
|
verifyRequestSession(request) {
|
|
1530
1625
|
const auth = this.auth;
|
|
1531
1626
|
if (!auth) return null;
|
|
@@ -1535,28 +1630,6 @@ var DashboardAuthPageGuard = class {
|
|
|
1535
1630
|
secret: auth.secret
|
|
1536
1631
|
});
|
|
1537
1632
|
}
|
|
1538
|
-
/**
|
|
1539
|
-
* Sliding renewal: a valid cookie past 50% of its TTL is transparently re-issued on the
|
|
1540
|
-
* response, so an active user never gets logged out mid-session.
|
|
1541
|
-
*/
|
|
1542
|
-
maybeRenew(response, request, session) {
|
|
1543
|
-
const auth = this.auth;
|
|
1544
|
-
if (!auth) return;
|
|
1545
|
-
const now = Date.now();
|
|
1546
|
-
if (now - session.iat <= auth.ttlMs / 2) return;
|
|
1547
|
-
issueSessionCookie({
|
|
1548
|
-
id: session.sub,
|
|
1549
|
-
...session.name !== void 0 ? {
|
|
1550
|
-
name: session.name
|
|
1551
|
-
} : {},
|
|
1552
|
-
roles: session.roles
|
|
1553
|
-
}, {
|
|
1554
|
-
auth,
|
|
1555
|
-
request,
|
|
1556
|
-
response,
|
|
1557
|
-
now
|
|
1558
|
-
});
|
|
1559
|
-
}
|
|
1560
1633
|
};
|
|
1561
1634
|
DashboardAuthPageGuard = _ts_decorate6([
|
|
1562
1635
|
Injectable4(),
|
|
@@ -1715,13 +1788,38 @@ function resolveDashboardAuth(options) {
|
|
|
1715
1788
|
if (typeof options.secret !== "string" || options.secret === "") {
|
|
1716
1789
|
throw new Error("AgentDashboardModule dashboardAuth: `secret` is required and must be a non-empty string (HMAC-SHA256 signing key, 32+ bytes recommended). Failing closed.");
|
|
1717
1790
|
}
|
|
1718
|
-
|
|
1719
|
-
|
|
1791
|
+
const modes = [];
|
|
1792
|
+
if (options.session !== void 0) {
|
|
1793
|
+
if (typeof options.session !== "function") {
|
|
1794
|
+
throw new Error("AgentDashboardModule dashboardAuth: `session` must be a function.");
|
|
1795
|
+
}
|
|
1796
|
+
modes.push("session");
|
|
1797
|
+
}
|
|
1798
|
+
if (options.login !== void 0) {
|
|
1799
|
+
if (typeof options.login !== "function") {
|
|
1800
|
+
throw new Error("AgentDashboardModule dashboardAuth: `login` must be a function.");
|
|
1801
|
+
}
|
|
1802
|
+
modes.push("login");
|
|
1803
|
+
}
|
|
1804
|
+
if (options.revalidate !== void 0 && typeof options.revalidate !== "function") {
|
|
1805
|
+
throw new Error("AgentDashboardModule dashboardAuth: `revalidate` must be a function.");
|
|
1806
|
+
}
|
|
1807
|
+
if (modes.length === 0) {
|
|
1808
|
+
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.");
|
|
1720
1809
|
}
|
|
1721
1810
|
return {
|
|
1722
1811
|
secret: options.secret,
|
|
1723
1812
|
ttlMs: durationToMs(options.ttl ?? DEFAULT_TTL),
|
|
1724
|
-
|
|
1813
|
+
modes,
|
|
1814
|
+
...options.session !== void 0 ? {
|
|
1815
|
+
session: options.session
|
|
1816
|
+
} : {},
|
|
1817
|
+
...options.login !== void 0 ? {
|
|
1818
|
+
login: options.login
|
|
1819
|
+
} : {},
|
|
1820
|
+
...options.revalidate !== void 0 ? {
|
|
1821
|
+
revalidate: options.revalidate
|
|
1822
|
+
} : {}
|
|
1725
1823
|
};
|
|
1726
1824
|
}
|
|
1727
1825
|
__name(resolveDashboardAuth, "resolveDashboardAuth");
|