@xopcai/xopc 0.0.373 → 0.0.374
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/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear--kDkSTqC.js → agent-avatar-dicebear-BrA20N2m.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-z4_2-Kn2.js → agent-defaults-settings-panel-BZrOdxou.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-plugin-dialog-BYndK83K.js → agent-plugin-dialog-B3ux1AhY.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-CVo96cx1.js → agents-CXlXFU6M.js} +3 -3
- package/dist/gateway/static/root/assets/{app-management-settings-panel-D9oOJKiH.js → app-management-settings-panel-BXahEVPm.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-B0-8Cdyv.js → appearance-settings-CE2qJMkD.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-DasVc6i4.js → apps-page-DGVOnCxZ.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-BlCNqy2i.js → automations-page-BWL7eT4_.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-workspace-C8ipDP05.js → automations-workspace-BxIShhkZ.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-Cktlez6g.js → block-editor-3n446-mX.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-KRfDl8ej.js → browser-automations-page-BmTK7Gtn.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-BraQ4wnh.js → browser-settings-page-DBQ-WETQ.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-page-B3m8xGzd.js → capabilities-page-D-nQ6Zzi.js} +2 -2
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-VQ4fHuBV.js → capabilities-settings-panel-Dx1fpBmH.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-header-actions-f5Ido4Eg.js → capability-header-actions-BRMqvQVb.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-N4Vc2nEG.js → channels-DXfEP1FR.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-BwvTKwsn.js → chat-terminal-dock-BRdzCjWO.js} +1 -1
- package/dist/gateway/static/root/assets/{computer-settings-page-CAwUsKpw.js → computer-settings-page-BhCHMRpD.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-C0HuAMuH.js → connector-service-page-BXE8Z-Ll.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-BcBmW8JT.js → connectors-page-D9RZjhw8.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-DiQxRpe-.js → date-picker-BJ7N92wm.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-Ds0_BJbN.js → dependency-picker-gyxCM-hb.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-ZMEOYwrR.js → desktop-pet-B-WM4l-L.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DkyTqD07.js → desktop-pet-settings-usJqcew5.js} +1 -1
- package/dist/gateway/static/root/assets/{device-pairing-wizard-CvaI5ZJZ.js → device-pairing-wizard-DoSR4DGk.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-Bfv93eK1.js → directory-picker-path-field-DqVlV2YH.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-JXKGtIdM.js → extension-page-CUule9SU.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-lsQ2xvbr.js → extension-settings-page-_OFukkEJ.js} +1 -1
- package/dist/gateway/static/root/assets/{fallback-models-7bG0AND1.js → fallback-models-CiSc3h8i.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-BpbcoPx9.js → gateway-settings-qSUrpS1h.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-BxctC0aJ.js → home-page-COjDsuzg.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-Bq8CazCb.js → imports-page-DdvIj-ZL.js} +1 -1
- package/dist/gateway/static/root/assets/{index-B40-KDN8.js → index-DEaVabvo.js} +6 -6
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-kkAevkl2.js → keyboard-shortcuts-settings-DbqFlNsF.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-abLaf1hW.js → local-app-workbench-page-REowUzkp.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-nwsnwYjK.js → local-apps-page-DdCMNn_z.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-BEgYS-Xg.js → logs-page-B_6fHDoi.js} +1 -1
- package/dist/gateway/static/root/assets/management-settings-D4vcSRE3.js +1 -0
- package/dist/gateway/static/root/assets/{note-detail-panel-CCnfurBR.js → note-detail-panel-B7U6EbAi.js} +3 -3
- package/dist/gateway/static/root/assets/{notes-page-D9u_znxM.js → notes-page-BzHVaH8j.js} +1 -1
- package/dist/gateway/static/root/assets/{page-context-capture-button-BO3FoRej.js → page-context-capture-button-D7Y4vFRN.js} +1 -1
- package/dist/gateway/static/root/assets/personal-page-E6huhFk4.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-Dso2_hyl.js → product-open-page-CK_czbBx.js} +1 -1
- package/dist/gateway/static/root/assets/{product-preview-content-CkvVb3EA.js → product-preview-content-CU6KlaVP.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-UjrrzE3H.js → project-detail-page-c3ye2bdq.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-C1h63P2M.js → projects-page-BA1UuuRF.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-BJifH8AB.js → remote-access-hub-D_FLVZAm.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-vG1wqcEb.js → runtime-tools-settings-panel-Cxjmwdyf.js} +1 -1
- package/dist/gateway/static/root/assets/{scenes-page-CwoAoYMX.js → scenes-page-Av47PHdM.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-BIsHdyz7.js → schema-form-IM7QeSm3.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-BcCLp3yU.js → sessions-page-Bol3ScEc.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DpCanqrD.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-z9Jlk0BL.js → settings-page-BeVtwwVd.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-CrpXECqe.js → setup-status-panel-zTmrMwMm.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-D9XpTJXP.js → shares-settings-Bkhkt_6M.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-api-DtPOf1aW.js → skill-api-Dgwc707w.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-Bq9-2b9U.js → skills-page-CFIte-vM.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-P7T729uD.js → system-settings-panel-Ck6zGDHb.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-CsB9AFx6.js → task-detail-page-C3ZPEZqw.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-CuowqIZ7.js → tunnel-api-CjxMpAm2.js} +1 -1
- package/dist/gateway/static/root/assets/{usage-page-avX3msoZ.js → usage-page-Dnhp9xQ4.js} +1 -1
- package/dist/gateway/static/root/assets/{user-model-page-DGDBWw7P.js → user-model-page-sx1lNWKf.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BgJNz2tH.js → work-discovery-overlay-CVd_y3K2.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-1I2q2J_U.js → workflow-run-setup-panel-Dwg40uGK.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-DhJl9pnO.js → workflows-page-BQR4JdXB.js} +1 -1
- package/dist/gateway/static/root/assets/{xopc-cloud-account-card-CnPBP1V_.js → xopc-cloud-account-card-CaKc_J7j.js} +1 -1
- package/dist/gateway/static/root/index.html +1 -1
- package/dist/package.js +1 -1
- package/dist/packages/realtime-protocol/src/voice.js +11 -0
- package/dist/src/agent/agent-manager.js +4 -4
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/embedded/model-runtime.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +2 -2
- package/dist/src/agent/embedded/run-turn.js +2 -2
- package/dist/src/agent/image/tool-model-config.js +1 -1
- package/dist/src/agent/service.js +3 -3
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/tasks/task-judge-service.js +3 -3
- package/dist/src/agent-config/schema.d.ts +9 -0
- package/dist/src/agent-config/schema.js +1 -0
- package/dist/src/ai-assist/text-assist.js +1 -1
- package/dist/src/auth/credentials.js +2 -2
- package/dist/src/auth/model-credential-store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/chat-commands/builtins/config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/image-providers.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/gateway/shared.js +2 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/cli/commands/onboard/model.js +3 -3
- package/dist/src/computer/runtime.js +1 -1
- package/dist/src/config/gateway-bind.js +2 -1
- package/dist/src/config/index.js +5 -5
- package/dist/src/config/loader.js +1 -1
- package/dist/src/config/models-json.d.ts +8 -8
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/config/schema.d.ts +13 -12
- package/dist/src/config/schema.js +7 -3
- package/dist/src/daemon/constants.js +14 -9
- package/dist/src/daemon/index.js +4 -1
- package/dist/src/daemon/install-plan.js +2 -1
- package/dist/src/daemon/launchd.js +2 -1
- package/dist/src/daemon/schtasks.js +2 -1
- package/dist/src/daemon/service-audit.js +2 -1
- package/dist/src/daemon/service.js +2 -1
- package/dist/src/daemon/systemd.js +2 -1
- package/dist/src/extensions/activation-context.js +1 -1
- package/dist/src/gateway/client-ip.js +2 -1
- package/dist/src/gateway/hono/app.js +2 -1
- package/dist/src/gateway/hono/lib/config-payload.js +2 -2
- package/dist/src/gateway/hono/middleware/auth.d.ts +3 -5
- package/dist/src/gateway/hono/middleware/auth.js +56 -14
- package/dist/src/gateway/hono/middleware/logger.js +2 -1
- package/dist/src/gateway/hono/middleware/public-device-rate-limit.d.ts +16 -0
- package/dist/src/gateway/hono/middleware/public-device-rate-limit.js +43 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +3 -2
- package/dist/src/gateway/hono/oauth-async.js +2 -1
- package/dist/src/gateway/hono/routes/browser.js +2 -1
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/config.js +2 -1
- package/dist/src/gateway/hono/routes/device-pairing-approval.d.ts +3 -8
- package/dist/src/gateway/hono/routes/device-pairing-approval.js +5 -20
- package/dist/src/gateway/hono/routes/devices.js +25 -9
- package/dist/src/gateway/hono/routes/endpoint-tools.js +1 -0
- package/dist/src/gateway/hono/routes/models.js +3 -3
- package/dist/src/gateway/hono/routes/observability.js +1 -1
- package/dist/src/gateway/hono/routes/personal-agent.js +3 -2
- package/dist/src/gateway/hono/routes/public-gateway.js +6 -6
- package/dist/src/gateway/hono/routes/shares.js +2 -1
- package/dist/src/gateway/hono/routes/voice.js +2 -1
- package/dist/src/gateway/host.js +9 -4
- package/dist/src/gateway/index.js +8 -4
- package/dist/src/gateway/listen.js +2 -1
- package/dist/src/gateway/rate-limit/auth-policy.js +7 -11
- package/dist/src/gateway/rate-limit/buckets.d.ts +6 -0
- package/dist/src/gateway/rate-limit/buckets.js +211 -189
- package/dist/src/gateway/rate-limit/env-flags.js +4 -1
- package/dist/src/gateway/rate-limit/index.js +13 -4
- package/dist/src/gateway/runtime-config.js +5 -3
- package/dist/src/gateway/security/audit.js +3 -2
- package/dist/src/gateway/security/browser-session.js +2 -1
- package/dist/src/gateway/security/device-request-proof.d.ts +28 -0
- package/dist/src/gateway/security/device-request-proof.js +122 -0
- package/dist/src/gateway/security/loopback.js +7 -6
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service/session-command-service.js +1 -1
- package/dist/src/gateway/service.js +12 -10
- package/dist/src/gateway/tailscale-auth.js +2 -1
- package/dist/src/gateway/ws-security.js +2 -1
- package/dist/src/home-intelligence/generator.js +1 -1
- package/dist/src/infra/rate-limit/failure-limiter.js +78 -90
- package/dist/src/infra/rate-limit/index.js +11 -3
- package/dist/src/infra/rate-limit/keyed-store.js +52 -47
- package/dist/src/infra/rate-limit/rate-limiter.js +55 -58
- package/dist/src/infra/update-service-refresh.js +2 -1
- package/dist/src/notes/service.js +1 -1
- package/dist/src/observability/runtime.js +1 -1
- package/dist/src/personal-agent/proactivity/service.js +2 -2
- package/dist/src/personal-agent/reply-composer.js +2 -2
- package/dist/src/personal-agent/repository.d.ts +3 -0
- package/dist/src/personal-agent/repository.js +1 -0
- package/dist/src/personal-agent/service.d.ts +6 -2
- package/dist/src/personal-agent/service.js +4 -3
- package/dist/src/platform/client.d.ts +1 -1
- package/dist/src/platform/contracts.d.ts +1 -1
- package/dist/src/platform/index.js +1 -1
- package/dist/src/providers/index.js +4 -4
- package/dist/src/providers/model-registry.js +2 -2
- package/dist/src/providers/provider-auth-service.js +1 -1
- package/dist/src/providers/provider-disconnect-core.js +1 -1
- package/dist/src/providers/register-runtime-providers.js +1 -1
- package/dist/src/providers/xopc-cloud-catalog-coordinator.js +1 -1
- package/dist/src/realtime/runtime.js +6 -0
- package/dist/src/realtime/tickets.d.ts +1 -0
- package/dist/src/realtime/tickets.js +4 -0
- package/dist/src/remote-access/exposure-guards.js +2 -1
- package/dist/src/share/share-rate-limit.js +2 -1
- package/dist/src/share/share-url.js +2 -1
- package/dist/src/share/site-share-router.js +2 -1
- package/dist/src/storage/sqlite/device-access-repository.d.ts +7 -0
- package/dist/src/storage/sqlite/device-access-repository.js +22 -4
- package/dist/src/storage/sqlite/migrations/243_voice_opening_greetings.sql +12 -0
- package/dist/src/storage/sqlite/migrations/244_device_request_proofs.sql +8 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/tasks/task-main-update-decision-service.js +2 -2
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/dist/src/tui/tui.js +1 -1
- package/dist/src/tunnel/broker-client.js +2 -0
- package/dist/src/tunnel/tunnel-config.js +2 -2
- package/dist/src/tunnel/tunnel-rate-limit.js +2 -1
- package/dist/src/utils/logger/redact.js +4 -1
- package/dist/src/voice/platform-streams.d.ts +6 -0
- package/dist/src/voice/platform-streams.js +43 -4
- package/dist/src/voice/realtime/agentEngine.js +138 -83
- package/dist/src/voice/realtime/engine.d.ts +6 -0
- package/dist/src/voice/realtime/opening-greeting.d.ts +12 -0
- package/dist/src/voice/realtime/opening-greeting.js +22 -0
- package/dist/src/voice/realtime/runtime.js +90 -1
- package/dist/src/voice/realtime/runtime.types.d.ts +4 -0
- package/dist/src/work-discovery/service.js +2 -2
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/package.json +3 -3
- package/dist/gateway/static/root/assets/management-settings-D_JQ6_X0.js +0 -1
- package/dist/gateway/static/root/assets/personal-page-BJn6UHAF.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-D114UdRI.js +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getClientIpFromHeaders, init_loopback } from "../../security/loopback.js";
|
|
1
2
|
import { loadCompactionSourceSnapshot } from "../../../storage/sqlite/transcript-repository.js";
|
|
2
3
|
import { init_sqlite } from "../../../storage/sqlite/index.js";
|
|
3
4
|
import { FileServiceError } from "../../../files/file-service.js";
|
|
@@ -16,7 +17,6 @@ import { resolveReverseProxyPublicUrl } from "../../public-url.js";
|
|
|
16
17
|
import { audienceDefaults, cleanupStagedSite, decideShareKind, forgetStagedSite, makeDescription, makeTitle, probeShareTarget, rememberStagedSite, stageSingleHtmlAsSite } from "../../../share/share-auto.js";
|
|
17
18
|
import { deleteThumbnail, placeholderSvg, readThumbnail, scheduleThumbnail, thumbnailContentType, thumbnailExists } from "../../../share/share-thumbnail.js";
|
|
18
19
|
import { getGatewayFileSpaceService } from "../../file-space-service.js";
|
|
19
|
-
import { getClientIpFromHeaders } from "../../security/loopback.js";
|
|
20
20
|
import { SHARED_HTML_CSP } from "../../security/csp.js";
|
|
21
21
|
import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
22
22
|
import { renderFolderLandingPage, renderShareExpiredPage, renderShareLandingPage, renderSnapshotShareLandingPage } from "../../../share/share-landing.js";
|
|
@@ -31,6 +31,7 @@ import { createHash } from "node:crypto";
|
|
|
31
31
|
import { stat } from "node:fs/promises";
|
|
32
32
|
import { Readable } from "node:stream";
|
|
33
33
|
//#region src/gateway/hono/routes/shares.ts
|
|
34
|
+
init_loopback();
|
|
34
35
|
init_sqlite();
|
|
35
36
|
function getShareUrlContext(service) {
|
|
36
37
|
const gateway = service.currentConfig.gateway;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { voiceSelectionSchema } from "../../../../packages/realtime-protocol/src/voice-catalog.js";
|
|
2
2
|
import { VOICE_TIMING_METRICS, createVoiceSessionRequestSchema, init_voice } from "../../../../packages/realtime-protocol/src/voice.js";
|
|
3
3
|
import { getDefaultModelSync, init_providers, resolveModel } from "../../../providers/index.js";
|
|
4
|
-
import { completeWithResolvedCredentials } from "../../../providers/model-call.js";
|
|
5
4
|
import { isPersonalConversation } from "../../../personal-agent/repository.js";
|
|
5
|
+
import { completeWithResolvedCredentials } from "../../../providers/model-call.js";
|
|
6
6
|
import { resolveSttProviderConfigSlice } from "../../../voice/stt/config-slice.js";
|
|
7
7
|
import { STTTranscriptionError, transcribe } from "../../../voice/stt/transcribe-core.js";
|
|
8
8
|
import { isSTTAvailable } from "../../../voice/stt/availability.js";
|
|
@@ -184,6 +184,7 @@ function registerVoiceRoutes(authenticated, deps) {
|
|
|
184
184
|
ok: true,
|
|
185
185
|
payload: {
|
|
186
186
|
enabled,
|
|
187
|
+
openingGreeting: true,
|
|
187
188
|
capabilities: {
|
|
188
189
|
dictation: availability(Boolean(stt)),
|
|
189
190
|
assistant: availability(Boolean(stt && tts)),
|
package/dist/src/gateway/host.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import "
|
|
1
|
+
import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { init_constants } from "../daemon/constants.js";
|
|
2
3
|
import { networkInterfaces } from "node:os";
|
|
3
4
|
//#region src/gateway/host.ts
|
|
4
5
|
/** True when the bind address is local-only (127.x, localhost, ::1). */
|
|
@@ -13,8 +14,6 @@ function isAllInterfacesHost(host) {
|
|
|
13
14
|
const normalized = host.trim();
|
|
14
15
|
return normalized === "0.0.0.0" || normalized === "::" || normalized === "*";
|
|
15
16
|
}
|
|
16
|
-
/** Vite dev server origins for the gateway console (`web/` defaults to port 3000). */
|
|
17
|
-
const GATEWAY_DEV_CONSOLE_ORIGINS = ["http://localhost:3000", "http://127.0.0.1:3000"];
|
|
18
17
|
/** Non-internal IPv4 addresses that can serve this gateway on the local network. */
|
|
19
18
|
function enumerateLanGatewayCandidates(port) {
|
|
20
19
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -86,5 +85,11 @@ function resolveAllowedBrowserOrigins(params) {
|
|
|
86
85
|
if (reverseProxyOrigin && !origins.includes(reverseProxyOrigin)) origins.push(reverseProxyOrigin);
|
|
87
86
|
return origins;
|
|
88
87
|
}
|
|
88
|
+
var GATEWAY_DEV_CONSOLE_ORIGINS;
|
|
89
|
+
var init_host = __esmMin((() => {
|
|
90
|
+
init_constants();
|
|
91
|
+
GATEWAY_DEV_CONSOLE_ORIGINS = ["http://localhost:3000", "http://127.0.0.1:3000"];
|
|
92
|
+
}));
|
|
89
93
|
//#endregion
|
|
90
|
-
|
|
94
|
+
init_host();
|
|
95
|
+
export { GATEWAY_DEV_CONSOLE_ORIGINS, buildDefaultCorsOrigins, enumerateLanGatewayCandidates, init_host, isAllInterfacesHost, isLoopbackHost, originFromGatewayPublicUrl, resolveAllowedBrowserOrigins, resolveEffectiveGatewayPort, resolveGatewayCorsOrigins, resolveGatewayServiceListenPort };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { buckets } from "./rate-limit/buckets.js";
|
|
2
|
+
import { buildDefaultCorsOrigins, init_host, isAllInterfacesHost, isLoopbackHost, resolveEffectiveGatewayPort, resolveGatewayServiceListenPort } from "./host.js";
|
|
3
|
+
import { isGatewayStrictSecurityEnabled } from "./rate-limit/env-flags.js";
|
|
4
|
+
import { init_rate_limit } from "./rate-limit/index.js";
|
|
2
5
|
import { defaultGatewayBindMode, isContainerEnvironment, resolveGatewayBindHost, resolveGatewayBindHostSync, resolveGatewayBindMode, resolveGatewayEffectiveHost } from "../config/gateway-bind.js";
|
|
3
6
|
import { GatewayLockError, acquireGatewayLock } from "./lock.js";
|
|
4
7
|
import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
|
|
5
8
|
import { resolveGatewayListenHost, resolveGatewayListenPlan } from "./listen.js";
|
|
6
|
-
import { buckets } from "./rate-limit/buckets.js";
|
|
7
|
-
import { isGatewayStrictSecurityEnabled } from "./rate-limit/env-flags.js";
|
|
8
|
-
import "./rate-limit/index.js";
|
|
9
9
|
import { assertGatewayRuntimeConfig } from "./runtime-config.js";
|
|
10
10
|
import { restartGatewayProcessWithFreshPid } from "./respawn.js";
|
|
11
11
|
import { GatewayService } from "./service.js";
|
|
@@ -16,4 +16,8 @@ import { checkPortAvailable, forceFreePortAndWait, listPortListeners, parseLsofO
|
|
|
16
16
|
import { apiError, apiOk } from "./protocol.js";
|
|
17
17
|
import "./hono/index.js";
|
|
18
18
|
import { assertSecureGatewayHttpUrl, assertSecureWebSocketUrl, isInsecurePrivateWsAllowed, isSecureWebSocketUrl } from "./ws-security.js";
|
|
19
|
+
//#region src/gateway/index.ts
|
|
20
|
+
init_host();
|
|
21
|
+
init_rate_limit();
|
|
22
|
+
//#endregion
|
|
19
23
|
export { GatewayLockError, GatewayServer, GatewayService, acquireGatewayLock, apiError, apiOk, assertGatewayAuthConfigured, assertGatewayRuntimeConfig, assertSecureGatewayHttpUrl, assertSecureWebSocketUrl, buckets, buildDefaultCorsOrigins, checkPortAvailable, createHonoApp, defaultGatewayBindMode, extractToken, forceFreePortAndWait, isAllInterfacesHost, isContainerEnvironment, isGatewayStrictSecurityEnabled, isInsecurePrivateWsAllowed, isLoopbackHost, isSecureWebSocketUrl, listPortListeners, parseLsofOutput, resolveEffectiveGatewayPort, resolveGatewayAuth, resolveGatewayBindHost, resolveGatewayBindHostSync, resolveGatewayBindMode, resolveGatewayEffectiveHost, resolveGatewayListenHost, resolveGatewayListenPlan, resolveGatewayServiceListenPort, restartGatewayProcessWithFreshPid, runGatewayLoop, validateToken };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { buildDefaultCorsOrigins, isAllInterfacesHost, isLoopbackHost } from "./host.js";
|
|
1
|
+
import { buildDefaultCorsOrigins, init_host, isAllInterfacesHost, isLoopbackHost } from "./host.js";
|
|
2
2
|
import { resolveGatewayBindHostSync, resolveGatewayBindMode, resolveGatewayCustomBindHost } from "../config/gateway-bind.js";
|
|
3
3
|
//#region src/gateway/listen.ts
|
|
4
|
+
init_host();
|
|
4
5
|
/** Resolve the effective HTTP listen host (CLI bind override > config bind). */
|
|
5
6
|
function resolveGatewayListenHost(params) {
|
|
6
7
|
return resolveGatewayBindHostSync({
|
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __esmMin } from "../../../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { init_loopback, isLoopbackClientIp, isLoopbackEmbeddedBrowserClient } from "../security/loopback.js";
|
|
2
3
|
//#region src/gateway/rate-limit/auth-policy.ts
|
|
3
4
|
/**
|
|
4
|
-
* Auth-failure rate-limit policy: how to derive a tracking key from a request,
|
|
5
|
-
* and whether a given client should be exempted before counting.
|
|
6
|
-
*
|
|
7
|
-
* The {@link FailureLimiter} primitive is intentionally policy-free — this
|
|
8
|
-
* module is the only place that knows about IPs, browser origins, and the
|
|
9
|
-
* loopback exemption. Adding a new exemption rule (e.g. private CIDRs) means
|
|
10
|
-
* editing this file alone; the limiter primitive does not change.
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
5
|
* Decide whether to track this client and, if so, what key identifies them.
|
|
14
6
|
* Browser clients are tracked separately (origin + IP) so a rogue `<iframe>`
|
|
15
7
|
* cannot piggyback on a CLI client's bucket and DoS it.
|
|
@@ -43,5 +35,9 @@ function resolveAuthTracking(params) {
|
|
|
43
35
|
function buildBrowserOriginKey(origin, clientIp) {
|
|
44
36
|
return `browser-origin:${origin.trim().toLowerCase()}|${clientIp.trim()}`;
|
|
45
37
|
}
|
|
38
|
+
var init_auth_policy = __esmMin((() => {
|
|
39
|
+
init_loopback();
|
|
40
|
+
}));
|
|
46
41
|
//#endregion
|
|
47
|
-
|
|
42
|
+
init_auth_policy();
|
|
43
|
+
export { buildBrowserOriginKey, init_auth_policy, resolveAuthTracking };
|
|
@@ -35,6 +35,9 @@ declare class BucketRegistry {
|
|
|
35
35
|
private authFailureLimiter?;
|
|
36
36
|
private authFailureSignature?;
|
|
37
37
|
private identityChallengeLimiter?;
|
|
38
|
+
private publicDeviceGlobalLimiter?;
|
|
39
|
+
private publicDeviceSourceLimiter?;
|
|
40
|
+
private deviceRefreshLimiter?;
|
|
38
41
|
private strictApiLimiter?;
|
|
39
42
|
private chatApiLimiter?;
|
|
40
43
|
private mediaApiLimiter?;
|
|
@@ -51,6 +54,9 @@ declare class BucketRegistry {
|
|
|
51
54
|
* config read.
|
|
52
55
|
*/
|
|
53
56
|
authFailure(cfg: ResolvedAuthRateLimitConfig): FailureLimiter;
|
|
57
|
+
publicDeviceGlobal(): RateLimiter;
|
|
58
|
+
publicDeviceSource(): RateLimiter;
|
|
59
|
+
deviceRefresh(): RateLimiter;
|
|
54
60
|
/** Global pre-authentication signing budget; independent of authenticated traffic. */
|
|
55
61
|
identityChallenge(): RateLimiter;
|
|
56
62
|
/** Authenticated admin / mutation endpoints — 150 req / 60 s per client IP. */
|
|
@@ -1,30 +1,8 @@
|
|
|
1
|
+
import { __esmMin } from "../../../_virtual/_rolldown/runtime.js";
|
|
1
2
|
import { RateLimiter } from "../../infra/rate-limit/rate-limiter.js";
|
|
2
3
|
import { FailureLimiter } from "../../infra/rate-limit/failure-limiter.js";
|
|
4
|
+
import { init_rate_limit } from "../../infra/rate-limit/index.js";
|
|
3
5
|
//#region src/gateway/rate-limit/buckets.ts
|
|
4
|
-
/**
|
|
5
|
-
* Named rate-limit buckets used across the gateway. Each is a thin wrapper
|
|
6
|
-
* over a primitive limiter ({@link RateLimiter} or {@link FailureLimiter})
|
|
7
|
-
* that hard-codes its config and exposes a small surface.
|
|
8
|
-
*
|
|
9
|
-
* All buckets are owned by a process-level singleton {@link BucketRegistry}
|
|
10
|
-
* so that:
|
|
11
|
-
* - lifecycle (cleanup timers) is centralized — `destroyAll()` on shutdown,
|
|
12
|
-
* - tests get one obvious reset entry point (`resetAllForTests`),
|
|
13
|
-
* - new buckets are added in exactly one place.
|
|
14
|
-
*
|
|
15
|
-
* Tuning policy:
|
|
16
|
-
* - `auth_failure` is read from runtime config because users tune it per
|
|
17
|
-
* deployment. Other buckets keep static defaults until a real need
|
|
18
|
-
* emerges to expose them. (YAGNI > premature configurability.)
|
|
19
|
-
*/
|
|
20
|
-
const DEFAULT_AUTH_RATE_LIMIT = {
|
|
21
|
-
enabled: true,
|
|
22
|
-
maxFailures: 5,
|
|
23
|
-
windowMs: 900 * 1e3,
|
|
24
|
-
blockDurationMs: 300 * 1e3,
|
|
25
|
-
burstCoalesceMs: 1e3,
|
|
26
|
-
exemptLoopback: true
|
|
27
|
-
};
|
|
28
6
|
function resolveAuthRateLimit(input) {
|
|
29
7
|
if (!input) return { ...DEFAULT_AUTH_RATE_LIMIT };
|
|
30
8
|
const blockDurationMs = input.blockDurationMs ?? input.lockoutMs ?? DEFAULT_AUTH_RATE_LIMIT.blockDurationMs;
|
|
@@ -43,170 +21,214 @@ function authPolicyConfig(cfg) {
|
|
|
43
21
|
exemptLoopback: cfg.exemptLoopback
|
|
44
22
|
};
|
|
45
23
|
}
|
|
46
|
-
var BucketRegistry
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
24
|
+
var DEFAULT_AUTH_RATE_LIMIT, BucketRegistry, buckets;
|
|
25
|
+
var init_buckets = __esmMin((() => {
|
|
26
|
+
init_rate_limit();
|
|
27
|
+
DEFAULT_AUTH_RATE_LIMIT = {
|
|
28
|
+
enabled: true,
|
|
29
|
+
maxFailures: 5,
|
|
30
|
+
windowMs: 900 * 1e3,
|
|
31
|
+
blockDurationMs: 300 * 1e3,
|
|
32
|
+
burstCoalesceMs: 1e3,
|
|
33
|
+
exemptLoopback: true
|
|
34
|
+
};
|
|
35
|
+
BucketRegistry = class {
|
|
36
|
+
authFailureLimiter;
|
|
37
|
+
authFailureSignature;
|
|
38
|
+
identityChallengeLimiter;
|
|
39
|
+
publicDeviceGlobalLimiter;
|
|
40
|
+
publicDeviceSourceLimiter;
|
|
41
|
+
deviceRefreshLimiter;
|
|
42
|
+
strictApiLimiter;
|
|
43
|
+
chatApiLimiter;
|
|
44
|
+
mediaApiLimiter;
|
|
45
|
+
taskApiLimiter;
|
|
46
|
+
xopcCloudPollLimiter;
|
|
47
|
+
channelApiLimiter;
|
|
48
|
+
tunnelMutateLimiter;
|
|
49
|
+
pairingExchangeLimiter;
|
|
50
|
+
sharePublicShortLimiter;
|
|
51
|
+
sharePublicLongLimiter;
|
|
52
|
+
/**
|
|
53
|
+
* Reconfigured on the fly when `gateway.auth.rateLimit` is reloaded —
|
|
54
|
+
* compares a stable signature to avoid swapping out a hot bucket on every
|
|
55
|
+
* config read.
|
|
56
|
+
*/
|
|
57
|
+
authFailure(cfg) {
|
|
58
|
+
const sig = `${cfg.maxFailures}|${cfg.windowMs}|${cfg.blockDurationMs}|${cfg.burstCoalesceMs}`;
|
|
59
|
+
if (!this.authFailureLimiter || this.authFailureSignature !== sig) {
|
|
60
|
+
this.authFailureLimiter?.destroy();
|
|
61
|
+
this.authFailureLimiter = new FailureLimiter({
|
|
62
|
+
maxFailures: cfg.maxFailures,
|
|
63
|
+
windowMs: cfg.windowMs,
|
|
64
|
+
blockDurationMs: cfg.blockDurationMs,
|
|
65
|
+
burstCoalesceMs: cfg.burstCoalesceMs
|
|
66
|
+
});
|
|
67
|
+
this.authFailureSignature = sig;
|
|
68
|
+
}
|
|
69
|
+
return this.authFailureLimiter;
|
|
70
|
+
}
|
|
71
|
+
publicDeviceGlobal() {
|
|
72
|
+
return this.publicDeviceGlobalLimiter ??= new RateLimiter({
|
|
73
|
+
maxRequests: 1200,
|
|
74
|
+
windowMs: 6e4
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
publicDeviceSource() {
|
|
78
|
+
return this.publicDeviceSourceLimiter ??= new RateLimiter({
|
|
79
|
+
maxRequests: 300,
|
|
80
|
+
windowMs: 6e4
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
deviceRefresh() {
|
|
84
|
+
return this.deviceRefreshLimiter ??= new RateLimiter({
|
|
85
|
+
maxRequests: 30,
|
|
86
|
+
windowMs: 6e4
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/** Global pre-authentication signing budget; independent of authenticated traffic. */
|
|
90
|
+
identityChallenge() {
|
|
91
|
+
return this.identityChallengeLimiter ??= new RateLimiter({
|
|
92
|
+
maxRequests: 300,
|
|
93
|
+
windowMs: 6e4
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/** Authenticated admin / mutation endpoints — 150 req / 60 s per client IP. */
|
|
97
|
+
strictApi() {
|
|
98
|
+
if (!this.strictApiLimiter) this.strictApiLimiter = new RateLimiter({
|
|
99
|
+
maxRequests: 150,
|
|
100
|
+
windowMs: 6e4
|
|
101
|
+
});
|
|
102
|
+
return this.strictApiLimiter;
|
|
103
|
+
}
|
|
104
|
+
/** Interactive chat actions — 180 req / 60 s per client IP. */
|
|
105
|
+
chatApi() {
|
|
106
|
+
if (!this.chatApiLimiter) this.chatApiLimiter = new RateLimiter({
|
|
107
|
+
maxRequests: 180,
|
|
108
|
+
windowMs: 6e4
|
|
109
|
+
});
|
|
110
|
+
return this.chatApiLimiter;
|
|
111
|
+
}
|
|
112
|
+
/** Durable media chunk uploads — 300 req / 60 s per client IP. */
|
|
113
|
+
mediaApi() {
|
|
114
|
+
if (!this.mediaApiLimiter) this.mediaApiLimiter = new RateLimiter({
|
|
115
|
+
maxRequests: 300,
|
|
116
|
+
windowMs: 6e4
|
|
117
|
+
});
|
|
118
|
+
return this.mediaApiLimiter;
|
|
119
|
+
}
|
|
120
|
+
/** Interactive task and board mutations — 300 req / 60 s per client IP. */
|
|
121
|
+
taskApi() {
|
|
122
|
+
if (!this.taskApiLimiter) this.taskApiLimiter = new RateLimiter({
|
|
123
|
+
maxRequests: 300,
|
|
124
|
+
windowMs: 6e4
|
|
74
125
|
});
|
|
75
|
-
this.
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
this.authFailureLimiter = void 0;
|
|
182
|
-
this.identityChallengeLimiter = void 0;
|
|
183
|
-
this.strictApiLimiter = void 0;
|
|
184
|
-
this.chatApiLimiter = void 0;
|
|
185
|
-
this.mediaApiLimiter = void 0;
|
|
186
|
-
this.taskApiLimiter = void 0;
|
|
187
|
-
this.xopcCloudPollLimiter = void 0;
|
|
188
|
-
this.channelApiLimiter = void 0;
|
|
189
|
-
this.tunnelMutateLimiter = void 0;
|
|
190
|
-
this.pairingExchangeLimiter = void 0;
|
|
191
|
-
this.sharePublicShortLimiter = void 0;
|
|
192
|
-
this.sharePublicLongLimiter = void 0;
|
|
193
|
-
this.authFailureSignature = void 0;
|
|
194
|
-
}
|
|
195
|
-
/** @internal */
|
|
196
|
-
resetAllForTests() {
|
|
197
|
-
this.authFailureLimiter?.resetForTests();
|
|
198
|
-
this.strictApiLimiter?.resetForTests();
|
|
199
|
-
this.chatApiLimiter?.resetForTests();
|
|
200
|
-
this.mediaApiLimiter?.resetForTests();
|
|
201
|
-
this.taskApiLimiter?.resetForTests();
|
|
202
|
-
this.xopcCloudPollLimiter?.resetForTests();
|
|
203
|
-
this.channelApiLimiter?.resetForTests();
|
|
204
|
-
this.tunnelMutateLimiter?.resetForTests();
|
|
205
|
-
this.pairingExchangeLimiter?.resetForTests();
|
|
206
|
-
this.sharePublicShortLimiter?.resetForTests();
|
|
207
|
-
this.sharePublicLongLimiter?.resetForTests();
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
const buckets = new BucketRegistry();
|
|
126
|
+
return this.taskApiLimiter;
|
|
127
|
+
}
|
|
128
|
+
/** XOPC Cloud authorization polling — 60 req / 60 s per client IP. */
|
|
129
|
+
xopcCloudPoll() {
|
|
130
|
+
if (!this.xopcCloudPollLimiter) this.xopcCloudPollLimiter = new RateLimiter({
|
|
131
|
+
maxRequests: 60,
|
|
132
|
+
windowMs: 6e4
|
|
133
|
+
});
|
|
134
|
+
return this.xopcCloudPollLimiter;
|
|
135
|
+
}
|
|
136
|
+
/** Channel mutation/action endpoints — 20 req / 60 s per client IP. */
|
|
137
|
+
channelApi() {
|
|
138
|
+
if (!this.channelApiLimiter) this.channelApiLimiter = new RateLimiter({
|
|
139
|
+
maxRequests: 20,
|
|
140
|
+
windowMs: 6e4
|
|
141
|
+
});
|
|
142
|
+
return this.channelApiLimiter;
|
|
143
|
+
}
|
|
144
|
+
/** Tunnel mutation calls — 12 req / 5 min per gateway-token fingerprint. */
|
|
145
|
+
tunnelMutate() {
|
|
146
|
+
if (!this.tunnelMutateLimiter) this.tunnelMutateLimiter = new RateLimiter({
|
|
147
|
+
maxRequests: 12,
|
|
148
|
+
windowMs: 5 * 6e4
|
|
149
|
+
});
|
|
150
|
+
return this.tunnelMutateLimiter;
|
|
151
|
+
}
|
|
152
|
+
/** Failed pairing-exchange attempts — 30 failures / 5 min per client IP. */
|
|
153
|
+
pairingExchange() {
|
|
154
|
+
if (!this.pairingExchangeLimiter) this.pairingExchangeLimiter = new FailureLimiter({
|
|
155
|
+
maxFailures: 30,
|
|
156
|
+
windowMs: 5 * 6e4,
|
|
157
|
+
blockDurationMs: 5 * 6e4,
|
|
158
|
+
burstCoalesceMs: 0
|
|
159
|
+
});
|
|
160
|
+
return this.pairingExchangeLimiter;
|
|
161
|
+
}
|
|
162
|
+
/** Public share download short window — 60 req / min per client IP. */
|
|
163
|
+
sharePublicShort() {
|
|
164
|
+
if (!this.sharePublicShortLimiter) this.sharePublicShortLimiter = new RateLimiter({
|
|
165
|
+
maxRequests: 60,
|
|
166
|
+
windowMs: 6e4
|
|
167
|
+
});
|
|
168
|
+
return this.sharePublicShortLimiter;
|
|
169
|
+
}
|
|
170
|
+
/** Public share download long window — 300 req / 15 min per client IP. */
|
|
171
|
+
sharePublicLong() {
|
|
172
|
+
if (!this.sharePublicLongLimiter) this.sharePublicLongLimiter = new RateLimiter({
|
|
173
|
+
maxRequests: 300,
|
|
174
|
+
windowMs: 15 * 6e4
|
|
175
|
+
});
|
|
176
|
+
return this.sharePublicLongLimiter;
|
|
177
|
+
}
|
|
178
|
+
destroyAll() {
|
|
179
|
+
this.authFailureLimiter?.destroy();
|
|
180
|
+
this.identityChallengeLimiter?.destroy();
|
|
181
|
+
this.publicDeviceGlobalLimiter?.destroy();
|
|
182
|
+
this.publicDeviceSourceLimiter?.destroy();
|
|
183
|
+
this.deviceRefreshLimiter?.destroy();
|
|
184
|
+
this.strictApiLimiter?.destroy();
|
|
185
|
+
this.chatApiLimiter?.destroy();
|
|
186
|
+
this.mediaApiLimiter?.destroy();
|
|
187
|
+
this.taskApiLimiter?.destroy();
|
|
188
|
+
this.xopcCloudPollLimiter?.destroy();
|
|
189
|
+
this.channelApiLimiter?.destroy();
|
|
190
|
+
this.tunnelMutateLimiter?.destroy();
|
|
191
|
+
this.pairingExchangeLimiter?.destroy();
|
|
192
|
+
this.sharePublicShortLimiter?.destroy();
|
|
193
|
+
this.sharePublicLongLimiter?.destroy();
|
|
194
|
+
this.authFailureLimiter = void 0;
|
|
195
|
+
this.identityChallengeLimiter = void 0;
|
|
196
|
+
this.publicDeviceGlobalLimiter = void 0;
|
|
197
|
+
this.publicDeviceSourceLimiter = void 0;
|
|
198
|
+
this.deviceRefreshLimiter = void 0;
|
|
199
|
+
this.strictApiLimiter = void 0;
|
|
200
|
+
this.chatApiLimiter = void 0;
|
|
201
|
+
this.mediaApiLimiter = void 0;
|
|
202
|
+
this.taskApiLimiter = void 0;
|
|
203
|
+
this.xopcCloudPollLimiter = void 0;
|
|
204
|
+
this.channelApiLimiter = void 0;
|
|
205
|
+
this.tunnelMutateLimiter = void 0;
|
|
206
|
+
this.pairingExchangeLimiter = void 0;
|
|
207
|
+
this.sharePublicShortLimiter = void 0;
|
|
208
|
+
this.sharePublicLongLimiter = void 0;
|
|
209
|
+
this.authFailureSignature = void 0;
|
|
210
|
+
}
|
|
211
|
+
/** @internal */
|
|
212
|
+
resetAllForTests() {
|
|
213
|
+
this.authFailureLimiter?.resetForTests();
|
|
214
|
+
this.identityChallengeLimiter?.resetForTests();
|
|
215
|
+
this.publicDeviceGlobalLimiter?.resetForTests();
|
|
216
|
+
this.publicDeviceSourceLimiter?.resetForTests();
|
|
217
|
+
this.deviceRefreshLimiter?.resetForTests();
|
|
218
|
+
this.strictApiLimiter?.resetForTests();
|
|
219
|
+
this.chatApiLimiter?.resetForTests();
|
|
220
|
+
this.mediaApiLimiter?.resetForTests();
|
|
221
|
+
this.taskApiLimiter?.resetForTests();
|
|
222
|
+
this.xopcCloudPollLimiter?.resetForTests();
|
|
223
|
+
this.channelApiLimiter?.resetForTests();
|
|
224
|
+
this.tunnelMutateLimiter?.resetForTests();
|
|
225
|
+
this.pairingExchangeLimiter?.resetForTests();
|
|
226
|
+
this.sharePublicShortLimiter?.resetForTests();
|
|
227
|
+
this.sharePublicLongLimiter?.resetForTests();
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
buckets = new BucketRegistry();
|
|
231
|
+
}));
|
|
211
232
|
//#endregion
|
|
212
|
-
|
|
233
|
+
init_buckets();
|
|
234
|
+
export { authPolicyConfig, buckets, init_buckets, resolveAuthRateLimit };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { __esmMin } from "../../../_virtual/_rolldown/runtime.js";
|
|
1
2
|
//#region src/gateway/rate-limit/env-flags.ts
|
|
2
3
|
/**
|
|
3
4
|
* Process-level env-var feature flags that influence rate-limit and gateway
|
|
@@ -10,5 +11,7 @@ function isAuthRateLimitGloballyDisabled() {
|
|
|
10
11
|
function isGatewayStrictSecurityEnabled(cfg) {
|
|
11
12
|
return cfg?.gateway?.security?.strict === true || process.env.XOPC_GATEWAY_STRICT_SECURITY === "1";
|
|
12
13
|
}
|
|
14
|
+
var init_env_flags = __esmMin((() => {}));
|
|
13
15
|
//#endregion
|
|
14
|
-
|
|
16
|
+
init_env_flags();
|
|
17
|
+
export { init_env_flags, isAuthRateLimitGloballyDisabled, isGatewayStrictSecurityEnabled };
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { __esmMin } from "../../../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { authPolicyConfig, buckets, init_buckets, resolveAuthRateLimit } from "./buckets.js";
|
|
3
|
+
import { buildBrowserOriginKey, init_auth_policy, resolveAuthTracking } from "./auth-policy.js";
|
|
4
|
+
import { init_env_flags, isAuthRateLimitGloballyDisabled, isGatewayStrictSecurityEnabled } from "./env-flags.js";
|
|
5
|
+
//#region src/gateway/rate-limit/index.ts
|
|
6
|
+
var init_rate_limit = __esmMin((() => {
|
|
7
|
+
init_buckets();
|
|
8
|
+
init_auth_policy();
|
|
9
|
+
init_env_flags();
|
|
10
|
+
}));
|
|
11
|
+
//#endregion
|
|
12
|
+
init_rate_limit();
|
|
13
|
+
export { authPolicyConfig, buckets, buildBrowserOriginKey, init_rate_limit, isAuthRateLimitGloballyDisabled, isGatewayStrictSecurityEnabled, resolveAuthRateLimit, resolveAuthTracking };
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { isAllInterfacesHost, isLoopbackHost, resolveGatewayCorsOrigins } from "./host.js";
|
|
1
|
+
import { init_host, isAllInterfacesHost, isLoopbackHost, resolveGatewayCorsOrigins } from "./host.js";
|
|
2
|
+
import { isAuthRateLimitGloballyDisabled, isGatewayStrictSecurityEnabled } from "./rate-limit/env-flags.js";
|
|
3
|
+
import { init_rate_limit } from "./rate-limit/index.js";
|
|
2
4
|
import { resolveGatewayListenPlan } from "./listen.js";
|
|
3
5
|
import { assertTailscaleExposureCompatible } from "./tailscale-lifecycle.js";
|
|
4
6
|
import { requireTunnelGatewayToken } from "../tunnel/auth-policy.js";
|
|
5
|
-
import { isAuthRateLimitGloballyDisabled, isGatewayStrictSecurityEnabled } from "./rate-limit/env-flags.js";
|
|
6
|
-
import "./rate-limit/index.js";
|
|
7
7
|
//#region src/gateway/runtime-config.ts
|
|
8
|
+
init_rate_limit();
|
|
9
|
+
init_host();
|
|
8
10
|
function hasSharedSecret(auth) {
|
|
9
11
|
if (auth.mode === "trusted-proxy") return true;
|
|
10
12
|
if (auth.mode === "token") return typeof auth.token === "string" && auth.token.trim().length > 0;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { isAuthRateLimitGloballyDisabled, isGatewayStrictSecurityEnabled } from "../rate-limit/env-flags.js";
|
|
4
|
+
import { init_rate_limit } from "../rate-limit/index.js";
|
|
3
5
|
import { assertGatewayAuthConfigured, resolveGatewayAuth } from "../auth.js";
|
|
4
6
|
import { resolveGatewayListenPlan } from "../listen.js";
|
|
5
7
|
import { collectExposureConflicts, isRemoteGatewayInsecure, isTailnetBindUnavailable } from "../../remote-access/exposure-guards.js";
|
|
6
|
-
import { isAuthRateLimitGloballyDisabled, isGatewayStrictSecurityEnabled } from "../rate-limit/env-flags.js";
|
|
7
|
-
import "../rate-limit/index.js";
|
|
8
8
|
import { assertGatewayRuntimeConfig } from "../runtime-config.js";
|
|
9
9
|
//#region src/gateway/security/audit.ts
|
|
10
|
+
init_rate_limit();
|
|
10
11
|
init_logger();
|
|
11
12
|
const log = createLogger("SecurityAudit");
|
|
12
13
|
/** Minimum token length to resist brute-force even with rate limiting. */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { isLoopbackHost } from "../host.js";
|
|
1
|
+
import { init_host, isLoopbackHost } from "../host.js";
|
|
2
2
|
import { deleteCookie, getCookie, setCookie } from "hono/cookie";
|
|
3
3
|
//#region src/gateway/security/browser-session.ts
|
|
4
|
+
init_host();
|
|
4
5
|
function origin(c) {
|
|
5
6
|
return new URL(`http://${c.req.header("host") ?? new URL(c.req.url).host}`);
|
|
6
7
|
}
|