@xopcai/xopc 0.0.270 → 0.0.272
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/dist/assets/{auth-cwEj8rFb.js → auth-C1QI-uMG.js} +65 -14
- package/dist/browser-ext/dist/background.js +23 -2
- package/dist/browser-ext/dist/pairing-handoff.js +51 -0
- package/dist/browser-ext/dist/sidepanel.html +1 -1
- package/dist/browser-ext/dist/sidepanel.js +39 -27
- package/dist/browser-ext/manifest.json +12 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-D_0FmdRj.js → activity-store-DffqjeqQ.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-IZvEXak_.js → agent-avatar-dicebear-Cwj4HCYY.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-6CLfLxVc.js +1 -0
- package/dist/gateway/static/root/assets/agents-B6mu64fY.js +1 -0
- package/dist/gateway/static/root/assets/{api-O3TTQ4qN.js → api-CGLdye4i.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-Cqqsbzri.js → app-management-settings-panel-BLujSbaw.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-DaJyf32s.js → appearance-settings-BXMcueb8.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-BEgy4hY3.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-kDPnDTJI.js → archive-plugin-D4bUampf.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CJ3VceKS.js → attachment-load-CBGNA2Ys.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-JwMtU8XB.js → automations-page-dQyolNmy.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-DxRFrmrV.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DzyZXLBX.js → binary-plugins-bbvp81h2.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-kTt3gYIJ.js → block-editor-C8e6Wri4.js} +3 -3
- package/dist/gateway/static/root/assets/{browser-automation-inputs-BKohPYR4.js → browser-automation-inputs-oJWJtQa6.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-ktQfFPk-.js → browser-automations-page-CAcJQSjN.js} +2 -2
- package/dist/gateway/static/root/assets/browser-settings-page-TLAlqcPo.js +8 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-z-K_jrZz.js +8 -0
- package/dist/gateway/static/root/assets/channels-settings-Dzrk33aB.js +1 -0
- package/dist/gateway/static/root/assets/{channels-status-swr-DrqzYmDr.js → channels-status-swr-CfOPNnVr.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-CIFGGLGa.js → chat-terminal-dock-9ZOl92kh.js} +2 -2
- package/dist/gateway/static/root/assets/clock-3-DnrAnuyZ.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-B1dIoRNi.js +2 -0
- package/dist/gateway/static/root/assets/cron-expression-C26e13YU.js +2 -0
- package/dist/gateway/static/root/assets/date-picker-Dj6FRLF9.js +1 -0
- package/dist/gateway/static/root/assets/{dependency-picker-D3vNIjRI.js → dependency-picker-D1q89tVc.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-fQwRb_3p.js → desktop-pet-DfqZBvhp.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-DfOJ-GvT.js → desktop-pet-settings-HCEh2MOm.js} +1 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-CPth92s6.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-Cn53jB5-.js → extension-debug-page-C8cAWVoK.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-IDpLCxpC.js → extension-page-5N87Vaym.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-D85SAUFP.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-swr-B7dcmP7Q.js → gateway-config-swr-BjsDnB_n.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-Dqx8PmcT.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-JGhGMhVZ.js → gateway-startup-retry-BIf0eLWX.js} +1 -1
- package/dist/gateway/static/root/assets/git-branch-Dh9uxTot.js +1 -0
- package/dist/gateway/static/root/assets/heartbeat-settings-BpDWGE1a.js +1 -0
- package/dist/gateway/static/root/assets/home-page-DJaqpC8-.js +1 -0
- package/dist/gateway/static/root/assets/{image-generation-api-BJLX7Qrh.js → image-generation-api-1m8xTVS_.js} +1 -1
- package/dist/gateway/static/root/assets/index-C6PmD0cK.js +74 -0
- package/dist/gateway/static/root/assets/index-DKy1Qn1_.css +2 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CBvMTFFx.js → keyboard-shortcuts-settings-Byy8mCSq.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-l2AEiG2C.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-APCMNDvU.js → local-apps-page-BPo0wBgM.js} +1 -1
- package/dist/gateway/static/root/assets/locale-store-CRNble2Z.js +1 -0
- package/dist/gateway/static/root/assets/logs-page-X5FdLlXK.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-DT6NoIjm.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-BwjpJVPs.js → markdown-view-AglreSOj.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-C10byeaa.js → media-plugins-Bzka9qXu.js} +1 -1
- package/dist/gateway/static/root/assets/message-circle-Badhj-4D.js +1 -0
- package/dist/gateway/static/root/assets/message-square-fVE7Ghj1.js +1 -0
- package/dist/gateway/static/root/assets/{messages-D0V_bgRP.js → messages-DH_HCgmw.js} +3 -3
- package/dist/gateway/static/root/assets/note-detail-panel-BUJPoaGZ.js +5 -0
- package/dist/gateway/static/root/assets/notes-page-BwFpWRuo.js +8 -0
- package/dist/gateway/static/root/assets/{page-tabs-qQ36zncF.js → page-tabs-Ys0p65Lt.js} +1 -1
- package/dist/gateway/static/root/assets/popover-select-Dz_Qis2R.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-BiAJvvCo.js → preview-open-alternatives-iknB5xEp.js} +1 -1
- package/dist/gateway/static/root/assets/{proactive-card-CcNBqHoH.js → proactive-card-BPZDgNNR.js} +1 -1
- package/dist/gateway/static/root/assets/{proactive-page-C3K61jve.js → proactive-page-CxdZR-p2.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-CunnDP4w.js → product-open-page-W1o3f-kz.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-BU1RKAcy.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-z0X0tL8G.js +1 -0
- package/dist/gateway/static/root/assets/{registry-api-0JSegbNl.js → registry-api-DmYFpjsH.js} +1 -1
- package/dist/gateway/static/root/assets/remote-access-hub-NNTut2I8.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-bu_mwBTr.js → runtime-tools-settings-panel-DP1XyYO8.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-BE0sgZyz.js → schema-form-BMYKdzsH.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-B6SsHlz5.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-BQu8bAcN.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-CBo517lV.js → settings-form-section-2LGjz7bu.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-DBPimx93.js → settings-page-7DjpC9_C.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-Dj9jFWJt.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-DdV75VTe.js → share-preview-page-BxYdSi8c.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-CMqE0KuK.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-BXqSJymN.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-Cn_-nvRo.js → skills-page-DNEScMZH.js} +1 -1
- package/dist/gateway/static/root/assets/skills-page.utils-q88l65YU.js +1 -0
- package/dist/gateway/static/root/assets/system-settings-panel-8NIssGKj.js +1 -0
- package/dist/gateway/static/root/assets/task-detail-page-L6dp9v2y.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-1wryLgBQ.js → theme-store-BXZG3S25.js} +1 -1
- package/dist/gateway/static/root/assets/tunnel-api-CWsRPM84.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-N_lm4FdD.js → use-autosave-BwQuoTQU.js} +1 -1
- package/dist/gateway/static/root/assets/user-model-page-D4BucMrZ.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-DMsyVfri.js → voice-api-key-field-Bd03Ic0s.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-QWVmiAp3.js → voice-config-api-gggUp3u9.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BC0vAxp1.js → work-discovery-overlay-DF8PR_pK.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Cz9jQIlP.js → workflow-run-setup-panel-BiAAWlir.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DryKUMfA.js +6 -0
- package/dist/gateway/static/root/index.html +15 -11
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/device-pairing.js +2 -1
- package/dist/packages/gateway-contract/src/session-identity.js +37 -0
- package/dist/src/agent/memory/compaction-chunks.d.ts +18 -0
- package/dist/src/agent/memory/compaction-chunks.js +53 -0
- package/dist/src/agent/memory/compaction-request.d.ts +12 -0
- package/dist/src/agent/memory/compaction-request.js +72 -0
- package/dist/src/agent/memory/compaction.d.ts +3 -0
- package/dist/src/agent/memory/compaction.js +166 -118
- package/dist/src/agent/service.js +1 -0
- package/dist/src/browser/native-messaging-host.js +3 -1
- package/dist/src/cli/bin.js +2 -2
- package/dist/src/cli/commands/agent.js +2 -2
- package/dist/src/cli/commands/auth.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/extension-dev.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension.js +1 -1
- package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
- package/dist/src/cli/commands/gateway-ssh-tunnel.js +1 -1
- package/dist/src/cli/commands/models.js +2 -2
- package/dist/src/cli/commands/onboard.js +1 -1
- package/dist/src/cli/commands/platform.js +1 -1
- package/dist/src/cli/commands/profile.js +1 -1
- package/dist/src/cli/commands/tunnel.js +6 -1
- package/dist/src/cli/commands/update.js +1 -1
- package/dist/src/cli/extension-cli-register.js +1 -1
- package/dist/src/config/index.js +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/app.js +1 -0
- package/dist/src/gateway/hono/middleware/auth.d.ts +1 -2
- package/dist/src/gateway/hono/middleware/auth.js +49 -31
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +11 -15
- package/dist/src/gateway/hono/routes/browser-session.d.ts +3 -0
- package/dist/src/gateway/hono/routes/browser-session.js +43 -0
- package/dist/src/gateway/hono/routes/devices.js +61 -96
- package/dist/src/gateway/hono/routes/exposure.js +3 -7
- package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
- package/dist/src/gateway/hono/routes/models.js +60 -1
- package/dist/src/gateway/hono/routes/notes.js +3 -7
- package/dist/src/gateway/hono/routes/sessions.js +11 -0
- package/dist/src/gateway/hono/routes/shares.js +8 -20
- package/dist/src/gateway/hono/routes/site-shares.js +4 -8
- package/dist/src/gateway/hono/routes/tunnel.js +13 -13
- package/dist/src/gateway/image-generation-setup.d.ts +17 -0
- package/dist/src/gateway/image-generation-setup.js +30 -21
- package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
- package/dist/src/gateway/rate-limit/buckets.js +10 -0
- package/dist/src/gateway/run-loop.js +1 -1
- package/dist/src/gateway/runtime-config.js +2 -0
- package/dist/src/gateway/security/browser-session.d.ts +5 -0
- package/dist/src/gateway/security/browser-session.js +45 -0
- package/dist/src/gateway/security/gateway-principal.d.ts +1 -0
- package/dist/src/gateway/server.js +1 -1
- package/dist/src/gateway/service.d.ts +1 -0
- package/dist/src/gateway/service.js +11 -1
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/infra/rate-limit/keyed-store.d.ts +3 -0
- package/dist/src/infra/rate-limit/keyed-store.js +9 -2
- package/dist/src/proactive/policy/service.d.ts +1 -1
- package/dist/src/realtime/runtime.d.ts +2 -1
- package/dist/src/realtime/runtime.js +9 -3
- package/dist/src/realtime/tickets.d.ts +1 -0
- package/dist/src/realtime/tickets.js +3 -0
- package/dist/src/session/store.d.ts +2 -0
- package/dist/src/session/store.js +17 -2
- package/dist/src/session/types.d.ts +2 -1
- package/dist/src/storage/sqlite/browser-session-repository.d.ts +17 -0
- package/dist/src/storage/sqlite/browser-session-repository.js +54 -0
- package/dist/src/storage/sqlite/device-pairing-approval.js +2 -1
- package/dist/src/storage/sqlite/device-pairing-repository.d.ts +4 -10
- package/dist/src/storage/sqlite/device-pairing-repository.js +10 -62
- package/dist/src/storage/sqlite/index.d.ts +1 -1
- package/dist/src/storage/sqlite/index.js +2 -2
- package/dist/src/storage/sqlite/migrations/164_browser_sessions.sql +8 -0
- package/dist/src/storage/sqlite/migrations/165_device_pairing_target.sql +40 -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/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/session-identity-sql.d.ts +2 -0
- package/dist/src/storage/sqlite/session-identity-sql.js +18 -0
- package/dist/src/storage/sqlite/session-repository.js +26 -22
- package/dist/src/tunnel/auth-policy.d.ts +3 -0
- package/dist/src/tunnel/auth-policy.js +8 -0
- package/dist/src/tunnel/broker-client.d.ts +5 -15
- package/dist/src/tunnel/broker-client.js +37 -49
- package/dist/src/tunnel/frpc-binary.d.ts +8 -6
- package/dist/src/tunnel/frpc-binary.js +76 -88
- package/dist/src/tunnel/frpc-config.d.ts +2 -1
- package/dist/src/tunnel/frpc-config.js +29 -12
- package/dist/src/tunnel/frpc-release.d.ts +27 -0
- package/dist/src/tunnel/frpc-release.js +30 -0
- package/dist/src/tunnel/gateway-lifecycle.js +8 -2
- package/dist/src/tunnel/index.js +2 -1
- package/dist/src/tunnel/registration-proof.d.ts +19 -0
- package/dist/src/tunnel/registration-proof.js +37 -0
- package/dist/src/tunnel/tunnel-persist.js +3 -1
- package/dist/src/tunnel/tunnel-service.d.ts +1 -0
- package/dist/src/tunnel/tunnel-service.js +35 -8
- package/dist/src/tunnel/tunnel-state.js +11 -5
- package/dist/src/tunnel/tunnel-types.d.ts +2 -0
- package/dist/src/tunnel/well-known.js +5 -1
- package/dist/src/user-context/config.js +2 -2
- package/dist/src/utils/logger/redact.js +4 -0
- package/dist/src/voice/realtime/runtime.d.ts +1 -0
- package/dist/src/voice/realtime/runtime.js +17 -1
- package/dist/src/voice/realtime/runtime.types.d.ts +1 -0
- package/dist/src/workflows/service/workflow-run-service.js +2 -0
- package/dist/src/workflows/service/workflow-session-bridge.d.ts +1 -0
- package/dist/src/workflows/service/workflow-session-bridge.js +1 -0
- package/package.json +4 -4
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CE3ygr3l.js +0 -1
- package/dist/gateway/static/root/assets/agents-DzG2qw-c.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-B4lX6yoT.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-BiNBewg0.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-Dgdt5uVL.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BpDW-R9f.js +0 -7
- package/dist/gateway/static/root/assets/channels-settings-DU4EQnR0.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-CfJqy284.js +0 -2
- package/dist/gateway/static/root/assets/cron-expression-BNwbnrEb.js +0 -2
- package/dist/gateway/static/root/assets/date-picker-DKyirU4K.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-B1dds2bP.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-pp9jN0wl.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-B8_zTyev.js +0 -1
- package/dist/gateway/static/root/assets/home-page-g1KdAdLb.js +0 -1
- package/dist/gateway/static/root/assets/index-1zRt56Zt.css +0 -2
- package/dist/gateway/static/root/assets/index-OMnem2nr.js +0 -74
- package/dist/gateway/static/root/assets/local-app-workbench-page-bj75v2ZE.js +0 -2
- package/dist/gateway/static/root/assets/locale-store-BThkG0W5.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-BX7n39zV.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-CM62j8ZX.js +0 -1
- package/dist/gateway/static/root/assets/mobile-pairing-wizard-BCWfwVx3.js +0 -1
- package/dist/gateway/static/root/assets/note-detail-panel-koOqb0gX.js +0 -5
- package/dist/gateway/static/root/assets/notes-page-BH54rY3B.js +0 -8
- package/dist/gateway/static/root/assets/popover-select-CKBYnT3c.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-SL2g8MZY.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-BtxazT5J.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-BSb7b67A.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-ljcS2KVz.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CR9Y9LQm.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-J3AnooPW.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-AAm4Iwcp.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-pRCjP5sm.js +0 -1
- package/dist/gateway/static/root/assets/skills-page.utils-CfVAc_lu.js +0 -1
- package/dist/gateway/static/root/assets/system-settings-panel-B-pzalp-.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-CmrLy3PO.js +0 -1
- package/dist/gateway/static/root/assets/tunnel-api-Cgpnm2fL.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-u3QLDX6L.js +0 -2
- package/dist/gateway/static/root/assets/workflows-page-DA6OOK6X.js +0 -6
|
@@ -5,10 +5,10 @@ import { init_paths, resolveExtensionsDir } from "../../config/paths.js";
|
|
|
5
5
|
import { init_loader, loadConfig, saveConfig } from "../../config/loader.js";
|
|
6
6
|
import { checkEngineCompatibility } from "../../extensions/engine-check.js";
|
|
7
7
|
import { ExtensionLoader } from "../../extensions/loader.js";
|
|
8
|
+
import { getContextWithOpts } from "../context.js";
|
|
8
9
|
import { getExtensionLockfileManager } from "../../extensions/lockfile.js";
|
|
9
10
|
import { checkAllExtensionsHealth, getExtensionHealthChecker } from "../../extensions/health.js";
|
|
10
11
|
import { collectExtensionPackageDependencyIssues } from "../../extensions/package-contract.js";
|
|
11
|
-
import { getContextWithOpts } from "../context.js";
|
|
12
12
|
import { colors } from "../utils/colors.js";
|
|
13
13
|
import { createExtensionCreateCommand } from "./extension-create.js";
|
|
14
14
|
import { createExtensionDevCommand } from "./extension-dev.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { init_paths, resolveConfigPath } from "../../../config/paths.js";
|
|
2
2
|
import { loadConfig } from "../../../config/loader.js";
|
|
3
|
-
import { isRestartEnabled } from "../../../config/commands.flags.js";
|
|
4
3
|
import "../../../config/index.js";
|
|
4
|
+
import { isRestartEnabled } from "../../../config/commands.flags.js";
|
|
5
5
|
import { resolveGatewayService } from "../../../daemon/service.js";
|
|
6
6
|
import { authorizeGatewaySigusr1Restart, writeGatewayRestartIntentSync } from "../../../infra/restart.js";
|
|
7
7
|
import { findVerifiedGatewayListenerPidsOnPortSync, formatGatewayPidList, signalVerifiedGatewayPidSync } from "../../../infra/gateway-processes.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { startSshPortForward } from "../../infra/ssh-tunnel.js";
|
|
2
1
|
import { formatExamples } from "../registry.js";
|
|
2
|
+
import { startSshPortForward } from "../../infra/ssh-tunnel.js";
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
//#region src/cli/commands/gateway-ssh-tunnel.ts
|
|
5
5
|
function registerGatewaySshTunnelCommand(parent, ctx) {
|
|
@@ -2,11 +2,11 @@ import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
|
|
|
2
2
|
import { loadConfig, saveConfig } from "../../config/loader.js";
|
|
3
3
|
import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
|
|
4
4
|
import { getAllModels, getAvailableModels, getConfiguredProviders, getProviderAuthState, getProviderDisplayName, init_providers, isProviderConfigured, providerSupportsApiKey, providerSupportsOAuth, resolveModel } from "../../providers/index.js";
|
|
5
|
+
import { formatExamples, register } from "../registry.js";
|
|
6
|
+
import { getContextWithOpts } from "../context.js";
|
|
5
7
|
import "../../config/index.js";
|
|
6
8
|
import { prepareUpdateGlobalDefaults } from "../../gateway/global-defaults-admin.js";
|
|
7
9
|
import { disconnectProvider } from "../../providers/provider-disconnect.js";
|
|
8
|
-
import { formatExamples, register } from "../registry.js";
|
|
9
|
-
import { getContextWithOpts } from "../context.js";
|
|
10
10
|
import { colors } from "../utils/colors.js";
|
|
11
11
|
import { runCliOAuthLogin } from "../utils/oauth-login.js";
|
|
12
12
|
import { input } from "@inquirer/prompts";
|
|
@@ -2,8 +2,8 @@ import { init_paths_state, resolveStateDir } from "../../config/paths-state.js";
|
|
|
2
2
|
import { ConfigSchema, init_schema } from "../../config/schema.js";
|
|
3
3
|
import { saveConfig } from "../../config/loader.js";
|
|
4
4
|
import { resolveGatewayLocalClientHost } from "../../config/gateway-bind.js";
|
|
5
|
-
import "../../config/index.js";
|
|
6
5
|
import { formatExamples, register } from "../registry.js";
|
|
6
|
+
import "../../config/index.js";
|
|
7
7
|
import { provisionEagerRuntimes } from "../../runtime-tools/bootstrap.js";
|
|
8
8
|
import { colors } from "../utils/colors.js";
|
|
9
9
|
import { initWorkspace } from "../utils/init-workspace.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { loadConfig, saveConfig } from "../../config/loader.js";
|
|
2
|
-
import "../../config/index.js";
|
|
3
2
|
import { formatExamples, register } from "../registry.js";
|
|
3
|
+
import "../../config/index.js";
|
|
4
4
|
import { PLATFORM_RUNTIME_PROFILE, PLATFORM_RUNTIME_PROVIDER, PlatformRuntimeClient, discoverPlatform } from "../../platform/client.js";
|
|
5
5
|
import "../../platform/index.js";
|
|
6
6
|
import { getProfile, upsertAuthProfile } from "../../auth/profiles/profiles.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
-
import { createProfile, deleteProfile, getCurrentProfile, getSwitchCommand, listProfiles, resolveProfileStateDir } from "../../config/profile.js";
|
|
4
3
|
import { formatExamples, register } from "../registry.js";
|
|
4
|
+
import { createProfile, deleteProfile, getCurrentProfile, getSwitchCommand, listProfiles, resolveProfileStateDir } from "../../config/profile.js";
|
|
5
5
|
import { colors } from "../utils/colors.js";
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import Table from "cli-table3";
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { isXopcDatabaseOpen, openXopcDatabase } from "../../storage/sqlite/connection.js";
|
|
3
4
|
import { loadConfig, saveConfig } from "../../config/loader.js";
|
|
4
5
|
import { resolveGatewayEffectiveHost } from "../../config/gateway-bind.js";
|
|
5
6
|
import { ensureFrpcBinary } from "../../tunnel/frpc-binary.js";
|
|
6
7
|
import { resolveTunnelBrokerUrl, resolveTunnelRegistrationSecret } from "../../tunnel/env.js";
|
|
7
8
|
import { loadTunnelState } from "../../tunnel/tunnel-state.js";
|
|
8
9
|
import { getTunnelService } from "../../tunnel/tunnel-service.js";
|
|
10
|
+
import { formatExamples, register } from "../registry.js";
|
|
9
11
|
import "../../config/index.js";
|
|
12
|
+
import { resolveGatewayAuth } from "../../gateway/auth.js";
|
|
13
|
+
import { requireTunnelGatewayToken } from "../../tunnel/auth-policy.js";
|
|
10
14
|
import { TUNNEL_RISK_SUMMARY_LINES, TunnelConsentError, assertTunnelMayStart, hasValidTunnelConsent } from "../../tunnel/consent.js";
|
|
11
15
|
import { resolveFrpSubdomainHost } from "../../tunnel/frp-subdomain-host.js";
|
|
12
16
|
import { applyTunnelConsentToConfig, mergeTunnelConfigPatch, setTunnelEnabledInConfig } from "../../tunnel/tunnel-config.js";
|
|
13
|
-
import { formatExamples, register } from "../registry.js";
|
|
14
17
|
import "../../tunnel/index.js";
|
|
15
18
|
import { Command } from "commander";
|
|
16
19
|
//#region src/cli/commands/tunnel.ts
|
|
@@ -26,6 +29,7 @@ function resolveGatewayPortHost(config) {
|
|
|
26
29
|
};
|
|
27
30
|
}
|
|
28
31
|
function resolveGatewayToken(config) {
|
|
32
|
+
requireTunnelGatewayToken(resolveGatewayAuth({ authConfig: config.gateway.auth }));
|
|
29
33
|
const fromEnv = process.env.XOPC_GATEWAY_TOKEN?.trim();
|
|
30
34
|
if (fromEnv) return fromEnv;
|
|
31
35
|
const token = config.gateway.auth?.token?.trim();
|
|
@@ -155,6 +159,7 @@ function createTunnelCommand(ctx) {
|
|
|
155
159
|
});
|
|
156
160
|
const config = loadConfig(ctx.configPath);
|
|
157
161
|
assertTunnelMayStart(config);
|
|
162
|
+
if (!isXopcDatabaseOpen()) openXopcDatabase();
|
|
158
163
|
const { port, host } = resolveGatewayPortHost(config);
|
|
159
164
|
const token = resolveGatewayToken(config);
|
|
160
165
|
const tunnel = getTunnelService();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { PACKAGE_VERSION, init_package_version } from "../../package-version.js";
|
|
2
2
|
import { loadConfig } from "../../config/loader.js";
|
|
3
|
+
import { formatExamples, register } from "../registry.js";
|
|
3
4
|
import "../../config/index.js";
|
|
4
5
|
import { acquireUpdateLock } from "../../infra/update-lock.js";
|
|
5
6
|
import { normalizeUpdateChannel } from "../../infra/update-channels.js";
|
|
6
7
|
import { compareSemver, resolveNpmChannelTag } from "../../infra/update-check.js";
|
|
7
8
|
import { formatUpdateApiResult, resolveUpdateInstallSurface, runGatewayUpdateWithPostSteps } from "../../infra/update-runner.js";
|
|
8
|
-
import { formatExamples, register } from "../registry.js";
|
|
9
9
|
import { Command } from "commander";
|
|
10
10
|
//#region src/cli/commands/update.ts
|
|
11
11
|
init_package_version();
|
|
@@ -4,9 +4,9 @@ import { ExtensionLoader } from "../extensions/loader.js";
|
|
|
4
4
|
import "../extensions/index.js";
|
|
5
5
|
import { MessageBus } from "../infra/bus/queue.js";
|
|
6
6
|
import "../infra/bus/index.js";
|
|
7
|
+
import { createDefaultContext } from "./registry.js";
|
|
7
8
|
import { getWorkspacePath } from "../config/workspace-path-helpers.js";
|
|
8
9
|
import "../config/index.js";
|
|
9
|
-
import { createDefaultContext } from "./registry.js";
|
|
10
10
|
import { registerExtensionCliProgram } from "../extensions/sdk/channel-helpers.js";
|
|
11
11
|
import { join } from "path";
|
|
12
12
|
//#region src/cli/extension-cli-register.ts
|
package/dist/src/config/index.js
CHANGED
|
@@ -13,10 +13,10 @@ import { clearConfigValueCache, getAllowedCommands, getCacheStats, init_resolve_
|
|
|
13
13
|
import { CustomModelSchema, ImageGenerationCapabilitiesSchema, ImageGenerationModelSchema, ImageGenerationProviderSchema, ModelOverrideSchema, ModelsJsonSchema, OpenAICompatSchema, OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema, OpenRouterRoutingSchema, ProviderConfigSchema, VercelGatewayRoutingSchema, getDefaultModelValues, init_models_json, loadModelsJson, modelsJsonExists, saveModelsJson, validateModelsConfig } from "./models-json.js";
|
|
14
14
|
import { canonicalizeConfiguredMcpServer, isKnownCliMcpTypeAlias, normalizeConfiguredMcpServers, resolveXopcMcpTransportAlias } from "./mcp-config-normalize.js";
|
|
15
15
|
import { formatThinkingLevels, listThinkingLevels, normalizeElevatedMode, normalizeReasoningLevel, normalizeThinkLevel, normalizeVerboseLevel, thinkLevelToNumber } from "../agent/transcript/thinking-types.js";
|
|
16
|
-
import { diffConfigPaths } from "./diff.js";
|
|
17
16
|
import { getWorkspacePath } from "./workspace-path-helpers.js";
|
|
18
17
|
import { listAgentProfileMarkdownDirs, listAgentWorkspaceDirs } from "./workspace-dirs.js";
|
|
19
18
|
import { ProfileManager, createProfile, deleteProfile, getCurrentProfile, getProfileManager, getProfileNameFromDir, getSwitchCommand, listProfiles, resolveProfileStateDir } from "./profile.js";
|
|
19
|
+
import { diffConfigPaths } from "./diff.js";
|
|
20
20
|
import { BASE_RELOAD_RULES, buildReloadPlan, matchReloadRule } from "./rules.js";
|
|
21
21
|
import { ConfigHotReloader } from "./reload.js";
|
|
22
22
|
//#region src/config/index.ts
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { shouldSilence, stripHeartbeatToken } from "../../heartbeat/tokens.js";
|
|
4
|
+
import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
|
|
4
5
|
import { isWithinActiveHours } from "../../heartbeat/active-hours.js";
|
|
5
6
|
import { isHeartbeatContentEmpty } from "../../heartbeat/content-check.js";
|
|
6
|
-
import { appendCronEventLines } from "../../heartbeat/event-prompt.js";
|
|
7
7
|
import { createHeartbeatWake } from "../../heartbeat/wake.js";
|
|
8
8
|
import { resolveHeartbeatMdPath } from "../workspace-heartbeat-path.js";
|
|
9
9
|
import { readFile } from "fs/promises";
|
|
@@ -225,6 +225,7 @@ function createHonoApp(config) {
|
|
|
225
225
|
authenticated.use(auth({
|
|
226
226
|
getGatewayAuth: () => service.currentConfig.gateway?.auth,
|
|
227
227
|
getResolvedAuth: () => service.getResolvedAuth(),
|
|
228
|
+
isPublicTunnelEnabled: () => service.currentConfig.tunnel?.enabled === true,
|
|
228
229
|
getTrustedProxyContext: () => ({
|
|
229
230
|
trustedProxies: service.currentConfig.gateway?.trustedProxies,
|
|
230
231
|
allowRealIpFallback: service.currentConfig.gateway?.allowRealIpFallback === true
|
|
@@ -4,13 +4,12 @@ export interface AuthConfig {
|
|
|
4
4
|
/** Current gateway auth from config (for rate-limit settings); optional. */
|
|
5
5
|
getGatewayAuth?: () => GatewayAuthConfig | undefined;
|
|
6
6
|
getResolvedAuth?: () => ResolvedGatewayAuth;
|
|
7
|
+
isPublicTunnelEnabled?: () => boolean;
|
|
7
8
|
getTrustedProxyContext?: () => {
|
|
8
9
|
trustedProxies?: string[];
|
|
9
10
|
allowRealIpFallback?: boolean;
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
|
-
/** Exported for gateway security tests. */
|
|
13
|
-
export declare function isQueryTokenAllowedPath(path: string, method: string): boolean;
|
|
14
13
|
export declare function auth(config?: AuthConfig): import("hono").MiddlewareHandler<any, string, {}, (Response & import("hono").TypedResponse<{
|
|
15
14
|
error: string;
|
|
16
15
|
code: string;
|
|
@@ -5,11 +5,12 @@ import { authenticateDeviceAccessToken, getDevice } from "../../../storage/sqlit
|
|
|
5
5
|
import { safeEqualSecret } from "../../security/secret-equal.js";
|
|
6
6
|
import { resolveClientIpFromRequest } from "../../client-ip.js";
|
|
7
7
|
import { authPolicyConfig, buckets, resolveAuthRateLimit } from "../../rate-limit/buckets.js";
|
|
8
|
-
import { getClientIpFromHeaders } from "../../security/loopback.js";
|
|
9
8
|
import { resolveAuthTracking } from "../../rate-limit/auth-policy.js";
|
|
10
9
|
import { isAuthRateLimitGloballyDisabled } from "../../rate-limit/env-flags.js";
|
|
11
10
|
import "../../rate-limit/index.js";
|
|
11
|
+
import { authenticateBrowserSession } from "../../../storage/sqlite/browser-session-repository.js";
|
|
12
12
|
import { isChromeExtensionOrigin } from "../../security/origin-check.js";
|
|
13
|
+
import { browserCookieRequestAllowed, readBrowserSessionCookie, writeBrowserSessionCookie } from "../../security/browser-session.js";
|
|
13
14
|
import { authorizeTrustedProxy } from "../../trusted-proxy.js";
|
|
14
15
|
import { setGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
15
16
|
import { createMiddleware } from "hono/factory";
|
|
@@ -30,21 +31,6 @@ function extractTokenFromHeader(authHeader) {
|
|
|
30
31
|
if (parts.length === 2 && parts[0].toLowerCase() === "bearer") return parts[1];
|
|
31
32
|
return authHeader;
|
|
32
33
|
}
|
|
33
|
-
/**
|
|
34
|
-
* SECURITY: query-string tokens leak into server logs, Referer headers, and
|
|
35
|
-
* browser history. We accept them only for avatar `<img>` loads, where an
|
|
36
|
-
* Authorization header cannot be set. Realtime WebSocket authentication uses a
|
|
37
|
-
* one-time ticket acquired over authenticated HTTP.
|
|
38
|
-
*/
|
|
39
|
-
function extractTokenFromQuery(url) {
|
|
40
|
-
return new URL(url).searchParams.get("token");
|
|
41
|
-
}
|
|
42
|
-
const AGENT_AVATAR_GET_PATH = /^\/api\/agents\/[^/]+\/avatar$/;
|
|
43
|
-
/** Exported for gateway security tests. */
|
|
44
|
-
function isQueryTokenAllowedPath(path, method) {
|
|
45
|
-
if (method === "GET" && AGENT_AVATAR_GET_PATH.test(path)) return true;
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
34
|
function resolveRemoteAddress(c) {
|
|
49
35
|
try {
|
|
50
36
|
return getConnInfo(c).remote.address;
|
|
@@ -53,17 +39,16 @@ function resolveRemoteAddress(c) {
|
|
|
53
39
|
}
|
|
54
40
|
}
|
|
55
41
|
function resolveMiddlewareClientIp(c, trustedProxies, allowRealIpFallback) {
|
|
56
|
-
|
|
42
|
+
return resolveClientIpFromRequest({
|
|
57
43
|
remoteAddress: resolveRemoteAddress(c),
|
|
58
44
|
getHeader: (name) => c.req.header(name),
|
|
59
45
|
trustedProxies,
|
|
60
46
|
allowRealIpFallback
|
|
61
47
|
});
|
|
62
|
-
return getClientIpFromHeaders({ get: (name) => c.req.header(name) ?? void 0 });
|
|
63
48
|
}
|
|
64
|
-
function buildRateLimitContext(getGatewayAuth, clientIp, origin) {
|
|
49
|
+
function buildRateLimitContext(getGatewayAuth, clientIp, origin, enforce = false) {
|
|
65
50
|
const cfg = resolveAuthRateLimit(getGatewayAuth?.()?.rateLimit);
|
|
66
|
-
if (!(cfg.enabled && !isAuthRateLimitGloballyDisabled())) return {
|
|
51
|
+
if (!(cfg.enabled && (enforce || !isAuthRateLimitGloballyDisabled()))) return {
|
|
67
52
|
active: false,
|
|
68
53
|
cfg,
|
|
69
54
|
trackingKey: void 0
|
|
@@ -101,7 +86,18 @@ function blockedResponse(c, retryAfterSec) {
|
|
|
101
86
|
}, 429);
|
|
102
87
|
}
|
|
103
88
|
function auth(config) {
|
|
104
|
-
const { getGatewayAuth, getResolvedAuth, getTrustedProxyContext } = config || {};
|
|
89
|
+
const { getGatewayAuth: readGatewayAuth, getResolvedAuth, getTrustedProxyContext, isPublicTunnelEnabled } = config || {};
|
|
90
|
+
const getGatewayAuth = () => {
|
|
91
|
+
const current = readGatewayAuth?.();
|
|
92
|
+
return isPublicTunnelEnabled?.() ? {
|
|
93
|
+
...current,
|
|
94
|
+
rateLimit: {
|
|
95
|
+
...current?.rateLimit,
|
|
96
|
+
enabled: true,
|
|
97
|
+
exemptLoopback: false
|
|
98
|
+
}
|
|
99
|
+
} : current;
|
|
100
|
+
};
|
|
105
101
|
return createMiddleware(async (c, next) => {
|
|
106
102
|
const resolvedAuth = getResolvedAuth?.();
|
|
107
103
|
if (!resolvedAuth) {
|
|
@@ -115,13 +111,17 @@ function auth(config) {
|
|
|
115
111
|
}, 401);
|
|
116
112
|
}
|
|
117
113
|
const authMode = resolvedAuth.mode;
|
|
114
|
+
if (isPublicTunnelEnabled?.() && authMode !== "token") return c.json({
|
|
115
|
+
error: "Unauthorized",
|
|
116
|
+
code: "unsafe_tunnel_auth"
|
|
117
|
+
}, 401);
|
|
118
118
|
if (authMode === "trusted-proxy") {
|
|
119
119
|
const proxyContext = getTrustedProxyContext?.();
|
|
120
120
|
const trustedProxies = proxyContext?.trustedProxies;
|
|
121
121
|
const trustedProxyConfig = resolvedAuth?.trustedProxy;
|
|
122
122
|
const clientIp = resolveMiddlewareClientIp(c, trustedProxies, proxyContext?.allowRealIpFallback);
|
|
123
123
|
const origin = c.req.header("origin");
|
|
124
|
-
const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin);
|
|
124
|
+
const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin, isPublicTunnelEnabled?.());
|
|
125
125
|
if (!trustedProxyConfig) {
|
|
126
126
|
log.warn({
|
|
127
127
|
path: c.req.path,
|
|
@@ -199,16 +199,34 @@ function auth(config) {
|
|
|
199
199
|
const proxyContext = getTrustedProxyContext?.();
|
|
200
200
|
const clientIp = resolveMiddlewareClientIp(c, proxyContext?.trustedProxies, proxyContext?.allowRealIpFallback);
|
|
201
201
|
const origin = c.req.header("origin");
|
|
202
|
-
const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin);
|
|
202
|
+
const rl = buildRateLimitContext(getGatewayAuth, clientIp, origin, isPublicTunnelEnabled?.());
|
|
203
203
|
const authHeader = extractTokenFromHeader(c.req.header("authorization"));
|
|
204
|
+
const browserCookie = readBrowserSessionCookie(c);
|
|
205
|
+
if (!authHeader && browserCookie) {
|
|
206
|
+
if (!browserCookieRequestAllowed(c)) return c.json({
|
|
207
|
+
error: "Forbidden",
|
|
208
|
+
code: "csrf_rejected"
|
|
209
|
+
}, 403);
|
|
210
|
+
const session = authenticateBrowserSession(browserCookie, resolvedAuth);
|
|
211
|
+
if (!session) {
|
|
212
|
+
recordFailure(rl);
|
|
213
|
+
return c.json({
|
|
214
|
+
error: "Unauthorized",
|
|
215
|
+
code: "browser_session_expired"
|
|
216
|
+
}, 401);
|
|
217
|
+
}
|
|
218
|
+
if (session.renewed) writeBrowserSessionCookie(c, browserCookie, session.expiresAt);
|
|
219
|
+
setGatewayPrincipal(c, {
|
|
220
|
+
kind: "owner",
|
|
221
|
+
principalId: `browser:${session.sessionId}`,
|
|
222
|
+
browserSessionId: session.sessionId,
|
|
223
|
+
scopes: ["gateway.admin"]
|
|
224
|
+
});
|
|
225
|
+
recordSuccess(rl);
|
|
226
|
+
return next();
|
|
227
|
+
}
|
|
204
228
|
const requestPath = new URL(c.req.url).pathname;
|
|
205
|
-
const
|
|
206
|
-
if (!authHeader && queryToken === null && new URL(c.req.url).searchParams.has("token")) log.warn({
|
|
207
|
-
path: requestPath,
|
|
208
|
-
method: c.req.method,
|
|
209
|
-
clientIp
|
|
210
|
-
}, "Credential in query string rejected: use Authorization header for this endpoint");
|
|
211
|
-
const providedCredential = authHeader || queryToken;
|
|
229
|
+
const providedCredential = authHeader;
|
|
212
230
|
const browserExtensionOrigin = isChromeExtensionOrigin(origin) ? origin.toLowerCase() : void 0;
|
|
213
231
|
if (providedCredential && validateCredential(providedCredential, expectedCredential)) {
|
|
214
232
|
if (browserExtensionOrigin) return c.json({
|
|
@@ -294,4 +312,4 @@ function auth(config) {
|
|
|
294
312
|
});
|
|
295
313
|
}
|
|
296
314
|
//#endregion
|
|
297
|
-
export { auth
|
|
315
|
+
export { auth };
|
|
@@ -2,7 +2,6 @@ import { createLogger } from "../../../utils/logger/index.js";
|
|
|
2
2
|
import { init_logger } from "../../../utils/logger.js";
|
|
3
3
|
import { resolveClientIpFromRequest } from "../../client-ip.js";
|
|
4
4
|
import { buckets } from "../../rate-limit/buckets.js";
|
|
5
|
-
import { getClientIpFromHeaders } from "../../security/loopback.js";
|
|
6
5
|
import "../../rate-limit/index.js";
|
|
7
6
|
import { createMiddleware } from "hono/factory";
|
|
8
7
|
import { getConnInfo } from "@hono/node-server/conninfo";
|
|
@@ -15,21 +14,18 @@ init_logger();
|
|
|
15
14
|
const log = createLogger("Hono:StrictRateLimit");
|
|
16
15
|
function resolveClientIp(c, deps) {
|
|
17
16
|
const { trustedProxies, allowRealIpFallback } = deps.getTrustedProxyContext();
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
remoteAddress = void 0;
|
|
24
|
-
}
|
|
25
|
-
return resolveClientIpFromRequest({
|
|
26
|
-
remoteAddress,
|
|
27
|
-
getHeader: (name) => c.req.header(name),
|
|
28
|
-
trustedProxies,
|
|
29
|
-
allowRealIpFallback
|
|
30
|
-
});
|
|
17
|
+
let remoteAddress;
|
|
18
|
+
try {
|
|
19
|
+
remoteAddress = getConnInfo(c).remote.address;
|
|
20
|
+
} catch {
|
|
21
|
+
remoteAddress = void 0;
|
|
31
22
|
}
|
|
32
|
-
return
|
|
23
|
+
return resolveClientIpFromRequest({
|
|
24
|
+
remoteAddress,
|
|
25
|
+
getHeader: (name) => c.req.header(name),
|
|
26
|
+
trustedProxies,
|
|
27
|
+
allowRealIpFallback
|
|
28
|
+
});
|
|
33
29
|
}
|
|
34
30
|
function createClientRateLimitMiddleware(deps, options) {
|
|
35
31
|
return createMiddleware(async (c, next) => {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { BrowserSessionLimitError, createBrowserSession, deleteBrowserSession } from "../../../storage/sqlite/browser-session-repository.js";
|
|
2
|
+
import { browserCookieRequestAllowed, clearBrowserSessionCookie, writeBrowserSessionCookie } from "../../security/browser-session.js";
|
|
3
|
+
import { getGatewayPrincipal } from "../../security/gateway-principal.js";
|
|
4
|
+
//#region src/gateway/hono/routes/browser-session.ts
|
|
5
|
+
function registerBrowserSessionRoutes(app, deps) {
|
|
6
|
+
app.get("/api/browser-session", (c) => {
|
|
7
|
+
c.header("Cache-Control", "no-store");
|
|
8
|
+
const principal = getGatewayPrincipal(c);
|
|
9
|
+
return c.json({ sessionKey: principal.principalId });
|
|
10
|
+
});
|
|
11
|
+
app.post("/api/browser-session", deps.strictRateLimitMiddleware, (c) => {
|
|
12
|
+
const principal = getGatewayPrincipal(c);
|
|
13
|
+
if (principal.kind !== "owner" || !browserCookieRequestAllowed(c)) return c.json({ error: "Forbidden" }, 403);
|
|
14
|
+
let session;
|
|
15
|
+
try {
|
|
16
|
+
session = createBrowserSession(deps.service.getResolvedAuth(), principal.browserSessionId);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (error instanceof BrowserSessionLimitError) return c.json({ error: "Browser session limit reached" }, 409);
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
if (principal.browserSessionId) {
|
|
22
|
+
deps.service.realtime.disconnectPrincipal(principal.principalId);
|
|
23
|
+
deps.service.voiceRealtime.disconnectPrincipal(principal.principalId);
|
|
24
|
+
}
|
|
25
|
+
writeBrowserSessionCookie(c, session.token, session.expiresAt);
|
|
26
|
+
c.header("Cache-Control", "no-store");
|
|
27
|
+
return c.json({ sessionKey: `browser:${session.sessionId}` });
|
|
28
|
+
});
|
|
29
|
+
app.delete("/api/browser-session", (c) => {
|
|
30
|
+
if (!browserCookieRequestAllowed(c)) return c.json({ error: "Forbidden" }, 403);
|
|
31
|
+
const principal = getGatewayPrincipal(c);
|
|
32
|
+
if (principal.browserSessionId) {
|
|
33
|
+
deleteBrowserSession(principal.browserSessionId);
|
|
34
|
+
deps.service.realtime.disconnectPrincipal(principal.principalId);
|
|
35
|
+
deps.service.voiceRealtime.disconnectPrincipal(principal.principalId);
|
|
36
|
+
}
|
|
37
|
+
clearBrowserSessionCookie(c);
|
|
38
|
+
c.header("Cache-Control", "no-store");
|
|
39
|
+
return c.json({ ok: true });
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { registerBrowserSessionRoutes };
|