@dudousxd/nestjs-durable-dashboard 0.54.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/durable-client.d.ts +6 -1
- package/dist/client/durable-client.d.ts.map +1 -1
- package/dist/client/durable-client.js +9 -46
- package/dist/client/durable-client.js.map +1 -1
- package/dist/server/index.cjs +223 -1341
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +101 -388
- package/dist/server/index.d.ts +101 -388
- package/dist/server/index.js +208 -1320
- package/dist/server/index.js.map +1 -1
- package/dist/spa/assets/{bench-Dee6-QN_.js → bench-DCclNvcZ.js} +1 -1
- package/dist/spa/assets/index-B-wtX4GV.js +66 -0
- package/dist/spa/assets/{index-RjxbO7dU.js → index-ChjKRQZx.js} +1 -1
- package/dist/spa/assets/{preview-BscU9n0o.js → preview-CdsjvOrK.js} +1 -1
- package/dist/spa/bench.html +2 -2
- package/dist/spa/index.html +2 -2
- package/dist/spa/preview.html +2 -2
- package/package.json +5 -18
- 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 -26
- package/dist/react/open-console-button.js.map +0 -1
- package/dist/react/use-open-console.d.ts +0 -40
- package/dist/react/use-open-console.d.ts.map +0 -1
- package/dist/react/use-open-console.js +0 -77
- package/dist/react/use-open-console.js.map +0 -1
- package/dist/spa/assets/index-VXNPW483.js +0 -66
package/dist/server/index.cjs
CHANGED
|
@@ -24,21 +24,15 @@ var index_exports = {};
|
|
|
24
24
|
__export(index_exports, {
|
|
25
25
|
DASHBOARD_API_PATH: () => DASHBOARD_API_PATH,
|
|
26
26
|
DASHBOARD_BASE_PATH: () => DASHBOARD_BASE_PATH,
|
|
27
|
-
|
|
28
|
-
DURABLE_DASHBOARD_TOKEN_ENV: () => DURABLE_DASHBOARD_TOKEN_ENV,
|
|
27
|
+
DASHBOARD_PROTECTION_CHECK: () => DASHBOARD_PROTECTION_CHECK,
|
|
29
28
|
DashboardService: () => DashboardService,
|
|
30
29
|
DurableApiController: () => DurableApiController,
|
|
30
|
+
DurableApiControllerBase: () => DurableApiControllerBase,
|
|
31
31
|
DurableApiModule: () => DurableApiModule,
|
|
32
|
-
DurableApiSessionGuard: () => DurableApiSessionGuard,
|
|
33
|
-
DurableAuthController: () => DurableAuthController,
|
|
34
|
-
DurableDashboardGateGuard: () => DurableDashboardGateGuard,
|
|
35
32
|
DurableDashboardModule: () => DurableDashboardModule,
|
|
36
33
|
DurableUiController: () => DurableUiController,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
readDashboardToken: () => readDashboardToken,
|
|
40
|
-
reportDashboardGate: () => reportDashboardGate,
|
|
41
|
-
resolveDashboardGate: () => resolveDashboardGate
|
|
34
|
+
DurableUiControllerBase: () => DurableUiControllerBase,
|
|
35
|
+
UNPROTECTED_CONSOLE_IN_PRODUCTION: () => UNPROTECTED_CONSOLE_IN_PRODUCTION
|
|
42
36
|
});
|
|
43
37
|
module.exports = __toCommonJS(index_exports);
|
|
44
38
|
|
|
@@ -437,87 +431,6 @@ __name(runValueAxisFor, "runValueAxisFor");
|
|
|
437
431
|
|
|
438
432
|
// src/server/not-modified.ts
|
|
439
433
|
var import_common2 = require("@nestjs/common");
|
|
440
|
-
|
|
441
|
-
// src/server/auth/response.ts
|
|
442
|
-
function isRecord(value) {
|
|
443
|
-
return typeof value === "object" && value !== null;
|
|
444
|
-
}
|
|
445
|
-
__name(isRecord, "isRecord");
|
|
446
|
-
function isRawCookieResponse(value) {
|
|
447
|
-
return isRecord(value) && typeof value.getHeader === "function" && typeof value.setHeader === "function";
|
|
448
|
-
}
|
|
449
|
-
__name(isRawCookieResponse, "isRawCookieResponse");
|
|
450
|
-
function resolveCookieResponse(response) {
|
|
451
|
-
if (isRawCookieResponse(response)) return response;
|
|
452
|
-
if (isRecord(response) && isRawCookieResponse(response.raw)) return response.raw;
|
|
453
|
-
return null;
|
|
454
|
-
}
|
|
455
|
-
__name(resolveCookieResponse, "resolveCookieResponse");
|
|
456
|
-
function existingSetCookies(response) {
|
|
457
|
-
const current = response.getHeader("set-cookie");
|
|
458
|
-
if (Array.isArray(current)) return current;
|
|
459
|
-
if (typeof current === "string") return [
|
|
460
|
-
current
|
|
461
|
-
];
|
|
462
|
-
return [];
|
|
463
|
-
}
|
|
464
|
-
__name(existingSetCookies, "existingSetCookies");
|
|
465
|
-
function appendSetCookie(response, cookie) {
|
|
466
|
-
const raw = resolveCookieResponse(response);
|
|
467
|
-
if (!raw) return;
|
|
468
|
-
raw.setHeader("set-cookie", [
|
|
469
|
-
...existingSetCookies(raw),
|
|
470
|
-
cookie
|
|
471
|
-
]);
|
|
472
|
-
}
|
|
473
|
-
__name(appendSetCookie, "appendSetCookie");
|
|
474
|
-
function isRawRedirectResponse(value) {
|
|
475
|
-
return isRecord(value) && typeof value.getHeader === "function" && typeof value.setHeader === "function" && typeof value.end === "function";
|
|
476
|
-
}
|
|
477
|
-
__name(isRawRedirectResponse, "isRawRedirectResponse");
|
|
478
|
-
function resolveRedirectResponse(response) {
|
|
479
|
-
if (isRawRedirectResponse(response)) return response;
|
|
480
|
-
if (isRecord(response) && isRawRedirectResponse(response.raw)) return response.raw;
|
|
481
|
-
return null;
|
|
482
|
-
}
|
|
483
|
-
__name(resolveRedirectResponse, "resolveRedirectResponse");
|
|
484
|
-
function redirectRaw(response, location, status = 302) {
|
|
485
|
-
const raw = resolveRedirectResponse(response);
|
|
486
|
-
if (!raw) return;
|
|
487
|
-
raw.statusCode = status;
|
|
488
|
-
raw.setHeader("location", location);
|
|
489
|
-
raw.end();
|
|
490
|
-
}
|
|
491
|
-
__name(redirectRaw, "redirectRaw");
|
|
492
|
-
function responseAlreadyWritten(response) {
|
|
493
|
-
const raw = resolveRedirectResponse(response);
|
|
494
|
-
return raw?.headersSent === true;
|
|
495
|
-
}
|
|
496
|
-
__name(responseAlreadyWritten, "responseAlreadyWritten");
|
|
497
|
-
function writeHtmlRaw(response, html, status = 200) {
|
|
498
|
-
const raw = resolveRedirectResponse(response);
|
|
499
|
-
if (!raw) return;
|
|
500
|
-
raw.statusCode = status;
|
|
501
|
-
raw.setHeader("content-type", "text/html; charset=utf-8");
|
|
502
|
-
raw.setHeader("cache-control", "no-store, must-revalidate");
|
|
503
|
-
raw.end(html);
|
|
504
|
-
}
|
|
505
|
-
__name(writeHtmlRaw, "writeHtmlRaw");
|
|
506
|
-
function setRawHeader(response, name, value) {
|
|
507
|
-
resolveCookieResponse(response)?.setHeader(name, value);
|
|
508
|
-
}
|
|
509
|
-
__name(setRawHeader, "setRawHeader");
|
|
510
|
-
function writeNotModifiedRaw(response, etag) {
|
|
511
|
-
const raw = resolveRedirectResponse(response);
|
|
512
|
-
if (!raw) return;
|
|
513
|
-
raw.statusCode = 304;
|
|
514
|
-
raw.setHeader("etag", etag);
|
|
515
|
-
raw.setHeader("cache-control", "private, no-cache");
|
|
516
|
-
raw.end();
|
|
517
|
-
}
|
|
518
|
-
__name(writeNotModifiedRaw, "writeNotModifiedRaw");
|
|
519
|
-
|
|
520
|
-
// src/server/not-modified.ts
|
|
521
434
|
function _ts_decorate2(decorators, target, key, desc) {
|
|
522
435
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
523
436
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -532,6 +445,31 @@ function _ts_decorate2(decorators, target, key, desc) {
|
|
|
532
445
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
533
446
|
}
|
|
534
447
|
__name(_ts_decorate2, "_ts_decorate");
|
|
448
|
+
function isRawResponse(value) {
|
|
449
|
+
if (typeof value !== "object" || value === null) return false;
|
|
450
|
+
const candidate = value;
|
|
451
|
+
return typeof candidate.setHeader === "function" && typeof candidate.end === "function";
|
|
452
|
+
}
|
|
453
|
+
__name(isRawResponse, "isRawResponse");
|
|
454
|
+
function rawResponse(response) {
|
|
455
|
+
if (isRawResponse(response)) return response;
|
|
456
|
+
const raw = response?.raw;
|
|
457
|
+
return isRawResponse(raw) ? raw : null;
|
|
458
|
+
}
|
|
459
|
+
__name(rawResponse, "rawResponse");
|
|
460
|
+
function setRawHeader(response, name, value) {
|
|
461
|
+
rawResponse(response)?.setHeader(name, value);
|
|
462
|
+
}
|
|
463
|
+
__name(setRawHeader, "setRawHeader");
|
|
464
|
+
function writeNotModifiedRaw(response, etag) {
|
|
465
|
+
const raw = rawResponse(response);
|
|
466
|
+
if (!raw) return;
|
|
467
|
+
raw.statusCode = 304;
|
|
468
|
+
raw.setHeader("etag", etag);
|
|
469
|
+
raw.setHeader("cache-control", "private, no-cache");
|
|
470
|
+
raw.end();
|
|
471
|
+
}
|
|
472
|
+
__name(writeNotModifiedRaw, "writeNotModifiedRaw");
|
|
535
473
|
var NotModifiedException = class extends import_common2.HttpException {
|
|
536
474
|
static {
|
|
537
475
|
__name(this, "NotModifiedException");
|
|
@@ -847,10 +785,10 @@ var RunQueryAdapter = class {
|
|
|
847
785
|
}
|
|
848
786
|
unsupported(clause, "equals, notEquals, gt, gte, lt, lte, in");
|
|
849
787
|
}
|
|
850
|
-
applyOffsetPagination(qb,
|
|
788
|
+
applyOffsetPagination(qb, page, size) {
|
|
851
789
|
this.draft(qb).narrow({
|
|
852
790
|
limit: size,
|
|
853
|
-
offset: (
|
|
791
|
+
offset: (page - 1) * size
|
|
854
792
|
});
|
|
855
793
|
}
|
|
856
794
|
/**
|
|
@@ -1194,9 +1132,9 @@ function _ts_param2(paramIndex, decorator) {
|
|
|
1194
1132
|
}
|
|
1195
1133
|
__name(_ts_param2, "_ts_param");
|
|
1196
1134
|
var FAN_INLINE_MAX = 50;
|
|
1197
|
-
var
|
|
1135
|
+
var DurableApiControllerBase = class {
|
|
1198
1136
|
static {
|
|
1199
|
-
__name(this, "
|
|
1137
|
+
__name(this, "DurableApiControllerBase");
|
|
1200
1138
|
}
|
|
1201
1139
|
dashboard;
|
|
1202
1140
|
runner;
|
|
@@ -1326,7 +1264,7 @@ var DurableApiController = class {
|
|
|
1326
1264
|
}
|
|
1327
1265
|
/** One page of a summarized fan's members, in seq order. Versioned like {@link run}. */
|
|
1328
1266
|
async fanMembers(id, group, offset, limit, failed, ifNoneMatch, response) {
|
|
1329
|
-
const
|
|
1267
|
+
const page = await this.dashboard.getFanMembers(id, group, {
|
|
1330
1268
|
offset: offset === void 0 ? void 0 : Number(offset),
|
|
1331
1269
|
limit: limit === void 0 ? void 0 : Number(limit),
|
|
1332
1270
|
failedOnly: failed === "true",
|
|
@@ -1334,8 +1272,8 @@ var DurableApiController = class {
|
|
|
1334
1272
|
ifNoneMatch
|
|
1335
1273
|
}
|
|
1336
1274
|
});
|
|
1337
|
-
if (!
|
|
1338
|
-
const { etag, notModified, ...body } =
|
|
1275
|
+
if (!page) throw new import_common5.NotFoundException(`fan ${group} of run ${id} not found`);
|
|
1276
|
+
const { etag, notModified, ...body } = page;
|
|
1339
1277
|
if (etag) {
|
|
1340
1278
|
if (notModified) throw new NotModifiedException(etag);
|
|
1341
1279
|
setEtag(response, etag);
|
|
@@ -1433,7 +1371,7 @@ _ts_decorate5([
|
|
|
1433
1371
|
typeof RunQueryDraft === "undefined" ? Object : RunQueryDraft
|
|
1434
1372
|
]),
|
|
1435
1373
|
_ts_metadata4("design:returntype", Promise)
|
|
1436
|
-
],
|
|
1374
|
+
], DurableApiControllerBase.prototype, "runs", null);
|
|
1437
1375
|
_ts_decorate5([
|
|
1438
1376
|
(0, import_common5.Get)("runs/facets"),
|
|
1439
1377
|
_ts_param2(0, (0, import_nestjs_filter2.ApplyFilter)(RunFilter)),
|
|
@@ -1442,7 +1380,7 @@ _ts_decorate5([
|
|
|
1442
1380
|
typeof RunQueryDraft === "undefined" ? Object : RunQueryDraft
|
|
1443
1381
|
]),
|
|
1444
1382
|
_ts_metadata4("design:returntype", void 0)
|
|
1445
|
-
],
|
|
1383
|
+
], DurableApiControllerBase.prototype, "facets", null);
|
|
1446
1384
|
_ts_decorate5([
|
|
1447
1385
|
(0, import_common5.Get)("runs/values"),
|
|
1448
1386
|
_ts_param2(0, (0, import_common5.Query)()),
|
|
@@ -1451,20 +1389,20 @@ _ts_decorate5([
|
|
|
1451
1389
|
typeof Record === "undefined" ? Object : Record
|
|
1452
1390
|
]),
|
|
1453
1391
|
_ts_metadata4("design:returntype", void 0)
|
|
1454
|
-
],
|
|
1392
|
+
], DurableApiControllerBase.prototype, "values", null);
|
|
1455
1393
|
_ts_decorate5([
|
|
1456
1394
|
(0, import_common5.Get)("metrics"),
|
|
1457
1395
|
(0, import_common5.Header)("Content-Type", "text/plain; version=0.0.4"),
|
|
1458
1396
|
_ts_metadata4("design:type", Function),
|
|
1459
1397
|
_ts_metadata4("design:paramtypes", []),
|
|
1460
1398
|
_ts_metadata4("design:returntype", void 0)
|
|
1461
|
-
],
|
|
1399
|
+
], DurableApiControllerBase.prototype, "metrics", null);
|
|
1462
1400
|
_ts_decorate5([
|
|
1463
1401
|
(0, import_common5.Get)("workers"),
|
|
1464
1402
|
_ts_metadata4("design:type", Function),
|
|
1465
1403
|
_ts_metadata4("design:paramtypes", []),
|
|
1466
1404
|
_ts_metadata4("design:returntype", void 0)
|
|
1467
|
-
],
|
|
1405
|
+
], DurableApiControllerBase.prototype, "workers", null);
|
|
1468
1406
|
_ts_decorate5([
|
|
1469
1407
|
(0, import_common5.Get)("schedules"),
|
|
1470
1408
|
_ts_param2(0, (0, import_common5.Query)("namespace")),
|
|
@@ -1481,7 +1419,7 @@ _ts_decorate5([
|
|
|
1481
1419
|
String
|
|
1482
1420
|
]),
|
|
1483
1421
|
_ts_metadata4("design:returntype", void 0)
|
|
1484
|
-
],
|
|
1422
|
+
], DurableApiControllerBase.prototype, "schedules", null);
|
|
1485
1423
|
_ts_decorate5([
|
|
1486
1424
|
(0, import_common5.Post)("schedules/:id/pause"),
|
|
1487
1425
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1490,7 +1428,7 @@ _ts_decorate5([
|
|
|
1490
1428
|
String
|
|
1491
1429
|
]),
|
|
1492
1430
|
_ts_metadata4("design:returntype", void 0)
|
|
1493
|
-
],
|
|
1431
|
+
], DurableApiControllerBase.prototype, "pauseSchedule", null);
|
|
1494
1432
|
_ts_decorate5([
|
|
1495
1433
|
(0, import_common5.Post)("schedules/:id/resume"),
|
|
1496
1434
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1499,7 +1437,7 @@ _ts_decorate5([
|
|
|
1499
1437
|
String
|
|
1500
1438
|
]),
|
|
1501
1439
|
_ts_metadata4("design:returntype", void 0)
|
|
1502
|
-
],
|
|
1440
|
+
], DurableApiControllerBase.prototype, "resumeSchedule", null);
|
|
1503
1441
|
_ts_decorate5([
|
|
1504
1442
|
(0, import_common5.Post)("schedules/:id/trigger"),
|
|
1505
1443
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1508,7 +1446,7 @@ _ts_decorate5([
|
|
|
1508
1446
|
String
|
|
1509
1447
|
]),
|
|
1510
1448
|
_ts_metadata4("design:returntype", void 0)
|
|
1511
|
-
],
|
|
1449
|
+
], DurableApiControllerBase.prototype, "triggerSchedule", null);
|
|
1512
1450
|
_ts_decorate5([
|
|
1513
1451
|
(0, import_common5.Get)("workflows/:name/lifecycle"),
|
|
1514
1452
|
_ts_param2(0, (0, import_common5.Param)("name")),
|
|
@@ -1517,13 +1455,13 @@ _ts_decorate5([
|
|
|
1517
1455
|
String
|
|
1518
1456
|
]),
|
|
1519
1457
|
_ts_metadata4("design:returntype", Promise)
|
|
1520
|
-
],
|
|
1458
|
+
], DurableApiControllerBase.prototype, "workflowLifecycle", null);
|
|
1521
1459
|
_ts_decorate5([
|
|
1522
1460
|
(0, import_common5.Get)("topology"),
|
|
1523
1461
|
_ts_metadata4("design:type", Function),
|
|
1524
1462
|
_ts_metadata4("design:paramtypes", []),
|
|
1525
1463
|
_ts_metadata4("design:returntype", void 0)
|
|
1526
|
-
],
|
|
1464
|
+
], DurableApiControllerBase.prototype, "topology", null);
|
|
1527
1465
|
_ts_decorate5([
|
|
1528
1466
|
(0, import_common5.Get)("runs/:id"),
|
|
1529
1467
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1540,7 +1478,7 @@ _ts_decorate5([
|
|
|
1540
1478
|
Object
|
|
1541
1479
|
]),
|
|
1542
1480
|
_ts_metadata4("design:returntype", Promise)
|
|
1543
|
-
],
|
|
1481
|
+
], DurableApiControllerBase.prototype, "run", null);
|
|
1544
1482
|
_ts_decorate5([
|
|
1545
1483
|
(0, import_common5.Get)("runs/:id/fans/:group"),
|
|
1546
1484
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1563,7 +1501,7 @@ _ts_decorate5([
|
|
|
1563
1501
|
Object
|
|
1564
1502
|
]),
|
|
1565
1503
|
_ts_metadata4("design:returntype", Promise)
|
|
1566
|
-
],
|
|
1504
|
+
], DurableApiControllerBase.prototype, "fanMembers", null);
|
|
1567
1505
|
_ts_decorate5([
|
|
1568
1506
|
(0, import_common5.Sse)("runs/:id/stream"),
|
|
1569
1507
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1572,7 +1510,7 @@ _ts_decorate5([
|
|
|
1572
1510
|
String
|
|
1573
1511
|
]),
|
|
1574
1512
|
_ts_metadata4("design:returntype", void 0)
|
|
1575
|
-
],
|
|
1513
|
+
], DurableApiControllerBase.prototype, "stream", null);
|
|
1576
1514
|
_ts_decorate5([
|
|
1577
1515
|
(0, import_common5.Post)("runs/:id/retry"),
|
|
1578
1516
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1581,7 +1519,7 @@ _ts_decorate5([
|
|
|
1581
1519
|
String
|
|
1582
1520
|
]),
|
|
1583
1521
|
_ts_metadata4("design:returntype", void 0)
|
|
1584
|
-
],
|
|
1522
|
+
], DurableApiControllerBase.prototype, "retry", null);
|
|
1585
1523
|
_ts_decorate5([
|
|
1586
1524
|
(0, import_common5.Post)("runs/:id/retry-with-input"),
|
|
1587
1525
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1592,7 +1530,7 @@ _ts_decorate5([
|
|
|
1592
1530
|
Object
|
|
1593
1531
|
]),
|
|
1594
1532
|
_ts_metadata4("design:returntype", void 0)
|
|
1595
|
-
],
|
|
1533
|
+
], DurableApiControllerBase.prototype, "retryWithInput", null);
|
|
1596
1534
|
_ts_decorate5([
|
|
1597
1535
|
(0, import_common5.Post)("bulk/:action"),
|
|
1598
1536
|
_ts_param2(0, (0, import_common5.Param)("action")),
|
|
@@ -1605,7 +1543,7 @@ _ts_decorate5([
|
|
|
1605
1543
|
String
|
|
1606
1544
|
]),
|
|
1607
1545
|
_ts_metadata4("design:returntype", void 0)
|
|
1608
|
-
],
|
|
1546
|
+
], DurableApiControllerBase.prototype, "bulk", null);
|
|
1609
1547
|
_ts_decorate5([
|
|
1610
1548
|
(0, import_common5.Post)("runs/:id/cancel"),
|
|
1611
1549
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1616,7 +1554,7 @@ _ts_decorate5([
|
|
|
1616
1554
|
String
|
|
1617
1555
|
]),
|
|
1618
1556
|
_ts_metadata4("design:returntype", Promise)
|
|
1619
|
-
],
|
|
1557
|
+
], DurableApiControllerBase.prototype, "cancel", null);
|
|
1620
1558
|
_ts_decorate5([
|
|
1621
1559
|
(0, import_common5.Post)("runs/:id/republish-lifecycle"),
|
|
1622
1560
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1627,7 +1565,7 @@ _ts_decorate5([
|
|
|
1627
1565
|
Object
|
|
1628
1566
|
]),
|
|
1629
1567
|
_ts_metadata4("design:returntype", Promise)
|
|
1630
|
-
],
|
|
1568
|
+
], DurableApiControllerBase.prototype, "republishLifecycle", null);
|
|
1631
1569
|
_ts_decorate5([
|
|
1632
1570
|
(0, import_common5.Post)("runs/:id/continue"),
|
|
1633
1571
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1636,7 +1574,7 @@ _ts_decorate5([
|
|
|
1636
1574
|
String
|
|
1637
1575
|
]),
|
|
1638
1576
|
_ts_metadata4("design:returntype", Promise)
|
|
1639
|
-
],
|
|
1577
|
+
], DurableApiControllerBase.prototype, "continue", null);
|
|
1640
1578
|
_ts_decorate5([
|
|
1641
1579
|
(0, import_common5.Post)("runs/:id/redispatch"),
|
|
1642
1580
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1645,7 +1583,7 @@ _ts_decorate5([
|
|
|
1645
1583
|
String
|
|
1646
1584
|
]),
|
|
1647
1585
|
_ts_metadata4("design:returntype", Promise)
|
|
1648
|
-
],
|
|
1586
|
+
], DurableApiControllerBase.prototype, "redispatch", null);
|
|
1649
1587
|
_ts_decorate5([
|
|
1650
1588
|
(0, import_common5.Post)("webhooks/:token"),
|
|
1651
1589
|
_ts_param2(0, (0, import_common5.Param)("token")),
|
|
@@ -1656,7 +1594,7 @@ _ts_decorate5([
|
|
|
1656
1594
|
Object
|
|
1657
1595
|
]),
|
|
1658
1596
|
_ts_metadata4("design:returntype", Promise)
|
|
1659
|
-
],
|
|
1597
|
+
], DurableApiControllerBase.prototype, "webhook", null);
|
|
1660
1598
|
_ts_decorate5([
|
|
1661
1599
|
(0, import_common5.Get)("runs/:id/events/:key"),
|
|
1662
1600
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1667,7 +1605,7 @@ _ts_decorate5([
|
|
|
1667
1605
|
String
|
|
1668
1606
|
]),
|
|
1669
1607
|
_ts_metadata4("design:returntype", void 0)
|
|
1670
|
-
],
|
|
1608
|
+
], DurableApiControllerBase.prototype, "event", null);
|
|
1671
1609
|
_ts_decorate5([
|
|
1672
1610
|
(0, import_common5.Post)("runs/:id/updates/:name"),
|
|
1673
1611
|
_ts_param2(0, (0, import_common5.Param)("id")),
|
|
@@ -1680,8 +1618,8 @@ _ts_decorate5([
|
|
|
1680
1618
|
Object
|
|
1681
1619
|
]),
|
|
1682
1620
|
_ts_metadata4("design:returntype", void 0)
|
|
1683
|
-
],
|
|
1684
|
-
|
|
1621
|
+
], DurableApiControllerBase.prototype, "update", null);
|
|
1622
|
+
DurableApiControllerBase = _ts_decorate5([
|
|
1685
1623
|
(0, import_common5.Controller)(),
|
|
1686
1624
|
(0, import_common5.UseInterceptors)(import_nestjs_filter2.ApplyFilterInterceptor),
|
|
1687
1625
|
(0, import_common5.UseFilters)(NotModifiedFilter),
|
|
@@ -1690,7 +1628,7 @@ DurableApiController = _ts_decorate5([
|
|
|
1690
1628
|
typeof DashboardService === "undefined" ? Object : DashboardService,
|
|
1691
1629
|
typeof import_nestjs_filter2.FilterRunner === "undefined" ? Object : import_nestjs_filter2.FilterRunner
|
|
1692
1630
|
])
|
|
1693
|
-
],
|
|
1631
|
+
], DurableApiControllerBase);
|
|
1694
1632
|
function notFound(error) {
|
|
1695
1633
|
if (error instanceof Error && error.name === "ScheduleNotFoundError") {
|
|
1696
1634
|
throw new import_common5.NotFoundException(error.message);
|
|
@@ -1705,497 +1643,51 @@ function notSupportedByServer(error) {
|
|
|
1705
1643
|
throw error;
|
|
1706
1644
|
}
|
|
1707
1645
|
__name(notSupportedByServer, "notSupportedByServer");
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
// src/server/auth/dashboard-auth-config.ts
|
|
1713
|
-
var DASHBOARD_AUTH = Symbol("DASHBOARD_AUTH");
|
|
1714
|
-
var DEFAULT_TTL = "8h";
|
|
1715
|
-
var DEFAULT_TTL_MS = 8 * 60 * 60 * 1e3;
|
|
1716
|
-
var DURATION_UNITS = {
|
|
1717
|
-
s: 1e3,
|
|
1718
|
-
m: 60 * 1e3,
|
|
1719
|
-
h: 60 * 60 * 1e3,
|
|
1720
|
-
d: 24 * 60 * 60 * 1e3
|
|
1721
|
-
};
|
|
1722
|
-
function durationToMs(ttl) {
|
|
1723
|
-
const match = /^(\d+)([smhd])$/.exec(ttl.trim());
|
|
1724
|
-
if (!match) return DEFAULT_TTL_MS;
|
|
1725
|
-
const unit = DURATION_UNITS[match[2] ?? ""];
|
|
1726
|
-
if (unit === void 0) return DEFAULT_TTL_MS;
|
|
1727
|
-
return Number(match[1]) * unit;
|
|
1728
|
-
}
|
|
1729
|
-
__name(durationToMs, "durationToMs");
|
|
1730
|
-
function resolveDashboardAuth(options) {
|
|
1731
|
-
if (options === void 0) return null;
|
|
1732
|
-
if (typeof options.secret !== "string" || options.secret === "") {
|
|
1733
|
-
throw new Error("DurableDashboardModule: dashboardAuth.secret is required and must be a non-empty string (HMAC-SHA256 signing key, 32+ bytes recommended). Failing closed.");
|
|
1734
|
-
}
|
|
1735
|
-
const modes = [];
|
|
1736
|
-
if (options.session !== void 0) {
|
|
1737
|
-
if (typeof options.session !== "function") {
|
|
1738
|
-
throw new Error("DurableDashboardModule: dashboardAuth.session must be a function.");
|
|
1739
|
-
}
|
|
1740
|
-
modes.push("session");
|
|
1741
|
-
}
|
|
1742
|
-
if (options.login !== void 0) {
|
|
1743
|
-
if (typeof options.login !== "function") {
|
|
1744
|
-
throw new Error("DurableDashboardModule: dashboardAuth.login must be a function.");
|
|
1745
|
-
}
|
|
1746
|
-
modes.push("login");
|
|
1747
|
-
}
|
|
1748
|
-
if (options.revalidate !== void 0 && typeof options.revalidate !== "function") {
|
|
1749
|
-
throw new Error("DurableDashboardModule: dashboardAuth.revalidate must be a function.");
|
|
1750
|
-
}
|
|
1751
|
-
if (options.unauthenticatedPage !== void 0 && typeof options.unauthenticatedPage !== "function") {
|
|
1752
|
-
throw new Error("DurableDashboardModule: dashboardAuth.unauthenticatedPage must be a function.");
|
|
1753
|
-
}
|
|
1754
|
-
if (modes.length === 0) {
|
|
1755
|
-
throw new Error("DurableDashboardModule: dashboardAuth needs at least one of `session` or `login` (otherwise the cookie can never be minted). Failing closed.");
|
|
1756
|
-
}
|
|
1757
|
-
return {
|
|
1758
|
-
secret: options.secret,
|
|
1759
|
-
ttlMs: durationToMs(options.ttl ?? DEFAULT_TTL),
|
|
1760
|
-
modes,
|
|
1761
|
-
...options.session !== void 0 ? {
|
|
1762
|
-
session: options.session
|
|
1763
|
-
} : {},
|
|
1764
|
-
...options.login !== void 0 ? {
|
|
1765
|
-
login: options.login
|
|
1766
|
-
} : {},
|
|
1767
|
-
...options.revalidate !== void 0 ? {
|
|
1768
|
-
revalidate: options.revalidate
|
|
1769
|
-
} : {},
|
|
1770
|
-
...options.unauthenticatedPage !== void 0 ? {
|
|
1771
|
-
unauthenticatedPage: options.unauthenticatedPage
|
|
1772
|
-
} : {}
|
|
1773
|
-
};
|
|
1774
|
-
}
|
|
1775
|
-
__name(resolveDashboardAuth, "resolveDashboardAuth");
|
|
1776
|
-
|
|
1777
|
-
// src/server/auth/login-page.ts
|
|
1778
|
-
function page(content, title = "Durable") {
|
|
1779
|
-
return `<!doctype html>
|
|
1780
|
-
<html lang="en">
|
|
1781
|
-
<head>
|
|
1782
|
-
<meta charset="utf-8" />
|
|
1783
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
1784
|
-
<meta name="robots" content="noindex, nofollow" />
|
|
1785
|
-
<title>${title}</title>
|
|
1786
|
-
<style>
|
|
1787
|
-
:root { color-scheme: dark; }
|
|
1788
|
-
* { box-sizing: border-box; }
|
|
1789
|
-
body {
|
|
1790
|
-
margin: 0;
|
|
1791
|
-
min-height: 100vh;
|
|
1792
|
-
display: flex;
|
|
1793
|
-
align-items: center;
|
|
1794
|
-
justify-content: center;
|
|
1795
|
-
background: #09090b;
|
|
1796
|
-
color: #e4e4e7;
|
|
1797
|
-
font: 14px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
1798
|
-
padding: 16px;
|
|
1799
|
-
}
|
|
1800
|
-
.card {
|
|
1801
|
-
width: 100%;
|
|
1802
|
-
max-width: 384px;
|
|
1803
|
-
border: 1px solid #27272a;
|
|
1804
|
-
background: #18181b;
|
|
1805
|
-
border-radius: 8px;
|
|
1806
|
-
padding: 32px;
|
|
1807
|
-
box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.5);
|
|
1808
|
-
}
|
|
1809
|
-
.brand {
|
|
1810
|
-
margin: 0 0 24px;
|
|
1811
|
-
text-align: center;
|
|
1812
|
-
font-size: 18px;
|
|
1813
|
-
font-weight: 600;
|
|
1814
|
-
color: #34d399;
|
|
1815
|
-
}
|
|
1816
|
-
h1 {
|
|
1817
|
-
margin: 0 0 12px;
|
|
1818
|
-
font-size: 16px;
|
|
1819
|
-
font-weight: 600;
|
|
1820
|
-
color: #f4f4f5;
|
|
1821
|
-
}
|
|
1822
|
-
p { margin: 0 0 16px; color: #a1a1aa; }
|
|
1823
|
-
form { display: flex; flex-direction: column; gap: 16px; }
|
|
1824
|
-
label { display: flex; flex-direction: column; gap: 6px; }
|
|
1825
|
-
.field-label {
|
|
1826
|
-
font-size: 11px;
|
|
1827
|
-
text-transform: uppercase;
|
|
1828
|
-
letter-spacing: 0.05em;
|
|
1829
|
-
color: #71717a;
|
|
1830
|
-
}
|
|
1831
|
-
input {
|
|
1832
|
-
border-radius: 4px;
|
|
1833
|
-
border: 1px solid #3f3f46;
|
|
1834
|
-
background: #09090b;
|
|
1835
|
-
color: #f4f4f5;
|
|
1836
|
-
padding: 8px 12px;
|
|
1837
|
-
font: inherit;
|
|
1838
|
-
outline: none;
|
|
1839
|
-
}
|
|
1840
|
-
input:focus { border-color: rgb(52 211 153 / 0.6); }
|
|
1841
|
-
#error {
|
|
1842
|
-
display: none;
|
|
1843
|
-
margin: 0;
|
|
1844
|
-
font-size: 12px;
|
|
1845
|
-
color: #fb7185;
|
|
1846
|
-
}
|
|
1847
|
-
button, .button {
|
|
1848
|
-
margin-top: 8px;
|
|
1849
|
-
border-radius: 4px;
|
|
1850
|
-
border: 1px solid rgb(52 211 153 / 0.4);
|
|
1851
|
-
background: rgb(52 211 153 / 0.1);
|
|
1852
|
-
color: #6ee7b7;
|
|
1853
|
-
padding: 8px 12px;
|
|
1854
|
-
font: inherit;
|
|
1855
|
-
font-size: 12px;
|
|
1856
|
-
font-weight: 500;
|
|
1857
|
-
text-transform: uppercase;
|
|
1858
|
-
letter-spacing: 0.05em;
|
|
1859
|
-
cursor: pointer;
|
|
1860
|
-
display: inline-block;
|
|
1861
|
-
text-align: center;
|
|
1862
|
-
text-decoration: none;
|
|
1863
|
-
box-sizing: border-box;
|
|
1864
|
-
}
|
|
1865
|
-
button:hover:not(:disabled), .button:hover { background: rgb(52 211 153 / 0.2); }
|
|
1866
|
-
button:disabled { opacity: 0.6; cursor: default; }
|
|
1867
|
-
</style>
|
|
1868
|
-
</head>
|
|
1869
|
-
<body>
|
|
1870
|
-
<div class="card">
|
|
1871
|
-
${content}
|
|
1872
|
-
</div>
|
|
1873
|
-
</body>
|
|
1874
|
-
</html>`;
|
|
1875
|
-
}
|
|
1876
|
-
__name(page, "page");
|
|
1877
|
-
function renderLoginPage(basePath) {
|
|
1878
|
-
const loginAction = `${basePath}/login`;
|
|
1879
|
-
const defaultReturnTo = basePath;
|
|
1880
|
-
return page(`<p class="brand">Durable</p>
|
|
1881
|
-
<form id="login-form" autocomplete="on">
|
|
1882
|
-
<label>
|
|
1883
|
-
<span class="field-label">Username</span>
|
|
1884
|
-
<input id="username" name="username" type="text" autocomplete="username" required autofocus />
|
|
1885
|
-
</label>
|
|
1886
|
-
<label>
|
|
1887
|
-
<span class="field-label">Password</span>
|
|
1888
|
-
<input id="password" name="password" type="password" autocomplete="current-password" />
|
|
1889
|
-
</label>
|
|
1890
|
-
<p id="error" role="alert">Invalid username or password.</p>
|
|
1891
|
-
<button id="submit" type="submit">Sign in</button>
|
|
1892
|
-
</form>
|
|
1893
|
-
<script>
|
|
1894
|
-
(function () {
|
|
1895
|
-
var LOGIN_ACTION = ${JSON.stringify(loginAction)};
|
|
1896
|
-
var DEFAULT_RETURN_TO = ${JSON.stringify(defaultReturnTo)};
|
|
1897
|
-
var params = new URLSearchParams(window.location.search);
|
|
1898
|
-
var errorBox = document.getElementById('error');
|
|
1899
|
-
if (params.get('error')) errorBox.style.display = 'block';
|
|
1900
|
-
|
|
1901
|
-
function sameOriginReturnTo(value) {
|
|
1902
|
-
if (typeof value !== 'string' || value === '') return DEFAULT_RETURN_TO;
|
|
1903
|
-
if (value.charAt(0) !== '/' || value.charAt(1) === '/' || value.indexOf('://') !== -1) {
|
|
1904
|
-
return DEFAULT_RETURN_TO;
|
|
1905
|
-
}
|
|
1906
|
-
return value;
|
|
1646
|
+
var DurableApiController = class extends DurableApiControllerBase {
|
|
1647
|
+
static {
|
|
1648
|
+
__name(this, "DurableApiController");
|
|
1907
1649
|
}
|
|
1650
|
+
};
|
|
1651
|
+
DurableApiController = _ts_decorate5([
|
|
1652
|
+
(0, import_common5.Controller)()
|
|
1653
|
+
], DurableApiController);
|
|
1908
1654
|
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
errorBox.style.display = 'none';
|
|
1915
|
-
var returnTo = sameOriginReturnTo(params.get('returnTo'));
|
|
1916
|
-
fetch(LOGIN_ACTION, {
|
|
1917
|
-
method: 'POST',
|
|
1918
|
-
headers: { 'content-type': 'application/json' },
|
|
1919
|
-
credentials: 'same-origin',
|
|
1920
|
-
body: JSON.stringify({
|
|
1921
|
-
username: document.getElementById('username').value,
|
|
1922
|
-
password: document.getElementById('password').value,
|
|
1923
|
-
returnTo: returnTo,
|
|
1924
|
-
}),
|
|
1925
|
-
})
|
|
1926
|
-
.then(function (response) {
|
|
1927
|
-
if (!response.ok) throw new Error('unauthorized');
|
|
1928
|
-
return response.json();
|
|
1929
|
-
})
|
|
1930
|
-
.then(function (data) {
|
|
1931
|
-
window.location.href = data.redirectTo || DEFAULT_RETURN_TO;
|
|
1932
|
-
})
|
|
1933
|
-
.catch(function () {
|
|
1934
|
-
errorBox.style.display = 'block';
|
|
1935
|
-
submitButton.disabled = false;
|
|
1936
|
-
});
|
|
1937
|
-
});
|
|
1938
|
-
})();
|
|
1939
|
-
</script>`, "Sign in \u2014 Durable");
|
|
1940
|
-
}
|
|
1941
|
-
__name(renderLoginPage, "renderLoginPage");
|
|
1942
|
-
function renderSessionRequiredPage(basePath) {
|
|
1943
|
-
return page(`<h1>Open this console from your application</h1>
|
|
1944
|
-
<p>Your session is minted by the host app. Use its console launcher to sign in, then reload.</p>
|
|
1945
|
-
<a class="button" href="${basePath}">Retry</a>`);
|
|
1946
|
-
}
|
|
1947
|
-
__name(renderSessionRequiredPage, "renderSessionRequiredPage");
|
|
1948
|
-
|
|
1949
|
-
// src/server/auth/request.ts
|
|
1950
|
-
function isRecord2(value) {
|
|
1951
|
-
return typeof value === "object" && value !== null;
|
|
1952
|
-
}
|
|
1953
|
-
__name(isRecord2, "isRecord");
|
|
1954
|
-
function readHeaders(request) {
|
|
1955
|
-
if (!isRecord2(request)) return {};
|
|
1956
|
-
const headers = request.headers;
|
|
1957
|
-
return isRecord2(headers) ? headers : {};
|
|
1958
|
-
}
|
|
1959
|
-
__name(readHeaders, "readHeaders");
|
|
1960
|
-
function headerToString(value) {
|
|
1961
|
-
if (typeof value === "string") return value;
|
|
1962
|
-
if (Array.isArray(value) && value.every((part) => typeof part === "string")) {
|
|
1963
|
-
return value.join(",");
|
|
1964
|
-
}
|
|
1965
|
-
return void 0;
|
|
1966
|
-
}
|
|
1967
|
-
__name(headerToString, "headerToString");
|
|
1968
|
-
function readCookieHeader(request) {
|
|
1969
|
-
return headerToString(readHeaders(request).cookie);
|
|
1970
|
-
}
|
|
1971
|
-
__name(readCookieHeader, "readCookieHeader");
|
|
1972
|
-
function isHttpsRequest(request) {
|
|
1973
|
-
if (isRecord2(request) && request.protocol === "https") return true;
|
|
1974
|
-
const forwarded = headerToString(readHeaders(request)["x-forwarded-proto"]);
|
|
1975
|
-
if (forwarded === void 0) return false;
|
|
1976
|
-
return forwarded.split(",").map((proto) => proto.trim().toLowerCase()).includes("https");
|
|
1977
|
-
}
|
|
1978
|
-
__name(isHttpsRequest, "isHttpsRequest");
|
|
1979
|
-
function originalRequestUrl(request) {
|
|
1980
|
-
if (!isRecord2(request)) return "/";
|
|
1981
|
-
if (typeof request.originalUrl === "string" && request.originalUrl !== "") {
|
|
1982
|
-
return request.originalUrl;
|
|
1983
|
-
}
|
|
1984
|
-
if (typeof request.url === "string" && request.url !== "") return request.url;
|
|
1985
|
-
return "/";
|
|
1986
|
-
}
|
|
1987
|
-
__name(originalRequestUrl, "originalRequestUrl");
|
|
1988
|
-
function sanitizeReturnTo(candidate, fallback) {
|
|
1989
|
-
if (typeof candidate !== "string") return fallback;
|
|
1990
|
-
if (!candidate.startsWith("/")) return fallback;
|
|
1991
|
-
if (candidate.startsWith("//")) return fallback;
|
|
1992
|
-
if (candidate.includes("://")) return fallback;
|
|
1993
|
-
return candidate;
|
|
1994
|
-
}
|
|
1995
|
-
__name(sanitizeReturnTo, "sanitizeReturnTo");
|
|
1655
|
+
// src/server/durable-dashboard.module.ts
|
|
1656
|
+
var import_reflect_metadata2 = require("reflect-metadata");
|
|
1657
|
+
var import_nestjs_filter3 = require("@dudousxd/nestjs-filter");
|
|
1658
|
+
var import_common7 = require("@nestjs/common");
|
|
1659
|
+
var import_core = require("@nestjs/core");
|
|
1996
1660
|
|
|
1997
|
-
// src/server/
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
}
|
|
2010
|
-
if (name in cookies) continue;
|
|
2011
|
-
try {
|
|
2012
|
-
cookies[name] = decodeURIComponent(rawValue);
|
|
2013
|
-
} catch {
|
|
2014
|
-
cookies[name] = rawValue;
|
|
1661
|
+
// src/server/controller-decorators.ts
|
|
1662
|
+
var import_reflect_metadata = require("reflect-metadata");
|
|
1663
|
+
var CAN_ANYONE_METADATA = "authorization:can-anyone";
|
|
1664
|
+
function markOpenToAuthorization(controller) {
|
|
1665
|
+
Reflect.defineMetadata(CAN_ANYONE_METADATA, true, controller);
|
|
1666
|
+
}
|
|
1667
|
+
__name(markOpenToAuthorization, "markOpenToAuthorization");
|
|
1668
|
+
function controllerFor(base, decorators) {
|
|
1669
|
+
if (decorators === void 0 || decorators.length === 0) return base;
|
|
1670
|
+
const derived = class extends base {
|
|
1671
|
+
static {
|
|
1672
|
+
__name(this, "derived");
|
|
2015
1673
|
}
|
|
2016
|
-
}
|
|
2017
|
-
return cookies;
|
|
2018
|
-
}
|
|
2019
|
-
__name(parseCookieHeader, "parseCookieHeader");
|
|
2020
|
-
function serializeSetCookie(name, value, options) {
|
|
2021
|
-
const parts = [
|
|
2022
|
-
`${name}=${options.clear ? "" : encodeURIComponent(value)}`
|
|
2023
|
-
];
|
|
2024
|
-
parts.push(`Path=${options.path}`);
|
|
2025
|
-
parts.push("HttpOnly");
|
|
2026
|
-
parts.push("SameSite=Lax");
|
|
2027
|
-
if (options.secure) parts.push("Secure");
|
|
2028
|
-
if (options.clear) {
|
|
2029
|
-
parts.push("Max-Age=0");
|
|
2030
|
-
parts.push("Expires=Thu, 01 Jan 1970 00:00:00 GMT");
|
|
2031
|
-
} else {
|
|
2032
|
-
parts.push(`Max-Age=${options.maxAgeSeconds}`);
|
|
2033
|
-
}
|
|
2034
|
-
return parts.join("; ");
|
|
2035
|
-
}
|
|
2036
|
-
__name(serializeSetCookie, "serializeSetCookie");
|
|
2037
|
-
|
|
2038
|
-
// src/server/auth/session-cookie.ts
|
|
2039
|
-
var import_node_crypto = require("crypto");
|
|
2040
|
-
var EXP_GRACE_MS = 3e4;
|
|
2041
|
-
function base64urlEncode(value) {
|
|
2042
|
-
return Buffer.from(value, "utf8").toString("base64url");
|
|
2043
|
-
}
|
|
2044
|
-
__name(base64urlEncode, "base64urlEncode");
|
|
2045
|
-
function base64urlDecode(value) {
|
|
2046
|
-
return Buffer.from(value, "base64url").toString("utf8");
|
|
2047
|
-
}
|
|
2048
|
-
__name(base64urlDecode, "base64urlDecode");
|
|
2049
|
-
function hmac(secret, payload) {
|
|
2050
|
-
return (0, import_node_crypto.createHmac)("sha256", secret).update(payload).digest("base64url");
|
|
2051
|
-
}
|
|
2052
|
-
__name(hmac, "hmac");
|
|
2053
|
-
function signSessionCookie(user, options) {
|
|
2054
|
-
const issuedAt = options.now ?? Date.now();
|
|
2055
|
-
const session = {
|
|
2056
|
-
sub: user.id,
|
|
2057
|
-
...user.name !== void 0 ? {
|
|
2058
|
-
name: user.name
|
|
2059
|
-
} : {},
|
|
2060
|
-
roles: user.roles ?? [],
|
|
2061
|
-
iat: issuedAt,
|
|
2062
|
-
exp: issuedAt + options.ttlMs
|
|
2063
|
-
};
|
|
2064
|
-
const encodedPayload = base64urlEncode(JSON.stringify(session));
|
|
2065
|
-
const signature = hmac(options.secret, encodedPayload);
|
|
2066
|
-
return `${encodedPayload}.${signature}`;
|
|
2067
|
-
}
|
|
2068
|
-
__name(signSessionCookie, "signSessionCookie");
|
|
2069
|
-
function isSessionPayload(value) {
|
|
2070
|
-
if (typeof value !== "object" || value === null) return false;
|
|
2071
|
-
const record = {
|
|
2072
|
-
...value
|
|
2073
1674
|
};
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
if (!Array.isArray(record.roles)) return false;
|
|
2077
|
-
if (!record.roles.every((role) => typeof role === "string")) return false;
|
|
2078
|
-
if (typeof record.iat !== "number" || !Number.isFinite(record.iat)) return false;
|
|
2079
|
-
if (typeof record.exp !== "number" || !Number.isFinite(record.exp)) return false;
|
|
2080
|
-
return true;
|
|
2081
|
-
}
|
|
2082
|
-
__name(isSessionPayload, "isSessionPayload");
|
|
2083
|
-
function verifySessionCookie(value, options) {
|
|
2084
|
-
try {
|
|
2085
|
-
const dot = value.indexOf(".");
|
|
2086
|
-
if (dot <= 0 || dot === value.length - 1) return null;
|
|
2087
|
-
const encodedPayload = value.slice(0, dot);
|
|
2088
|
-
const providedSignature = value.slice(dot + 1);
|
|
2089
|
-
const expectedSignature = hmac(options.secret, encodedPayload);
|
|
2090
|
-
const provided = Buffer.from(providedSignature, "base64url");
|
|
2091
|
-
const expected = Buffer.from(expectedSignature, "base64url");
|
|
2092
|
-
if (provided.length !== expected.length) return null;
|
|
2093
|
-
if (!(0, import_node_crypto.timingSafeEqual)(provided, expected)) return null;
|
|
2094
|
-
const decoded = JSON.parse(base64urlDecode(encodedPayload));
|
|
2095
|
-
if (!isSessionPayload(decoded)) return null;
|
|
2096
|
-
const now = options.now ?? Date.now();
|
|
2097
|
-
if (now > decoded.exp + EXP_GRACE_MS) return null;
|
|
2098
|
-
const session = {
|
|
2099
|
-
sub: decoded.sub,
|
|
2100
|
-
...decoded.name !== void 0 ? {
|
|
2101
|
-
name: decoded.name
|
|
2102
|
-
} : {},
|
|
2103
|
-
roles: decoded.roles,
|
|
2104
|
-
iat: decoded.iat,
|
|
2105
|
-
exp: decoded.exp
|
|
2106
|
-
};
|
|
2107
|
-
return session;
|
|
2108
|
-
} catch {
|
|
2109
|
-
return null;
|
|
2110
|
-
}
|
|
2111
|
-
}
|
|
2112
|
-
__name(verifySessionCookie, "verifySessionCookie");
|
|
2113
|
-
|
|
2114
|
-
// src/server/auth/session-cookie-io.ts
|
|
2115
|
-
var SESSION_COOKIE_NAME = "durable_dashboard_session";
|
|
2116
|
-
var COOKIE_PATH = "/";
|
|
2117
|
-
function issueSessionCookie(user, context) {
|
|
2118
|
-
const value = signSessionCookie(user, {
|
|
2119
|
-
secret: context.auth.secret,
|
|
2120
|
-
ttlMs: context.auth.ttlMs,
|
|
2121
|
-
...context.now !== void 0 ? {
|
|
2122
|
-
now: context.now
|
|
2123
|
-
} : {}
|
|
1675
|
+
Object.defineProperty(derived, "name", {
|
|
1676
|
+
value: base.name
|
|
2124
1677
|
});
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
});
|
|
2130
|
-
appendSetCookie(context.response, cookie);
|
|
2131
|
-
}
|
|
2132
|
-
__name(issueSessionCookie, "issueSessionCookie");
|
|
2133
|
-
function clearSessionCookie(context) {
|
|
2134
|
-
const cookie = serializeSetCookie(SESSION_COOKIE_NAME, "", {
|
|
2135
|
-
path: COOKIE_PATH,
|
|
2136
|
-
maxAgeSeconds: 0,
|
|
2137
|
-
secure: isHttpsRequest(context.request),
|
|
2138
|
-
clear: true
|
|
2139
|
-
});
|
|
2140
|
-
appendSetCookie(context.response, cookie);
|
|
2141
|
-
}
|
|
2142
|
-
__name(clearSessionCookie, "clearSessionCookie");
|
|
2143
|
-
function readSessionFromRequest(auth, request) {
|
|
2144
|
-
const cookieValue = parseCookieHeader(readCookieHeader(request))[SESSION_COOKIE_NAME];
|
|
2145
|
-
if (cookieValue === void 0) return null;
|
|
2146
|
-
return verifySessionCookie(cookieValue, {
|
|
2147
|
-
secret: auth.secret
|
|
2148
|
-
});
|
|
2149
|
-
}
|
|
2150
|
-
__name(readSessionFromRequest, "readSessionFromRequest");
|
|
2151
|
-
var inFlightRevalidations = /* @__PURE__ */ new Map();
|
|
2152
|
-
function revalidateOnce(auth, user) {
|
|
2153
|
-
const revalidate = auth.revalidate;
|
|
2154
|
-
if (!revalidate) return Promise.resolve(true);
|
|
2155
|
-
const key = `${auth.secret}:${user.id}`;
|
|
2156
|
-
const inFlight = inFlightRevalidations.get(key);
|
|
2157
|
-
if (inFlight) return inFlight;
|
|
2158
|
-
const call = Promise.resolve().then(() => revalidate(user)).catch(() => false).finally(() => {
|
|
2159
|
-
inFlightRevalidations.delete(key);
|
|
2160
|
-
});
|
|
2161
|
-
inFlightRevalidations.set(key, call);
|
|
2162
|
-
return call;
|
|
2163
|
-
}
|
|
2164
|
-
__name(revalidateOnce, "revalidateOnce");
|
|
2165
|
-
async function maybeRenewSession(auth, session, request, response, now = Date.now()) {
|
|
2166
|
-
if (now - session.iat <= auth.ttlMs / 2) return true;
|
|
2167
|
-
const user = {
|
|
2168
|
-
id: session.sub,
|
|
2169
|
-
...session.name !== void 0 ? {
|
|
2170
|
-
name: session.name
|
|
2171
|
-
} : {},
|
|
2172
|
-
roles: session.roles
|
|
2173
|
-
};
|
|
2174
|
-
const allowed = await revalidateOnce(auth, user);
|
|
2175
|
-
if (!allowed) {
|
|
2176
|
-
clearSessionCookie({
|
|
2177
|
-
request,
|
|
2178
|
-
response
|
|
2179
|
-
});
|
|
2180
|
-
return false;
|
|
1678
|
+
markOpenToAuthorization(derived);
|
|
1679
|
+
let decorated = derived;
|
|
1680
|
+
for (const decorator of decorators) {
|
|
1681
|
+
decorated = decorator(decorated) ?? decorated;
|
|
2181
1682
|
}
|
|
2182
|
-
|
|
2183
|
-
auth,
|
|
2184
|
-
request,
|
|
2185
|
-
response,
|
|
2186
|
-
now
|
|
2187
|
-
});
|
|
2188
|
-
return true;
|
|
1683
|
+
return decorated;
|
|
2189
1684
|
}
|
|
2190
|
-
__name(
|
|
1685
|
+
__name(controllerFor, "controllerFor");
|
|
2191
1686
|
|
|
2192
1687
|
// src/server/durable-ui.controller.ts
|
|
2193
1688
|
var import_node_fs = require("fs");
|
|
2194
1689
|
var import_node_path = require("path");
|
|
2195
1690
|
var import_node_url = require("url");
|
|
2196
|
-
var import_common8 = require("@nestjs/common");
|
|
2197
|
-
|
|
2198
|
-
// src/server/auth/login-redirect.exception.ts
|
|
2199
1691
|
var import_common6 = require("@nestjs/common");
|
|
2200
1692
|
function _ts_decorate6(decorators, target, key, desc) {
|
|
2201
1693
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -2211,46 +1703,6 @@ function _ts_decorate6(decorators, target, key, desc) {
|
|
|
2211
1703
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2212
1704
|
}
|
|
2213
1705
|
__name(_ts_decorate6, "_ts_decorate");
|
|
2214
|
-
var DashboardLoginRedirectException = class extends import_common6.HttpException {
|
|
2215
|
-
static {
|
|
2216
|
-
__name(this, "DashboardLoginRedirectException");
|
|
2217
|
-
}
|
|
2218
|
-
location;
|
|
2219
|
-
constructor(location) {
|
|
2220
|
-
super({
|
|
2221
|
-
location
|
|
2222
|
-
}, import_common6.HttpStatus.FOUND), this.location = location;
|
|
2223
|
-
}
|
|
2224
|
-
};
|
|
2225
|
-
var DashboardLoginRedirectFilter = class {
|
|
2226
|
-
static {
|
|
2227
|
-
__name(this, "DashboardLoginRedirectFilter");
|
|
2228
|
-
}
|
|
2229
|
-
catch(exception, host) {
|
|
2230
|
-
const response = host.switchToHttp().getResponse();
|
|
2231
|
-
redirectRaw(response, exception.location);
|
|
2232
|
-
}
|
|
2233
|
-
};
|
|
2234
|
-
DashboardLoginRedirectFilter = _ts_decorate6([
|
|
2235
|
-
(0, import_common6.Catch)(DashboardLoginRedirectException)
|
|
2236
|
-
], DashboardLoginRedirectFilter);
|
|
2237
|
-
|
|
2238
|
-
// src/server/auth/session-required.exception.ts
|
|
2239
|
-
var import_common7 = require("@nestjs/common");
|
|
2240
|
-
function _ts_decorate7(decorators, target, key, desc) {
|
|
2241
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2242
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
2243
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
2244
|
-
} else {
|
|
2245
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
2246
|
-
if (d = decorators[i]) {
|
|
2247
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2248
|
-
}
|
|
2249
|
-
}
|
|
2250
|
-
}
|
|
2251
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2252
|
-
}
|
|
2253
|
-
__name(_ts_decorate7, "_ts_decorate");
|
|
2254
1706
|
function _ts_metadata5(metadataKey, metadataValue) {
|
|
2255
1707
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
2256
1708
|
return Reflect.metadata(metadataKey, metadataValue);
|
|
@@ -2263,91 +1715,6 @@ function _ts_param3(paramIndex, decorator) {
|
|
|
2263
1715
|
};
|
|
2264
1716
|
}
|
|
2265
1717
|
__name(_ts_param3, "_ts_param");
|
|
2266
|
-
var DashboardSessionRequiredException = class extends import_common7.HttpException {
|
|
2267
|
-
static {
|
|
2268
|
-
__name(this, "DashboardSessionRequiredException");
|
|
2269
|
-
}
|
|
2270
|
-
basePath;
|
|
2271
|
-
constructor(basePath) {
|
|
2272
|
-
super({
|
|
2273
|
-
basePath
|
|
2274
|
-
}, import_common7.HttpStatus.UNAUTHORIZED), this.basePath = basePath;
|
|
2275
|
-
}
|
|
2276
|
-
};
|
|
2277
|
-
var DashboardSessionRequiredFilter = class _DashboardSessionRequiredFilter {
|
|
2278
|
-
static {
|
|
2279
|
-
__name(this, "DashboardSessionRequiredFilter");
|
|
2280
|
-
}
|
|
2281
|
-
auth;
|
|
2282
|
-
logger = new import_common7.Logger(_DashboardSessionRequiredFilter.name);
|
|
2283
|
-
warned = false;
|
|
2284
|
-
constructor(auth = null) {
|
|
2285
|
-
this.auth = auth;
|
|
2286
|
-
}
|
|
2287
|
-
async catch(exception, host) {
|
|
2288
|
-
const http = host.switchToHttp();
|
|
2289
|
-
const response = http.getResponse();
|
|
2290
|
-
const hook = this.auth?.unauthenticatedPage;
|
|
2291
|
-
if (hook) {
|
|
2292
|
-
try {
|
|
2293
|
-
await hook({
|
|
2294
|
-
request: http.getRequest(),
|
|
2295
|
-
response,
|
|
2296
|
-
basePath: exception.basePath
|
|
2297
|
-
});
|
|
2298
|
-
if (responseAlreadyWritten(response)) return;
|
|
2299
|
-
this.warnOnce("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.");
|
|
2300
|
-
} catch (error) {
|
|
2301
|
-
this.warnOnce(`dashboardAuth.unauthenticatedPage threw; falling back to the built-in page. ${String(error)}`);
|
|
2302
|
-
if (responseAlreadyWritten(response)) return;
|
|
2303
|
-
}
|
|
2304
|
-
}
|
|
2305
|
-
writeHtmlRaw(response, renderSessionRequiredPage(exception.basePath), import_common7.HttpStatus.UNAUTHORIZED);
|
|
2306
|
-
}
|
|
2307
|
-
/** Once per process, not once per request: a broken hook fires on every denied navigation. */
|
|
2308
|
-
warnOnce(message) {
|
|
2309
|
-
if (this.warned) return;
|
|
2310
|
-
this.warned = true;
|
|
2311
|
-
this.logger.warn(message);
|
|
2312
|
-
}
|
|
2313
|
-
};
|
|
2314
|
-
DashboardSessionRequiredFilter = _ts_decorate7([
|
|
2315
|
-
(0, import_common7.Catch)(DashboardSessionRequiredException),
|
|
2316
|
-
_ts_param3(0, (0, import_common7.Optional)()),
|
|
2317
|
-
_ts_param3(0, (0, import_common7.Inject)(DASHBOARD_AUTH)),
|
|
2318
|
-
_ts_metadata5("design:type", Function),
|
|
2319
|
-
_ts_metadata5("design:paramtypes", [
|
|
2320
|
-
Object
|
|
2321
|
-
])
|
|
2322
|
-
], DashboardSessionRequiredFilter);
|
|
2323
|
-
|
|
2324
|
-
// src/server/durable-ui.controller.ts
|
|
2325
|
-
function _ts_decorate8(decorators, target, key, desc) {
|
|
2326
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2327
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
2328
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
2329
|
-
} else {
|
|
2330
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
2331
|
-
if (d = decorators[i]) {
|
|
2332
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2333
|
-
}
|
|
2334
|
-
}
|
|
2335
|
-
}
|
|
2336
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2337
|
-
}
|
|
2338
|
-
__name(_ts_decorate8, "_ts_decorate");
|
|
2339
|
-
function _ts_metadata6(metadataKey, metadataValue) {
|
|
2340
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
2341
|
-
return Reflect.metadata(metadataKey, metadataValue);
|
|
2342
|
-
}
|
|
2343
|
-
}
|
|
2344
|
-
__name(_ts_metadata6, "_ts_metadata");
|
|
2345
|
-
function _ts_param4(paramIndex, decorator) {
|
|
2346
|
-
return function(target, key) {
|
|
2347
|
-
decorator(target, key, paramIndex);
|
|
2348
|
-
};
|
|
2349
|
-
}
|
|
2350
|
-
__name(_ts_param4, "_ts_param");
|
|
2351
1718
|
var DASHBOARD_BASE_PATH = Symbol("DASHBOARD_BASE_PATH");
|
|
2352
1719
|
var DASHBOARD_API_PATH = Symbol("DASHBOARD_API_PATH");
|
|
2353
1720
|
var BUILD_BASE = "/durable";
|
|
@@ -2364,9 +1731,9 @@ var CONTENT_TYPES = {
|
|
|
2364
1731
|
".woff2": "font/woff2",
|
|
2365
1732
|
".ico": "image/x-icon"
|
|
2366
1733
|
};
|
|
2367
|
-
var
|
|
1734
|
+
var DurableUiControllerBase = class {
|
|
2368
1735
|
static {
|
|
2369
|
-
__name(this, "
|
|
1736
|
+
__name(this, "DurableUiControllerBase");
|
|
2370
1737
|
}
|
|
2371
1738
|
basePath;
|
|
2372
1739
|
apiBasePath;
|
|
@@ -2380,7 +1747,7 @@ var DurableUiController = class {
|
|
|
2380
1747
|
index() {
|
|
2381
1748
|
const indexPath = (0, import_node_path.join)(this.dir, "index.html");
|
|
2382
1749
|
if (!(0, import_node_fs.existsSync)(indexPath)) {
|
|
2383
|
-
throw new
|
|
1750
|
+
throw new import_common6.NotFoundException("Dashboard is not built. Run the package build.");
|
|
2384
1751
|
}
|
|
2385
1752
|
const html = (0, import_node_fs.readFileSync)(indexPath, "utf8").replaceAll(`="${BUILD_BASE}/`, `="${this.basePath}/`);
|
|
2386
1753
|
const inject = `<script>window.__DURABLE_BASE__='${this.basePath}';window.__DURABLE_API__='${this.apiBasePath}';</script>`;
|
|
@@ -2388,235 +1755,57 @@ var DurableUiController = class {
|
|
|
2388
1755
|
}
|
|
2389
1756
|
asset(file) {
|
|
2390
1757
|
const safe = (0, import_node_path.basename)(file);
|
|
2391
|
-
if (safe !== file) throw new
|
|
1758
|
+
if (safe !== file) throw new import_common6.NotFoundException();
|
|
2392
1759
|
const root = (0, import_node_path.resolve)(this.dir, "assets");
|
|
2393
1760
|
const assetPath = (0, import_node_path.resolve)(root, safe);
|
|
2394
1761
|
if (!assetPath.startsWith(root + import_node_path.sep) || !(0, import_node_fs.existsSync)(assetPath)) {
|
|
2395
|
-
throw new
|
|
1762
|
+
throw new import_common6.NotFoundException();
|
|
2396
1763
|
}
|
|
2397
1764
|
const type = CONTENT_TYPES[(0, import_node_path.extname)(safe)] ?? "application/octet-stream";
|
|
2398
|
-
return new
|
|
1765
|
+
return new import_common6.StreamableFile((0, import_node_fs.readFileSync)(assetPath), {
|
|
2399
1766
|
type
|
|
2400
1767
|
});
|
|
2401
1768
|
}
|
|
2402
1769
|
};
|
|
2403
|
-
|
|
2404
|
-
(0,
|
|
2405
|
-
(0,
|
|
2406
|
-
(0,
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
],
|
|
2411
|
-
|
|
2412
|
-
(0,
|
|
2413
|
-
(0,
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
1770
|
+
_ts_decorate6([
|
|
1771
|
+
(0, import_common6.Get)(),
|
|
1772
|
+
(0, import_common6.Header)("Content-Type", "text/html; charset=utf-8"),
|
|
1773
|
+
(0, import_common6.Header)("Cache-Control", "no-store, must-revalidate"),
|
|
1774
|
+
_ts_metadata5("design:type", Function),
|
|
1775
|
+
_ts_metadata5("design:paramtypes", []),
|
|
1776
|
+
_ts_metadata5("design:returntype", String)
|
|
1777
|
+
], DurableUiControllerBase.prototype, "index", null);
|
|
1778
|
+
_ts_decorate6([
|
|
1779
|
+
(0, import_common6.Get)("assets/:file"),
|
|
1780
|
+
(0, import_common6.Header)("Cache-Control", "public, max-age=31536000, immutable"),
|
|
1781
|
+
_ts_param3(0, (0, import_common6.Param)("file")),
|
|
1782
|
+
_ts_metadata5("design:type", Function),
|
|
1783
|
+
_ts_metadata5("design:paramtypes", [
|
|
2417
1784
|
String
|
|
2418
1785
|
]),
|
|
2419
|
-
|
|
2420
|
-
],
|
|
2421
|
-
|
|
2422
|
-
(0,
|
|
2423
|
-
(0,
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
_ts_metadata6("design:paramtypes", [
|
|
1786
|
+
_ts_metadata5("design:returntype", typeof import_common6.StreamableFile === "undefined" ? Object : import_common6.StreamableFile)
|
|
1787
|
+
], DurableUiControllerBase.prototype, "asset", null);
|
|
1788
|
+
DurableUiControllerBase = _ts_decorate6([
|
|
1789
|
+
(0, import_common6.Controller)(),
|
|
1790
|
+
_ts_param3(0, (0, import_common6.Inject)(DASHBOARD_BASE_PATH)),
|
|
1791
|
+
_ts_param3(1, (0, import_common6.Inject)(DASHBOARD_API_PATH)),
|
|
1792
|
+
_ts_metadata5("design:type", Function),
|
|
1793
|
+
_ts_metadata5("design:paramtypes", [
|
|
2428
1794
|
String,
|
|
2429
1795
|
String
|
|
2430
1796
|
])
|
|
2431
|
-
],
|
|
2432
|
-
|
|
2433
|
-
// src/server/durable-auth.controller.ts
|
|
2434
|
-
function _ts_decorate9(decorators, target, key, desc) {
|
|
2435
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2436
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
2437
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
2438
|
-
} else {
|
|
2439
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
2440
|
-
if (d = decorators[i]) {
|
|
2441
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2442
|
-
}
|
|
2443
|
-
}
|
|
2444
|
-
}
|
|
2445
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2446
|
-
}
|
|
2447
|
-
__name(_ts_decorate9, "_ts_decorate");
|
|
2448
|
-
function _ts_metadata7(metadataKey, metadataValue) {
|
|
2449
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
2450
|
-
return Reflect.metadata(metadataKey, metadataValue);
|
|
2451
|
-
}
|
|
2452
|
-
}
|
|
2453
|
-
__name(_ts_metadata7, "_ts_metadata");
|
|
2454
|
-
function _ts_param5(paramIndex, decorator) {
|
|
2455
|
-
return function(target, key) {
|
|
2456
|
-
decorator(target, key, paramIndex);
|
|
2457
|
-
};
|
|
2458
|
-
}
|
|
2459
|
-
__name(_ts_param5, "_ts_param");
|
|
2460
|
-
function isString(value) {
|
|
2461
|
-
return typeof value === "string";
|
|
2462
|
-
}
|
|
2463
|
-
__name(isString, "isString");
|
|
2464
|
-
var DurableAuthController = class _DurableAuthController {
|
|
1797
|
+
], DurableUiControllerBase);
|
|
1798
|
+
var DurableUiController = class extends DurableUiControllerBase {
|
|
2465
1799
|
static {
|
|
2466
|
-
__name(this, "
|
|
2467
|
-
}
|
|
2468
|
-
auth;
|
|
2469
|
-
basePath;
|
|
2470
|
-
logger = new import_common9.Logger(_DurableAuthController.name);
|
|
2471
|
-
/** Warn once per hook kind so a throwing hook doesn't spam logs on every failed attempt. */
|
|
2472
|
-
warnedHooks = /* @__PURE__ */ new Set();
|
|
2473
|
-
constructor(auth, basePath) {
|
|
2474
|
-
this.auth = auth;
|
|
2475
|
-
this.basePath = basePath;
|
|
2476
|
-
}
|
|
2477
|
-
// The login page reads `returnTo`/`error` from `location.search` client-side (see
|
|
2478
|
-
// `login-page.ts`), so this response never varies per request and needs no templating beyond
|
|
2479
|
-
// the developer-controlled `basePath`.
|
|
2480
|
-
loginPage() {
|
|
2481
|
-
const auth = this.requireAuth();
|
|
2482
|
-
if (!auth.modes.includes("login")) throw new import_common9.NotFoundException();
|
|
2483
|
-
return renderLoginPage(this.basePath);
|
|
2484
|
-
}
|
|
2485
|
-
// Called by the login page's own fetch (JSON, not a classic form POST — see `login-page.ts` for
|
|
2486
|
-
// why: it keeps the login page working with no host-configured body parser beyond the
|
|
2487
|
-
// JSON one Nest wires in by default on both Express and Fastify). Uniform `401` on any failure
|
|
2488
|
-
// (unknown user, wrong password, throwing hook) — no user-enumeration.
|
|
2489
|
-
async login(body, request, response) {
|
|
2490
|
-
const auth = this.requireAuth();
|
|
2491
|
-
if (!auth.modes.includes("login")) throw new import_common9.NotFoundException();
|
|
2492
|
-
if (!isString(body?.username) || !isString(body?.password)) {
|
|
2493
|
-
throw new import_common9.BadRequestException("Body must include string `username` and `password`.");
|
|
2494
|
-
}
|
|
2495
|
-
const { username, password } = body;
|
|
2496
|
-
const user = await this.runHook("login", () => auth.login?.(username, password) ?? null);
|
|
2497
|
-
if (!user) throw new import_common9.UnauthorizedException({
|
|
2498
|
-
message: "Invalid username or password."
|
|
2499
|
-
});
|
|
2500
|
-
issueSessionCookie(user, {
|
|
2501
|
-
auth,
|
|
2502
|
-
request,
|
|
2503
|
-
response
|
|
2504
|
-
});
|
|
2505
|
-
return {
|
|
2506
|
-
redirectTo: sanitizeReturnTo(body.returnTo, this.basePath)
|
|
2507
|
-
};
|
|
2508
|
-
}
|
|
2509
|
-
// Mode A: the host frontend (carrying its own auth) POSTs here; the host hook validates the raw
|
|
2510
|
-
// request and returns the session user, or `null` to deny. This is the SSO path — the host's own
|
|
2511
|
-
// guard decides, and no credential ever reaches this library.
|
|
2512
|
-
async session(request, response) {
|
|
2513
|
-
const auth = this.requireAuth();
|
|
2514
|
-
if (!auth.modes.includes("session")) throw new import_common9.NotFoundException();
|
|
2515
|
-
const user = await this.runHook("session", () => auth.session?.(request) ?? null);
|
|
2516
|
-
if (!user) throw new import_common9.UnauthorizedException();
|
|
2517
|
-
issueSessionCookie(user, {
|
|
2518
|
-
auth,
|
|
2519
|
-
request,
|
|
2520
|
-
response
|
|
2521
|
-
});
|
|
2522
|
-
}
|
|
2523
|
-
// Plain `GET` (not `POST`): logging out only ever destroys the CALLER's own session, so it's
|
|
2524
|
-
// safe/idempotent from the caller's perspective — a simple `<a href>` (no JS, no CSRF token)
|
|
2525
|
-
// works. Non-passthrough `@Res()`: this handler owns the response outright (clears the cookie,
|
|
2526
|
-
// then redirects), so Nest must not also try to send a return value afterwards.
|
|
2527
|
-
logout(request, response) {
|
|
2528
|
-
clearSessionCookie({
|
|
2529
|
-
request,
|
|
2530
|
-
response
|
|
2531
|
-
});
|
|
2532
|
-
redirectRaw(response, this.auth?.modes.includes("login") ? `${this.basePath}/login` : this.basePath);
|
|
2533
|
-
}
|
|
2534
|
-
requireAuth() {
|
|
2535
|
-
if (!this.auth) throw new import_common9.NotFoundException();
|
|
2536
|
-
return this.auth;
|
|
2537
|
-
}
|
|
2538
|
-
/**
|
|
2539
|
-
* Run a host hook (`login` or `session`) defensively: a throw is treated as a denial (uniform
|
|
2540
|
-
* failure) and warn-logged once PER KIND, so a buggy hook never 500s the endpoint into a
|
|
2541
|
-
* stack-trace leak nor floods the logs on repeated bad attempts.
|
|
2542
|
-
*/
|
|
2543
|
-
async runHook(kind, run) {
|
|
2544
|
-
try {
|
|
2545
|
-
return await run() ?? null;
|
|
2546
|
-
} catch (error) {
|
|
2547
|
-
if (!this.warnedHooks.has(kind)) {
|
|
2548
|
-
this.warnedHooks.add(kind);
|
|
2549
|
-
this.logger.warn(`dashboardAuth ${kind} hook threw; treating as denial. ${error instanceof Error ? error.message : String(error)}`);
|
|
2550
|
-
}
|
|
2551
|
-
return null;
|
|
2552
|
-
}
|
|
1800
|
+
__name(this, "DurableUiController");
|
|
2553
1801
|
}
|
|
2554
1802
|
};
|
|
2555
|
-
|
|
2556
|
-
(0,
|
|
2557
|
-
|
|
2558
|
-
(0, import_common9.Header)("Cache-Control", "no-store, must-revalidate"),
|
|
2559
|
-
_ts_metadata7("design:type", Function),
|
|
2560
|
-
_ts_metadata7("design:paramtypes", []),
|
|
2561
|
-
_ts_metadata7("design:returntype", String)
|
|
2562
|
-
], DurableAuthController.prototype, "loginPage", null);
|
|
2563
|
-
_ts_decorate9([
|
|
2564
|
-
(0, import_common9.Post)("login"),
|
|
2565
|
-
(0, import_common9.HttpCode)(200),
|
|
2566
|
-
_ts_param5(0, (0, import_common9.Body)()),
|
|
2567
|
-
_ts_param5(1, (0, import_common9.Req)()),
|
|
2568
|
-
_ts_param5(2, (0, import_common9.Res)({
|
|
2569
|
-
passthrough: true
|
|
2570
|
-
})),
|
|
2571
|
-
_ts_metadata7("design:type", Function),
|
|
2572
|
-
_ts_metadata7("design:paramtypes", [
|
|
2573
|
-
typeof LoginBody === "undefined" ? Object : LoginBody,
|
|
2574
|
-
Object,
|
|
2575
|
-
Object
|
|
2576
|
-
]),
|
|
2577
|
-
_ts_metadata7("design:returntype", Promise)
|
|
2578
|
-
], DurableAuthController.prototype, "login", null);
|
|
2579
|
-
_ts_decorate9([
|
|
2580
|
-
(0, import_common9.Post)("session"),
|
|
2581
|
-
(0, import_common9.HttpCode)(204),
|
|
2582
|
-
_ts_param5(0, (0, import_common9.Req)()),
|
|
2583
|
-
_ts_param5(1, (0, import_common9.Res)({
|
|
2584
|
-
passthrough: true
|
|
2585
|
-
})),
|
|
2586
|
-
_ts_metadata7("design:type", Function),
|
|
2587
|
-
_ts_metadata7("design:paramtypes", [
|
|
2588
|
-
Object,
|
|
2589
|
-
Object
|
|
2590
|
-
]),
|
|
2591
|
-
_ts_metadata7("design:returntype", Promise)
|
|
2592
|
-
], DurableAuthController.prototype, "session", null);
|
|
2593
|
-
_ts_decorate9([
|
|
2594
|
-
(0, import_common9.Get)("logout"),
|
|
2595
|
-
_ts_param5(0, (0, import_common9.Req)()),
|
|
2596
|
-
_ts_param5(1, (0, import_common9.Res)()),
|
|
2597
|
-
_ts_metadata7("design:type", Function),
|
|
2598
|
-
_ts_metadata7("design:paramtypes", [
|
|
2599
|
-
Object,
|
|
2600
|
-
Object
|
|
2601
|
-
]),
|
|
2602
|
-
_ts_metadata7("design:returntype", void 0)
|
|
2603
|
-
], DurableAuthController.prototype, "logout", null);
|
|
2604
|
-
DurableAuthController = _ts_decorate9([
|
|
2605
|
-
(0, import_common9.Controller)(),
|
|
2606
|
-
_ts_param5(0, (0, import_common9.Optional)()),
|
|
2607
|
-
_ts_param5(0, (0, import_common9.Inject)(DASHBOARD_AUTH)),
|
|
2608
|
-
_ts_param5(1, (0, import_common9.Inject)(DASHBOARD_BASE_PATH)),
|
|
2609
|
-
_ts_metadata7("design:type", Function),
|
|
2610
|
-
_ts_metadata7("design:paramtypes", [
|
|
2611
|
-
Object,
|
|
2612
|
-
String
|
|
2613
|
-
])
|
|
2614
|
-
], DurableAuthController);
|
|
1803
|
+
DurableUiController = _ts_decorate6([
|
|
1804
|
+
(0, import_common6.Controller)()
|
|
1805
|
+
], DurableUiController);
|
|
2615
1806
|
|
|
2616
|
-
// src/server/durable-dashboard
|
|
2617
|
-
|
|
2618
|
-
var import_common10 = require("@nestjs/common");
|
|
2619
|
-
function _ts_decorate10(decorators, target, key, desc) {
|
|
1807
|
+
// src/server/durable-dashboard.module.ts
|
|
1808
|
+
function _ts_decorate7(decorators, target, key, desc) {
|
|
2620
1809
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2621
1810
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
2622
1811
|
r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -2629,342 +1818,59 @@ function _ts_decorate10(decorators, target, key, desc) {
|
|
|
2629
1818
|
}
|
|
2630
1819
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2631
1820
|
}
|
|
2632
|
-
__name(
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
decorator(target, key, paramIndex);
|
|
2642
|
-
};
|
|
2643
|
-
}
|
|
2644
|
-
__name(_ts_param6, "_ts_param");
|
|
2645
|
-
var DURABLE_DASHBOARD_TOKEN_ENV = "DURABLE_DASHBOARD_TOKEN";
|
|
2646
|
-
var DASHBOARD_GATE = Symbol("DASHBOARD_GATE");
|
|
2647
|
-
var LOG_CONTEXT = "DurableDashboard";
|
|
2648
|
-
var HOW_TO_CONFIGURE = [
|
|
2649
|
-
"Configure one of: `guards: [YourAuthGuard]`, `dashboardAuth: { secret, session | login }`",
|
|
2650
|
-
"(or `useDashboardAuth` in forRootAsync), a bearer token via the `token` option or the",
|
|
2651
|
-
`${DURABLE_DASHBOARD_TOKEN_ENV} env var, or \`allowUnauthenticated: true\` when the console is`,
|
|
2652
|
-
"already protected outside this module (a global guard, a reverse proxy, a private network)."
|
|
1821
|
+
__name(_ts_decorate7, "_ts_decorate");
|
|
1822
|
+
markOpenToAuthorization(DurableApiController);
|
|
1823
|
+
markOpenToAuthorization(DurableUiController);
|
|
1824
|
+
var DASHBOARD_PROTECTION_CHECK = Symbol("DASHBOARD_PROTECTION_CHECK");
|
|
1825
|
+
var UNPROTECTED_CONSOLE_IN_PRODUCTION = [
|
|
1826
|
+
"DurableDashboardModule: NODE_ENV=production and the durable console is mounted with no",
|
|
1827
|
+
"protection, so the app refuses to boot. Protect it one of two ways:",
|
|
1828
|
+
"(1) decorators on the mounted console: DurableDashboardModule.forRoot({ decorators: [UseGuards(AuthenticationGuard), Can(ConsolePolicy, 'view')] });",
|
|
1829
|
+
"(2) mount it yourself: DurableDashboardModule.forRoot({ routes: false }) plus @Controller('durable') @UseGuards(AuthenticationGuard) @Can(ConsolePolicy, 'view') class ConsoleUi extends DurableUiControllerBase {} (and the same over DurableApiControllerBase at 'durable/api')."
|
|
2653
1830
|
].join(" ");
|
|
2654
1831
|
function isProduction() {
|
|
2655
1832
|
return (process.env.NODE_ENV ?? "").trim().toLowerCase() === "production";
|
|
2656
1833
|
}
|
|
2657
1834
|
__name(isProduction, "isProduction");
|
|
2658
|
-
function
|
|
2659
|
-
if (options.hasGuards || auth !== null) return {
|
|
2660
|
-
mode: "delegated"
|
|
2661
|
-
};
|
|
2662
|
-
const token = options.token ?? process.env[DURABLE_DASHBOARD_TOKEN_ENV];
|
|
2663
|
-
if (typeof token === "string" && token !== "") return {
|
|
2664
|
-
mode: "token",
|
|
2665
|
-
token
|
|
2666
|
-
};
|
|
2667
|
-
if (options.allowUnauthenticated === true) return {
|
|
2668
|
-
mode: "open"
|
|
2669
|
-
};
|
|
1835
|
+
function protectionCheckProvider() {
|
|
2670
1836
|
return {
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
switch (gate.mode) {
|
|
2677
|
-
case "open":
|
|
2678
|
-
logger.warn("allowUnauthenticated: true. The durable console (including retry/cancel and other mutating endpoints) is served with NO authentication from this module. Only do this when a global guard or reverse proxy already protects it.");
|
|
2679
|
-
return;
|
|
2680
|
-
case "token":
|
|
2681
|
-
if (options.allowUnauthenticated === true) {
|
|
2682
|
-
logger.warn("allowUnauthenticated: true is ignored because a dashboard token is configured; requests must carry the token.");
|
|
2683
|
-
}
|
|
2684
|
-
return;
|
|
2685
|
-
case "unconfigured":
|
|
2686
|
-
logger.warn([
|
|
2687
|
-
"The durable console is UNAUTHENTICATED: no guards, dashboardAuth, token or",
|
|
2688
|
-
"allowUnauthenticated were configured. It is served open because NODE_ENV is not",
|
|
2689
|
-
'"production", but it WILL deny every request when NODE_ENV=production.',
|
|
2690
|
-
HOW_TO_CONFIGURE
|
|
2691
|
-
].join(" "));
|
|
2692
|
-
return;
|
|
2693
|
-
case "deny":
|
|
2694
|
-
logger.error([
|
|
2695
|
-
"The durable console has no authentication configured and NODE_ENV=production, so it",
|
|
2696
|
-
"is failing closed: every console request (UI and API) is denied.",
|
|
2697
|
-
HOW_TO_CONFIGURE
|
|
2698
|
-
].join(" "));
|
|
2699
|
-
return;
|
|
2700
|
-
case "delegated":
|
|
2701
|
-
return;
|
|
2702
|
-
}
|
|
2703
|
-
}
|
|
2704
|
-
__name(reportDashboardGate, "reportDashboardGate");
|
|
2705
|
-
function dashboardGateProvider(options) {
|
|
2706
|
-
return {
|
|
2707
|
-
provide: DASHBOARD_GATE,
|
|
2708
|
-
inject: [
|
|
2709
|
-
DASHBOARD_AUTH
|
|
2710
|
-
],
|
|
2711
|
-
useFactory: /* @__PURE__ */ __name((auth) => {
|
|
2712
|
-
const gate = resolveDashboardGate(options, auth);
|
|
2713
|
-
reportDashboardGate(gate, options);
|
|
2714
|
-
return gate;
|
|
1837
|
+
provide: DASHBOARD_PROTECTION_CHECK,
|
|
1838
|
+
useFactory: /* @__PURE__ */ __name(() => {
|
|
1839
|
+
if (isProduction()) throw new Error(UNPROTECTED_CONSOLE_IN_PRODUCTION);
|
|
1840
|
+
new import_common7.Logger("DurableDashboard").warn("The durable console is mounted with no `decorators`, so it is served OPEN (retry/cancel included). That is refused when NODE_ENV=production: pass `decorators` (e.g. [UseGuards(AuthenticationGuard), Can(ConsolePolicy, 'view')]) or mount it yourself with `routes: false`.");
|
|
1841
|
+
return true;
|
|
2715
1842
|
}, "useFactory")
|
|
2716
1843
|
};
|
|
2717
1844
|
}
|
|
2718
|
-
__name(
|
|
2719
|
-
function
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
return void 0;
|
|
2730
|
-
}
|
|
2731
|
-
__name(headerValue, "headerValue");
|
|
2732
|
-
function readDashboardToken(request) {
|
|
2733
|
-
if (!isRecord3(request)) return void 0;
|
|
2734
|
-
const authorization = headerValue(request, "authorization");
|
|
2735
|
-
if (authorization) {
|
|
2736
|
-
const match = /^Bearer\s+(.+)$/i.exec(authorization);
|
|
2737
|
-
if (match?.[1]) return match[1].trim();
|
|
2738
|
-
}
|
|
2739
|
-
const header = headerValue(request, "x-durable-token");
|
|
2740
|
-
if (header) return header.trim();
|
|
2741
|
-
const method = typeof request.method === "string" ? request.method.toUpperCase() : "";
|
|
2742
|
-
if (method === "GET" || method === "HEAD") {
|
|
2743
|
-
const query = request.query;
|
|
2744
|
-
if (isRecord3(query)) {
|
|
2745
|
-
const value = query.token;
|
|
2746
|
-
if (typeof value === "string" && value !== "") return value;
|
|
2747
|
-
}
|
|
2748
|
-
}
|
|
2749
|
-
return void 0;
|
|
2750
|
-
}
|
|
2751
|
-
__name(readDashboardToken, "readDashboardToken");
|
|
2752
|
-
function secretsMatch(provided, expected) {
|
|
2753
|
-
const a = Buffer.from(provided);
|
|
2754
|
-
const b = Buffer.from(expected);
|
|
2755
|
-
if (a.length !== b.length) return false;
|
|
2756
|
-
return (0, import_node_crypto2.timingSafeEqual)(a, b);
|
|
2757
|
-
}
|
|
2758
|
-
__name(secretsMatch, "secretsMatch");
|
|
2759
|
-
var DurableDashboardGateGuard = class {
|
|
2760
|
-
static {
|
|
2761
|
-
__name(this, "DurableDashboardGateGuard");
|
|
2762
|
-
}
|
|
2763
|
-
gate;
|
|
2764
|
-
constructor(gate) {
|
|
2765
|
-
this.gate = gate;
|
|
2766
|
-
}
|
|
2767
|
-
canActivate(context) {
|
|
2768
|
-
switch (this.gate.mode) {
|
|
2769
|
-
case "delegated":
|
|
2770
|
-
case "open":
|
|
2771
|
-
case "unconfigured":
|
|
2772
|
-
return true;
|
|
2773
|
-
case "deny":
|
|
2774
|
-
throw new import_common10.ForbiddenException([
|
|
2775
|
-
"Durable dashboard authentication is not configured, and NODE_ENV=production denies",
|
|
2776
|
-
"an unauthenticated console.",
|
|
2777
|
-
HOW_TO_CONFIGURE
|
|
2778
|
-
].join(" "));
|
|
2779
|
-
case "token": {
|
|
2780
|
-
const provided = readDashboardToken(context.switchToHttp().getRequest());
|
|
2781
|
-
if (provided !== void 0 && secretsMatch(provided, this.gate.token ?? "")) return true;
|
|
2782
|
-
throw new import_common10.UnauthorizedException("A valid durable dashboard token is required (Authorization: Bearer <token>, x-durable-token, or ?token= on GET).");
|
|
2783
|
-
}
|
|
2784
|
-
}
|
|
2785
|
-
}
|
|
2786
|
-
};
|
|
2787
|
-
DurableDashboardGateGuard = _ts_decorate10([
|
|
2788
|
-
(0, import_common10.Injectable)(),
|
|
2789
|
-
_ts_param6(0, (0, import_common10.Inject)(DASHBOARD_GATE)),
|
|
2790
|
-
_ts_metadata8("design:type", Function),
|
|
2791
|
-
_ts_metadata8("design:paramtypes", [
|
|
2792
|
-
typeof DashboardGate === "undefined" ? Object : DashboardGate
|
|
2793
|
-
])
|
|
2794
|
-
], DurableDashboardGateGuard);
|
|
2795
|
-
|
|
2796
|
-
// src/server/durable-dashboard.module.ts
|
|
2797
|
-
var import_reflect_metadata = require("reflect-metadata");
|
|
2798
|
-
var import_nestjs_filter3 = require("@dudousxd/nestjs-filter");
|
|
2799
|
-
var import_common12 = require("@nestjs/common");
|
|
2800
|
-
var import_core = require("@nestjs/core");
|
|
2801
|
-
|
|
2802
|
-
// src/server/durable-session.guard.ts
|
|
2803
|
-
var import_common11 = require("@nestjs/common");
|
|
2804
|
-
function _ts_decorate11(decorators, target, key, desc) {
|
|
2805
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2806
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
2807
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
2808
|
-
} else {
|
|
2809
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
2810
|
-
if (d = decorators[i]) {
|
|
2811
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2812
|
-
}
|
|
2813
|
-
}
|
|
2814
|
-
}
|
|
2815
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2816
|
-
}
|
|
2817
|
-
__name(_ts_decorate11, "_ts_decorate");
|
|
2818
|
-
function _ts_metadata9(metadataKey, metadataValue) {
|
|
2819
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
2820
|
-
return Reflect.metadata(metadataKey, metadataValue);
|
|
2821
|
-
}
|
|
2822
|
-
}
|
|
2823
|
-
__name(_ts_metadata9, "_ts_metadata");
|
|
2824
|
-
function _ts_param7(paramIndex, decorator) {
|
|
2825
|
-
return function(target, key) {
|
|
2826
|
-
decorator(target, key, paramIndex);
|
|
2827
|
-
};
|
|
2828
|
-
}
|
|
2829
|
-
__name(_ts_param7, "_ts_param");
|
|
2830
|
-
var DurableUiSessionGuard = class {
|
|
2831
|
-
static {
|
|
2832
|
-
__name(this, "DurableUiSessionGuard");
|
|
2833
|
-
}
|
|
2834
|
-
auth;
|
|
2835
|
-
basePath;
|
|
2836
|
-
constructor(auth, basePath) {
|
|
2837
|
-
this.auth = auth;
|
|
2838
|
-
this.basePath = basePath;
|
|
2839
|
-
}
|
|
2840
|
-
async canActivate(context) {
|
|
2841
|
-
if (!this.auth) return true;
|
|
2842
|
-
const auth = this.auth;
|
|
2843
|
-
const http = context.switchToHttp();
|
|
2844
|
-
const request = http.getRequest();
|
|
2845
|
-
const session = readSessionFromRequest(auth, request);
|
|
2846
|
-
if (!session) {
|
|
2847
|
-
this.denyUnauthenticated(auth, request);
|
|
2848
|
-
}
|
|
2849
|
-
if (!await maybeRenewSession(auth, session, request, http.getResponse())) {
|
|
2850
|
-
this.denyUnauthenticated(auth, request);
|
|
2851
|
-
}
|
|
2852
|
-
return true;
|
|
2853
|
-
}
|
|
2854
|
-
/**
|
|
2855
|
-
* A revoked session (the host's `revalidate` hook says no) is denied exactly like an absent
|
|
2856
|
-
* one — by design, there is nothing left to distinguish "never had a session" from "had one,
|
|
2857
|
-
* then lost it" once the cookie is cleared, so both get the same Mode-aware treatment.
|
|
2858
|
-
*
|
|
2859
|
-
* Takes `auth` explicitly rather than reading `this.auth`: `canActivate`'s `!this.auth` early
|
|
2860
|
-
* return narrows the field within that method only — TS doesn't carry it across a method call
|
|
2861
|
-
* — so callers pass the already-narrowed value instead of this method re-deriving (or
|
|
2862
|
-
* asserting away) the nullability.
|
|
2863
|
-
*/
|
|
2864
|
-
denyUnauthenticated(auth, request) {
|
|
2865
|
-
if (!auth.modes.includes("login")) throw new DashboardSessionRequiredException(this.basePath);
|
|
2866
|
-
const returnTo = encodeURIComponent(originalRequestUrl(request));
|
|
2867
|
-
throw new DashboardLoginRedirectException(`${this.basePath}/login?returnTo=${returnTo}`);
|
|
2868
|
-
}
|
|
2869
|
-
};
|
|
2870
|
-
DurableUiSessionGuard = _ts_decorate11([
|
|
2871
|
-
(0, import_common11.Injectable)(),
|
|
2872
|
-
_ts_param7(0, (0, import_common11.Inject)(DASHBOARD_AUTH)),
|
|
2873
|
-
_ts_param7(1, (0, import_common11.Inject)(DASHBOARD_BASE_PATH)),
|
|
2874
|
-
_ts_metadata9("design:type", Function),
|
|
2875
|
-
_ts_metadata9("design:paramtypes", [
|
|
2876
|
-
Object,
|
|
2877
|
-
String
|
|
2878
|
-
])
|
|
2879
|
-
], DurableUiSessionGuard);
|
|
2880
|
-
var DurableApiSessionGuard = class {
|
|
2881
|
-
static {
|
|
2882
|
-
__name(this, "DurableApiSessionGuard");
|
|
2883
|
-
}
|
|
2884
|
-
auth;
|
|
2885
|
-
constructor(auth) {
|
|
2886
|
-
this.auth = auth;
|
|
2887
|
-
}
|
|
2888
|
-
async canActivate(context) {
|
|
2889
|
-
if (!this.auth) return true;
|
|
2890
|
-
const auth = this.auth;
|
|
2891
|
-
const http = context.switchToHttp();
|
|
2892
|
-
const request = http.getRequest();
|
|
2893
|
-
const session = readSessionFromRequest(auth, request);
|
|
2894
|
-
if (!session) throw this.unauthorized(auth);
|
|
2895
|
-
if (!await maybeRenewSession(auth, session, request, http.getResponse())) {
|
|
2896
|
-
throw this.unauthorized(auth);
|
|
2897
|
-
}
|
|
2898
|
-
return true;
|
|
2899
|
-
}
|
|
2900
|
-
/**
|
|
2901
|
-
* A bare 401 body carrying `{ auth: { modes } }` — mirrors `@dudousxd/nestjs-telescope`'s
|
|
2902
|
-
* dashboardAuth 401. The API is fetched (never navigated), so this is the ONLY way the console
|
|
2903
|
-
* SPA (`durable-client.ts`) learns which auth surface to send the operator to on a mid-session
|
|
2904
|
-
* 401; `DurableUiSessionGuard`'s redirect/session-required exceptions above don't reach it.
|
|
2905
|
-
*/
|
|
2906
|
-
unauthorized(auth) {
|
|
2907
|
-
return new import_common11.UnauthorizedException({
|
|
2908
|
-
auth: {
|
|
2909
|
-
modes: auth.modes
|
|
2910
|
-
}
|
|
2911
|
-
});
|
|
2912
|
-
}
|
|
2913
|
-
};
|
|
2914
|
-
DurableApiSessionGuard = _ts_decorate11([
|
|
2915
|
-
(0, import_common11.Injectable)(),
|
|
2916
|
-
_ts_param7(0, (0, import_common11.Inject)(DASHBOARD_AUTH)),
|
|
2917
|
-
_ts_metadata9("design:type", Function),
|
|
2918
|
-
_ts_metadata9("design:paramtypes", [
|
|
2919
|
-
Object
|
|
2920
|
-
])
|
|
2921
|
-
], DurableApiSessionGuard);
|
|
2922
|
-
|
|
2923
|
-
// src/server/durable-dashboard.module.ts
|
|
2924
|
-
function _ts_decorate12(decorators, target, key, desc) {
|
|
2925
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2926
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
2927
|
-
r = Reflect.decorate(decorators, target, key, desc);
|
|
2928
|
-
} else {
|
|
2929
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
2930
|
-
if (d = decorators[i]) {
|
|
2931
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2932
|
-
}
|
|
2933
|
-
}
|
|
2934
|
-
}
|
|
2935
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2936
|
-
}
|
|
2937
|
-
__name(_ts_decorate12, "_ts_decorate");
|
|
2938
|
-
var GUARDS_METADATA = "__guards__";
|
|
1845
|
+
__name(protectionCheckProvider, "protectionCheckProvider");
|
|
1846
|
+
function assertNothingToDecorate(options) {
|
|
1847
|
+
if (options.decorators === void 0) return;
|
|
1848
|
+
throw new Error([
|
|
1849
|
+
"DurableDashboardModule.forRoot({ routes: false }) mounts no controllers, so `decorators`",
|
|
1850
|
+
"would protect nothing. Put your protection on the controllers you mount (extend",
|
|
1851
|
+
"DurableUiControllerBase / DurableApiControllerBase and decorate them with @UseGuards /",
|
|
1852
|
+
"@Can), and drop `decorators`."
|
|
1853
|
+
].join(" "));
|
|
1854
|
+
}
|
|
1855
|
+
__name(assertNothingToDecorate, "assertNothingToDecorate");
|
|
2939
1856
|
function normalize(path) {
|
|
2940
1857
|
return `/${path.replace(/^\/+|\/+$/g, "")}`;
|
|
2941
1858
|
}
|
|
2942
1859
|
__name(normalize, "normalize");
|
|
2943
|
-
function stampGuards(hostGuards, builtIn, controller) {
|
|
2944
|
-
const merged = [
|
|
2945
|
-
...builtIn.filter((guard) => guard !== void 0),
|
|
2946
|
-
...hostGuards ?? []
|
|
2947
|
-
];
|
|
2948
|
-
Reflect.defineMetadata(GUARDS_METADATA, merged, controller);
|
|
2949
|
-
}
|
|
2950
|
-
__name(stampGuards, "stampGuards");
|
|
2951
1860
|
var DurableApiModule = class _DurableApiModule {
|
|
2952
1861
|
static {
|
|
2953
1862
|
__name(this, "DurableApiModule");
|
|
2954
1863
|
}
|
|
2955
1864
|
static register(options) {
|
|
2956
|
-
|
|
2957
|
-
options.authMayBeConfigured ? DurableApiSessionGuard : void 0,
|
|
2958
|
-
options.stampGate ? DurableDashboardGateGuard : void 0
|
|
2959
|
-
], DurableApiController);
|
|
1865
|
+
const routes = options.routes !== false;
|
|
2960
1866
|
return {
|
|
2961
1867
|
module: _DurableApiModule,
|
|
2962
1868
|
imports: [
|
|
2963
1869
|
...options.imports ?? []
|
|
2964
1870
|
],
|
|
2965
|
-
controllers: [
|
|
2966
|
-
DurableApiController
|
|
2967
|
-
],
|
|
1871
|
+
controllers: routes ? [
|
|
1872
|
+
controllerFor(DurableApiController, options.decorators)
|
|
1873
|
+
] : [],
|
|
2968
1874
|
providers: [
|
|
2969
1875
|
DashboardService,
|
|
2970
1876
|
// `@dudousxd/nestjs-filter` is wired PRIVATELY here rather than through
|
|
@@ -2997,82 +1903,81 @@ var DurableApiModule = class _DurableApiModule {
|
|
|
2997
1903
|
provide: RUN_QUERY_ADAPTER,
|
|
2998
1904
|
useExisting: RunQueryAdapter
|
|
2999
1905
|
},
|
|
3000
|
-
RunFilter
|
|
3001
|
-
options.authProvider,
|
|
3002
|
-
DurableApiSessionGuard,
|
|
3003
|
-
// Resolved ONCE here (this module is imported by the UI module, which reuses it via the
|
|
3004
|
-
// export below), so the boot report is logged once per mount.
|
|
3005
|
-
dashboardGateProvider(options.gate),
|
|
3006
|
-
DurableDashboardGateGuard,
|
|
3007
|
-
...options.guards ?? []
|
|
1906
|
+
RunFilter
|
|
3008
1907
|
],
|
|
3009
|
-
|
|
1908
|
+
// Self-mounted (`routes: false`): the host's own subclass of `DurableApiControllerBase` is
|
|
1909
|
+
// hosted in the HOST's module, so what its constructor injects must be exported. `FilterRunner`
|
|
1910
|
+
// is only exported then: exporting it from a mounted console would shadow a host's own
|
|
1911
|
+
// `FilterModule` runner in whatever module imports the dashboard.
|
|
1912
|
+
exports: routes ? [
|
|
1913
|
+
DashboardService
|
|
1914
|
+
] : [
|
|
3010
1915
|
DashboardService,
|
|
3011
|
-
|
|
1916
|
+
import_nestjs_filter3.FilterRunner
|
|
3012
1917
|
]
|
|
3013
1918
|
};
|
|
3014
1919
|
}
|
|
3015
1920
|
};
|
|
3016
|
-
DurableApiModule =
|
|
3017
|
-
(0,
|
|
1921
|
+
DurableApiModule = _ts_decorate7([
|
|
1922
|
+
(0, import_common7.Module)({})
|
|
3018
1923
|
], DurableApiModule);
|
|
3019
1924
|
var DurableDashboardModule = class _DurableDashboardModule {
|
|
3020
1925
|
static {
|
|
3021
1926
|
__name(this, "DurableDashboardModule");
|
|
3022
1927
|
}
|
|
3023
1928
|
static forRoot(options = {}) {
|
|
3024
|
-
const authProvider = {
|
|
3025
|
-
provide: DASHBOARD_AUTH,
|
|
3026
|
-
useValue: resolveDashboardAuth(options.dashboardAuth)
|
|
3027
|
-
};
|
|
3028
|
-
const authConfigured = options.dashboardAuth !== void 0;
|
|
3029
|
-
return _DurableDashboardModule.build(options, authProvider, authConfigured, authConfigured);
|
|
3030
|
-
}
|
|
3031
|
-
static forRootAsync(options) {
|
|
3032
|
-
const authProvider = {
|
|
3033
|
-
provide: DASHBOARD_AUTH,
|
|
3034
|
-
inject: options.inject ?? [],
|
|
3035
|
-
useFactory: /* @__PURE__ */ __name(async (...deps) => resolveDashboardAuth(await options.useDashboardAuth(...deps)), "useFactory")
|
|
3036
|
-
};
|
|
3037
|
-
return _DurableDashboardModule.build(options, authProvider, true, false);
|
|
3038
|
-
}
|
|
3039
|
-
/** Shared wiring: static routing + the API module, with `dashboardAuth` supplied by `authProvider`. */
|
|
3040
|
-
static build(options, authProvider, authMayBeConfigured, authStaticallyConfigured) {
|
|
3041
1929
|
const basePath = normalize(options.basePath ?? "/durable");
|
|
3042
1930
|
const apiBasePath = normalize(options.apiBasePath ?? `${basePath}/api`);
|
|
3043
|
-
const
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
}
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
1931
|
+
const pathProviders = [
|
|
1932
|
+
{
|
|
1933
|
+
provide: DASHBOARD_BASE_PATH,
|
|
1934
|
+
useValue: basePath
|
|
1935
|
+
},
|
|
1936
|
+
{
|
|
1937
|
+
provide: DASHBOARD_API_PATH,
|
|
1938
|
+
useValue: apiBasePath
|
|
1939
|
+
}
|
|
1940
|
+
];
|
|
1941
|
+
if (options.routes === false) {
|
|
1942
|
+
assertNothingToDecorate(options);
|
|
1943
|
+
const api = DurableApiModule.register({
|
|
1944
|
+
...options.imports ? {
|
|
1945
|
+
imports: options.imports
|
|
1946
|
+
} : {},
|
|
1947
|
+
routes: false
|
|
1948
|
+
});
|
|
1949
|
+
return {
|
|
1950
|
+
module: _DurableDashboardModule,
|
|
1951
|
+
imports: [
|
|
1952
|
+
...options.imports ?? [],
|
|
1953
|
+
api
|
|
1954
|
+
],
|
|
1955
|
+
controllers: [],
|
|
1956
|
+
providers: pathProviders,
|
|
1957
|
+
// What a host's subclasses of `DurableUiControllerBase` / `DurableApiControllerBase` inject:
|
|
1958
|
+
// the SPA's paths, and the read/action service and the filter runner via the API module.
|
|
1959
|
+
exports: [
|
|
1960
|
+
DurableApiModule,
|
|
1961
|
+
DASHBOARD_BASE_PATH,
|
|
1962
|
+
DASHBOARD_API_PATH
|
|
1963
|
+
]
|
|
1964
|
+
};
|
|
1965
|
+
}
|
|
1966
|
+
const decorated = (options.decorators?.length ?? 0) > 0;
|
|
3058
1967
|
return {
|
|
3059
1968
|
module: _DurableDashboardModule,
|
|
3060
1969
|
imports: [
|
|
3061
1970
|
...options.imports ?? [],
|
|
3062
|
-
//
|
|
3063
|
-
//
|
|
1971
|
+
// Host imports must reach the API controller's HOST module: enhancers resolve from their
|
|
1972
|
+
// controller's own module, never from a parent (see DurableApiModule.register).
|
|
3064
1973
|
// Spread-only-when-set: exactOptionalPropertyTypes rejects an explicit `undefined`.
|
|
3065
1974
|
DurableApiModule.register({
|
|
3066
1975
|
...options.imports ? {
|
|
3067
1976
|
imports: options.imports
|
|
3068
1977
|
} : {},
|
|
3069
|
-
...options.
|
|
3070
|
-
|
|
3071
|
-
} : {}
|
|
3072
|
-
authProvider,
|
|
3073
|
-
authMayBeConfigured,
|
|
3074
|
-
gate,
|
|
3075
|
-
stampGate
|
|
1978
|
+
...options.decorators ? {
|
|
1979
|
+
decorators: options.decorators
|
|
1980
|
+
} : {}
|
|
3076
1981
|
}),
|
|
3077
1982
|
import_core.RouterModule.register([
|
|
3078
1983
|
{
|
|
@@ -3086,30 +1991,13 @@ var DurableDashboardModule = class _DurableDashboardModule {
|
|
|
3086
1991
|
])
|
|
3087
1992
|
],
|
|
3088
1993
|
controllers: [
|
|
3089
|
-
DurableUiController,
|
|
3090
|
-
// The auth controller (login page + logout) only exists when dashboardAuth might be
|
|
3091
|
-
// configured — mounting it unconditionally would add a new `/login` route even for hosts
|
|
3092
|
-
// that never set `dashboardAuth`, breaking "absent -> today's behavior byte-for-byte".
|
|
3093
|
-
...authMayBeConfigured ? [
|
|
3094
|
-
DurableAuthController
|
|
3095
|
-
] : []
|
|
1994
|
+
controllerFor(DurableUiController, options.decorators)
|
|
3096
1995
|
],
|
|
3097
1996
|
providers: [
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
{
|
|
3103
|
-
provide: DASHBOARD_API_PATH,
|
|
3104
|
-
useValue: apiBasePath
|
|
3105
|
-
},
|
|
3106
|
-
authProvider,
|
|
3107
|
-
DurableUiSessionGuard,
|
|
3108
|
-
// `DASHBOARD_GATE` itself comes from the imported DurableApiModule (resolved once there).
|
|
3109
|
-
DurableDashboardGateGuard,
|
|
3110
|
-
// DurableUiController (and DurableAuthController, when present) are hosted HERE, so their
|
|
3111
|
-
// guards DI-instantiate from this module.
|
|
3112
|
-
...options.guards ?? []
|
|
1997
|
+
...pathProviders,
|
|
1998
|
+
...decorated ? [] : [
|
|
1999
|
+
protectionCheckProvider()
|
|
2000
|
+
]
|
|
3113
2001
|
],
|
|
3114
2002
|
// Re-export the API module so its DashboardService reaches importers (e.g. flip's own controllers).
|
|
3115
2003
|
exports: [
|
|
@@ -3118,27 +2006,21 @@ var DurableDashboardModule = class _DurableDashboardModule {
|
|
|
3118
2006
|
};
|
|
3119
2007
|
}
|
|
3120
2008
|
};
|
|
3121
|
-
DurableDashboardModule =
|
|
3122
|
-
(0,
|
|
2009
|
+
DurableDashboardModule = _ts_decorate7([
|
|
2010
|
+
(0, import_common7.Module)({})
|
|
3123
2011
|
], DurableDashboardModule);
|
|
3124
2012
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3125
2013
|
0 && (module.exports = {
|
|
3126
2014
|
DASHBOARD_API_PATH,
|
|
3127
2015
|
DASHBOARD_BASE_PATH,
|
|
3128
|
-
|
|
3129
|
-
DURABLE_DASHBOARD_TOKEN_ENV,
|
|
2016
|
+
DASHBOARD_PROTECTION_CHECK,
|
|
3130
2017
|
DashboardService,
|
|
3131
2018
|
DurableApiController,
|
|
2019
|
+
DurableApiControllerBase,
|
|
3132
2020
|
DurableApiModule,
|
|
3133
|
-
DurableApiSessionGuard,
|
|
3134
|
-
DurableAuthController,
|
|
3135
|
-
DurableDashboardGateGuard,
|
|
3136
2021
|
DurableDashboardModule,
|
|
3137
2022
|
DurableUiController,
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
readDashboardToken,
|
|
3141
|
-
reportDashboardGate,
|
|
3142
|
-
resolveDashboardGate
|
|
2023
|
+
DurableUiControllerBase,
|
|
2024
|
+
UNPROTECTED_CONSOLE_IN_PRODUCTION
|
|
3143
2025
|
});
|
|
3144
2026
|
//# sourceMappingURL=index.cjs.map
|