@dudousxd/nestjs-agent-dashboard 0.19.0 → 0.20.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.
@@ -1,8 +1,10 @@
1
1
  const __importMetaUrl = require('url').pathToFileURL(__filename).href;
2
2
  "use strict";
3
+ var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
6
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
9
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
10
  var __export = (target, all) => {
@@ -17,6 +19,14 @@ var __copyProps = (to, from, except, desc) => {
17
19
  }
18
20
  return to;
19
21
  };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
+ mod
29
+ ));
20
30
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
31
 
22
32
  // src/server/index.ts
@@ -31,12 +41,25 @@ __export(index_exports, {
31
41
  AgentApiModule: () => AgentApiModule,
32
42
  AgentDashboardModule: () => AgentDashboardModule,
33
43
  AgentUiController: () => AgentUiController,
44
+ CONSOLE_AUTHORIZE_MISSING_WARNING: () => CONSOLE_AUTHORIZE_MISSING_WARNING,
45
+ CONSOLE_GATE: () => CONSOLE_GATE,
46
+ CONSOLE_PAGE_METADATA: () => CONSOLE_PAGE_METADATA,
47
+ ConsoleAccessDenied: () => ConsoleAccessDenied,
48
+ ConsoleAuthorizeFilter: () => ConsoleAuthorizeFilter,
49
+ ConsoleAuthorizeGuard: () => ConsoleAuthorizeGuard,
50
+ ConsolePage: () => ConsolePage,
34
51
  DASHBOARD_API_PATH: () => DASHBOARD_API_PATH,
35
52
  DASHBOARD_APPROVAL_ACTOR_REF: () => DASHBOARD_APPROVAL_ACTOR_REF,
36
53
  DASHBOARD_BASE_PATH: () => DASHBOARD_BASE_PATH,
54
+ DASHBOARD_CONSOLE_OPTIONS: () => DASHBOARD_CONSOLE_OPTIONS,
55
+ DashboardConsoleAccess: () => DashboardConsoleAccess,
37
56
  DashboardService: () => DashboardService,
57
+ UseConsoleAuthorize: () => UseConsoleAuthorize,
38
58
  agentDashboardMountPaths: () => agentDashboardMountPaths,
39
- parsePriceInput: () => parsePriceInput
59
+ authorizeByToken: () => authorizeByToken,
60
+ normalizeConsoleResult: () => normalizeConsoleResult,
61
+ parsePriceInput: () => parsePriceInput,
62
+ resolveConsoleAuthorize: () => resolveConsoleAuthorize
40
63
  });
41
64
  module.exports = __toCommonJS(index_exports);
42
65
 
@@ -121,6 +144,7 @@ var AGENT_ACTOR_RESOLVER = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:ac
121
144
  var DASHBOARD_BASE_PATH = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:base-path");
122
145
  var DASHBOARD_API_PATH = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:api-path");
123
146
  var DASHBOARD_APPROVAL_ACTOR_REF = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:approval-actor-ref");
147
+ var DASHBOARD_CONSOLE_OPTIONS = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:console-options");
124
148
 
125
149
  // src/server/dashboard.service.ts
