@dudousxd/nestjs-agent-dashboard 0.17.0 → 0.19.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 +28 -132
- package/dist/client/agent-client.d.ts +47 -1
- package/dist/client/agent-client.d.ts.map +1 -1
- package/dist/client/agent-client.js +0 -4
- package/dist/client/agent-client.js.map +1 -1
- package/dist/server/index.cjs +286 -1373
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +37 -287
- package/dist/server/index.d.ts +37 -287
- package/dist/server/index.js +239 -1323
- package/dist/server/index.js.map +1 -1
- package/dist/spa/assets/index-B1znMy6W.css +1 -0
- package/dist/spa/assets/{index-DKPuTuEx.js → index-DzukxAmy.js} +1 -1
- package/dist/spa/assets/index-eW1zMwDF.js +25 -0
- package/dist/spa/assets/{preview-BgeSHiwH.js → preview-Ch59R-LE.js} +1 -1
- package/dist/spa/index.html +3 -3
- package/dist/spa/preview.html +3 -3
- package/package.json +6 -20
- package/dist/client/console-session.d.ts +0 -63
- package/dist/client/console-session.d.ts.map +0 -1
- package/dist/client/console-session.js +0 -107
- package/dist/client/console-session.js.map +0 -1
- package/dist/react/index.d.ts +0 -4
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/index.js +0 -14
- package/dist/react/index.js.map +0 -1
- package/dist/react/open-console-button.d.ts +0 -26
- package/dist/react/open-console-button.d.ts.map +0 -1
- package/dist/react/open-console-button.js +0 -29
- package/dist/react/open-console-button.js.map +0 -1
- package/dist/react/use-open-console.d.ts +0 -34
- package/dist/react/use-open-console.d.ts.map +0 -1
- package/dist/react/use-open-console.js +0 -70
- package/dist/react/use-open-console.js.map +0 -1
- package/dist/spa/assets/index-B2rAzTPe.js +0 -25
- package/dist/spa/assets/index-P6B28Wyx.css +0 -1
package/dist/server/index.js
CHANGED
|
@@ -2,401 +2,13 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
4
|
// src/server/agent-api.controller.ts
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
// src/server/auth/dashboard-auth.guard.ts
|
|
8
|
-
import { Inject, Injectable, Optional, UnauthorizedException } from "@nestjs/common";
|
|
9
|
-
|
|
10
|
-
// src/server/tokens.ts
|
|
11
|
-
var AGENT_GOVERNANCE_QUERIES = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:governance-queries");
|
|
12
|
-
var AGENT_ACTOR_DIRECTORY = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:actor-directory");
|
|
13
|
-
var AGENT_PRICING_STORE = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:pricing-store");
|
|
14
|
-
var AGENT_APPROVAL_PORT = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:approval-port");
|
|
15
|
-
var AGENT_ACTOR_RESOLVER = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:actor-resolver");
|
|
16
|
-
var DASHBOARD_BASE_PATH = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:base-path");
|
|
17
|
-
var DASHBOARD_API_PATH = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:api-path");
|
|
18
|
-
var DASHBOARD_APPROVAL_ACTOR_REF = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:approval-actor-ref");
|
|
19
|
-
var DASHBOARD_AUTH = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:dashboard-auth");
|
|
20
|
-
|
|
21
|
-
// src/server/auth/cookie-header.ts
|
|
22
|
-
function parseCookieHeader(header) {
|
|
23
|
-
const cookies = {};
|
|
24
|
-
if (typeof header !== "string" || header === "") return cookies;
|
|
25
|
-
for (const segment of header.split(";")) {
|
|
26
|
-
const eq = segment.indexOf("=");
|
|
27
|
-
if (eq <= 0) continue;
|
|
28
|
-
const name = segment.slice(0, eq).trim();
|
|
29
|
-
if (name === "") continue;
|
|
30
|
-
let rawValue = segment.slice(eq + 1).trim();
|
|
31
|
-
if (rawValue.length >= 2 && rawValue.startsWith('"') && rawValue.endsWith('"')) {
|
|
32
|
-
rawValue = rawValue.slice(1, -1);
|
|
33
|
-
}
|
|
34
|
-
if (name in cookies) continue;
|
|
35
|
-
try {
|
|
36
|
-
cookies[name] = decodeURIComponent(rawValue);
|
|
37
|
-
} catch {
|
|
38
|
-
cookies[name] = rawValue;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return cookies;
|
|
42
|
-
}
|
|
43
|
-
__name(parseCookieHeader, "parseCookieHeader");
|
|
44
|
-
function serializeSetCookie(name, value, options) {
|
|
45
|
-
const parts = [
|
|
46
|
-
`${name}=${options.clear ? "" : encodeURIComponent(value)}`
|
|
47
|
-
];
|
|
48
|
-
parts.push(`Path=${options.path}`);
|
|
49
|
-
parts.push("HttpOnly");
|
|
50
|
-
parts.push("SameSite=Lax");
|
|
51
|
-
if (options.secure) parts.push("Secure");
|
|
52
|
-
if (options.clear) {
|
|
53
|
-
parts.push("Max-Age=0");
|
|
54
|
-
parts.push("Expires=Thu, 01 Jan 1970 00:00:00 GMT");
|
|
55
|
-
} else {
|
|
56
|
-
parts.push(`Max-Age=${options.maxAgeSeconds}`);
|
|
57
|
-
}
|
|
58
|
-
return parts.join("; ");
|
|
59
|
-
}
|
|
60
|
-
__name(serializeSetCookie, "serializeSetCookie");
|
|
61
|
-
|
|
62
|
-
// src/server/auth/http-request.ts
|
|
63
|
-
function isRecord(value) {
|
|
64
|
-
return typeof value === "object" && value !== null;
|
|
65
|
-
}
|
|
66
|
-
__name(isRecord, "isRecord");
|
|
67
|
-
function readHeaders(request) {
|
|
68
|
-
if (!isRecord(request)) return {};
|
|
69
|
-
const headers = request.headers;
|
|
70
|
-
return isRecord(headers) ? headers : {};
|
|
71
|
-
}
|
|
72
|
-
__name(readHeaders, "readHeaders");
|
|
73
|
-
function headerToString(value) {
|
|
74
|
-
if (typeof value === "string") return value;
|
|
75
|
-
if (Array.isArray(value) && value.every((part) => typeof part === "string")) {
|
|
76
|
-
return value.join(",");
|
|
77
|
-
}
|
|
78
|
-
return void 0;
|
|
79
|
-
}
|
|
80
|
-
__name(headerToString, "headerToString");
|
|
81
|
-
function readCookieHeader(request) {
|
|
82
|
-
return headerToString(readHeaders(request).cookie);
|
|
83
|
-
}
|
|
84
|
-
__name(readCookieHeader, "readCookieHeader");
|
|
85
|
-
function isHttpsRequest(request) {
|
|
86
|
-
if (isRecord(request) && request.protocol === "https") return true;
|
|
87
|
-
const forwarded = headerToString(readHeaders(request)["x-forwarded-proto"]);
|
|
88
|
-
if (forwarded === void 0) return false;
|
|
89
|
-
return forwarded.split(",").map((proto) => proto.trim().toLowerCase()).includes("https");
|
|
90
|
-
}
|
|
91
|
-
__name(isHttpsRequest, "isHttpsRequest");
|
|
92
|
-
function readOriginalUrl(request) {
|
|
93
|
-
if (!isRecord(request)) return "/";
|
|
94
|
-
const originalUrl = request.originalUrl;
|
|
95
|
-
if (typeof originalUrl === "string" && originalUrl !== "") return originalUrl;
|
|
96
|
-
const url = request.url;
|
|
97
|
-
return typeof url === "string" && url !== "" ? url : "/";
|
|
98
|
-
}
|
|
99
|
-
__name(readOriginalUrl, "readOriginalUrl");
|
|
100
|
-
function attachSession(request, session) {
|
|
101
|
-
if (!isRecord(request)) return;
|
|
102
|
-
const target = request;
|
|
103
|
-
target.dashboardSession = session;
|
|
104
|
-
}
|
|
105
|
-
__name(attachSession, "attachSession");
|
|
106
|
-
|
|
107
|
-
// src/server/auth/response.ts
|
|
108
|
-
function isRecord2(value) {
|
|
109
|
-
return typeof value === "object" && value !== null;
|
|
110
|
-
}
|
|
111
|
-
__name(isRecord2, "isRecord");
|
|
112
|
-
function isHeaderCapableResponse(value) {
|
|
113
|
-
return isRecord2(value) && typeof value.getHeader === "function" && typeof value.setHeader === "function";
|
|
114
|
-
}
|
|
115
|
-
__name(isHeaderCapableResponse, "isHeaderCapableResponse");
|
|
116
|
-
function resolveHeaderCapableResponse(response) {
|
|
117
|
-
if (isHeaderCapableResponse(response)) return response;
|
|
118
|
-
if (isRecord2(response) && isHeaderCapableResponse(response.raw)) return response.raw;
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
__name(resolveHeaderCapableResponse, "resolveHeaderCapableResponse");
|
|
122
|
-
function existingSetCookies(response) {
|
|
123
|
-
const current = response.getHeader("set-cookie");
|
|
124
|
-
if (Array.isArray(current)) return current;
|
|
125
|
-
if (typeof current === "string") return [
|
|
126
|
-
current
|
|
127
|
-
];
|
|
128
|
-
return [];
|
|
129
|
-
}
|
|
130
|
-
__name(existingSetCookies, "existingSetCookies");
|
|
131
|
-
function appendSetCookie(response, cookie) {
|
|
132
|
-
const raw = resolveHeaderCapableResponse(response);
|
|
133
|
-
if (!raw) return;
|
|
134
|
-
raw.setHeader("set-cookie", [
|
|
135
|
-
...existingSetCookies(raw),
|
|
136
|
-
cookie
|
|
137
|
-
]);
|
|
138
|
-
}
|
|
139
|
-
__name(appendSetCookie, "appendSetCookie");
|
|
140
|
-
function isRawNodeResponse(value) {
|
|
141
|
-
return isRecord2(value) && typeof value.getHeader === "function" && typeof value.setHeader === "function" && typeof value.end === "function";
|
|
142
|
-
}
|
|
143
|
-
__name(isRawNodeResponse, "isRawNodeResponse");
|
|
144
|
-
function resolveRawResponse(response) {
|
|
145
|
-
if (isRawNodeResponse(response)) return response;
|
|
146
|
-
if (isRecord2(response) && isRawNodeResponse(response.raw)) return response.raw;
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
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");
|
|
164
|
-
function sendRedirect(response, status, location) {
|
|
165
|
-
const raw = resolveRawResponse(response);
|
|
166
|
-
if (!raw) return;
|
|
167
|
-
raw.statusCode = status;
|
|
168
|
-
raw.setHeader("location", location);
|
|
169
|
-
raw.end();
|
|
170
|
-
}
|
|
171
|
-
__name(sendRedirect, "sendRedirect");
|
|
172
|
-
|
|
173
|
-
// src/server/auth/session-cookie.ts
|
|
174
|
-
import { createHmac, timingSafeEqual } from "crypto";
|
|
175
|
-
var EXP_GRACE_MS = 3e4;
|
|
176
|
-
function base64urlEncode(value) {
|
|
177
|
-
return Buffer.from(value, "utf8").toString("base64url");
|
|
178
|
-
}
|
|
179
|
-
__name(base64urlEncode, "base64urlEncode");
|
|
180
|
-
function base64urlDecode(value) {
|
|
181
|
-
return Buffer.from(value, "base64url").toString("utf8");
|
|
182
|
-
}
|
|
183
|
-
__name(base64urlDecode, "base64urlDecode");
|
|
184
|
-
function hmac(secret, payload) {
|
|
185
|
-
return createHmac("sha256", secret).update(payload).digest("base64url");
|
|
186
|
-
}
|
|
187
|
-
__name(hmac, "hmac");
|
|
188
|
-
function signSessionCookie(user, options) {
|
|
189
|
-
const issuedAt = options.now ?? Date.now();
|
|
190
|
-
const session = {
|
|
191
|
-
sub: user.id,
|
|
192
|
-
...user.name !== void 0 ? {
|
|
193
|
-
name: user.name
|
|
194
|
-
} : {},
|
|
195
|
-
roles: user.roles ?? [],
|
|
196
|
-
iat: issuedAt,
|
|
197
|
-
exp: issuedAt + options.ttlMs
|
|
198
|
-
};
|
|
199
|
-
const encodedPayload = base64urlEncode(JSON.stringify(session));
|
|
200
|
-
const signature = hmac(options.secret, encodedPayload);
|
|
201
|
-
return `${encodedPayload}.${signature}`;
|
|
202
|
-
}
|
|
203
|
-
__name(signSessionCookie, "signSessionCookie");
|
|
204
|
-
function isSessionPayload(value) {
|
|
205
|
-
if (typeof value !== "object" || value === null) return false;
|
|
206
|
-
const record = {
|
|
207
|
-
...value
|
|
208
|
-
};
|
|
209
|
-
if (typeof record.sub !== "string") return false;
|
|
210
|
-
if (record.name !== void 0 && typeof record.name !== "string") return false;
|
|
211
|
-
if (!Array.isArray(record.roles)) return false;
|
|
212
|
-
if (!record.roles.every((role) => typeof role === "string")) return false;
|
|
213
|
-
if (typeof record.iat !== "number" || !Number.isFinite(record.iat)) return false;
|
|
214
|
-
if (typeof record.exp !== "number" || !Number.isFinite(record.exp)) return false;
|
|
215
|
-
return true;
|
|
216
|
-
}
|
|
217
|
-
__name(isSessionPayload, "isSessionPayload");
|
|
218
|
-
function verifySessionCookie(value, options) {
|
|
219
|
-
try {
|
|
220
|
-
const dot = value.indexOf(".");
|
|
221
|
-
if (dot <= 0 || dot === value.length - 1) return null;
|
|
222
|
-
const encodedPayload = value.slice(0, dot);
|
|
223
|
-
const providedSignature = value.slice(dot + 1);
|
|
224
|
-
const expectedSignature = hmac(options.secret, encodedPayload);
|
|
225
|
-
const provided = Buffer.from(providedSignature, "base64url");
|
|
226
|
-
const expected = Buffer.from(expectedSignature, "base64url");
|
|
227
|
-
if (provided.length !== expected.length) return null;
|
|
228
|
-
if (!timingSafeEqual(provided, expected)) return null;
|
|
229
|
-
const decoded = JSON.parse(base64urlDecode(encodedPayload));
|
|
230
|
-
if (!isSessionPayload(decoded)) return null;
|
|
231
|
-
const now = options.now ?? Date.now();
|
|
232
|
-
if (now > decoded.exp + EXP_GRACE_MS) return null;
|
|
233
|
-
const session = {
|
|
234
|
-
sub: decoded.sub,
|
|
235
|
-
...decoded.name !== void 0 ? {
|
|
236
|
-
name: decoded.name
|
|
237
|
-
} : {},
|
|
238
|
-
roles: decoded.roles,
|
|
239
|
-
iat: decoded.iat,
|
|
240
|
-
exp: decoded.exp
|
|
241
|
-
};
|
|
242
|
-
return session;
|
|
243
|
-
} catch {
|
|
244
|
-
return null;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
__name(verifySessionCookie, "verifySessionCookie");
|
|
248
|
-
|
|
249
|
-
// src/server/auth/session-cookie-io.ts
|
|
250
|
-
var SESSION_COOKIE_NAME = "agent_dashboard_session";
|
|
251
|
-
var COOKIE_PATH = "/";
|
|
252
|
-
function issueSessionCookie(user, context) {
|
|
253
|
-
const value = signSessionCookie(user, {
|
|
254
|
-
secret: context.auth.secret,
|
|
255
|
-
ttlMs: context.auth.ttlMs,
|
|
256
|
-
...context.now !== void 0 ? {
|
|
257
|
-
now: context.now
|
|
258
|
-
} : {}
|
|
259
|
-
});
|
|
260
|
-
const cookie = serializeSetCookie(SESSION_COOKIE_NAME, value, {
|
|
261
|
-
path: COOKIE_PATH,
|
|
262
|
-
maxAgeSeconds: Math.floor(context.auth.ttlMs / 1e3),
|
|
263
|
-
secure: isHttpsRequest(context.request)
|
|
264
|
-
});
|
|
265
|
-
appendSetCookie(context.response, cookie);
|
|
266
|
-
}
|
|
267
|
-
__name(issueSessionCookie, "issueSessionCookie");
|
|
268
|
-
function clearSessionCookie(context) {
|
|
269
|
-
const cookie = serializeSetCookie(SESSION_COOKIE_NAME, "", {
|
|
270
|
-
path: COOKIE_PATH,
|
|
271
|
-
maxAgeSeconds: 0,
|
|
272
|
-
secure: isHttpsRequest(context.request),
|
|
273
|
-
clear: true
|
|
274
|
-
});
|
|
275
|
-
appendSetCookie(context.response, cookie);
|
|
276
|
-
}
|
|
277
|
-
__name(clearSessionCookie, "clearSessionCookie");
|
|
278
|
-
var inFlightRevalidations = /* @__PURE__ */ new Map();
|
|
279
|
-
function revalidationKey(session) {
|
|
280
|
-
return `${session.sub}:${session.iat}`;
|
|
281
|
-
}
|
|
282
|
-
__name(revalidationKey, "revalidationKey");
|
|
283
|
-
function getOrStartRevalidation(auth, session, user) {
|
|
284
|
-
const hook = auth.revalidate;
|
|
285
|
-
if (!hook) return Promise.resolve(true);
|
|
286
|
-
const key = revalidationKey(session);
|
|
287
|
-
const inFlight = inFlightRevalidations.get(key);
|
|
288
|
-
if (inFlight) return inFlight;
|
|
289
|
-
const outcome = (async () => {
|
|
290
|
-
try {
|
|
291
|
-
return await hook(user);
|
|
292
|
-
} catch {
|
|
293
|
-
return false;
|
|
294
|
-
}
|
|
295
|
-
})().finally(() => {
|
|
296
|
-
inFlightRevalidations.delete(key);
|
|
297
|
-
});
|
|
298
|
-
inFlightRevalidations.set(key, outcome);
|
|
299
|
-
return outcome;
|
|
300
|
-
}
|
|
301
|
-
__name(getOrStartRevalidation, "getOrStartRevalidation");
|
|
302
|
-
async function maybeRenewSession(auth, session, request, response, now = Date.now()) {
|
|
303
|
-
if (now - session.iat <= auth.ttlMs / 2) return true;
|
|
304
|
-
const user = {
|
|
305
|
-
id: session.sub,
|
|
306
|
-
...session.name !== void 0 ? {
|
|
307
|
-
name: session.name
|
|
308
|
-
} : {},
|
|
309
|
-
roles: session.roles
|
|
310
|
-
};
|
|
311
|
-
const allowed = await getOrStartRevalidation(auth, session, user);
|
|
312
|
-
if (!allowed) {
|
|
313
|
-
clearSessionCookie({
|
|
314
|
-
request,
|
|
315
|
-
response
|
|
316
|
-
});
|
|
317
|
-
return false;
|
|
318
|
-
}
|
|
319
|
-
issueSessionCookie(user, {
|
|
320
|
-
auth,
|
|
321
|
-
request,
|
|
322
|
-
response,
|
|
323
|
-
now
|
|
324
|
-
});
|
|
325
|
-
return true;
|
|
326
|
-
}
|
|
327
|
-
__name(maybeRenewSession, "maybeRenewSession");
|
|
328
|
-
|
|
329
|
-
// src/server/auth/dashboard-auth.guard.ts
|
|
330
|
-
function _ts_decorate(decorators, target, key, desc) {
|
|
331
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
332
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
333
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
334
|
-
} else {
|
|
335
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
336
|
-
if (d = decorators[i]) {
|
|
337
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
342
|
-
}
|
|
343
|
-
__name(_ts_decorate, "_ts_decorate");
|
|
344
|
-
function _ts_metadata(metadataKey, metadataValue) {
|
|
345
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
346
|
-
return Reflect.metadata(metadataKey, metadataValue);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
__name(_ts_metadata, "_ts_metadata");
|
|
350
|
-
function _ts_param(paramIndex, decorator) {
|
|
351
|
-
return function(target, key) {
|
|
352
|
-
decorator(target, key, paramIndex);
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
__name(_ts_param, "_ts_param");
|
|
356
|
-
var DashboardAuthGuard = class {
|
|
357
|
-
static {
|
|
358
|
-
__name(this, "DashboardAuthGuard");
|
|
359
|
-
}
|
|
360
|
-
auth;
|
|
361
|
-
constructor(auth) {
|
|
362
|
-
this.auth = auth;
|
|
363
|
-
}
|
|
364
|
-
async canActivate(context) {
|
|
365
|
-
if (!this.auth) return true;
|
|
366
|
-
const http = context.switchToHttp();
|
|
367
|
-
const request = http.getRequest();
|
|
368
|
-
const session = this.verifyRequestSession(request);
|
|
369
|
-
if (!session) throw new UnauthorizedException();
|
|
370
|
-
attachSession(request, session);
|
|
371
|
-
if (!await maybeRenewSession(this.auth, session, request, http.getResponse())) {
|
|
372
|
-
throw new UnauthorizedException();
|
|
373
|
-
}
|
|
374
|
-
return true;
|
|
375
|
-
}
|
|
376
|
-
verifyRequestSession(request) {
|
|
377
|
-
const auth = this.auth;
|
|
378
|
-
if (!auth) return null;
|
|
379
|
-
const cookieValue = parseCookieHeader(readCookieHeader(request))[SESSION_COOKIE_NAME];
|
|
380
|
-
if (cookieValue === void 0) return null;
|
|
381
|
-
return verifySessionCookie(cookieValue, {
|
|
382
|
-
secret: auth.secret
|
|
383
|
-
});
|
|
384
|
-
}
|
|
385
|
-
};
|
|
386
|
-
DashboardAuthGuard = _ts_decorate([
|
|
387
|
-
Injectable(),
|
|
388
|
-
_ts_param(0, Optional()),
|
|
389
|
-
_ts_param(0, Inject(DASHBOARD_AUTH)),
|
|
390
|
-
_ts_metadata("design:type", Function),
|
|
391
|
-
_ts_metadata("design:paramtypes", [
|
|
392
|
-
Object
|
|
393
|
-
])
|
|
394
|
-
], DashboardAuthGuard);
|
|
5
|
+
import { CanAnyone } from "@dudousxd/nestjs-agent-core";
|
|
6
|
+
import { Body, Controller, Get, HttpCode, Inject as Inject2, Optional as Optional2, Param, Post, Query, Req, Sse } from "@nestjs/common";
|
|
395
7
|
|
|
396
8
|
// src/server/dashboard.service.ts
|
|
397
9
|
import { subscribe, unsubscribe } from "diagnostics_channel";
|
|
398
10
|
import { channelName } from "@dudousxd/nestjs-diagnostics";
|
|
399
|
-
import { Inject
|
|
11
|
+
import { Inject, Injectable, NotFoundException, NotImplementedException, Optional } from "@nestjs/common";
|
|
400
12
|
import { Observable as Observable2 } from "rxjs";
|
|
401
13
|
|
|
402
14
|
// src/server/parse-approval-decision.ts
|
|
@@ -461,8 +73,18 @@ function isFiniteNonNegative(value) {
|
|
|
461
73
|
}
|
|
462
74
|
__name(isFiniteNonNegative, "isFiniteNonNegative");
|
|
463
75
|
|
|
76
|
+
// src/server/tokens.ts
|
|
77
|
+
var AGENT_GOVERNANCE_QUERIES = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:governance-queries");
|
|
78
|
+
var AGENT_ACTOR_DIRECTORY = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:actor-directory");
|
|
79
|
+
var AGENT_PRICING_STORE = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:pricing-store");
|
|
80
|
+
var AGENT_APPROVAL_PORT = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:approval-port");
|
|
81
|
+
var AGENT_ACTOR_RESOLVER = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent:actor-resolver");
|
|
82
|
+
var DASHBOARD_BASE_PATH = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:base-path");
|
|
83
|
+
var DASHBOARD_API_PATH = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:api-path");
|
|
84
|
+
var DASHBOARD_APPROVAL_ACTOR_REF = /* @__PURE__ */ Symbol.for("@dudousxd/nestjs-agent-dashboard:approval-actor-ref");
|
|
85
|
+
|
|
464
86
|
// src/server/dashboard.service.ts
|
|
465
|
-
function
|
|
87
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
466
88
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
467
89
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
468
90
|
r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -475,19 +97,19 @@ function _ts_decorate2(decorators, target, key, desc) {
|
|
|
475
97
|
}
|
|
476
98
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
477
99
|
}
|
|
478
|
-
__name(
|
|
479
|
-
function
|
|
100
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
101
|
+
function _ts_metadata(metadataKey, metadataValue) {
|
|
480
102
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
481
103
|
return Reflect.metadata(metadataKey, metadataValue);
|
|
482
104
|
}
|
|
483
105
|
}
|
|
484
|
-
__name(
|
|
485
|
-
function
|
|
106
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
107
|
+
function _ts_param(paramIndex, decorator) {
|
|
486
108
|
return function(target, key) {
|
|
487
109
|
decorator(target, key, paramIndex);
|
|
488
110
|
};
|
|
489
111
|
}
|
|
490
|
-
__name(
|
|
112
|
+
__name(_ts_param, "_ts_param");
|
|
491
113
|
var PRICING_STORE_UNBOUND_MESSAGE = "Pricing CRUD is unavailable: no AGENT_PRICING_STORE is bound. Bind a pricing store (e.g. MikroOrmPricingStore from @dudousxd/nestjs-agent-store-mikro-orm) to enable it.";
|
|
492
114
|
var APPROVAL_PORT_UNBOUND_MESSAGE = "Approve/reject is unavailable: no AGENT_APPROVAL_PORT is bound. Import AgentModule from @dudousxd/nestjs-agent alongside this dashboard to enable it \u2014 the approvals inbox stays read-only until then.";
|
|
493
115
|
var GENUI_STATS_UNSUPPORTED_MESSAGE = "Generative UI telemetry is unavailable: the bound AGENT_GOVERNANCE_QUERIES store does not implement genuiStats. Use a store adapter that records generative-UI calls (recordGenuiCalls) to enable it.";
|
|
@@ -521,16 +143,20 @@ var DashboardService = class {
|
|
|
521
143
|
}
|
|
522
144
|
/** Spend/usage overview for a day range: by-model + by-actor spend and the daily trend, in parallel. */
|
|
523
145
|
async spend(range) {
|
|
524
|
-
const [byModel, byActorRaw, trend] = await Promise.all([
|
|
146
|
+
const [byModel, byActorRaw, trend, byFeature] = await Promise.all([
|
|
525
147
|
this.queries.spendByModel(range),
|
|
526
148
|
this.queries.spendByActor(range),
|
|
527
|
-
this.queries.usageTrend(range)
|
|
149
|
+
this.queries.usageTrend(range),
|
|
150
|
+
this.queries.spendByFeature?.(range)
|
|
528
151
|
]);
|
|
529
152
|
const byActor = await this.withActorLabels(byActorRaw);
|
|
530
153
|
return {
|
|
531
154
|
byModel,
|
|
532
155
|
byActor,
|
|
533
|
-
trend
|
|
156
|
+
trend,
|
|
157
|
+
...byFeature !== void 0 ? {
|
|
158
|
+
byFeature
|
|
159
|
+
} : {}
|
|
534
160
|
};
|
|
535
161
|
}
|
|
536
162
|
/** Top threads by cost for a day range (default 10, highest cost first). */
|
|
@@ -752,17 +378,17 @@ var DashboardService = class {
|
|
|
752
378
|
});
|
|
753
379
|
}
|
|
754
380
|
};
|
|
755
|
-
DashboardService =
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
381
|
+
DashboardService = _ts_decorate([
|
|
382
|
+
Injectable(),
|
|
383
|
+
_ts_param(0, Inject(AGENT_GOVERNANCE_QUERIES)),
|
|
384
|
+
_ts_param(1, Optional()),
|
|
385
|
+
_ts_param(1, Inject(AGENT_ACTOR_DIRECTORY)),
|
|
386
|
+
_ts_param(2, Optional()),
|
|
387
|
+
_ts_param(2, Inject(AGENT_PRICING_STORE)),
|
|
388
|
+
_ts_param(3, Optional()),
|
|
389
|
+
_ts_param(3, Inject(AGENT_APPROVAL_PORT)),
|
|
390
|
+
_ts_metadata("design:type", Function),
|
|
391
|
+
_ts_metadata("design:paramtypes", [
|
|
766
392
|
typeof AgentGovernanceQueries === "undefined" ? Object : AgentGovernanceQueries,
|
|
767
393
|
typeof ActorDirectory === "undefined" ? Object : ActorDirectory,
|
|
768
394
|
typeof AgentPricingStore === "undefined" ? Object : AgentPricingStore,
|
|
@@ -930,7 +556,7 @@ function parseApprovalWhere(raw) {
|
|
|
930
556
|
__name(parseApprovalWhere, "parseApprovalWhere");
|
|
931
557
|
|
|
932
558
|
// src/server/agent-api.controller.ts
|
|
933
|
-
function
|
|
559
|
+
function _ts_decorate2(decorators, target, key, desc) {
|
|
934
560
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
935
561
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
936
562
|
r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -943,19 +569,19 @@ function _ts_decorate3(decorators, target, key, desc) {
|
|
|
943
569
|
}
|
|
944
570
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
945
571
|
}
|
|
946
|
-
__name(
|
|
947
|
-
function
|
|
572
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
573
|
+
function _ts_metadata2(metadataKey, metadataValue) {
|
|
948
574
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
949
575
|
return Reflect.metadata(metadataKey, metadataValue);
|
|
950
576
|
}
|
|
951
577
|
}
|
|
952
|
-
__name(
|
|
953
|
-
function
|
|
578
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
579
|
+
function _ts_param2(paramIndex, decorator) {
|
|
954
580
|
return function(target, key) {
|
|
955
581
|
decorator(target, key, paramIndex);
|
|
956
582
|
};
|
|
957
583
|
}
|
|
958
|
-
__name(
|
|
584
|
+
__name(_ts_param2, "_ts_param");
|
|
959
585
|
var DAY_MS = 864e5;
|
|
960
586
|
var ISO_DAY2 = /^\d{4}-\d{2}-\d{2}$/;
|
|
961
587
|
function utcDay(daysAgo) {
|
|
@@ -1173,620 +799,222 @@ var AgentApiController = class {
|
|
|
1173
799
|
return this.dashboard.streamEvents();
|
|
1174
800
|
}
|
|
1175
801
|
};
|
|
1176
|
-
|
|
802
|
+
_ts_decorate2([
|
|
1177
803
|
Get("spend"),
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
804
|
+
_ts_param2(0, Query("from")),
|
|
805
|
+
_ts_param2(1, Query("to")),
|
|
806
|
+
_ts_metadata2("design:type", Function),
|
|
807
|
+
_ts_metadata2("design:paramtypes", [
|
|
1182
808
|
String,
|
|
1183
809
|
String
|
|
1184
810
|
]),
|
|
1185
|
-
|
|
811
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1186
812
|
], AgentApiController.prototype, "spend", null);
|
|
1187
|
-
|
|
813
|
+
_ts_decorate2([
|
|
1188
814
|
Get("top-threads"),
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
815
|
+
_ts_param2(0, Query("from")),
|
|
816
|
+
_ts_param2(1, Query("to")),
|
|
817
|
+
_ts_param2(2, Query("limit")),
|
|
818
|
+
_ts_metadata2("design:type", Function),
|
|
819
|
+
_ts_metadata2("design:paramtypes", [
|
|
1194
820
|
String,
|
|
1195
821
|
String,
|
|
1196
822
|
String
|
|
1197
823
|
]),
|
|
1198
|
-
|
|
824
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1199
825
|
], AgentApiController.prototype, "topThreads", null);
|
|
1200
|
-
|
|
826
|
+
_ts_decorate2([
|
|
1201
827
|
Get("reliability"),
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
828
|
+
_ts_param2(0, Query("from")),
|
|
829
|
+
_ts_param2(1, Query("to")),
|
|
830
|
+
_ts_metadata2("design:type", Function),
|
|
831
|
+
_ts_metadata2("design:paramtypes", [
|
|
1206
832
|
String,
|
|
1207
833
|
String
|
|
1208
834
|
]),
|
|
1209
|
-
|
|
835
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1210
836
|
], AgentApiController.prototype, "reliability", null);
|
|
1211
|
-
|
|
837
|
+
_ts_decorate2([
|
|
1212
838
|
Get("runs"),
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
839
|
+
_ts_param2(0, Query("limit")),
|
|
840
|
+
_ts_metadata2("design:type", Function),
|
|
841
|
+
_ts_metadata2("design:paramtypes", [
|
|
1216
842
|
String
|
|
1217
843
|
]),
|
|
1218
|
-
|
|
844
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1219
845
|
], AgentApiController.prototype, "runs", null);
|
|
1220
|
-
|
|
846
|
+
_ts_decorate2([
|
|
1221
847
|
Get("runs-page"),
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
848
|
+
_ts_param2(0, Query("page")),
|
|
849
|
+
_ts_param2(1, Query("limit")),
|
|
850
|
+
_ts_param2(2, Query("where")),
|
|
851
|
+
_ts_metadata2("design:type", Function),
|
|
852
|
+
_ts_metadata2("design:paramtypes", [
|
|
1227
853
|
String,
|
|
1228
854
|
String,
|
|
1229
855
|
typeof Record === "undefined" ? Object : Record
|
|
1230
856
|
]),
|
|
1231
|
-
|
|
857
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1232
858
|
], AgentApiController.prototype, "runsPage", null);
|
|
1233
|
-
|
|
859
|
+
_ts_decorate2([
|
|
1234
860
|
Get("runs/:runId"),
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
861
|
+
_ts_param2(0, Param("runId")),
|
|
862
|
+
_ts_metadata2("design:type", Function),
|
|
863
|
+
_ts_metadata2("design:paramtypes", [
|
|
1238
864
|
String
|
|
1239
865
|
]),
|
|
1240
|
-
|
|
866
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1241
867
|
], AgentApiController.prototype, "runDetail", null);
|
|
1242
|
-
|
|
868
|
+
_ts_decorate2([
|
|
1243
869
|
Get("tool-calls"),
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
870
|
+
_ts_param2(0, Query("limit")),
|
|
871
|
+
_ts_metadata2("design:type", Function),
|
|
872
|
+
_ts_metadata2("design:paramtypes", [
|
|
1247
873
|
String
|
|
1248
874
|
]),
|
|
1249
|
-
|
|
875
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1250
876
|
], AgentApiController.prototype, "toolCalls", null);
|
|
1251
|
-
|
|
877
|
+
_ts_decorate2([
|
|
1252
878
|
Get("tool-calls-page"),
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
879
|
+
_ts_param2(0, Query("page")),
|
|
880
|
+
_ts_param2(1, Query("limit")),
|
|
881
|
+
_ts_param2(2, Query("where")),
|
|
882
|
+
_ts_metadata2("design:type", Function),
|
|
883
|
+
_ts_metadata2("design:paramtypes", [
|
|
1258
884
|
String,
|
|
1259
885
|
String,
|
|
1260
886
|
typeof Record === "undefined" ? Object : Record
|
|
1261
887
|
]),
|
|
1262
|
-
|
|
888
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1263
889
|
], AgentApiController.prototype, "toolCallsPage", null);
|
|
1264
|
-
|
|
890
|
+
_ts_decorate2([
|
|
1265
891
|
Get("approvals"),
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
892
|
+
_ts_param2(0, Query("limit")),
|
|
893
|
+
_ts_metadata2("design:type", Function),
|
|
894
|
+
_ts_metadata2("design:paramtypes", [
|
|
1269
895
|
String
|
|
1270
896
|
]),
|
|
1271
|
-
|
|
897
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1272
898
|
], AgentApiController.prototype, "approvals", null);
|
|
1273
|
-
|
|
899
|
+
_ts_decorate2([
|
|
1274
900
|
Get("approvals-page"),
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
901
|
+
_ts_param2(0, Query("page")),
|
|
902
|
+
_ts_param2(1, Query("limit")),
|
|
903
|
+
_ts_param2(2, Query("where")),
|
|
904
|
+
_ts_metadata2("design:type", Function),
|
|
905
|
+
_ts_metadata2("design:paramtypes", [
|
|
1280
906
|
String,
|
|
1281
907
|
String,
|
|
1282
908
|
typeof Record === "undefined" ? Object : Record
|
|
1283
909
|
]),
|
|
1284
|
-
|
|
910
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1285
911
|
], AgentApiController.prototype, "approvalsPage", null);
|
|
1286
|
-
|
|
912
|
+
_ts_decorate2([
|
|
1287
913
|
Post("approvals/:toolCallId"),
|
|
1288
914
|
HttpCode(204),
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
915
|
+
_ts_param2(0, Param("toolCallId")),
|
|
916
|
+
_ts_param2(1, Body()),
|
|
917
|
+
_ts_param2(2, Req()),
|
|
918
|
+
_ts_metadata2("design:type", Function),
|
|
919
|
+
_ts_metadata2("design:paramtypes", [
|
|
1294
920
|
String,
|
|
1295
921
|
Object,
|
|
1296
922
|
Object
|
|
1297
923
|
]),
|
|
1298
|
-
|
|
924
|
+
_ts_metadata2("design:returntype", Promise)
|
|
1299
925
|
], AgentApiController.prototype, "decideApproval", null);
|
|
1300
|
-
|
|
926
|
+
_ts_decorate2([
|
|
1301
927
|
Get("tools"),
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
928
|
+
_ts_param2(0, Query("from")),
|
|
929
|
+
_ts_param2(1, Query("to")),
|
|
930
|
+
_ts_metadata2("design:type", Function),
|
|
931
|
+
_ts_metadata2("design:paramtypes", [
|
|
1306
932
|
String,
|
|
1307
933
|
String
|
|
1308
934
|
]),
|
|
1309
|
-
|
|
935
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1310
936
|
], AgentApiController.prototype, "tools", null);
|
|
1311
|
-
|
|
937
|
+
_ts_decorate2([
|
|
1312
938
|
Get("genui"),
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
939
|
+
_ts_param2(0, Query("from")),
|
|
940
|
+
_ts_param2(1, Query("to")),
|
|
941
|
+
_ts_metadata2("design:type", Function),
|
|
942
|
+
_ts_metadata2("design:paramtypes", [
|
|
1317
943
|
String,
|
|
1318
944
|
String
|
|
1319
945
|
]),
|
|
1320
|
-
|
|
946
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1321
947
|
], AgentApiController.prototype, "genui", null);
|
|
1322
|
-
|
|
948
|
+
_ts_decorate2([
|
|
1323
949
|
Get("threads"),
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
950
|
+
_ts_param2(0, Query("limit")),
|
|
951
|
+
_ts_metadata2("design:type", Function),
|
|
952
|
+
_ts_metadata2("design:paramtypes", [
|
|
1327
953
|
String
|
|
1328
954
|
]),
|
|
1329
|
-
|
|
955
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1330
956
|
], AgentApiController.prototype, "threads", null);
|
|
1331
|
-
|
|
957
|
+
_ts_decorate2([
|
|
1332
958
|
Get("threads-page"),
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
959
|
+
_ts_param2(0, Query("page")),
|
|
960
|
+
_ts_param2(1, Query("limit")),
|
|
961
|
+
_ts_param2(2, Query("where")),
|
|
962
|
+
_ts_metadata2("design:type", Function),
|
|
963
|
+
_ts_metadata2("design:paramtypes", [
|
|
1338
964
|
String,
|
|
1339
965
|
String,
|
|
1340
966
|
typeof Record === "undefined" ? Object : Record
|
|
1341
967
|
]),
|
|
1342
|
-
|
|
968
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1343
969
|
], AgentApiController.prototype, "threadsPage", null);
|
|
1344
|
-
|
|
970
|
+
_ts_decorate2([
|
|
1345
971
|
Get("threads/:threadId"),
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
972
|
+
_ts_param2(0, Param("threadId")),
|
|
973
|
+
_ts_param2(1, Query("messages")),
|
|
974
|
+
_ts_param2(2, Query("runs")),
|
|
975
|
+
_ts_metadata2("design:type", Function),
|
|
976
|
+
_ts_metadata2("design:paramtypes", [
|
|
1351
977
|
String,
|
|
1352
978
|
String,
|
|
1353
979
|
String
|
|
1354
980
|
]),
|
|
1355
|
-
|
|
981
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1356
982
|
], AgentApiController.prototype, "threadDetail", null);
|
|
1357
|
-
|
|
983
|
+
_ts_decorate2([
|
|
1358
984
|
Get("pricing"),
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
985
|
+
_ts_metadata2("design:type", Function),
|
|
986
|
+
_ts_metadata2("design:paramtypes", []),
|
|
987
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1362
988
|
], AgentApiController.prototype, "listPrices", null);
|
|
1363
|
-
|
|
989
|
+
_ts_decorate2([
|
|
1364
990
|
Post("pricing"),
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
991
|
+
_ts_param2(0, Body()),
|
|
992
|
+
_ts_metadata2("design:type", Function),
|
|
993
|
+
_ts_metadata2("design:paramtypes", [
|
|
1368
994
|
Object
|
|
1369
995
|
]),
|
|
1370
|
-
|
|
996
|
+
_ts_metadata2("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
1371
997
|
], AgentApiController.prototype, "upsertPrice", null);
|
|
1372
|
-
|
|
998
|
+
_ts_decorate2([
|
|
1373
999
|
Sse("stream"),
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1000
|
+
_ts_metadata2("design:type", Function),
|
|
1001
|
+
_ts_metadata2("design:paramtypes", []),
|
|
1002
|
+
_ts_metadata2("design:returntype", typeof Observable === "undefined" ? Object : Observable)
|
|
1377
1003
|
], AgentApiController.prototype, "stream", null);
|
|
1378
|
-
AgentApiController =
|
|
1004
|
+
AgentApiController = _ts_decorate2([
|
|
1005
|
+
CanAnyone(),
|
|
1379
1006
|
Controller(),
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
_ts_metadata3("design:paramtypes", [
|
|
1007
|
+
_ts_param2(1, Inject2(DASHBOARD_APPROVAL_ACTOR_REF)),
|
|
1008
|
+
_ts_param2(2, Optional2()),
|
|
1009
|
+
_ts_param2(2, Inject2(AGENT_ACTOR_RESOLVER)),
|
|
1010
|
+
_ts_metadata2("design:type", Function),
|
|
1011
|
+
_ts_metadata2("design:paramtypes", [
|
|
1386
1012
|
typeof DashboardService === "undefined" ? Object : DashboardService,
|
|
1387
1013
|
Object,
|
|
1388
1014
|
typeof ActorResolver === "undefined" ? Object : ActorResolver
|
|
1389
1015
|
])
|
|
1390
1016
|
], AgentApiController);
|
|
1391
1017
|
|
|
1392
|
-
// src/server/agent-dashboard-auth.controller.ts
|
|
1393
|
-
import { Body as Body2, Controller as Controller2, Get as Get2, Header, HttpCode as HttpCode2, Inject as Inject4, Logger, NotFoundException as NotFoundException2, Optional as Optional4, Post as Post2, Query as Query2, Req as Req2, Res, UnauthorizedException as UnauthorizedException2 } from "@nestjs/common";
|
|
1394
|
-
|
|
1395
|
-
// src/server/auth/login-page.ts
|
|
1396
|
-
function escapeHtml(value) {
|
|
1397
|
-
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1398
|
-
}
|
|
1399
|
-
__name(escapeHtml, "escapeHtml");
|
|
1400
|
-
function pageShell(content, title) {
|
|
1401
|
-
return `<!doctype html>
|
|
1402
|
-
<html lang="en">
|
|
1403
|
-
<head>
|
|
1404
|
-
<meta charset="utf-8" />
|
|
1405
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
1406
|
-
<meta name="robots" content="noindex, nofollow" />
|
|
1407
|
-
<title>${title}</title>
|
|
1408
|
-
<style>
|
|
1409
|
-
:root { color-scheme: dark; }
|
|
1410
|
-
* { box-sizing: border-box; }
|
|
1411
|
-
body {
|
|
1412
|
-
margin: 0;
|
|
1413
|
-
min-height: 100vh;
|
|
1414
|
-
display: flex;
|
|
1415
|
-
align-items: center;
|
|
1416
|
-
justify-content: center;
|
|
1417
|
-
background: #09090b;
|
|
1418
|
-
color: #e4e4e7;
|
|
1419
|
-
font: 14px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
1420
|
-
padding: 16px;
|
|
1421
|
-
}
|
|
1422
|
-
.card {
|
|
1423
|
-
width: 100%;
|
|
1424
|
-
max-width: 384px;
|
|
1425
|
-
border: 1px solid #27272a;
|
|
1426
|
-
background: #18181b;
|
|
1427
|
-
border-radius: 8px;
|
|
1428
|
-
padding: 32px;
|
|
1429
|
-
box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.5);
|
|
1430
|
-
}
|
|
1431
|
-
.brand {
|
|
1432
|
-
margin: 0 0 24px;
|
|
1433
|
-
text-align: center;
|
|
1434
|
-
font-size: 18px;
|
|
1435
|
-
font-weight: 600;
|
|
1436
|
-
color: #34d399;
|
|
1437
|
-
}
|
|
1438
|
-
h1 {
|
|
1439
|
-
margin: 0 0 12px;
|
|
1440
|
-
font-size: 16px;
|
|
1441
|
-
font-weight: 600;
|
|
1442
|
-
color: #f4f4f5;
|
|
1443
|
-
}
|
|
1444
|
-
p { margin: 0 0 16px; color: #a1a1aa; }
|
|
1445
|
-
form { display: flex; flex-direction: column; gap: 16px; }
|
|
1446
|
-
label { display: flex; flex-direction: column; gap: 6px; }
|
|
1447
|
-
.field-label {
|
|
1448
|
-
font-size: 11px;
|
|
1449
|
-
text-transform: uppercase;
|
|
1450
|
-
letter-spacing: 0.05em;
|
|
1451
|
-
color: #71717a;
|
|
1452
|
-
}
|
|
1453
|
-
input {
|
|
1454
|
-
border-radius: 4px;
|
|
1455
|
-
border: 1px solid #3f3f46;
|
|
1456
|
-
background: #09090b;
|
|
1457
|
-
color: #f4f4f5;
|
|
1458
|
-
padding: 8px 12px;
|
|
1459
|
-
font: inherit;
|
|
1460
|
-
outline: none;
|
|
1461
|
-
}
|
|
1462
|
-
input:focus { border-color: rgb(52 211 153 / 0.6); }
|
|
1463
|
-
.error { margin: 0; font-size: 12px; color: #fb7185; }
|
|
1464
|
-
button {
|
|
1465
|
-
margin-top: 8px;
|
|
1466
|
-
border-radius: 4px;
|
|
1467
|
-
border: 1px solid rgb(52 211 153 / 0.4);
|
|
1468
|
-
background: rgb(52 211 153 / 0.1);
|
|
1469
|
-
color: #6ee7b7;
|
|
1470
|
-
padding: 8px 12px;
|
|
1471
|
-
font: inherit;
|
|
1472
|
-
font-size: 12px;
|
|
1473
|
-
font-weight: 500;
|
|
1474
|
-
text-transform: uppercase;
|
|
1475
|
-
letter-spacing: 0.05em;
|
|
1476
|
-
cursor: pointer;
|
|
1477
|
-
}
|
|
1478
|
-
button:hover { background: rgb(52 211 153 / 0.2); }
|
|
1479
|
-
</style>
|
|
1480
|
-
</head>
|
|
1481
|
-
<body>
|
|
1482
|
-
<div class="card">
|
|
1483
|
-
${content}
|
|
1484
|
-
</div>
|
|
1485
|
-
</body>
|
|
1486
|
-
</html>`;
|
|
1487
|
-
}
|
|
1488
|
-
__name(pageShell, "pageShell");
|
|
1489
|
-
function renderLoginPage(options) {
|
|
1490
|
-
const action = escapeHtml(options.actionUrl);
|
|
1491
|
-
const returnTo = escapeHtml(options.returnTo);
|
|
1492
|
-
const errorBanner = options.error === true ? '<p role="alert" class="error">Invalid username or password.</p>' : "";
|
|
1493
|
-
return pageShell(`<p class="brand">AI Gateway</p>
|
|
1494
|
-
<form method="post" action="${action}">
|
|
1495
|
-
<input type="hidden" name="returnTo" value="${returnTo}" />
|
|
1496
|
-
<label>
|
|
1497
|
-
<span class="field-label">Username</span>
|
|
1498
|
-
<input type="text" name="username" autocomplete="username" autofocus />
|
|
1499
|
-
</label>
|
|
1500
|
-
<label>
|
|
1501
|
-
<span class="field-label">Password</span>
|
|
1502
|
-
<input type="password" name="password" autocomplete="current-password" />
|
|
1503
|
-
</label>
|
|
1504
|
-
${errorBanner}
|
|
1505
|
-
<button type="submit">Sign in</button>
|
|
1506
|
-
</form>`, "Sign in \u2014 AI Gateway");
|
|
1507
|
-
}
|
|
1508
|
-
__name(renderLoginPage, "renderLoginPage");
|
|
1509
|
-
function renderSessionRequiredPage() {
|
|
1510
|
-
return pageShell(`<p class="brand">AI Gateway</p>
|
|
1511
|
-
<h1>Open this console from your application</h1>
|
|
1512
|
-
<p>Your session is minted by the host app. Use its console launcher to sign in, then reload.</p>`, "Sign in \u2014 AI Gateway");
|
|
1513
|
-
}
|
|
1514
|
-
__name(renderSessionRequiredPage, "renderSessionRequiredPage");
|
|
1515
|
-
|
|
1516
|
-
// src/server/auth/sanitize-return-to.ts
|
|
1517
|
-
function sanitizeReturnTo(basePath, returnTo) {
|
|
1518
|
-
if (typeof returnTo !== "string" || returnTo === "") return basePath;
|
|
1519
|
-
if (!returnTo.startsWith("/") || returnTo.startsWith("//")) return basePath;
|
|
1520
|
-
if (returnTo !== basePath && !returnTo.startsWith(`${basePath}/`) && !returnTo.startsWith(`${basePath}?`)) {
|
|
1521
|
-
return basePath;
|
|
1522
|
-
}
|
|
1523
|
-
return returnTo;
|
|
1524
|
-
}
|
|
1525
|
-
__name(sanitizeReturnTo, "sanitizeReturnTo");
|
|
1526
|
-
|
|
1527
|
-
// src/server/agent-dashboard-auth.controller.ts
|
|
1528
|
-
function _ts_decorate4(decorators, target, key, desc) {
|
|
1529
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1530
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
1531
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
1532
|
-
} else {
|
|
1533
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
1534
|
-
if (d = decorators[i]) {
|
|
1535
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1536
|
-
}
|
|
1537
|
-
}
|
|
1538
|
-
}
|
|
1539
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1540
|
-
}
|
|
1541
|
-
__name(_ts_decorate4, "_ts_decorate");
|
|
1542
|
-
function _ts_metadata4(metadataKey, metadataValue) {
|
|
1543
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
1544
|
-
return Reflect.metadata(metadataKey, metadataValue);
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1547
|
-
__name(_ts_metadata4, "_ts_metadata");
|
|
1548
|
-
function _ts_param4(paramIndex, decorator) {
|
|
1549
|
-
return function(target, key) {
|
|
1550
|
-
decorator(target, key, paramIndex);
|
|
1551
|
-
};
|
|
1552
|
-
}
|
|
1553
|
-
__name(_ts_param4, "_ts_param");
|
|
1554
|
-
function isNonEmptyString(value) {
|
|
1555
|
-
return typeof value === "string" && value.trim() !== "";
|
|
1556
|
-
}
|
|
1557
|
-
__name(isNonEmptyString, "isNonEmptyString");
|
|
1558
|
-
function isString(value) {
|
|
1559
|
-
return typeof value === "string";
|
|
1560
|
-
}
|
|
1561
|
-
__name(isString, "isString");
|
|
1562
|
-
var AgentDashboardAuthController = class _AgentDashboardAuthController {
|
|
1563
|
-
static {
|
|
1564
|
-
__name(this, "AgentDashboardAuthController");
|
|
1565
|
-
}
|
|
1566
|
-
auth;
|
|
1567
|
-
basePath;
|
|
1568
|
-
logger = new Logger(_AgentDashboardAuthController.name);
|
|
1569
|
-
/** Warn once PER HOOK KIND (not per request) so a broken hook can't be used to flood the logs. */
|
|
1570
|
-
warnedHooks = /* @__PURE__ */ new Set();
|
|
1571
|
-
constructor(auth, basePath) {
|
|
1572
|
-
this.auth = auth;
|
|
1573
|
-
this.basePath = basePath;
|
|
1574
|
-
}
|
|
1575
|
-
loginPage(req, res, returnToQuery, error) {
|
|
1576
|
-
const auth = this.requireAuth();
|
|
1577
|
-
if (!auth.modes.includes("login")) throw new NotFoundException2();
|
|
1578
|
-
const returnTo = sanitizeReturnTo(this.basePath, returnToQuery);
|
|
1579
|
-
if (this.currentSession(req)) {
|
|
1580
|
-
res.status(302);
|
|
1581
|
-
res.setHeader("Location", returnTo);
|
|
1582
|
-
return "";
|
|
1583
|
-
}
|
|
1584
|
-
return renderLoginPage({
|
|
1585
|
-
actionUrl: `${this.basePath}/auth/login`,
|
|
1586
|
-
returnTo,
|
|
1587
|
-
error: error !== void 0
|
|
1588
|
-
});
|
|
1589
|
-
}
|
|
1590
|
-
async login(body, req, res) {
|
|
1591
|
-
const auth = this.requireAuth();
|
|
1592
|
-
if (!auth.modes.includes("login")) throw new NotFoundException2();
|
|
1593
|
-
const returnTo = sanitizeReturnTo(this.basePath, body?.returnTo);
|
|
1594
|
-
const username = body?.username;
|
|
1595
|
-
const password = body?.password;
|
|
1596
|
-
if (!isNonEmptyString(username) || password !== void 0 && !isString(password)) {
|
|
1597
|
-
this.redirectToLoginError(res, returnTo);
|
|
1598
|
-
return "";
|
|
1599
|
-
}
|
|
1600
|
-
const user = await this.runHook("login", () => auth.login?.(username.trim(), isString(password) ? password : "") ?? null);
|
|
1601
|
-
if (!user) {
|
|
1602
|
-
this.redirectToLoginError(res, returnTo);
|
|
1603
|
-
return "";
|
|
1604
|
-
}
|
|
1605
|
-
issueSessionCookie(user, {
|
|
1606
|
-
auth,
|
|
1607
|
-
request: req,
|
|
1608
|
-
response: res
|
|
1609
|
-
});
|
|
1610
|
-
res.status(302);
|
|
1611
|
-
res.setHeader("Location", returnTo);
|
|
1612
|
-
return "";
|
|
1613
|
-
}
|
|
1614
|
-
logout(req, res) {
|
|
1615
|
-
clearSessionCookie({
|
|
1616
|
-
request: req,
|
|
1617
|
-
response: res
|
|
1618
|
-
});
|
|
1619
|
-
res.status(302);
|
|
1620
|
-
res.setHeader("Location", this.auth && !this.auth.modes.includes("login") ? `${this.basePath}/auth/session-required` : `${this.basePath}/auth/login`);
|
|
1621
|
-
return "";
|
|
1622
|
-
}
|
|
1623
|
-
// Mode A: the host frontend (carrying its own auth) POSTs here; the host hook validates the raw
|
|
1624
|
-
// request and returns the session user, or `null` to deny. No credential reaches this library.
|
|
1625
|
-
async session(request, response) {
|
|
1626
|
-
const auth = this.requireAuth();
|
|
1627
|
-
if (!auth.modes.includes("session")) throw new NotFoundException2();
|
|
1628
|
-
const user = await this.runHook("session", () => auth.session?.(request) ?? null);
|
|
1629
|
-
if (!user) throw new UnauthorizedException2();
|
|
1630
|
-
issueSessionCookie(user, {
|
|
1631
|
-
auth,
|
|
1632
|
-
request,
|
|
1633
|
-
response
|
|
1634
|
-
});
|
|
1635
|
-
}
|
|
1636
|
-
// Mode-A-only landing: the host mints the session, so there is nothing to submit here. Serves
|
|
1637
|
-
// as the redirect target `DashboardAuthPageGuard` bounces to instead of `/auth/login`, which
|
|
1638
|
-
// 404s under Mode A (see `loginPage` above).
|
|
1639
|
-
//
|
|
1640
|
-
// Non-passthrough `@Res()` (unlike its sibling routes) because `dashboardAuth.unauthenticatedPage`
|
|
1641
|
-
// hands the response to the HOST, which writes and ends it itself — there is no return value for
|
|
1642
|
-
// Nest to send, and letting Nest also send one would double-write. The `Content-Type` /
|
|
1643
|
-
// `Cache-Control` this route used to carry as decorators move into `sendHtml` for the built-in
|
|
1644
|
-
// path; the host owns its own headers on the hook path.
|
|
1645
|
-
async sessionRequiredPage(req, res) {
|
|
1646
|
-
const auth = this.requireAuth();
|
|
1647
|
-
if (auth.modes.includes("login")) throw new NotFoundException2();
|
|
1648
|
-
const hook = auth.unauthenticatedPage;
|
|
1649
|
-
if (hook) {
|
|
1650
|
-
try {
|
|
1651
|
-
await hook({
|
|
1652
|
-
request: req,
|
|
1653
|
-
response: res,
|
|
1654
|
-
basePath: this.basePath
|
|
1655
|
-
});
|
|
1656
|
-
if (responseAlreadyWritten(res)) return;
|
|
1657
|
-
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.");
|
|
1658
|
-
} catch (error) {
|
|
1659
|
-
this.warnHookOnce("unauthenticatedPage", `dashboardAuth.unauthenticatedPage threw; falling back to the built-in page. ${String(error)}`);
|
|
1660
|
-
if (responseAlreadyWritten(res)) return;
|
|
1661
|
-
}
|
|
1662
|
-
}
|
|
1663
|
-
sendHtml(res, 200, renderSessionRequiredPage());
|
|
1664
|
-
}
|
|
1665
|
-
/** Uniform failure: same redirect (generic error flag) whether the user is unknown or the password is wrong. */
|
|
1666
|
-
redirectToLoginError(res, returnTo) {
|
|
1667
|
-
res.status(303);
|
|
1668
|
-
res.setHeader("Location", `${this.basePath}/auth/login?error=1&returnTo=${encodeURIComponent(returnTo)}`);
|
|
1669
|
-
}
|
|
1670
|
-
currentSession(req) {
|
|
1671
|
-
const auth = this.auth;
|
|
1672
|
-
if (!auth) return false;
|
|
1673
|
-
const cookieValue = parseCookieHeader(readCookieHeader(req))[SESSION_COOKIE_NAME];
|
|
1674
|
-
if (cookieValue === void 0) return false;
|
|
1675
|
-
return verifySessionCookie(cookieValue, {
|
|
1676
|
-
secret: auth.secret
|
|
1677
|
-
}) !== null;
|
|
1678
|
-
}
|
|
1679
|
-
/**
|
|
1680
|
-
* Run a host hook (`login` or `session`) defensively: a throw (sync or async) is treated as a
|
|
1681
|
-
* denial (`null`) and warn-logged ONCE PER KIND, so a buggy/unreachable hook never 500s the
|
|
1682
|
-
* endpoint into a stack-trace leak nor floods the logs on repeated bad attempts.
|
|
1683
|
-
*/
|
|
1684
|
-
async runHook(kind, run) {
|
|
1685
|
-
try {
|
|
1686
|
-
return await run() ?? null;
|
|
1687
|
-
} catch (error) {
|
|
1688
|
-
this.warnHookOnce(kind, `AgentDashboardModule dashboardAuth ${kind} hook threw; treating as denial. ${error instanceof Error ? error.message : String(error)}`);
|
|
1689
|
-
return null;
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
|
-
/**
|
|
1693
|
-
* Warn once per hook kind for the life of the process, not once per request: a broken hook fires
|
|
1694
|
-
* on every denied navigation and would otherwise flood the logs.
|
|
1695
|
-
*/
|
|
1696
|
-
warnHookOnce(kind, message) {
|
|
1697
|
-
if (this.warnedHooks.has(kind)) return;
|
|
1698
|
-
this.warnedHooks.add(kind);
|
|
1699
|
-
this.logger.warn(message);
|
|
1700
|
-
}
|
|
1701
|
-
requireAuth() {
|
|
1702
|
-
if (!this.auth) throw new NotFoundException2();
|
|
1703
|
-
return this.auth;
|
|
1704
|
-
}
|
|
1705
|
-
};
|
|
1706
|
-
_ts_decorate4([
|
|
1707
|
-
Get2("login"),
|
|
1708
|
-
Header("Content-Type", "text/html; charset=utf-8"),
|
|
1709
|
-
Header("Cache-Control", "no-store"),
|
|
1710
|
-
_ts_param4(0, Req2()),
|
|
1711
|
-
_ts_param4(1, Res({
|
|
1712
|
-
passthrough: true
|
|
1713
|
-
})),
|
|
1714
|
-
_ts_param4(2, Query2("returnTo")),
|
|
1715
|
-
_ts_param4(3, Query2("error")),
|
|
1716
|
-
_ts_metadata4("design:type", Function),
|
|
1717
|
-
_ts_metadata4("design:paramtypes", [
|
|
1718
|
-
typeof AuthPageRequest === "undefined" ? Object : AuthPageRequest,
|
|
1719
|
-
typeof AuthPageResponse === "undefined" ? Object : AuthPageResponse,
|
|
1720
|
-
String,
|
|
1721
|
-
String
|
|
1722
|
-
]),
|
|
1723
|
-
_ts_metadata4("design:returntype", String)
|
|
1724
|
-
], AgentDashboardAuthController.prototype, "loginPage", null);
|
|
1725
|
-
_ts_decorate4([
|
|
1726
|
-
Post2("login"),
|
|
1727
|
-
_ts_param4(0, Body2()),
|
|
1728
|
-
_ts_param4(1, Req2()),
|
|
1729
|
-
_ts_param4(2, Res({
|
|
1730
|
-
passthrough: true
|
|
1731
|
-
})),
|
|
1732
|
-
_ts_metadata4("design:type", Function),
|
|
1733
|
-
_ts_metadata4("design:paramtypes", [
|
|
1734
|
-
typeof LoginFormBody === "undefined" ? Object : LoginFormBody,
|
|
1735
|
-
Object,
|
|
1736
|
-
typeof AuthPageResponse === "undefined" ? Object : AuthPageResponse
|
|
1737
|
-
]),
|
|
1738
|
-
_ts_metadata4("design:returntype", Promise)
|
|
1739
|
-
], AgentDashboardAuthController.prototype, "login", null);
|
|
1740
|
-
_ts_decorate4([
|
|
1741
|
-
Post2("logout"),
|
|
1742
|
-
_ts_param4(0, Req2()),
|
|
1743
|
-
_ts_param4(1, Res({
|
|
1744
|
-
passthrough: true
|
|
1745
|
-
})),
|
|
1746
|
-
_ts_metadata4("design:type", Function),
|
|
1747
|
-
_ts_metadata4("design:paramtypes", [
|
|
1748
|
-
Object,
|
|
1749
|
-
typeof AuthPageResponse === "undefined" ? Object : AuthPageResponse
|
|
1750
|
-
]),
|
|
1751
|
-
_ts_metadata4("design:returntype", String)
|
|
1752
|
-
], AgentDashboardAuthController.prototype, "logout", null);
|
|
1753
|
-
_ts_decorate4([
|
|
1754
|
-
Post2("session"),
|
|
1755
|
-
HttpCode2(204),
|
|
1756
|
-
_ts_param4(0, Req2()),
|
|
1757
|
-
_ts_param4(1, Res({
|
|
1758
|
-
passthrough: true
|
|
1759
|
-
})),
|
|
1760
|
-
_ts_metadata4("design:type", Function),
|
|
1761
|
-
_ts_metadata4("design:paramtypes", [
|
|
1762
|
-
Object,
|
|
1763
|
-
Object
|
|
1764
|
-
]),
|
|
1765
|
-
_ts_metadata4("design:returntype", Promise)
|
|
1766
|
-
], AgentDashboardAuthController.prototype, "session", null);
|
|
1767
|
-
_ts_decorate4([
|
|
1768
|
-
Get2("session-required"),
|
|
1769
|
-
_ts_param4(0, Req2()),
|
|
1770
|
-
_ts_param4(1, Res()),
|
|
1771
|
-
_ts_metadata4("design:type", Function),
|
|
1772
|
-
_ts_metadata4("design:paramtypes", [
|
|
1773
|
-
typeof AuthPageRequest === "undefined" ? Object : AuthPageRequest,
|
|
1774
|
-
Object
|
|
1775
|
-
]),
|
|
1776
|
-
_ts_metadata4("design:returntype", Promise)
|
|
1777
|
-
], AgentDashboardAuthController.prototype, "sessionRequiredPage", null);
|
|
1778
|
-
AgentDashboardAuthController = _ts_decorate4([
|
|
1779
|
-
Controller2("auth"),
|
|
1780
|
-
_ts_param4(0, Optional4()),
|
|
1781
|
-
_ts_param4(0, Inject4(DASHBOARD_AUTH)),
|
|
1782
|
-
_ts_param4(1, Inject4(DASHBOARD_BASE_PATH)),
|
|
1783
|
-
_ts_metadata4("design:type", Function),
|
|
1784
|
-
_ts_metadata4("design:paramtypes", [
|
|
1785
|
-
Object,
|
|
1786
|
-
String
|
|
1787
|
-
])
|
|
1788
|
-
], AgentDashboardAuthController);
|
|
1789
|
-
|
|
1790
1018
|
// src/server/normalize-path.ts
|
|
1791
1019
|
function normalizeDashboardPath(path) {
|
|
1792
1020
|
return `/${path.replace(/^\/+|\/+$/g, "")}`;
|
|
@@ -1813,6 +1041,7 @@ function agentDashboardMountPaths(options) {
|
|
|
1813
1041
|
__name(agentDashboardMountPaths, "agentDashboardMountPaths");
|
|
1814
1042
|
|
|
1815
1043
|
// src/server/agent-dashboard.module.ts
|
|
1044
|
+
import { withControllerDecorators } from "@dudousxd/nestjs-agent-core";
|
|
1816
1045
|
import "reflect-metadata";
|
|
1817
1046
|
import { Module } from "@nestjs/common";
|
|
1818
1047
|
import { RouterModule } from "@nestjs/core";
|
|
@@ -1821,145 +1050,9 @@ import { RouterModule } from "@nestjs/core";
|
|
|
1821
1050
|
import { existsSync, readFileSync } from "fs";
|
|
1822
1051
|
import { basename, extname, join, resolve, sep } from "path";
|
|
1823
1052
|
import { fileURLToPath } from "url";
|
|
1824
|
-
import {
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
import { Inject as Inject5, Injectable as Injectable4, Optional as Optional5 } from "@nestjs/common";
|
|
1828
|
-
|
|
1829
|
-
// src/server/auth/dashboard-auth-redirect.ts
|
|
1830
|
-
import { Catch, Injectable as Injectable3 } from "@nestjs/common";
|
|
1831
|
-
function _ts_decorate5(decorators, target, key, desc) {
|
|
1832
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1833
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
1834
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
1835
|
-
} else {
|
|
1836
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
1837
|
-
if (d = decorators[i]) {
|
|
1838
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
}
|
|
1842
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1843
|
-
}
|
|
1844
|
-
__name(_ts_decorate5, "_ts_decorate");
|
|
1845
|
-
var DashboardAuthRedirect = class extends Error {
|
|
1846
|
-
static {
|
|
1847
|
-
__name(this, "DashboardAuthRedirect");
|
|
1848
|
-
}
|
|
1849
|
-
redirectTo;
|
|
1850
|
-
constructor(redirectTo) {
|
|
1851
|
-
super(`Redirect to ${redirectTo}`), this.redirectTo = redirectTo;
|
|
1852
|
-
this.name = "DashboardAuthRedirect";
|
|
1853
|
-
}
|
|
1854
|
-
};
|
|
1855
|
-
var DashboardAuthRedirectFilter = class {
|
|
1856
|
-
static {
|
|
1857
|
-
__name(this, "DashboardAuthRedirectFilter");
|
|
1858
|
-
}
|
|
1859
|
-
catch(exception, host) {
|
|
1860
|
-
const response = host.switchToHttp().getResponse();
|
|
1861
|
-
sendRedirect(response, 302, exception.redirectTo);
|
|
1862
|
-
}
|
|
1863
|
-
};
|
|
1864
|
-
DashboardAuthRedirectFilter = _ts_decorate5([
|
|
1865
|
-
Injectable3(),
|
|
1866
|
-
Catch(DashboardAuthRedirect)
|
|
1867
|
-
], DashboardAuthRedirectFilter);
|
|
1868
|
-
|
|
1869
|
-
// src/server/auth/dashboard-auth-page.guard.ts
|
|
1870
|
-
function _ts_decorate6(decorators, target, key, desc) {
|
|
1871
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1872
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
1873
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
1874
|
-
} else {
|
|
1875
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
1876
|
-
if (d = decorators[i]) {
|
|
1877
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1878
|
-
}
|
|
1879
|
-
}
|
|
1880
|
-
}
|
|
1881
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1882
|
-
}
|
|
1883
|
-
__name(_ts_decorate6, "_ts_decorate");
|
|
1884
|
-
function _ts_metadata5(metadataKey, metadataValue) {
|
|
1885
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
1886
|
-
return Reflect.metadata(metadataKey, metadataValue);
|
|
1887
|
-
}
|
|
1888
|
-
}
|
|
1889
|
-
__name(_ts_metadata5, "_ts_metadata");
|
|
1890
|
-
function _ts_param5(paramIndex, decorator) {
|
|
1891
|
-
return function(target, key) {
|
|
1892
|
-
decorator(target, key, paramIndex);
|
|
1893
|
-
};
|
|
1894
|
-
}
|
|
1895
|
-
__name(_ts_param5, "_ts_param");
|
|
1896
|
-
var DashboardAuthPageGuard = class {
|
|
1897
|
-
static {
|
|
1898
|
-
__name(this, "DashboardAuthPageGuard");
|
|
1899
|
-
}
|
|
1900
|
-
auth;
|
|
1901
|
-
basePath;
|
|
1902
|
-
constructor(auth, basePath) {
|
|
1903
|
-
this.auth = auth;
|
|
1904
|
-
this.basePath = basePath;
|
|
1905
|
-
}
|
|
1906
|
-
async canActivate(context) {
|
|
1907
|
-
if (!this.auth) return true;
|
|
1908
|
-
const auth = this.auth;
|
|
1909
|
-
const http = context.switchToHttp();
|
|
1910
|
-
const request = http.getRequest();
|
|
1911
|
-
const session = this.verifyRequestSession(request);
|
|
1912
|
-
if (!session) this.deny(auth, request);
|
|
1913
|
-
attachSession(request, session);
|
|
1914
|
-
if (!await maybeRenewSession(auth, session, request, http.getResponse())) {
|
|
1915
|
-
this.deny(auth, request);
|
|
1916
|
-
}
|
|
1917
|
-
return true;
|
|
1918
|
-
}
|
|
1919
|
-
/**
|
|
1920
|
-
* No valid session: bounce the browser navigation onward. Under Mode B (`login` configured)
|
|
1921
|
-
* that's the built-in login screen, carrying `returnTo` back to the page that was requested.
|
|
1922
|
-
* Under Mode-A-only there is no login screen to redirect to — the host mints the session
|
|
1923
|
-
* itself — so this instead serves the instruction page rather than redirecting into a 404.
|
|
1924
|
-
* Pulled out of `canActivate` so both the "no session at all" and the "revalidate revoked a
|
|
1925
|
-
* renewable session" paths reuse the exact same mode-aware deny logic.
|
|
1926
|
-
*
|
|
1927
|
-
* Takes `auth` explicitly rather than reading `this.auth`: `canActivate`'s `!this.auth` early
|
|
1928
|
-
* return narrows the field within that method only — TS doesn't carry it across a method call —
|
|
1929
|
-
* so the caller passes the already-narrowed value instead of this method re-deriving (or
|
|
1930
|
-
* asserting away) the nullability.
|
|
1931
|
-
*/
|
|
1932
|
-
deny(auth, request) {
|
|
1933
|
-
if (!auth.modes.includes("login")) {
|
|
1934
|
-
throw new DashboardAuthRedirect(`${this.basePath}/auth/session-required`);
|
|
1935
|
-
}
|
|
1936
|
-
const returnTo = readOriginalUrl(request);
|
|
1937
|
-
throw new DashboardAuthRedirect(`${this.basePath}/auth/login?returnTo=${encodeURIComponent(returnTo)}`);
|
|
1938
|
-
}
|
|
1939
|
-
verifyRequestSession(request) {
|
|
1940
|
-
const auth = this.auth;
|
|
1941
|
-
if (!auth) return null;
|
|
1942
|
-
const cookieValue = parseCookieHeader(readCookieHeader(request))[SESSION_COOKIE_NAME];
|
|
1943
|
-
if (cookieValue === void 0) return null;
|
|
1944
|
-
return verifySessionCookie(cookieValue, {
|
|
1945
|
-
secret: auth.secret
|
|
1946
|
-
});
|
|
1947
|
-
}
|
|
1948
|
-
};
|
|
1949
|
-
DashboardAuthPageGuard = _ts_decorate6([
|
|
1950
|
-
Injectable4(),
|
|
1951
|
-
_ts_param5(0, Optional5()),
|
|
1952
|
-
_ts_param5(0, Inject5(DASHBOARD_AUTH)),
|
|
1953
|
-
_ts_param5(1, Inject5(DASHBOARD_BASE_PATH)),
|
|
1954
|
-
_ts_metadata5("design:type", Function),
|
|
1955
|
-
_ts_metadata5("design:paramtypes", [
|
|
1956
|
-
Object,
|
|
1957
|
-
String
|
|
1958
|
-
])
|
|
1959
|
-
], DashboardAuthPageGuard);
|
|
1960
|
-
|
|
1961
|
-
// src/server/agent-ui.controller.ts
|
|
1962
|
-
function _ts_decorate7(decorators, target, key, desc) {
|
|
1053
|
+
import { CanAnyone as CanAnyone2 } from "@dudousxd/nestjs-agent-core";
|
|
1054
|
+
import { Controller as Controller2, Get as Get2, Header, Inject as Inject3, NotFoundException as NotFoundException2, Param as Param2, Req as Req2, Res, StreamableFile } from "@nestjs/common";
|
|
1055
|
+
function _ts_decorate3(decorators, target, key, desc) {
|
|
1963
1056
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1964
1057
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
1965
1058
|
r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1972,19 +1065,19 @@ function _ts_decorate7(decorators, target, key, desc) {
|
|
|
1972
1065
|
}
|
|
1973
1066
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1974
1067
|
}
|
|
1975
|
-
__name(
|
|
1976
|
-
function
|
|
1068
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
1069
|
+
function _ts_metadata3(metadataKey, metadataValue) {
|
|
1977
1070
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
1978
1071
|
return Reflect.metadata(metadataKey, metadataValue);
|
|
1979
1072
|
}
|
|
1980
1073
|
}
|
|
1981
|
-
__name(
|
|
1982
|
-
function
|
|
1074
|
+
__name(_ts_metadata3, "_ts_metadata");
|
|
1075
|
+
function _ts_param3(paramIndex, decorator) {
|
|
1983
1076
|
return function(target, key) {
|
|
1984
1077
|
decorator(target, key, paramIndex);
|
|
1985
1078
|
};
|
|
1986
1079
|
}
|
|
1987
|
-
__name(
|
|
1080
|
+
__name(_ts_param3, "_ts_param");
|
|
1988
1081
|
var BUILD_BASE = "/ai-gateway";
|
|
1989
1082
|
function spaDir() {
|
|
1990
1083
|
return fileURLToPath(new URL("../spa", import.meta.url));
|
|
@@ -2020,7 +1113,7 @@ var AgentUiController = class {
|
|
|
2020
1113
|
}
|
|
2021
1114
|
const indexPath = join(this.dir, "index.html");
|
|
2022
1115
|
if (!existsSync(indexPath)) {
|
|
2023
|
-
throw new
|
|
1116
|
+
throw new NotFoundException2("Dashboard is not built. Run the package build.");
|
|
2024
1117
|
}
|
|
2025
1118
|
const html = readFileSync(indexPath, "utf8").replaceAll(`="${BUILD_BASE}/`, `="${this.basePath}/`);
|
|
2026
1119
|
const inject = `<script>window.__AGENT_BASE__='${this.basePath}';window.__AGENT_API__='${this.apiBasePath}';</script>`;
|
|
@@ -2028,11 +1121,11 @@ var AgentUiController = class {
|
|
|
2028
1121
|
}
|
|
2029
1122
|
asset(file) {
|
|
2030
1123
|
const safe = basename(file);
|
|
2031
|
-
if (safe !== file) throw new
|
|
1124
|
+
if (safe !== file) throw new NotFoundException2();
|
|
2032
1125
|
const root = resolve(this.dir, "assets");
|
|
2033
1126
|
const assetPath = resolve(root, safe);
|
|
2034
1127
|
if (!assetPath.startsWith(root + sep) || !existsSync(assetPath)) {
|
|
2035
|
-
throw new
|
|
1128
|
+
throw new NotFoundException2();
|
|
2036
1129
|
}
|
|
2037
1130
|
const type = CONTENT_TYPES[extname(safe)] ?? "application/octet-stream";
|
|
2038
1131
|
return new StreamableFile(readFileSync(assetPath), {
|
|
@@ -2040,143 +1133,45 @@ var AgentUiController = class {
|
|
|
2040
1133
|
});
|
|
2041
1134
|
}
|
|
2042
1135
|
};
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
1136
|
+
_ts_decorate3([
|
|
1137
|
+
Get2(),
|
|
1138
|
+
Header("Content-Type", "text/html; charset=utf-8"),
|
|
1139
|
+
Header("Cache-Control", "no-store, must-revalidate"),
|
|
1140
|
+
_ts_param3(0, Req2()),
|
|
1141
|
+
_ts_param3(1, Res({
|
|
2049
1142
|
passthrough: true
|
|
2050
1143
|
})),
|
|
2051
|
-
|
|
2052
|
-
|
|
1144
|
+
_ts_metadata3("design:type", Function),
|
|
1145
|
+
_ts_metadata3("design:paramtypes", [
|
|
2053
1146
|
typeof UiPageRequest === "undefined" ? Object : UiPageRequest,
|
|
2054
1147
|
typeof UiPageResponse === "undefined" ? Object : UiPageResponse
|
|
2055
1148
|
]),
|
|
2056
|
-
|
|
1149
|
+
_ts_metadata3("design:returntype", String)
|
|
2057
1150
|
], AgentUiController.prototype, "index", null);
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
1151
|
+
_ts_decorate3([
|
|
1152
|
+
Get2("assets/:file"),
|
|
1153
|
+
Header("Cache-Control", "public, max-age=31536000, immutable"),
|
|
1154
|
+
_ts_param3(0, Param2("file")),
|
|
1155
|
+
_ts_metadata3("design:type", Function),
|
|
1156
|
+
_ts_metadata3("design:paramtypes", [
|
|
2064
1157
|
String
|
|
2065
1158
|
]),
|
|
2066
|
-
|
|
1159
|
+
_ts_metadata3("design:returntype", typeof StreamableFile === "undefined" ? Object : StreamableFile)
|
|
2067
1160
|
], AgentUiController.prototype, "asset", null);
|
|
2068
|
-
AgentUiController =
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
_ts_metadata6("design:paramtypes", [
|
|
1161
|
+
AgentUiController = _ts_decorate3([
|
|
1162
|
+
CanAnyone2(),
|
|
1163
|
+
Controller2(),
|
|
1164
|
+
_ts_param3(0, Inject3(DASHBOARD_BASE_PATH)),
|
|
1165
|
+
_ts_param3(1, Inject3(DASHBOARD_API_PATH)),
|
|
1166
|
+
_ts_metadata3("design:type", Function),
|
|
1167
|
+
_ts_metadata3("design:paramtypes", [
|
|
2076
1168
|
String,
|
|
2077
1169
|
String
|
|
2078
1170
|
])
|
|
2079
1171
|
], AgentUiController);
|
|
2080
1172
|
|
|
2081
|
-
// src/server/auth/dashboard-auth-config.ts
|
|
2082
|
-
var DEFAULT_TTL = "8h";
|
|
2083
|
-
function unitToMs(unit) {
|
|
2084
|
-
switch (unit) {
|
|
2085
|
-
case "ms":
|
|
2086
|
-
return 1;
|
|
2087
|
-
case "s":
|
|
2088
|
-
return 1e3;
|
|
2089
|
-
case "m":
|
|
2090
|
-
return 6e4;
|
|
2091
|
-
case "h":
|
|
2092
|
-
return 36e5;
|
|
2093
|
-
case "d":
|
|
2094
|
-
return 864e5;
|
|
2095
|
-
default:
|
|
2096
|
-
return void 0;
|
|
2097
|
-
}
|
|
2098
|
-
}
|
|
2099
|
-
__name(unitToMs, "unitToMs");
|
|
2100
|
-
function durationToMs(duration) {
|
|
2101
|
-
const match = /^(\d+)(ms|s|m|h|d)$/.exec(duration.trim());
|
|
2102
|
-
const amount = match?.[1];
|
|
2103
|
-
const unit = match?.[2] !== void 0 ? unitToMs(match[2]) : void 0;
|
|
2104
|
-
if (amount === void 0 || unit === void 0) {
|
|
2105
|
-
throw new Error(`AgentDashboardModule dashboardAuth: invalid \`ttl\` duration: ${duration}`);
|
|
2106
|
-
}
|
|
2107
|
-
return Number(amount) * unit;
|
|
2108
|
-
}
|
|
2109
|
-
__name(durationToMs, "durationToMs");
|
|
2110
|
-
function resolveDashboardAuth(options) {
|
|
2111
|
-
if (options === void 0) return null;
|
|
2112
|
-
if (typeof options.secret !== "string" || options.secret === "") {
|
|
2113
|
-
throw new Error("AgentDashboardModule dashboardAuth: `secret` is required and must be a non-empty string (HMAC-SHA256 signing key, 32+ bytes recommended). Failing closed.");
|
|
2114
|
-
}
|
|
2115
|
-
const modes = [];
|
|
2116
|
-
if (options.session !== void 0) {
|
|
2117
|
-
if (typeof options.session !== "function") {
|
|
2118
|
-
throw new Error("AgentDashboardModule dashboardAuth: `session` must be a function.");
|
|
2119
|
-
}
|
|
2120
|
-
modes.push("session");
|
|
2121
|
-
}
|
|
2122
|
-
if (options.login !== void 0) {
|
|
2123
|
-
if (typeof options.login !== "function") {
|
|
2124
|
-
throw new Error("AgentDashboardModule dashboardAuth: `login` must be a function.");
|
|
2125
|
-
}
|
|
2126
|
-
modes.push("login");
|
|
2127
|
-
}
|
|
2128
|
-
if (options.revalidate !== void 0 && typeof options.revalidate !== "function") {
|
|
2129
|
-
throw new Error("AgentDashboardModule dashboardAuth: `revalidate` must be a function.");
|
|
2130
|
-
}
|
|
2131
|
-
if (options.unauthenticatedPage !== void 0 && typeof options.unauthenticatedPage !== "function") {
|
|
2132
|
-
throw new Error("AgentDashboardModule dashboardAuth: `unauthenticatedPage` must be a function.");
|
|
2133
|
-
}
|
|
2134
|
-
if (modes.length === 0) {
|
|
2135
|
-
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.");
|
|
2136
|
-
}
|
|
2137
|
-
return {
|
|
2138
|
-
secret: options.secret,
|
|
2139
|
-
ttlMs: durationToMs(options.ttl ?? DEFAULT_TTL),
|
|
2140
|
-
modes,
|
|
2141
|
-
...options.session !== void 0 ? {
|
|
2142
|
-
session: options.session
|
|
2143
|
-
} : {},
|
|
2144
|
-
...options.login !== void 0 ? {
|
|
2145
|
-
login: options.login
|
|
2146
|
-
} : {},
|
|
2147
|
-
...options.revalidate !== void 0 ? {
|
|
2148
|
-
revalidate: options.revalidate
|
|
2149
|
-
} : {},
|
|
2150
|
-
...options.unauthenticatedPage !== void 0 ? {
|
|
2151
|
-
unauthenticatedPage: options.unauthenticatedPage
|
|
2152
|
-
} : {}
|
|
2153
|
-
};
|
|
2154
|
-
}
|
|
2155
|
-
__name(resolveDashboardAuth, "resolveDashboardAuth");
|
|
2156
|
-
|
|
2157
|
-
// src/server/guards.ts
|
|
2158
|
-
import "reflect-metadata";
|
|
2159
|
-
var GUARDS_METADATA = "__guards__";
|
|
2160
|
-
function isGuardClass(guard) {
|
|
2161
|
-
return typeof guard === "function";
|
|
2162
|
-
}
|
|
2163
|
-
__name(isGuardClass, "isGuardClass");
|
|
2164
|
-
function baseGuards(controller) {
|
|
2165
|
-
return Reflect.getOwnMetadata(GUARDS_METADATA, controller) ?? [];
|
|
2166
|
-
}
|
|
2167
|
-
__name(baseGuards, "baseGuards");
|
|
2168
|
-
function stampGuards(guards, entries) {
|
|
2169
|
-
for (const [controller, base] of entries) {
|
|
2170
|
-
Reflect.defineMetadata(GUARDS_METADATA, [
|
|
2171
|
-
...base,
|
|
2172
|
-
...guards ?? []
|
|
2173
|
-
], controller);
|
|
2174
|
-
}
|
|
2175
|
-
}
|
|
2176
|
-
__name(stampGuards, "stampGuards");
|
|
2177
|
-
|
|
2178
1173
|
// src/server/agent-dashboard.module.ts
|
|
2179
|
-
function
|
|
1174
|
+
function _ts_decorate4(decorators, target, key, desc) {
|
|
2180
1175
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2181
1176
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
2182
1177
|
r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -2189,37 +1184,33 @@ function _ts_decorate8(decorators, target, key, desc) {
|
|
|
2189
1184
|
}
|
|
2190
1185
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2191
1186
|
}
|
|
2192
|
-
__name(
|
|
2193
|
-
var API_BASE_GUARDS = baseGuards(AgentApiController);
|
|
2194
|
-
var UI_BASE_GUARDS = baseGuards(AgentUiController);
|
|
1187
|
+
__name(_ts_decorate4, "_ts_decorate");
|
|
2195
1188
|
function normalize(path) {
|
|
2196
1189
|
return normalizeDashboardPath(path);
|
|
2197
1190
|
}
|
|
2198
1191
|
__name(normalize, "normalize");
|
|
1192
|
+
function assertProtected(options) {
|
|
1193
|
+
if (process.env.NODE_ENV !== "production") return;
|
|
1194
|
+
if (options.routes === false) return;
|
|
1195
|
+
if ((options.decorators ?? []).length > 0) return;
|
|
1196
|
+
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.");
|
|
1197
|
+
}
|
|
1198
|
+
__name(assertProtected, "assertProtected");
|
|
2199
1199
|
var AgentApiModule = class _AgentApiModule {
|
|
2200
1200
|
static {
|
|
2201
1201
|
__name(this, "AgentApiModule");
|
|
2202
1202
|
}
|
|
2203
1203
|
static register(options) {
|
|
2204
|
-
stampGuards(options.guards, [
|
|
2205
|
-
[
|
|
2206
|
-
AgentApiController,
|
|
2207
|
-
API_BASE_GUARDS
|
|
2208
|
-
]
|
|
2209
|
-
]);
|
|
2210
1204
|
return {
|
|
2211
1205
|
module: _AgentApiModule,
|
|
2212
1206
|
imports: [
|
|
2213
1207
|
...options.imports ?? []
|
|
2214
1208
|
],
|
|
2215
|
-
controllers: [
|
|
1209
|
+
controllers: options.routes === false ? [] : withControllerDecorators([
|
|
2216
1210
|
AgentApiController
|
|
2217
|
-
],
|
|
1211
|
+
], options.decorators),
|
|
2218
1212
|
providers: [
|
|
2219
1213
|
DashboardService,
|
|
2220
|
-
DashboardAuthGuard,
|
|
2221
|
-
options.dashboardAuth,
|
|
2222
|
-
...(options.guards ?? []).filter(isGuardClass),
|
|
2223
1214
|
// `useValue` even when `options.approvalActorRef` is `undefined` — AgentApiController
|
|
2224
1215
|
// injects this WITHOUT `@Optional()`.
|
|
2225
1216
|
{
|
|
@@ -2227,17 +1218,15 @@ var AgentApiModule = class _AgentApiModule {
|
|
|
2227
1218
|
useValue: options.approvalActorRef
|
|
2228
1219
|
}
|
|
2229
1220
|
],
|
|
2230
|
-
//
|
|
2231
|
-
// directly by AgentDashboardModule, which imports this module) resolve the SAME instance
|
|
2232
|
-
// instead of re-running a host's async factory a second time.
|
|
1221
|
+
// What a self-mounted `AgentApiController` subclass injects, too (`routes: false`).
|
|
2233
1222
|
exports: [
|
|
2234
1223
|
DashboardService,
|
|
2235
|
-
|
|
1224
|
+
DASHBOARD_APPROVAL_ACTOR_REF
|
|
2236
1225
|
]
|
|
2237
1226
|
};
|
|
2238
1227
|
}
|
|
2239
1228
|
};
|
|
2240
|
-
AgentApiModule =
|
|
1229
|
+
AgentApiModule = _ts_decorate4([
|
|
2241
1230
|
Module({})
|
|
2242
1231
|
], AgentApiModule);
|
|
2243
1232
|
var AgentDashboardModule = class _AgentDashboardModule {
|
|
@@ -2245,116 +1234,44 @@ var AgentDashboardModule = class _AgentDashboardModule {
|
|
|
2245
1234
|
__name(this, "AgentDashboardModule");
|
|
2246
1235
|
}
|
|
2247
1236
|
static forRoot(options = {}) {
|
|
1237
|
+
assertProtected(options);
|
|
2248
1238
|
const basePath = normalize(options.basePath ?? "/ai-gateway");
|
|
2249
1239
|
const apiBasePath = normalize(options.apiBasePath ?? `${basePath}/api`);
|
|
2250
|
-
stampGuards(options.guards, [
|
|
2251
|
-
[
|
|
2252
|
-
AgentUiController,
|
|
2253
|
-
UI_BASE_GUARDS
|
|
2254
|
-
]
|
|
2255
|
-
]);
|
|
2256
|
-
const dashboardAuthProvider = {
|
|
2257
|
-
provide: DASHBOARD_AUTH,
|
|
2258
|
-
useValue: resolveDashboardAuth(options.dashboardAuth)
|
|
2259
|
-
};
|
|
2260
1240
|
return {
|
|
2261
1241
|
module: _AgentDashboardModule,
|
|
2262
1242
|
imports: [
|
|
2263
1243
|
...options.imports ?? [],
|
|
2264
|
-
// Guards + host imports must reach the API controller's HOST module — enhancers resolve
|
|
2265
|
-
// from their controller's own module, never from a parent (see AgentApiModule.register).
|
|
2266
1244
|
// Spread-only-when-set: exactOptionalPropertyTypes rejects an explicit `undefined`.
|
|
2267
1245
|
AgentApiModule.register({
|
|
2268
1246
|
...options.imports ? {
|
|
2269
1247
|
imports: options.imports
|
|
2270
1248
|
} : {},
|
|
2271
|
-
...options.
|
|
2272
|
-
|
|
1249
|
+
...options.decorators ? {
|
|
1250
|
+
decorators: options.decorators
|
|
2273
1251
|
} : {},
|
|
2274
|
-
...options.
|
|
2275
|
-
|
|
2276
|
-
} : {},
|
|
2277
|
-
dashboardAuth: dashboardAuthProvider
|
|
2278
|
-
}),
|
|
2279
|
-
RouterModule.register([
|
|
2280
|
-
{
|
|
2281
|
-
path: basePath,
|
|
2282
|
-
module: _AgentDashboardModule
|
|
2283
|
-
},
|
|
2284
|
-
{
|
|
2285
|
-
path: apiBasePath,
|
|
2286
|
-
module: AgentApiModule
|
|
2287
|
-
}
|
|
2288
|
-
])
|
|
2289
|
-
],
|
|
2290
|
-
controllers: [
|
|
2291
|
-
AgentUiController,
|
|
2292
|
-
AgentDashboardAuthController
|
|
2293
|
-
],
|
|
2294
|
-
providers: [
|
|
2295
|
-
{
|
|
2296
|
-
provide: DASHBOARD_BASE_PATH,
|
|
2297
|
-
useValue: basePath
|
|
2298
|
-
},
|
|
2299
|
-
{
|
|
2300
|
-
provide: DASHBOARD_API_PATH,
|
|
2301
|
-
useValue: apiBasePath
|
|
2302
|
-
},
|
|
2303
|
-
DashboardAuthPageGuard,
|
|
2304
|
-
// AgentUiController is hosted HERE, so its guards DI-instantiate from this module.
|
|
2305
|
-
...(options.guards ?? []).filter(isGuardClass)
|
|
2306
|
-
],
|
|
2307
|
-
// Re-export the API module so its DashboardService reaches importers (e.g. the host's own controllers).
|
|
2308
|
-
exports: [
|
|
2309
|
-
AgentApiModule
|
|
2310
|
-
]
|
|
2311
|
-
};
|
|
2312
|
-
}
|
|
2313
|
-
static forRootAsync(options) {
|
|
2314
|
-
const basePath = normalize(options.basePath ?? "/ai-gateway");
|
|
2315
|
-
const apiBasePath = normalize(options.apiBasePath ?? `${basePath}/api`);
|
|
2316
|
-
stampGuards(options.guards, [
|
|
2317
|
-
[
|
|
2318
|
-
AgentUiController,
|
|
2319
|
-
UI_BASE_GUARDS
|
|
2320
|
-
]
|
|
2321
|
-
]);
|
|
2322
|
-
const dashboardAuthProvider = {
|
|
2323
|
-
provide: DASHBOARD_AUTH,
|
|
2324
|
-
inject: options.inject ?? [],
|
|
2325
|
-
useFactory: /* @__PURE__ */ __name(async (...deps) => resolveDashboardAuth(await options.useDashboardAuth(...deps)), "useFactory")
|
|
2326
|
-
};
|
|
2327
|
-
return {
|
|
2328
|
-
module: _AgentDashboardModule,
|
|
2329
|
-
imports: [
|
|
2330
|
-
...options.imports ?? [],
|
|
2331
|
-
AgentApiModule.register({
|
|
2332
|
-
...options.imports ? {
|
|
2333
|
-
imports: options.imports
|
|
2334
|
-
} : {},
|
|
2335
|
-
...options.guards ? {
|
|
2336
|
-
guards: options.guards
|
|
1252
|
+
...options.routes === false ? {
|
|
1253
|
+
routes: false
|
|
2337
1254
|
} : {},
|
|
2338
1255
|
...options.approvalActorRef ? {
|
|
2339
1256
|
approvalActorRef: options.approvalActorRef
|
|
2340
|
-
} : {}
|
|
2341
|
-
dashboardAuth: dashboardAuthProvider
|
|
1257
|
+
} : {}
|
|
2342
1258
|
}),
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
AgentUiController,
|
|
2356
|
-
AgentDashboardAuthController
|
|
1259
|
+
...options.routes === false ? [] : [
|
|
1260
|
+
RouterModule.register([
|
|
1261
|
+
{
|
|
1262
|
+
path: basePath,
|
|
1263
|
+
module: _AgentDashboardModule
|
|
1264
|
+
},
|
|
1265
|
+
{
|
|
1266
|
+
path: apiBasePath,
|
|
1267
|
+
module: AgentApiModule
|
|
1268
|
+
}
|
|
1269
|
+
])
|
|
1270
|
+
]
|
|
2357
1271
|
],
|
|
1272
|
+
controllers: options.routes === false ? [] : withControllerDecorators([
|
|
1273
|
+
AgentUiController
|
|
1274
|
+
], options.decorators),
|
|
2358
1275
|
providers: [
|
|
2359
1276
|
{
|
|
2360
1277
|
provide: DASHBOARD_BASE_PATH,
|
|
@@ -2363,17 +1280,19 @@ var AgentDashboardModule = class _AgentDashboardModule {
|
|
|
2363
1280
|
{
|
|
2364
1281
|
provide: DASHBOARD_API_PATH,
|
|
2365
1282
|
useValue: apiBasePath
|
|
2366
|
-
}
|
|
2367
|
-
DashboardAuthPageGuard,
|
|
2368
|
-
...(options.guards ?? []).filter(isGuardClass)
|
|
1283
|
+
}
|
|
2369
1284
|
],
|
|
1285
|
+
// Re-export the API module so its DashboardService reaches importers (e.g. the host's own
|
|
1286
|
+
// controllers), and the paths a self-mounted `AgentUiController` subclass injects.
|
|
2370
1287
|
exports: [
|
|
2371
|
-
AgentApiModule
|
|
1288
|
+
AgentApiModule,
|
|
1289
|
+
DASHBOARD_BASE_PATH,
|
|
1290
|
+
DASHBOARD_API_PATH
|
|
2372
1291
|
]
|
|
2373
1292
|
};
|
|
2374
1293
|
}
|
|
2375
1294
|
};
|
|
2376
|
-
AgentDashboardModule =
|
|
1295
|
+
AgentDashboardModule = _ts_decorate4([
|
|
2377
1296
|
Module({})
|
|
2378
1297
|
], AgentDashboardModule);
|
|
2379
1298
|
export {
|
|
@@ -2384,16 +1303,13 @@ export {
|
|
|
2384
1303
|
AGENT_PRICING_STORE,
|
|
2385
1304
|
AgentApiController,
|
|
2386
1305
|
AgentApiModule,
|
|
2387
|
-
AgentDashboardAuthController,
|
|
2388
1306
|
AgentDashboardModule,
|
|
2389
1307
|
AgentUiController,
|
|
2390
1308
|
DASHBOARD_API_PATH,
|
|
2391
1309
|
DASHBOARD_APPROVAL_ACTOR_REF,
|
|
2392
|
-
DASHBOARD_AUTH,
|
|
2393
1310
|
DASHBOARD_BASE_PATH,
|
|
2394
1311
|
DashboardService,
|
|
2395
1312
|
agentDashboardMountPaths,
|
|
2396
|
-
parsePriceInput
|
|
2397
|
-
resolveDashboardAuth
|
|
1313
|
+
parsePriceInput
|
|
2398
1314
|
};
|
|
2399
1315
|
//# sourceMappingURL=index.js.map
|