@camstack/server 1.2.594 → 1.2.596
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/addon-root-inventory.js +50 -11
- package/dist/agent/addon-scan.js +44 -6
- package/dist/agent/agent-addon-runtime.js +8 -3
- package/dist/agent/agent-addon-updates.js +52 -12
- package/dist/agent/agent-cap-dispatch-service.js +5 -3
- package/dist/agent/agent-config.js +42 -7
- package/dist/agent/agent-deploy-swap.js +41 -5
- package/dist/agent/agent-group-runner.js +47 -8
- package/dist/agent/agent-http-auth.js +22 -10
- package/dist/agent/agent-http.js +113 -64
- package/dist/agent/agent-hub-addon-update.js +16 -10
- package/dist/agent/agent-hub-registration.js +7 -4
- package/dist/agent/agent-infra-capabilities.js +9 -5
- package/dist/agent/agent-json-file.js +42 -5
- package/dist/agent/agent-mesh-gate.js +8 -5
- package/dist/agent/agent-node-certificates.js +28 -25
- package/dist/agent/agent-pairing-local.js +47 -10
- package/dist/agent/agent-pairing-routes.js +20 -16
- package/dist/agent/agent-pairing-store.js +58 -18
- package/dist/agent/agent-reconnect.js +4 -1
- package/dist/agent/agent-service.js +71 -35
- package/dist/agent/agent-sniffing-listener.js +48 -11
- package/dist/agent/agent-undeploy.js +41 -5
- package/dist/agent/agent-update-routes.js +19 -14
- package/dist/agent/agent-update-service.js +80 -38
- package/dist/agent/apply-model-distribution.js +4 -1
- package/dist/agent/apply-stage-dev-uploads.js +9 -6
- package/dist/agent/derive-hub-url.js +8 -3
- package/dist/agent/fetch-bundle-from-hub.js +9 -6
- package/dist/agent/hubs-found.js +43 -6
- package/dist/agent/infra-boot-guard.js +4 -1
- package/dist/agent/infra-boot-plan.js +6 -2
- package/dist/agent/main.js +183 -148
- package/dist/agent/register-agent-cap-dispatch.js +6 -3
- package/dist/agent/serial-queue.js +7 -2
- package/dist/agent-status-page.js +4 -1
- package/dist/api/addon-upload.js +61 -22
- package/dist/api/agent-addon-delivery.js +11 -6
- package/dist/api/auth-whoami.js +4 -1
- package/dist/api/backup-download-pump.js +9 -5
- package/dist/api/backup-download.js +10 -7
- package/dist/api/core/addon-settings.router.js +19 -16
- package/dist/api/core/agent-pairing.router.js +79 -76
- package/dist/api/core/agents.router.js +24 -21
- package/dist/api/core/auth-admin-tokens.procedures.js +52 -48
- package/dist/api/core/auth-device-cert.procedures.js +67 -62
- package/dist/api/core/auth-limits.js +25 -16
- package/dist/api/core/auth-reauth.procedures.js +37 -32
- package/dist/api/core/auth-revoke-credentials.procedures.js +26 -22
- package/dist/api/core/auth-sessions.procedures.js +56 -52
- package/dist/api/core/auth.router.js +304 -300
- package/dist/api/core/cap-providers.js +121 -74
- package/dist/api/core/capabilities.router.js +37 -34
- package/dist/api/core/capability-preference-writes.js +17 -10
- package/dist/api/core/certificates.router.js +109 -106
- package/dist/api/core/cluster-nodes.router.js +18 -15
- package/dist/api/core/collection-preference.js +6 -2
- package/dist/api/core/event-bus-proxy.router.js +37 -34
- package/dist/api/core/failure-contributions.js +8 -4
- package/dist/api/core/hwaccel.router.js +20 -17
- package/dist/api/core/integration-secrets.js +12 -8
- package/dist/api/core/lifecycle-job-runner.js +49 -13
- package/dist/api/core/live-events.router.js +32 -29
- package/dist/api/core/load-contributions.js +8 -4
- package/dist/api/core/logging-settings.js +43 -30
- package/dist/api/core/logs.router.js +43 -40
- package/dist/api/core/notifications.router.js +18 -15
- package/dist/api/core/public-event-filter.js +8 -4
- package/dist/api/core/repl.router.js +21 -18
- package/dist/api/core/request-census-settings.js +16 -11
- package/dist/api/core/server-management.provider.js +4 -1
- package/dist/api/core/server-name.js +17 -9
- package/dist/api/core/site-location.js +24 -16
- package/dist/api/core/stream-probe.router.js +24 -21
- package/dist/api/core/system-events.router.js +26 -23
- package/dist/api/cors/cors-policy.js +29 -20
- package/dist/api/cors/register-cors-policy.js +14 -9
- package/dist/api/deploy-stage-registry.js +10 -6
- package/dist/api/dev-uploads-bundle.js +50 -12
- package/dist/api/health/adaptive-probe.routes.js +13 -9
- package/dist/api/health/health.routes.js +13 -8
- package/dist/api/hub-cluster-url.js +9 -3
- package/dist/api/model-distributor.js +50 -12
- package/dist/api/oauth2/consent-page.js +13 -10
- package/dist/api/oauth2/oauth2-routes.js +25 -17
- package/dist/api/oauth2/private-host.js +4 -1
- package/dist/api/server-upload-propagate.js +51 -15
- package/dist/api/server-upload.js +50 -13
- package/dist/api/sse-no-compression.js +4 -1
- package/dist/api/static/frame-policy.js +9 -4
- package/dist/api/static/precompressed-asset.js +57 -15
- package/dist/api/static/spa-mount.js +47 -8
- package/dist/api/static/spa-static.js +12 -5
- package/dist/api/tarball-manifest.js +44 -7
- package/dist/api/trpc/cap-mount-helpers.js +12 -7
- package/dist/api/trpc/cap-route-error-formatter.js +13 -10
- package/dist/api/trpc/cap-router-runtime.js +51 -40
- package/dist/api/trpc/client-ip.js +20 -9
- package/dist/api/trpc/core-cap-bridge.js +42 -32
- package/dist/api/trpc/device-collection-dispatch.js +27 -23
- package/dist/api/trpc/device-config-secret-redaction.js +40 -24
- package/dist/api/trpc/generated-cap-mounts.js +225 -219
- package/dist/api/trpc/generated-cap-routers.js +5167 -4852
- package/dist/api/trpc/http-request-census-hook.js +11 -8
- package/dist/api/trpc/http-request-census.js +41 -34
- package/dist/api/trpc/http-request-census.singleton.js +8 -4
- package/dist/api/trpc/localized-schema-paths.js +4 -1
- package/dist/api/trpc/principal-visibility.js +22 -14
- package/dist/api/trpc/remote-addon-update-grant.js +4 -1
- package/dist/api/trpc/scope-access.js +15 -10
- package/dist/api/trpc/server-provided-caps.js +7 -3
- package/dist/api/trpc/share-view-access.js +14 -6
- package/dist/api/trpc/trpc-error-device-tags.js +6 -3
- package/dist/api/trpc/trpc-error-principal.js +6 -2
- package/dist/api/trpc/trpc.context.js +25 -20
- package/dist/api/trpc/trpc.middleware.js +46 -38
- package/dist/api/trpc/trpc.router.js +99 -58
- package/dist/api/trpc/user-error.js +8 -5
- package/dist/api/trpc/ws-request-census.js +24 -17
- package/dist/api/trpc/ws-slow-consumer-guard.js +16 -11
- package/dist/api/upload-auth.js +9 -5
- package/dist/auth/addon-route-jwt-gate.js +7 -4
- package/dist/auth/addon-route-share-gate.js +12 -7
- package/dist/auth/app-confirm-page.js +22 -17
- package/dist/auth/app-confirm-routes.js +31 -26
- package/dist/auth/app-confirmations.js +44 -7
- package/dist/auth/app-page-shell.js +30 -17
- package/dist/auth/app-page-strings.js +17 -11
- package/dist/auth/app-passkey-page.js +21 -16
- package/dist/auth/app-passkey-routes.js +41 -37
- package/dist/auth/app-refused-route.js +18 -13
- package/dist/auth/auth-network-policy.js +15 -11
- package/dist/auth/auth-provider-gate.js +9 -4
- package/dist/auth/auth-rate-limit.js +7 -3
- package/dist/auth/client-address.js +9 -6
- package/dist/auth/device-enroll-proofs.js +43 -6
- package/dist/auth/external-link-intents.js +7 -3
- package/dist/auth/hub-sessions.js +12 -6
- package/dist/auth/native-link-completions.js +11 -7
- package/dist/auth/native-return.js +13 -9
- package/dist/auth/passkey-provider.js +32 -26
- package/dist/auth/second-factors.js +10 -6
- package/dist/auth/session-connections.js +12 -6
- package/dist/auth/session-cookie.js +23 -12
- package/dist/auth/session-lifetimes.js +12 -8
- package/dist/auth/session-mint.js +11 -4
- package/dist/auth/sso-finish-app.js +16 -13
- package/dist/auth/sso-finish-deps.js +27 -21
- package/dist/auth/sso-finish.js +38 -28
- package/dist/auth/sso-routes.js +25 -22
- package/dist/auth/used-bridge-ids.js +5 -1
- package/dist/boot/boot-config.js +55 -16
- package/dist/boot/init-sequence.js +4 -1
- package/dist/boot/integration-id-backfill.js +8 -3
- package/dist/boot/platform-keychain-key.js +42 -5
- package/dist/boot/post-boot.service.js +18 -14
- package/dist/boot/reconcile-lifecycle-jobs.js +6 -3
- package/dist/boot/retired-public-url-env.js +8 -4
- package/dist/bootstrap-packages.js +4 -1
- package/dist/closure-node-modules.js +38 -2
- package/dist/core/addon/addon-call-gateway.js +5 -1
- package/dist/core/addon/addon-package.service.js +123 -83
- package/dist/core/addon/addon-process-view.js +6 -2
- package/dist/core/addon/addon-realign-plan.js +4 -1
- package/dist/core/addon/addon-registry.service.js +187 -146
- package/dist/core/addon/addon-row-manifest.js +4 -1
- package/dist/core/addon/addon-search.service.js +7 -3
- package/dist/core/addon/addon-settings-provider.js +3 -1
- package/dist/core/addon/addon-uninstall.js +11 -4
- package/dist/core/addon/addon.tokens.js +5 -2
- package/dist/core/addon/device-meta-mirror.js +13 -8
- package/dist/core/addon/forked-custom-actions.js +11 -6
- package/dist/core/addon/integration-visibility.js +6 -3
- package/dist/core/addon/materialize-route-path.js +4 -1
- package/dist/core/addon/package-dir-utils.js +45 -8
- package/dist/core/addon/prune-misplaced-addons.js +43 -5
- package/dist/core/addon/runner-convergence.js +4 -1
- package/dist/core/addon/runner-serialization.js +4 -1
- package/dist/core/addon/runner-spawn-fanout.js +8 -3
- package/dist/core/addon/settings-door-wiring.js +8 -5
- package/dist/core/addon/single-flight-refresh.js +4 -1
- package/dist/core/addon-bridge/addon-bridge.service.js +44 -7
- package/dist/core/addon-pages/addon-pages.service.js +40 -3
- package/dist/core/addon-widgets/addon-widgets.service.js +42 -4
- package/dist/core/agent/agent-addon-backfill.js +17 -9
- package/dist/core/agent/agent-delivery-ledger.js +7 -3
- package/dist/core/agent/agent-liveness-event.js +6 -2
- package/dist/core/agent/agent-pairing-http.js +45 -41
- package/dist/core/agent/agent-registry.service.js +89 -50
- package/dist/core/agent/cluster-node-history-mirror.js +7 -3
- package/dist/core/agent/cluster-node-history-store.js +35 -31
- package/dist/core/agent/hub-agent-pairing.js +5 -1
- package/dist/core/agent/node-certificates-client.js +6 -3
- package/dist/core/agent/node-directory.js +4 -1
- package/dist/core/app-links/well-known-app-links.js +6 -2
- package/dist/core/auth/auth.service.js +8 -3
- package/dist/core/auth/handoff-code.service.js +49 -11
- package/dist/core/auth/record-kinds.js +19 -16
- package/dist/core/auth/share-token.service.js +79 -42
- package/dist/core/capability/capability.service.js +5 -1
- package/dist/core/config/config.schema.js +6 -1
- package/dist/core/config/config.service.js +6 -2
- package/dist/core/events/event-bus.service.js +7 -3
- package/dist/core/feature/feature.service.js +6 -2
- package/dist/core/lifecycle/lifecycle-runner.singleton.js +10 -5
- package/dist/core/lifecycle/lifecycle-state-machine.js +5 -1
- package/dist/core/logging/log-ring-buffer.js +5 -1
- package/dist/core/logging/logging.service.js +9 -5
- package/dist/core/logging/scoped-logger.js +5 -1
- package/dist/core/moleculer/agent-readiness-pull.js +4 -1
- package/dist/core/moleculer/agent-registration-request.js +7 -3
- package/dist/core/moleculer/cap-call-fn.js +7 -4
- package/dist/core/moleculer/cap-route-authority.js +8 -3
- package/dist/core/moleculer/hub-mesh-guard.js +9 -5
- package/dist/core/moleculer/moleculer.service.js +86 -79
- package/dist/core/network/network-quality.service.js +6 -2
- package/dist/core/notification/notification-wrapper.service.js +7 -3
- package/dist/core/notification/toast-wrapper.service.js +7 -3
- package/dist/core/provider/provider.tokens.js +4 -1
- package/dist/core/repl/repl-engine.service.js +8 -4
- package/dist/core/runner-health/runner-boot-check.js +15 -7
- package/dist/core/runner-health/update-preflight.js +14 -9
- package/dist/core/server-update/server-update.service.js +49 -12
- package/dist/core/server-update/system-apply-closure-patches.js +42 -6
- package/dist/core/server-update/system-ensure-prebuilds.js +6 -3
- package/dist/core/server-update/system-exec-npm.js +5 -2
- package/dist/core/storage/fs-storage-backend.js +5 -1
- package/dist/core/storage/storage-location-manager.js +5 -1
- package/dist/core/storage/storage.service.js +6 -2
- package/dist/core/streaming/ffmpeg-stream-info.js +8 -3
- package/dist/core/streaming/stream-probe.service.js +16 -12
- package/dist/core/streaming/ttl-cache.js +5 -1
- package/dist/core/topology/topology-emitter.service.js +23 -19
- package/dist/core/update-availability-emitter.js +7 -3
- package/dist/core/update-availability-store.js +45 -8
- package/dist/core/updates/agent-installed-packages.js +9 -5
- package/dist/core/updates/restart-marker.js +8 -3
- package/dist/core/updates/update-check-scheduler.js +18 -13
- package/dist/core/updates/wrapper-update-checker.js +7 -3
- package/dist/first-boot-addon-plan.js +6 -2
- package/dist/framework-nodepath.js +38 -2
- package/dist/i18n/request-lang.js +11 -7
- package/dist/launcher.js +65 -30
- package/dist/lifecycle-journal-path.js +38 -2
- package/dist/main.js +324 -286
- package/dist/manual-boot.js +156 -117
- package/dist/node-role.js +4 -1
- package/dist/package-inventory.js +48 -7
- package/dist/pending-restore.js +43 -7
- package/dist/single-copy-cleanup-runner.js +45 -9
- package/dist/single-copy-cleanup.js +15 -7
- package/dist/sqlite-restore.js +48 -9
- package/dist/starter.js +39 -4
- package/dist/ui-serving/lazy-ui-serving.js +39 -3
- package/package.json +7 -7
|
@@ -1,3 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.isSafeDevUploadVersion = isSafeDevUploadVersion;
|
|
37
|
+
exports.packDevUploadVersionDir = packDevUploadVersionDir;
|
|
38
|
+
exports.unpackDevUploadVersionBundle = unpackDevUploadVersionBundle;
|
|
1
39
|
/**
|
|
2
40
|
* Pack / unpack a hub `server-root/dev-uploads/<version>/` directory for
|
|
3
41
|
* agent fan-out (`POST /api/server-upload/propagate` → `$agent.stageDevUploads`).
|
|
@@ -5,15 +43,15 @@
|
|
|
5
43
|
* One gzipped tar carries every tarball + `manifest.json`. Fail-closed on
|
|
6
44
|
* path traversal and on a layout that would not satisfy RootUpdateService.
|
|
7
45
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
46
|
+
const fs = __importStar(require("node:fs"));
|
|
47
|
+
const os = __importStar(require("node:os"));
|
|
48
|
+
const path = __importStar(require("node:path"));
|
|
49
|
+
const tar = __importStar(require("tar"));
|
|
50
|
+
const index_js_1 = require("../server-root/index.js");
|
|
13
51
|
/** Version chars safe as a single path segment (matches server-upload). */
|
|
14
52
|
const SAFE_VERSION_RE = /^[0-9A-Za-z][0-9A-Za-z.-]*$/;
|
|
15
|
-
|
|
16
|
-
return SAFE_VERSION_RE.test(version) && isDevChannelVersion(version);
|
|
53
|
+
function isSafeDevUploadVersion(version) {
|
|
54
|
+
return SAFE_VERSION_RE.test(version) && (0, index_js_1.isDevChannelVersion)(version);
|
|
17
55
|
}
|
|
18
56
|
function hasPathTraversal(name) {
|
|
19
57
|
return name.includes('/') || name.includes('\\') || name.includes('..');
|
|
@@ -22,8 +60,8 @@ function hasPathTraversal(name) {
|
|
|
22
60
|
* Pack every file in `versionDir` (basename entries only) into a gzipped tar.
|
|
23
61
|
* Refuses if the manifest is missing/invalid or lists a missing tarball.
|
|
24
62
|
*/
|
|
25
|
-
|
|
26
|
-
const manifest = readDevUploadManifest(versionDir);
|
|
63
|
+
async function packDevUploadVersionDir(versionDir) {
|
|
64
|
+
const manifest = (0, index_js_1.readDevUploadManifest)(versionDir);
|
|
27
65
|
if (manifest === null) {
|
|
28
66
|
throw new Error(`dev-uploads manifest missing or invalid in ${versionDir}`);
|
|
29
67
|
}
|
|
@@ -36,7 +74,7 @@ export async function packDevUploadVersionDir(versionDir) {
|
|
|
36
74
|
throw new Error(`dev-uploads tarball listed in manifest is missing: ${filename}`);
|
|
37
75
|
}
|
|
38
76
|
}
|
|
39
|
-
if (!fs.existsSync(path.join(versionDir, DEV_UPLOAD_MANIFEST_FILE))) {
|
|
77
|
+
if (!fs.existsSync(path.join(versionDir, index_js_1.DEV_UPLOAD_MANIFEST_FILE))) {
|
|
40
78
|
throw new Error(`dev-uploads manifest file missing in ${versionDir}`);
|
|
41
79
|
}
|
|
42
80
|
const entries = fs.readdirSync(versionDir).filter((name) => {
|
|
@@ -62,7 +100,7 @@ export async function packDevUploadVersionDir(versionDir) {
|
|
|
62
100
|
* atomically (stage sibling + rename). Validates version shape, entry names,
|
|
63
101
|
* and that the extracted layout matches the manifest.
|
|
64
102
|
*/
|
|
65
|
-
|
|
103
|
+
async function unpackDevUploadVersionBundle(args) {
|
|
66
104
|
const { serverRoot, version, bundle } = args;
|
|
67
105
|
if (!isSafeDevUploadVersion(version)) {
|
|
68
106
|
throw new Error(`Refused: version "${version}" is not a safe dev-channel version for staging`);
|
|
@@ -94,7 +132,7 @@ export async function unpackDevUploadVersionBundle(args) {
|
|
|
94
132
|
if (refusedEntry !== null) {
|
|
95
133
|
throw new Error(`Refused: archive entry is not a basename: ${refusedEntry}`);
|
|
96
134
|
}
|
|
97
|
-
const manifest = readDevUploadManifest(stagingDir);
|
|
135
|
+
const manifest = (0, index_js_1.readDevUploadManifest)(stagingDir);
|
|
98
136
|
if (manifest === null) {
|
|
99
137
|
throw new Error('extracted archive has no valid manifest.json');
|
|
100
138
|
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ADAPTIVE_PROBE_PER_IP_PER_MINUTE = exports.ADAPTIVE_PROBE_BYTES = void 0;
|
|
4
|
+
exports.registerAdaptiveProbeRoute = registerAdaptiveProbeRoute;
|
|
1
5
|
/**
|
|
2
6
|
* Burst blob for adaptive-tier downlink measurement (D635).
|
|
3
7
|
*
|
|
@@ -20,16 +24,16 @@
|
|
|
20
24
|
* check the stream data plane applies — and is rate-limited per client IP.
|
|
21
25
|
* Everything a refusal returns is a few bytes.
|
|
22
26
|
*/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
const node_crypto_1 = require("node:crypto");
|
|
28
|
+
const health_routes_js_1 = require("./health.routes.js");
|
|
29
|
+
const auth_rate_limit_js_1 = require("../../auth/auth-rate-limit.js");
|
|
30
|
+
exports.ADAPTIVE_PROBE_BYTES = 1024 * 1024;
|
|
27
31
|
/**
|
|
28
32
|
* Probes a client IP may draw per minute: 12. The client probes at most once
|
|
29
33
|
* per 30 s per app (single-flight + cache), so 12 leaves room for several
|
|
30
34
|
* apps/devices behind one NAT and caps an abuser at 12 MiB/min.
|
|
31
35
|
*/
|
|
32
|
-
|
|
36
|
+
exports.ADAPTIVE_PROBE_PER_IP_PER_MINUTE = 12;
|
|
33
37
|
/**
|
|
34
38
|
* Random, so it is INCOMPRESSIBLE. The previous body was one repeated byte and
|
|
35
39
|
* `@fastify/compress` (global in `main.ts`; its default types include
|
|
@@ -37,11 +41,11 @@ export const ADAPTIVE_PROBE_PER_IP_PER_MINUTE = 12;
|
|
|
37
41
|
* trip and called it bandwidth. `compress: false` below stops our own
|
|
38
42
|
* compressor; randomness also defeats one in a relay on the way.
|
|
39
43
|
*/
|
|
40
|
-
const BODY = randomBytes(ADAPTIVE_PROBE_BYTES);
|
|
41
|
-
|
|
44
|
+
const BODY = (0, node_crypto_1.randomBytes)(exports.ADAPTIVE_PROBE_BYTES);
|
|
45
|
+
function registerAdaptiveProbeRoute(fastify, deps) {
|
|
42
46
|
fastify.get('/adaptive-probe', { compress: false }, async (req, reply) => {
|
|
43
47
|
reply.header('cache-control', 'no-store');
|
|
44
|
-
const authorized = isAuthorizedHealthRequest({
|
|
48
|
+
const authorized = (0, health_routes_js_1.isAuthorizedHealthRequest)({
|
|
45
49
|
...(typeof req.headers.authorization === 'string'
|
|
46
50
|
? { authorization: req.headers.authorization }
|
|
47
51
|
: {}),
|
|
@@ -49,7 +53,7 @@ export function registerAdaptiveProbeRoute(fastify, deps) {
|
|
|
49
53
|
}, deps.verifyToken);
|
|
50
54
|
if (!authorized)
|
|
51
55
|
return reply.status(401).send({ ok: false, error: 'unauthorized' });
|
|
52
|
-
const key = clientKeyFromRequest(req, deps.network);
|
|
56
|
+
const key = (0, auth_rate_limit_js_1.clientKeyFromRequest)(req, deps.network);
|
|
53
57
|
if (key !== null) {
|
|
54
58
|
const verdict = deps.limiter.check(`adaptive-probe:${key}`);
|
|
55
59
|
if (!verdict.allowed) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Health endpoints — fast probe surface for monitoring (k8s, uptime,
|
|
3
4
|
* external watchdogs).
|
|
@@ -18,13 +19,17 @@
|
|
|
18
19
|
* monitors talking to the hub and monitors talking directly to an agent
|
|
19
20
|
* (`http://<agent>:4444/health`) see identical payloads.
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.buildHubHealth = buildHubHealth;
|
|
24
|
+
exports.isAuthorizedHealthRequest = isAuthorizedHealthRequest;
|
|
25
|
+
exports.registerHealthRoutes = registerHealthRoutes;
|
|
26
|
+
const runner_boot_check_js_1 = require("../../core/runner-health/runner-boot-check.js");
|
|
27
|
+
const session_cookie_js_1 = require("../../auth/session-cookie.js");
|
|
23
28
|
const AGENT_HEALTH_TIMEOUT_MS = 3_000;
|
|
24
29
|
function nowIso() {
|
|
25
30
|
return new Date().toISOString();
|
|
26
31
|
}
|
|
27
|
-
|
|
32
|
+
async function buildHubHealth(deps, proc = process) {
|
|
28
33
|
// Fan-out-free: in-memory registry snapshot only, never a per-node RPC (#26).
|
|
29
34
|
const nodes = deps.agentRegistry.listNodeLiveness();
|
|
30
35
|
const remote = nodes.filter((n) => !n.isHub);
|
|
@@ -35,7 +40,7 @@ export async function buildHubHealth(deps, proc = process) {
|
|
|
35
40
|
const runners = check === undefined
|
|
36
41
|
? undefined
|
|
37
42
|
: {
|
|
38
|
-
degraded: isRunnerBootCheckDegraded(check),
|
|
43
|
+
degraded: (0, runner_boot_check_js_1.isRunnerBootCheckDegraded)(check),
|
|
39
44
|
expected: check.expected,
|
|
40
45
|
running: check.running,
|
|
41
46
|
failed: check.failed.length,
|
|
@@ -85,16 +90,16 @@ async function fetchAgentHealth(deps, nodeId) {
|
|
|
85
90
|
* (agent ids, versions, pids) — public probes get only `{ok}`.
|
|
86
91
|
* Pure over (headers, verifier) so the spec exercises it directly.
|
|
87
92
|
*/
|
|
88
|
-
|
|
93
|
+
function isAuthorizedHealthRequest(headers, verifyToken) {
|
|
89
94
|
const bearer = headers.authorization?.startsWith('Bearer ')
|
|
90
95
|
? headers.authorization.slice('Bearer '.length)
|
|
91
96
|
: null;
|
|
92
|
-
const cookieToken = readSessionCookieFromHeader(headers.cookie);
|
|
97
|
+
const cookieToken = (0, session_cookie_js_1.readSessionCookieFromHeader)(headers.cookie);
|
|
93
98
|
for (const token of [bearer, cookieToken]) {
|
|
94
99
|
if (!token)
|
|
95
100
|
continue;
|
|
96
101
|
try {
|
|
97
|
-
if (isSessionGradeJwtPayload(verifyToken(token)))
|
|
102
|
+
if ((0, session_cookie_js_1.isSessionGradeJwtPayload)(verifyToken(token)))
|
|
98
103
|
return true;
|
|
99
104
|
}
|
|
100
105
|
catch {
|
|
@@ -103,7 +108,7 @@ export function isAuthorizedHealthRequest(headers, verifyToken) {
|
|
|
103
108
|
}
|
|
104
109
|
return false;
|
|
105
110
|
}
|
|
106
|
-
|
|
111
|
+
function registerHealthRoutes(fastify, deps) {
|
|
107
112
|
const authorized = (req) => isAuthorizedHealthRequest({
|
|
108
113
|
...(typeof req.headers.authorization === 'string'
|
|
109
114
|
? { authorization: req.headers.authorization }
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HubAddressUnavailableError = void 0;
|
|
4
|
+
exports.resolveHubBaseUrl = resolveHubBaseUrl;
|
|
5
|
+
exports.clusterBaseUrlResolver = clusterBaseUrlResolver;
|
|
1
6
|
/** Thrown when the hub cannot name an address `audience` can reach. */
|
|
2
|
-
|
|
7
|
+
class HubAddressUnavailableError extends Error {
|
|
3
8
|
audience;
|
|
4
9
|
reason;
|
|
5
10
|
constructor(audience, reason) {
|
|
@@ -12,12 +17,13 @@ export class HubAddressUnavailableError extends Error {
|
|
|
12
17
|
this.name = 'HubAddressUnavailableError';
|
|
13
18
|
}
|
|
14
19
|
}
|
|
20
|
+
exports.HubAddressUnavailableError = HubAddressUnavailableError;
|
|
15
21
|
/**
|
|
16
22
|
* Resolve the hub's base URL for `audience` from the live provider. Called per
|
|
17
23
|
* delivery — interfaces and the allowlist move, and a deploy is rare enough
|
|
18
24
|
* that a cache would only add a way to be stale.
|
|
19
25
|
*/
|
|
20
|
-
|
|
26
|
+
async function resolveHubBaseUrl(getSource, audience) {
|
|
21
27
|
const source = getSource();
|
|
22
28
|
if (source === null)
|
|
23
29
|
throw new HubAddressUnavailableError(audience, 'local-network-unavailable');
|
|
@@ -26,6 +32,6 @@ export async function resolveHubBaseUrl(getSource, audience) {
|
|
|
26
32
|
throw new HubAddressUnavailableError(audience, 'no-reachable-endpoint');
|
|
27
33
|
return baseUrl;
|
|
28
34
|
}
|
|
29
|
-
|
|
35
|
+
function clusterBaseUrlResolver(getSource) {
|
|
30
36
|
return () => resolveHubBaseUrl(getSource, 'internal');
|
|
31
37
|
}
|
|
@@ -1,8 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.tarModelFiles = tarModelFiles;
|
|
37
|
+
exports.distributeModelWith = distributeModelWith;
|
|
38
|
+
exports.buildModelDistributorProvider = buildModelDistributorProvider;
|
|
39
|
+
const node_child_process_1 = require("node:child_process");
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const path = __importStar(require("node:path"));
|
|
42
|
+
const system_1 = require("@camstack/system");
|
|
43
|
+
const addon_upload_js_1 = require("./addon-upload.js");
|
|
6
44
|
const AGENT_DISTRIBUTE_TIMEOUT_MS = 60_000;
|
|
7
45
|
function hubModelsDir() {
|
|
8
46
|
return path.join(process.env['CAMSTACK_DATA'] ?? 'camstack-data', 'models');
|
|
@@ -12,9 +50,9 @@ function hubModelsDir() {
|
|
|
12
50
|
* Async (spawn, not execFileSync) so a large model doesn't block the event
|
|
13
51
|
* loop. The agent untars this exact buffer into its own modelsDir.
|
|
14
52
|
*/
|
|
15
|
-
|
|
53
|
+
function tarModelFiles(cwd, files) {
|
|
16
54
|
return new Promise((resolve, reject) => {
|
|
17
|
-
const child = spawn('tar', ['-czf', '-', '-C', cwd, ...files]);
|
|
55
|
+
const child = (0, node_child_process_1.spawn)('tar', ['-czf', '-', '-C', cwd, ...files]);
|
|
18
56
|
const chunks = [];
|
|
19
57
|
const errChunks = [];
|
|
20
58
|
child.stdout.on('data', (c) => chunks.push(c));
|
|
@@ -33,7 +71,7 @@ export function tarModelFiles(cwd, files) {
|
|
|
33
71
|
* precondition-check → collect → tar → stage → trigger the agent pull.
|
|
34
72
|
* `nodeId === 'hub'` is a no-op (the artifact is already resident).
|
|
35
73
|
*/
|
|
36
|
-
|
|
74
|
+
async function distributeModelWith(seam, input) {
|
|
37
75
|
const { targetNodeId, modelId, format, entry } = input;
|
|
38
76
|
if (targetNodeId === 'hub') {
|
|
39
77
|
return { ok: true, sha256: '', bytes: 0, path: seam.modelsDir };
|
|
@@ -41,7 +79,7 @@ export async function distributeModelWith(seam, input) {
|
|
|
41
79
|
if (!seam.isPresent(entry, format)) {
|
|
42
80
|
throw new Error(`model ${modelId}/${format} not present on hub — download or convert it first`);
|
|
43
81
|
}
|
|
44
|
-
const files = collectModelFiles(entry, format).filter((f) => seam.fileExists(f));
|
|
82
|
+
const files = (0, system_1.collectModelFiles)(entry, format).filter((f) => seam.fileExists(f));
|
|
45
83
|
if (files.length === 0) {
|
|
46
84
|
throw new Error(`model ${modelId}/${format} resolved no files to distribute`);
|
|
47
85
|
}
|
|
@@ -56,17 +94,17 @@ export async function distributeModelWith(seam, input) {
|
|
|
56
94
|
* Moleculer broker + the deploy-stage registry, which a forked addon can't
|
|
57
95
|
* reach.
|
|
58
96
|
*/
|
|
59
|
-
|
|
97
|
+
function buildModelDistributorProvider(moleculer, loggingService,
|
|
60
98
|
/** The `local-network` cap's cluster address (`hub-cluster-url.ts`). */
|
|
61
99
|
resolveClusterBaseUrl) {
|
|
62
100
|
const logger = loggingService.createLogger('model-distributor');
|
|
63
101
|
const modelsDir = hubModelsDir();
|
|
64
102
|
const seam = {
|
|
65
103
|
modelsDir,
|
|
66
|
-
isPresent: (entry, format) => isModelDownloaded(modelsDir, entry, format),
|
|
104
|
+
isPresent: (entry, format) => (0, system_1.isModelDownloaded)(modelsDir, entry, format),
|
|
67
105
|
fileExists: (rel) => fs.existsSync(path.join(modelsDir, rel)),
|
|
68
106
|
tar: (files) => tarModelFiles(modelsDir, files),
|
|
69
|
-
stage: async (buffer) => buildHubHttpSource(buffer, await resolveClusterBaseUrl()),
|
|
107
|
+
stage: async (buffer) => (0, addon_upload_js_1.buildHubHttpSource)(buffer, await resolveClusterBaseUrl()),
|
|
70
108
|
callAgent: async (nodeId, payload) => {
|
|
71
109
|
const broker = moleculer?.broker;
|
|
72
110
|
if (!broker)
|
|
@@ -1,25 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderConsentPage = renderConsentPage;
|
|
4
|
+
const app_page_shell_js_1 = require("../../auth/app-page-shell.js");
|
|
5
|
+
const app_page_strings_js_1 = require("../../auth/app-page-strings.js");
|
|
3
6
|
/** Allow/Deny consent screen on the hub's shared page shell (the look of the
|
|
4
7
|
* app sign-in pages). Submitting POSTs to the same path with the hidden query
|
|
5
8
|
* fields + `consent=allow|deny`. */
|
|
6
|
-
|
|
9
|
+
function renderConsentPage(input) {
|
|
7
10
|
const hidden = Object.entries(input.hidden)
|
|
8
|
-
.map(([name, value]) => appHiddenField(name, value))
|
|
11
|
+
.map(([name, value]) => (0, app_page_shell_js_1.appHiddenField)(name, value))
|
|
9
12
|
.join('');
|
|
10
|
-
const t = appStrings(input.lang).consent;
|
|
13
|
+
const t = (0, app_page_strings_js_1.appStrings)(input.lang).consent;
|
|
11
14
|
const destination = input.redirectUri
|
|
12
|
-
? `<p class="hint">${escapeHtml(t.sendingTo)}<code>${escapeHtml(input.redirectUri)}</code></p>`
|
|
15
|
+
? `<p class="hint">${(0, app_page_shell_js_1.escapeHtml)(t.sendingTo)}<code>${(0, app_page_shell_js_1.escapeHtml)(input.redirectUri)}</code></p>`
|
|
13
16
|
: '';
|
|
14
|
-
return renderAppPage({
|
|
17
|
+
return (0, app_page_shell_js_1.renderAppPage)({
|
|
15
18
|
lang: input.lang,
|
|
16
19
|
title: `${t.titlePrefix}${input.displayName}`,
|
|
17
20
|
heading: `${t.headingPrefix}${input.displayName}`,
|
|
18
21
|
body: [
|
|
19
|
-
`<p>${escapeHtml(t.signedInAs)}<strong>${escapeHtml(input.username)}</strong></p>`,
|
|
20
|
-
appHint(`${t.grantPrefix}${input.scopeSummary}`),
|
|
22
|
+
`<p>${(0, app_page_shell_js_1.escapeHtml)(t.signedInAs)}<strong>${(0, app_page_shell_js_1.escapeHtml)(input.username)}</strong></p>`,
|
|
23
|
+
(0, app_page_shell_js_1.appHint)(`${t.grantPrefix}${input.scopeSummary}`),
|
|
21
24
|
destination,
|
|
22
|
-
`<form method="POST">${hidden}<div class="actions">${appSubmitButton(t.allow, 'consent', 'allow')}${appSubmitButton(t.deny, 'consent', 'deny', true)}</div></form>`,
|
|
25
|
+
`<form method="POST">${hidden}<div class="actions">${(0, app_page_shell_js_1.appSubmitButton)(t.allow, 'consent', 'allow')}${(0, app_page_shell_js_1.appSubmitButton)(t.deny, 'consent', 'deny', true)}</div></form>`,
|
|
23
26
|
].join(''),
|
|
24
27
|
});
|
|
25
28
|
}
|
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.redactAuthorizeQuery = redactAuthorizeQuery;
|
|
4
|
+
exports.describeAuthorizeCall = describeAuthorizeCall;
|
|
5
|
+
exports.validateAuthorizeQuery = validateAuthorizeQuery;
|
|
6
|
+
exports.isRedirectUriAllowed = isRedirectUriAllowed;
|
|
7
|
+
exports.summariseScopes = summariseScopes;
|
|
8
|
+
exports.registerOauth2Routes = registerOauth2Routes;
|
|
9
|
+
const session_cookie_js_1 = require("../../auth/session-cookie.js");
|
|
10
|
+
const app_page_strings_js_1 = require("../../auth/app-page-strings.js");
|
|
11
|
+
const consent_page_js_1 = require("./consent-page.js");
|
|
12
|
+
const private_host_js_1 = require("./private-host.js");
|
|
5
13
|
/**
|
|
6
14
|
* Query keys whose VALUE may be logged.
|
|
7
15
|
*
|
|
@@ -26,7 +34,7 @@ function truncate(value, max) {
|
|
|
26
34
|
return value.length > max ? `${value.slice(0, max)}…` : value;
|
|
27
35
|
}
|
|
28
36
|
/** Rebuild a query string with every non-allow-listed value replaced. */
|
|
29
|
-
|
|
37
|
+
function redactAuthorizeQuery(rawQuery) {
|
|
30
38
|
if (rawQuery === '')
|
|
31
39
|
return '';
|
|
32
40
|
const parts = [];
|
|
@@ -49,7 +57,7 @@ function describeReferer(raw) {
|
|
|
49
57
|
}
|
|
50
58
|
}
|
|
51
59
|
/** Everything the log is allowed to know about an inbound authorize call. */
|
|
52
|
-
|
|
60
|
+
function describeAuthorizeCall(url, headers, hasSessionCookie) {
|
|
53
61
|
const q = url.indexOf('?');
|
|
54
62
|
const ua = headers['user-agent'];
|
|
55
63
|
return {
|
|
@@ -110,7 +118,7 @@ function resolveIntegrationParam(raw) {
|
|
|
110
118
|
* NOT checked — that pair is verified only at the Lambda boundary, and a
|
|
111
119
|
* PUBLIC client (`requiresPkce`) has no secret to check it against at all;
|
|
112
120
|
* the S256 challenge is what binds the code to its requester instead. */
|
|
113
|
-
|
|
121
|
+
function validateAuthorizeQuery(q, knownIntegrations, pendingAddons = []) {
|
|
114
122
|
if (q.response_type !== 'code')
|
|
115
123
|
return { ok: false, status: 400, error: 'unsupported_response_type' };
|
|
116
124
|
// Four distinct faults used to collapse into one opaque string.
|
|
@@ -190,7 +198,7 @@ export function validateAuthorizeQuery(q, knownIntegrations, pendingAddons = [])
|
|
|
190
198
|
* `startsWith` on a string the browser will parse differently is exactly how an
|
|
191
199
|
* allow-list gets walked around.
|
|
192
200
|
*/
|
|
193
|
-
|
|
201
|
+
function isRedirectUriAllowed(redirectUri, allowedPrefixes, allowedPrivateHostPaths = []) {
|
|
194
202
|
if (allowedPrefixes.some((p) => redirectUri.startsWith(p)))
|
|
195
203
|
return true;
|
|
196
204
|
if (allowedPrivateHostPaths.length === 0)
|
|
@@ -204,12 +212,12 @@ export function isRedirectUriAllowed(redirectUri, allowedPrefixes, allowedPrivat
|
|
|
204
212
|
}
|
|
205
213
|
if (url.protocol !== 'http:' && url.protocol !== 'https:')
|
|
206
214
|
return false;
|
|
207
|
-
if (!isPrivateHost(url.hostname))
|
|
215
|
+
if (!(0, private_host_js_1.isPrivateHost)(url.hostname))
|
|
208
216
|
return false;
|
|
209
217
|
return allowedPrivateHostPaths.includes(url.pathname);
|
|
210
218
|
}
|
|
211
219
|
/** One-line human summary of a scope list for the consent screen. */
|
|
212
|
-
|
|
220
|
+
function summariseScopes(scopes) {
|
|
213
221
|
if (scopes.some((s) => s.type === 'category' && s.target === 'device')) {
|
|
214
222
|
return 'view and control all your cameras and devices';
|
|
215
223
|
}
|
|
@@ -249,10 +257,10 @@ function refuseAuthorize(reply, logger, method, call, refusal) {
|
|
|
249
257
|
* it" is invisible and every refusal reads as a first arrival.
|
|
250
258
|
*/
|
|
251
259
|
function refuseUnauthenticated(request, reply, logger, call, reason) {
|
|
252
|
-
const redirected = shouldRedirectToLogin(request.method, request.headers.accept);
|
|
260
|
+
const redirected = (0, session_cookie_js_1.shouldRedirectToLogin)(request.method, request.headers.accept);
|
|
253
261
|
logger.info(redirected ? 'oauth2 authorize bounced to login' : 'oauth2 authorize refused: unauthenticated', { meta: { method: request.method, reason, redirected, ...call } });
|
|
254
262
|
if (redirected)
|
|
255
|
-
return reply.redirect(loginRedirectUrl(request.url));
|
|
263
|
+
return reply.redirect((0, session_cookie_js_1.loginRedirectUrl)(request.url));
|
|
256
264
|
return reply.status(401).send({ error: 'unauthorized' });
|
|
257
265
|
}
|
|
258
266
|
/** Read integrationId → descriptor from every registered `oauth-integration`
|
|
@@ -278,7 +286,7 @@ function parseFormBody(raw) {
|
|
|
278
286
|
}
|
|
279
287
|
return result;
|
|
280
288
|
}
|
|
281
|
-
|
|
289
|
+
function registerOauth2Routes(fastify, deps) {
|
|
282
290
|
// Register a content-type parser for application/x-www-form-urlencoded so that
|
|
283
291
|
// consent POST and token POST can read form bodies. @fastify/formbody is not in
|
|
284
292
|
// the project's dependencies; we use URLSearchParams (Node built-in) instead.
|
|
@@ -295,7 +303,7 @@ export function registerOauth2Routes(fastify, deps) {
|
|
|
295
303
|
// the PWA service-worker navigate fallback, and the Vite dev proxy — no
|
|
296
304
|
// per-path special-casing anywhere.
|
|
297
305
|
fastify.get('/api/oauth2/authorize', async (request, reply) => {
|
|
298
|
-
const cookie = request.cookies[SESSION_COOKIE];
|
|
306
|
+
const cookie = request.cookies[session_cookie_js_1.SESSION_COOKIE];
|
|
299
307
|
const call = describeAuthorizeCall(request.url, request.headers, Boolean(cookie));
|
|
300
308
|
if (!cookie) {
|
|
301
309
|
return refuseUnauthenticated(request, reply, deps.logger, call, 'no-session-cookie');
|
|
@@ -333,8 +341,8 @@ export function registerOauth2Routes(fastify, deps) {
|
|
|
333
341
|
.status(400)
|
|
334
342
|
.send({ error: 'invalid_request — redirect_uri not allowed for this integration' });
|
|
335
343
|
}
|
|
336
|
-
const html = renderConsentPage({
|
|
337
|
-
lang: resolveAppPageLang({
|
|
344
|
+
const html = (0, consent_page_js_1.renderConsentPage)({
|
|
345
|
+
lang: (0, app_page_strings_js_1.resolveAppPageLang)({
|
|
338
346
|
lang: request.query['lang'],
|
|
339
347
|
acceptLanguage: request.headers['accept-language'],
|
|
340
348
|
}),
|
|
@@ -393,7 +401,7 @@ export function registerOauth2Routes(fastify, deps) {
|
|
|
393
401
|
});
|
|
394
402
|
// ─── POST /api/oauth2/authorize ───────────────────────────────────────────
|
|
395
403
|
fastify.post('/api/oauth2/authorize', async (request, reply) => {
|
|
396
|
-
const cookie = request.cookies[SESSION_COOKIE];
|
|
404
|
+
const cookie = request.cookies[session_cookie_js_1.SESSION_COOKIE];
|
|
397
405
|
// `query` is empty here by nature, not by loss: the consent POST carries its
|
|
398
406
|
// parameters as form fields. `method: POST` in the same line says so.
|
|
399
407
|
const call = describeAuthorizeCall(request.url, request.headers, Boolean(cookie));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Is this hostname unreachable from the public internet?
|
|
3
4
|
*
|
|
@@ -14,6 +15,8 @@
|
|
|
14
15
|
* not the one the browser will use). Names are admitted only by suffix, from a
|
|
15
16
|
* closed list of suffixes that cannot be registered on the public internet.
|
|
16
17
|
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.isPrivateHost = isPrivateHost;
|
|
17
20
|
/** Suffixes that are, by definition, not publicly routable names. */
|
|
18
21
|
const PRIVATE_NAME_SUFFIXES = ['.local', '.internal', '.home.arpa', '.ts.net'];
|
|
19
22
|
/** Names that are exactly the loopback host. */
|
|
@@ -64,7 +67,7 @@ function isPrivateIpv6(host) {
|
|
|
64
67
|
* True iff `host` (a `URL.hostname`, already lowercased by the URL parser) is
|
|
65
68
|
* private by literal inspection. Never resolves.
|
|
66
69
|
*/
|
|
67
|
-
|
|
70
|
+
function isPrivateHost(host) {
|
|
68
71
|
if (host === '')
|
|
69
72
|
return false;
|
|
70
73
|
if (LOOPBACK_NAMES.includes(host))
|