126
150
  function _ts_decorate(decorators, target, key, desc) {
@@ -1082,15 +1106,195 @@ __name(agentDashboardMountPaths, "agentDashboardMountPaths");
1082
1106
  // src/server/agent-dashboard.module.ts
1083
1107
  var import_nestjs_agent_core3 = require("@dudousxd/nestjs-agent-core");
1084
1108
  var import_reflect_metadata = require("reflect-metadata");
1085
- var import_common7 = require("@nestjs/common");
1086
- var import_core = require("@nestjs/core");
1109
+ var import_common9 = require("@nestjs/common");
1110
+ var import_core2 = require("@nestjs/core");
1087
1111
 
1088
1112
  // src/server/agent-ui.controller.ts
1089
1113
  var import_node_fs = require("fs");
1090
1114
  var import_node_path = require("path");
1091
1115
  var import_node_url = require("url");
1092
1116
  var import_nestjs_agent_core2 = require("@dudousxd/nestjs-agent-core");
1117
+ var import_common8 = require("@nestjs/common");
1118
+
1119
+ // src/server/console-authorize.guard.ts
1120
+ var import_common7 = require("@nestjs/common");
1121
+ var import_core = require("@nestjs/core");
1122
+
1123
+ // src/server/console-authorize.ts
1124
+ var import_node_crypto = require("crypto");
1093
1125
  var import_common6 = require("@nestjs/common");
1126
+ var CONSOLE_GATE = /* @__PURE__ */ Symbol.for("@dudousxd/aviary:console-gate");
1127
+ var PACKAGE = "@dudousxd/nestjs-agent-dashboard";
1128
+ var MODULE = "AgentDashboardModule";
1129
+ var logger = new import_common6.Logger(MODULE);
1130
+ var CONSOLE_AUTHORIZE_MISSING_WARNING = `[${PACKAGE}] console has no \`authorize\` configured: it is open outside production and denies every request in production. Set \`authorize\` in ${MODULE}.forRoot().`;
1131
+ var allow = /* @__PURE__ */ __name(() => ({
1132
+ allowed: true
1133
+ }), "allow");
1134
+ var forbidden = /* @__PURE__ */ __name(() => ({
1135
+ allowed: false,
1136
+ reason: "forbidden"
1137
+ }), "forbidden");
1138
+ var unauthenticated = /* @__PURE__ */ __name(() => ({
1139
+ allowed: false,
1140
+ reason: "unauthenticated"
1141
+ }), "unauthenticated");
1142
+ function isProduction() {
1143
+ return (process.env.NODE_ENV ?? "").trim().toLowerCase() === "production";
1144
+ }
1145
+ __name(isProduction, "isProduction");
1146
+ function normalizeConsoleResult(result) {
1147
+ if (result === true) return allow();
1148
+ if (result === null || typeof result !== "object") return forbidden();
1149
+ const value = result;
1150
+ if (typeof value.redirectTo === "string" && value.redirectTo !== "" && value.allowed !== true) {
1151
+ return {
1152
+ allowed: false,
1153
+ reason: "unauthenticated",
1154
+ redirectTo: value.redirectTo
1155
+ };
1156
+ }
1157
+ if (value.allowed === true) return allow();
1158
+ return value.reason === "unauthenticated" ? unauthenticated() : forbidden();
1159
+ }
1160
+ __name(normalizeConsoleResult, "normalizeConsoleResult");
1161
+ function isAuthorizerClass(value) {
1162
+ if (typeof value !== "function") return false;
1163
+ if (typeof value.prototype?.authorize === "function") {
1164
+ return true;
1165
+ }
1166
+ return /^class[\s{]/.test(Function.prototype.toString.call(value));
1167
+ }
1168
+ __name(isAuthorizerClass, "isAuthorizerClass");
1169
+ function isPolicyCheck(value) {
1170
+ return typeof value === "object" && value !== null && typeof value.policy === "function" && typeof value.ability === "string";
1171
+ }
1172
+ __name(isPolicyCheck, "isPolicyCheck");
1173
+ function lazyModuleClass(value) {
1174
+ if (typeof value !== "object" || value === null) return void 0;
1175
+ const candidate = value.default;
1176
+ return isAuthorizerClass(candidate) ? candidate : void 0;
1177
+ }
1178
+ __name(lazyModuleClass, "lazyModuleClass");
1179
+ function tryGet(moduleRef, token) {
1180
+ try {
1181
+ return moduleRef.get(token, {
1182
+ strict: false
1183
+ }) ?? void 0;
1184
+ } catch {
1185
+ return void 0;
1186
+ }
1187
+ }
1188
+ __name(tryGet, "tryGet");
1189
+ function classInstances(moduleRef) {
1190
+ const instances = /* @__PURE__ */ new Map();
1191
+ return (Class) => {
1192
+ let instance = instances.get(Class);
1193
+ if (instance === void 0) {
1194
+ const registered = tryGet(moduleRef, Class);
1195
+ instance = registered !== void 0 ? Promise.resolve(registered) : moduleRef.create(Class);
1196
+ instance.catch(() => instances.delete(Class));
1197
+ instances.set(Class, instance);
1198
+ }
1199
+ return instance;
1200
+ };
1201
+ }
1202
+ __name(classInstances, "classInstances");
1203
+ function hasUser(user) {
1204
+ return user !== null && user !== void 0 && user !== false;
1205
+ }
1206
+ __name(hasUser, "hasUser");
1207
+ async function policyDecider(check, moduleRef) {
1208
+ let mod;
1209
+ try {
1210
+ mod = await import("@nestjs/authorization");
1211
+ } catch {
1212
+ throw new Error(`${MODULE}: \`authorize: { policy, ability }\` needs @nestjs/authorization installed and AuthorizationModule imported; or pass a function, a class, or a gate name.`);
1213
+ }
1214
+ const service = tryGet(moduleRef, mod.AuthorizationService);
1215
+ if (service === void 0) {
1216
+ throw new Error(`${MODULE}: \`authorize: { policy, ability }\` needs AuthorizationModule.forRoot() from @nestjs/authorization imported in the app.`);
1217
+ }
1218
+ const options = tryGet(moduleRef, mod.AUTHORIZATION_MODULE_OPTIONS);
1219
+ const getUser = options?.getUser ?? mod.defaultGetUser;
1220
+ return async (context) => {
1221
+ const user = await getUser(context);
1222
+ const signedIn = hasUser(user);
1223
+ if (await service.can(check.policy, check.ability, signedIn ? user : null)) return allow();
1224
+ return signedIn ? forbidden() : unauthenticated();
1225
+ };
1226
+ }
1227
+ __name(policyDecider, "policyDecider");
1228
+ async function resolveConsoleAuthorize(authorize, moduleRef, options = {}) {
1229
+ const log = options.logger ?? logger;
1230
+ if (authorize === void 0) {
1231
+ if (options.warnIfMissing !== false) log.warn(CONSOLE_AUTHORIZE_MISSING_WARNING);
1232
+ const production = isProduction();
1233
+ return async () => production ? forbidden() : allow();
1234
+ }
1235
+ const instanceOf = classInstances(moduleRef);
1236
+ let decide;
1237
+ if (typeof authorize === "string") {
1238
+ const name = authorize;
1239
+ const gate = tryGet(moduleRef, CONSOLE_GATE);
1240
+ if (gate === void 0) {
1241
+ throw new Error(`${MODULE}: \`authorize: '${name}'\` needs @dudousxd/nestjs-authz's AuthzModule (it resolves gate names); or pass a function, a class, or { policy, ability }.`);
1242
+ }
1243
+ decide = /* @__PURE__ */ __name((context) => gate.allows(name, context), "decide");
1244
+ } else if (isPolicyCheck(authorize)) {
1245
+ decide = await policyDecider(authorize, moduleRef);
1246
+ } else if (isAuthorizerClass(authorize)) {
1247
+ const Class = authorize;
1248
+ decide = /* @__PURE__ */ __name(async (context) => (await instanceOf(Class)).authorize(context), "decide");
1249
+ } else if (typeof authorize === "function") {
1250
+ const fn = authorize;
1251
+ let lazyClass;
1252
+ decide = /* @__PURE__ */ __name(async (context) => {
1253
+ if (lazyClass !== void 0) return (await instanceOf(lazyClass)).authorize(context);
1254
+ const result = await fn(context);
1255
+ const Class = lazyModuleClass(result);
1256
+ if (Class === void 0) return result;
1257
+ lazyClass = Class;
1258
+ return (await instanceOf(Class)).authorize(context);
1259
+ }, "decide");
1260
+ } else {
1261
+ throw new Error(`${MODULE}: \`authorize\` must be a function, a class with authorize(), a lazy import, { policy, ability } or a gate name.`);
1262
+ }
1263
+ return async (context) => {
1264
+ try {
1265
+ return normalizeConsoleResult(await decide(context));
1266
+ } catch (error) {
1267
+ log.warn(`console \`authorize\` threw, denying the request: ${error instanceof Error ? error.message : String(error)}`);
1268
+ return forbidden();
1269
+ }
1270
+ };
1271
+ }
1272
+ __name(resolveConsoleAuthorize, "resolveConsoleAuthorize");
1273
+ function sha256(value) {
1274
+ return (0, import_node_crypto.createHash)("sha256").update(value).digest();
1275
+ }
1276
+ __name(sha256, "sha256");
1277
+ function authorizeByToken(options) {
1278
+ const token = options.token;
1279
+ if (typeof token !== "string" || token === "") {
1280
+ throw new Error("authorizeByToken: `token` is empty; set it (e.g. from an env var).");
1281
+ }
1282
+ const expected = sha256(token);
1283
+ return (context) => {
1284
+ const req = context.switchToHttp().getRequest();
1285
+ const header = req?.headers?.authorization;
1286
+ const value = Array.isArray(header) ? header[0] : header;
1287
+ const match = typeof value === "string" ? /^Bearer\s+(.+)$/i.exec(value.trim()) : null;
1288
+ if (match?.[1] !== void 0 && (0, import_node_crypto.timingSafeEqual)(sha256(match[1]), expected)) return true;
1289
+ return {
1290
+ allowed: false,
1291
+ reason: "unauthenticated"
1292
+ };
1293
+ };
1294
+ }
1295
+ __name(authorizeByToken, "authorizeByToken");
1296
+
1297
+ // src/server/console-authorize.guard.ts
1094
1298
  function _ts_decorate3(decorators, target, key, desc) {
1095
1299
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1096
1300
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
@@ -1117,6 +1321,161 @@ function _ts_param3(paramIndex, decorator) {
1117
1321
  };
1118
1322
  }
1119
1323
  __name(_ts_param3, "_ts_param");
1324
+ var DashboardConsoleAccess = class {
1325
+ static {
1326
+ __name(this, "DashboardConsoleAccess");
1327
+ }
1328
+ options;
1329
+ moduleRef;
1330
+ #decide;
1331
+ constructor(options, moduleRef) {
1332
+ this.options = options;
1333
+ this.moduleRef = moduleRef;
1334
+ }
1335
+ #resolving;
1336
+ /** Resolves `authorize` at boot: a configuration mistake fails the boot, and the warning logs once. */
1337
+ async onModuleInit() {
1338
+ this.#resolving ??= resolveConsoleAuthorize(this.options.authorize, this.moduleRef);
1339
+ this.#decide = await this.#resolving;
1340
+ }
1341
+ /** The decision for one request. */
1342
+ async check(context) {
1343
+ if (this.#decide === void 0) await this.onModuleInit();
1344
+ return this.#decide(context);
1345
+ }
1346
+ };
1347
+ DashboardConsoleAccess = _ts_decorate3([
1348
+ (0, import_common7.Injectable)(),
1349
+ _ts_param3(0, (0, import_common7.Inject)(DASHBOARD_CONSOLE_OPTIONS)),
1350
+ _ts_metadata3("design:type", Function),
1351
+ _ts_metadata3("design:paramtypes", [
1352
+ typeof DashboardConsoleOptions === "undefined" ? Object : DashboardConsoleOptions,
1353
+ typeof import_core.ModuleRef === "undefined" ? Object : import_core.ModuleRef
1354
+ ])
1355
+ ], DashboardConsoleAccess);
1356
+ var CONSOLE_PAGE_METADATA = "@dudousxd/nestjs-agent-dashboard:console-page";
1357
+ var ConsolePage = /* @__PURE__ */ __name(() => (0, import_common7.SetMetadata)(CONSOLE_PAGE_METADATA, true), "ConsolePage");
1358
+ var ConsoleAccessDenied = class extends import_common7.HttpException {
1359
+ static {
1360
+ __name(this, "ConsoleAccessDenied");
1361
+ }
1362
+ decision;
1363
+ page;
1364
+ constructor(decision, page) {
1365
+ super(decision.reason === "forbidden" ? {
1366
+ error: "forbidden"
1367
+ } : {
1368
+ error: "unauthenticated",
1369
+ ...decision.redirectTo !== void 0 ? {
1370
+ redirectTo: decision.redirectTo
1371
+ } : {}
1372
+ }, decision.reason === "forbidden" ? 403 : 401), this.decision = decision, this.page = page;
1373
+ }
1374
+ };
1375
+ function isPageNavigation(context) {
1376
+ if (context.getType() !== "http") return false;
1377
+ const page = Reflect.getMetadata(CONSOLE_PAGE_METADATA, context.getHandler()) === true || Reflect.getMetadata(CONSOLE_PAGE_METADATA, context.getClass()) === true;
1378
+ if (!page) return false;
1379
+ const req = context.switchToHttp().getRequest();
1380
+ if ((req.method ?? "GET").toUpperCase() !== "GET") return false;
1381
+ const accept = req.headers?.accept;
1382
+ const value = Array.isArray(accept) ? accept.join(",") : accept ?? "";
1383
+ return value.includes("text/html");
1384
+ }
1385
+ __name(isPageNavigation, "isPageNavigation");
1386
+ var ConsoleAuthorizeGuard = class {
1387
+ static {
1388
+ __name(this, "ConsoleAuthorizeGuard");
1389
+ }
1390
+ access;
1391
+ constructor(access) {
1392
+ this.access = access;
1393
+ }
1394
+ async canActivate(context) {
1395
+ const decision = await this.access.check(context);
1396
+ if (decision.allowed) return true;
1397
+ throw new ConsoleAccessDenied(decision, isPageNavigation(context));
1398
+ }
1399
+ };
1400
+ ConsoleAuthorizeGuard = _ts_decorate3([
1401
+ (0, import_common7.Injectable)(),
1402
+ _ts_metadata3("design:type", Function),
1403
+ _ts_metadata3("design:paramtypes", [
1404
+ typeof DashboardConsoleAccess === "undefined" ? Object : DashboardConsoleAccess
1405
+ ])
1406
+ ], ConsoleAuthorizeGuard);
1407
+ function deniedPage(title, message) {
1408
+ const body = "font-family:system-ui,sans-serif;display:grid;place-items:center;min-height:100vh;margin:0";
1409
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${title}</title></head><body style="${body}"><main style="text-align:center"><h1>${title}</h1><p>${message}</p></main></body></html>`;
1410
+ }
1411
+ __name(deniedPage, "deniedPage");
1412
+ var FORBIDDEN_PAGE = deniedPage("Access denied", "You do not have access to this console.");
1413
+ var UNAUTHENTICATED_PAGE = deniedPage("Sign in required", "Sign in to open this console.");
1414
+ var ConsoleAuthorizeFilter = class {
1415
+ static {
1416
+ __name(this, "ConsoleAuthorizeFilter");
1417
+ }
1418
+ adapterHost;
1419
+ constructor(adapterHost) {
1420
+ this.adapterHost = adapterHost;
1421
+ }
1422
+ catch(exception, host) {
1423
+ const adapter = this.adapterHost.httpAdapter;
1424
+ const res = host.switchToHttp().getResponse();
1425
+ const { decision, page } = exception;
1426
+ if (page && decision.reason === "unauthenticated" && decision.redirectTo !== void 0) {
1427
+ adapter.redirect(res, 302, decision.redirectTo);
1428
+ return;
1429
+ }
1430
+ if (page) {
1431
+ const forbidden2 = decision.reason === "forbidden";
1432
+ adapter.setHeader(res, "Content-Type", "text/html; charset=utf-8");
1433
+ adapter.reply(res, forbidden2 ? FORBIDDEN_PAGE : UNAUTHENTICATED_PAGE, forbidden2 ? 403 : 401);
1434
+ return;
1435
+ }
1436
+ adapter.reply(res, exception.getResponse(), exception.getStatus());
1437
+ }
1438
+ };
1439
+ ConsoleAuthorizeFilter = _ts_decorate3([
1440
+ (0, import_common7.Catch)(ConsoleAccessDenied),
1441
+ (0, import_common7.Injectable)(),
1442
+ _ts_metadata3("design:type", Function),
1443
+ _ts_metadata3("design:paramtypes", [
1444
+ typeof import_core.HttpAdapterHost === "undefined" ? Object : import_core.HttpAdapterHost
1445
+ ])
1446
+ ], ConsoleAuthorizeFilter);
1447
+ function UseConsoleAuthorize() {
1448
+ return (0, import_common7.applyDecorators)((0, import_common7.UseGuards)(ConsoleAuthorizeGuard), (0, import_common7.UseFilters)(ConsoleAuthorizeFilter));
1449
+ }
1450
+ __name(UseConsoleAuthorize, "UseConsoleAuthorize");
1451
+
1452
+ // src/server/agent-ui.controller.ts
1453
+ function _ts_decorate4(decorators, target, key, desc) {
1454
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1455
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
1456
+ r = Reflect.decorate(decorators, target, key, desc);
1457
+ } else {
1458
+ for (var i = decorators.length - 1; i >= 0; i--) {
1459
+ if (d = decorators[i]) {
1460
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1461
+ }
1462
+ }
1463
+ }
1464
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1465
+ }
1466
+ __name(_ts_decorate4, "_ts_decorate");
1467
+ function _ts_metadata4(metadataKey, metadataValue) {
1468
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
1469
+ return Reflect.metadata(metadataKey, metadataValue);
1470
+ }
1471
+ }
1472
+ __name(_ts_metadata4, "_ts_metadata");
1473
+ function _ts_param4(paramIndex, decorator) {
1474
+ return function(target, key) {
1475
+ decorator(target, key, paramIndex);
1476
+ };
1477
+ }
1478
+ __name(_ts_param4, "_ts_param");
1120
1479
  var BUILD_BASE = "/ai-gateway";
1121
1480
  function spaDir() {
1122
1481
  return (0, import_node_url.fileURLToPath)(new URL("../spa", __importMetaUrl));
@@ -1152,7 +1511,7 @@ var AgentUiController = class {
1152
1511
  }
1153
1512
  const indexPath = (0, import_node_path.join)(this.dir, "index.html");
1154
1513
  if (!(0, import_node_fs.existsSync)(indexPath)) {
1155
- throw new import_common6.NotFoundException("Dashboard is not built. Run the package build.");
1514
+ throw new import_common8.NotFoundException("Dashboard is not built. Run the package build.");
1156
1515
  }
1157
1516
  const html = (0, import_node_fs.readFileSync)(indexPath, "utf8").replaceAll(`="${BUILD_BASE}/`, `="${this.basePath}/`);
1158
1517
  const inject = `<script>window.__AGENT_BASE__='${this.basePath}';window.__AGENT_API__='${this.apiBasePath}';</script>`;
@@ -1160,57 +1519,58 @@ var AgentUiController = class {
1160
1519
  }
1161
1520
  asset(file) {
1162
1521
  const safe = (0, import_node_path.basename)(file);
1163
- if (safe !== file) throw new import_common6.NotFoundException();
1522
+ if (safe !== file) throw new import_common8.NotFoundException();
1164
1523
  const root = (0, import_node_path.resolve)(this.dir, "assets");
1165
1524
  const assetPath = (0, import_node_path.resolve)(root, safe);
1166
1525
  if (!assetPath.startsWith(root + import_node_path.sep) || !(0, import_node_fs.existsSync)(assetPath)) {
1167
- throw new import_common6.NotFoundException();
1526
+ throw new import_common8.NotFoundException();
1168
1527
  }
1169
1528
  const type = CONTENT_TYPES[(0, import_node_path.extname)(safe)] ?? "application/octet-stream";
1170
- return new import_common6.StreamableFile((0, import_node_fs.readFileSync)(assetPath), {
1529
+ return new import_common8.StreamableFile((0, import_node_fs.readFileSync)(assetPath), {
1171
1530
  type
1172
1531
  });
1173
1532
  }
1174
1533
  };
1175
- _ts_decorate3([
1176
- (0, import_common6.Get)(),
1177
- (0, import_common6.Header)("Content-Type", "text/html; charset=utf-8"),
1178
- (0, import_common6.Header)("Cache-Control", "no-store, must-revalidate"),
1179
- _ts_param3(0, (0, import_common6.Req)()),
1180
- _ts_param3(1, (0, import_common6.Res)({
1534
+ _ts_decorate4([
1535
+ (0, import_common8.Get)(),
1536
+ ConsolePage(),
1537
+ (0, import_common8.Header)("Content-Type", "text/html; charset=utf-8"),
1538
+ (0, import_common8.Header)("Cache-Control", "no-store, must-revalidate"),
1539
+ _ts_param4(0, (0, import_common8.Req)()),
1540
+ _ts_param4(1, (0, import_common8.Res)({
1181
1541
  passthrough: true
1182
1542
  })),
1183
- _ts_metadata3("design:type", Function),
1184
- _ts_metadata3("design:paramtypes", [
1543
+ _ts_metadata4("design:type", Function),
1544
+ _ts_metadata4("design:paramtypes", [
1185
1545
  typeof UiPageRequest === "undefined" ? Object : UiPageRequest,
1186
1546
  typeof UiPageResponse === "undefined" ? Object : UiPageResponse
1187
1547
  ]),
1188
- _ts_metadata3("design:returntype", String)
1548
+ _ts_metadata4("design:returntype", String)
1189
1549
  ], AgentUiController.prototype, "index", null);
1190
- _ts_decorate3([
1191
- (0, import_common6.Get)("assets/:file"),
1192
- (0, import_common6.Header)("Cache-Control", "public, max-age=31536000, immutable"),
1193
- _ts_param3(0, (0, import_common6.Param)("file")),
1194
- _ts_metadata3("design:type", Function),
1195
- _ts_metadata3("design:paramtypes", [
1550
+ _ts_decorate4([
1551
+ (0, import_common8.Get)("assets/:file"),
1552
+ (0, import_common8.Header)("Cache-Control", "public, max-age=31536000, immutable"),
1553
+ _ts_param4(0, (0, import_common8.Param)("file")),
1554
+ _ts_metadata4("design:type", Function),
1555
+ _ts_metadata4("design:paramtypes", [
1196
1556
  String
1197
1557
  ]),
1198
- _ts_metadata3("design:returntype", typeof import_common6.StreamableFile === "undefined" ? Object : import_common6.StreamableFile)
1558
+ _ts_metadata4("design:returntype", typeof import_common8.StreamableFile === "undefined" ? Object : import_common8.StreamableFile)
1199
1559
  ], AgentUiController.prototype, "asset", null);
1200
- AgentUiController = _ts_decorate3([
1560
+ AgentUiController = _ts_decorate4([
1201
1561
  (0, import_nestjs_agent_core2.CanAnyone)(),
1202
- (0, import_common6.Controller)(),
1203
- _ts_param3(0, (0, import_common6.Inject)(DASHBOARD_BASE_PATH)),
1204
- _ts_param3(1, (0, import_common6.Inject)(DASHBOARD_API_PATH)),
1205
- _ts_metadata3("design:type", Function),
1206
- _ts_metadata3("design:paramtypes", [
1562
+ (0, import_common8.Controller)(),
1563
+ _ts_param4(0, (0, import_common8.Inject)(DASHBOARD_BASE_PATH)),
1564
+ _ts_param4(1, (0, import_common8.Inject)(DASHBOARD_API_PATH)),
1565
+ _ts_metadata4("design:type", Function),
1566
+ _ts_metadata4("design:paramtypes", [
1207
1567
  String,
1208
1568
  String
1209
1569
  ])
1210
1570
  ], AgentUiController);
1211
1571
 
1212
1572
  // src/server/agent-dashboard.module.ts
1213
- function _ts_decorate4(decorators, target, key, desc) {
1573
+ function _ts_decorate5(decorators, target, key, desc) {
1214
1574
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1215
1575
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
1216
1576
  r = Reflect.decorate(decorators, target, key, desc);
@@ -1223,23 +1583,29 @@ function _ts_decorate4(decorators, target, key, desc) {
1223
1583
  }
1224
1584
  return c > 3 && r && Object.defineProperty(target, key, r), r;
1225
1585
  }
1226
- __name(_ts_decorate4, "_ts_decorate");
1586
+ __name(_ts_decorate5, "_ts_decorate");
1227
1587
  function normalize(path) {
1228
1588
  return normalizeDashboardPath(path);
1229
1589
  }
1230
1590
  __name(normalize, "normalize");
1231
- function assertProtected(options) {
1232
- if (process.env.NODE_ENV !== "production") return;
1233
- if (options.routes === false) return;
1234
- if ((options.decorators ?? []).length > 0) return;
1235
- throw new Error("AgentDashboardModule: the AI-gateway console would be served open in production. Say who reaches it, with `decorators: [UseGuards(AuthenticationGuard), Can(ConsolePolicy, 'view')]`, or mount its routes yourself with `routes: false` and extend `AgentApiController` / `AgentUiController` under your own guards.");
1591
+ function consoleDecorators(decorators) {
1592
+ return [
1593
+ ...decorators ?? [],
1594
+ (0, import_common9.UseGuards)(ConsoleAuthorizeGuard),
1595
+ (0, import_common9.UseFilters)(ConsoleAuthorizeFilter)
1596
+ ];
1236
1597
  }
1237
- __name(assertProtected, "assertProtected");
1598
+ __name(consoleDecorators, "consoleDecorators");
1238
1599
  var AgentApiModule = class _AgentApiModule {
1239
1600
  static {
1240
1601
  __name(this, "AgentApiModule");
1241
1602
  }
1242
1603
  static register(options) {
1604
+ const consoleOptions = {
1605
+ ...options.authorize !== void 0 ? {
1606
+ authorize: options.authorize
1607
+ } : {}
1608
+ };
1243
1609
  return {
1244
1610
  module: _AgentApiModule,
1245
1611
  imports: [
@@ -1247,7 +1613,7 @@ var AgentApiModule = class _AgentApiModule {
1247
1613
  ],
1248
1614
  controllers: options.routes === false ? [] : (0, import_nestjs_agent_core3.withControllerDecorators)([
1249
1615
  AgentApiController
1250
- ], options.decorators),
1616
+ ], consoleDecorators(options.decorators)),
1251
1617
  providers: [
1252
1618
  DashboardService,
1253
1619
  // `useValue` even when `options.approvalActorRef` is `undefined` — AgentApiController
@@ -1255,25 +1621,31 @@ var AgentApiModule = class _AgentApiModule {
1255
1621
  {
1256
1622
  provide: DASHBOARD_APPROVAL_ACTOR_REF,
1257
1623
  useValue: options.approvalActorRef
1258
- }
1624
+ },
1625
+ {
1626
+ provide: DASHBOARD_CONSOLE_OPTIONS,
1627
+ useValue: consoleOptions
1628
+ },
1629
+ DashboardConsoleAccess
1259
1630
  ],
1260
- // What a self-mounted `AgentApiController` subclass injects, too (`routes: false`).
1631
+ // What a self-mounted `AgentApiController` subclass injects, too (`routes: false`), and the
1632
+ // access check `UseConsoleAuthorize()` runs.
1261
1633
  exports: [
1262
1634
  DashboardService,
1263
- DASHBOARD_APPROVAL_ACTOR_REF
1635
+ DASHBOARD_APPROVAL_ACTOR_REF,
1636
+ DashboardConsoleAccess
1264
1637
  ]
1265
1638
  };
1266
1639
  }
1267
1640
  };
1268
- AgentApiModule = _ts_decorate4([
1269
- (0, import_common7.Module)({})
1641
+ AgentApiModule = _ts_decorate5([
1642
+ (0, import_common9.Module)({})
1270
1643
  ], AgentApiModule);
1271
1644
  var AgentDashboardModule = class _AgentDashboardModule {
1272
1645
  static {
1273
1646
  __name(this, "AgentDashboardModule");
1274
1647
  }
1275
1648
  static forRoot(options = {}) {
1276
- assertProtected(options);
1277
1649
  const basePath = normalize(options.basePath ?? "/ai-gateway");
1278
1650
  const apiBasePath = normalize(options.apiBasePath ?? `${basePath}/api`);
1279
1651
  return {
@@ -1293,10 +1665,13 @@ var AgentDashboardModule = class _AgentDashboardModule {
1293
1665
  } : {},
1294
1666
  ...options.approvalActorRef ? {
1295
1667
  approvalActorRef: options.approvalActorRef
1668
+ } : {},
1669
+ ...options.authorize !== void 0 ? {
1670
+ authorize: options.authorize
1296
1671
  } : {}
1297
1672
  }),
1298
1673
  ...options.routes === false ? [] : [
1299
- import_core.RouterModule.register([
1674
+ import_core2.RouterModule.register([
1300
1675
  {
1301
1676
  path: basePath,
1302
1677
  module: _AgentDashboardModule
@@ -1310,7 +1685,7 @@ var AgentDashboardModule = class _AgentDashboardModule {
1310
1685
  ],
1311
1686
  controllers: options.routes === false ? [] : (0, import_nestjs_agent_core3.withControllerDecorators)([
1312
1687
  AgentUiController
1313
- ], options.decorators),
1688
+ ], consoleDecorators(options.decorators)),
1314
1689
  providers: [
1315
1690
  {
1316
1691
  provide: DASHBOARD_BASE_PATH,
@@ -1331,8 +1706,8 @@ var AgentDashboardModule = class _AgentDashboardModule {
1331
1706
  };
1332
1707
  }
1333
1708
  };
1334
- AgentDashboardModule = _ts_decorate4([
1335
- (0, import_common7.Module)({})
1709
+ AgentDashboardModule = _ts_decorate5([
1710
+ (0, import_common9.Module)({})
1336
1711
  ], AgentDashboardModule);
1337
1712
  // Annotate the CommonJS export names for ESM import in node:
1338
1713
  0 && (module.exports = {
@@ -1345,11 +1720,24 @@ AgentDashboardModule = _ts_decorate4([
1345
1720
  AgentApiModule,
1346
1721
  AgentDashboardModule,
1347
1722
  AgentUiController,
1723
+ CONSOLE_AUTHORIZE_MISSING_WARNING,
1724
+ CONSOLE_GATE,
1725
+ CONSOLE_PAGE_METADATA,
1726
+ ConsoleAccessDenied,
1727
+ ConsoleAuthorizeFilter,
1728
+ ConsoleAuthorizeGuard,
1729
+ ConsolePage,
1348
1730
  DASHBOARD_API_PATH,
1349
1731
  DASHBOARD_APPROVAL_ACTOR_REF,
1350
1732
  DASHBOARD_BASE_PATH,
1733
+ DASHBOARD_CONSOLE_OPTIONS,
1734
+ DashboardConsoleAccess,
1351
1735
  DashboardService,
1736
+ UseConsoleAuthorize,
1352
1737
  agentDashboardMountPaths,
1353
- parsePriceInput
1738
+ authorizeByToken,
1739
+ normalizeConsoleResult,
1740
+ parsePriceInput,
1741
+ resolveConsoleAuthorize
1354
1742
  });
1355
1743
  //# sourceMappingURL=index.cjs.map