9router 0.3.29 → 0.3.31
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/app/.next/BUILD_ID +1 -1
- package/app/.next/app-path-routes-manifest.json +44 -42
- package/app/.next/build-manifest.json +2 -2
- package/app/.next/prerender-manifest.json +24 -0
- package/app/.next/routes-manifest.json +12 -0
- package/app/.next/server/app/(dashboard)/dashboard/cli-tools/page.js +2 -16
- package/app/.next/server/app/(dashboard)/dashboard/cli-tools/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/combos/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/combos/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/console-log/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/console-log/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/endpoint/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/mitm/page.js +2 -0
- package/app/.next/server/app/(dashboard)/dashboard/mitm/page.js.nft.json +1 -0
- package/app/.next/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -0
- package/app/.next/server/app/(dashboard)/dashboard/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/profile/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/profile/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page.js +2 -2
- package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/new/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/new/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/quota/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/quota/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/translator/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/translator/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/usage/page.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/usage/page.js.nft.json +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/_global-error.html +2 -2
- package/app/.next/server/app/_global-error.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/_not-found.html +1 -1
- package/app/.next/server/app/_not-found.rsc +3 -3
- package/app/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/app/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/app/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/cli-tools/antigravity-mitm/alias/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/cli-tools/antigravity-mitm/route.js +2 -2
- package/app/.next/server/app/api/cli-tools/antigravity-mitm/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/cli-tools/claude-settings/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/cli-tools/codex-settings/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/cli-tools/copilot-settings/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/cli-tools/droid-settings/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/cli-tools/openclaw-settings/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/cli-tools/opencode-settings/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/cloud/auth/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/cloud/credentials/update/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/cloud/model/resolve/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/cloud/models/alias/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/combos/[id]/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/combos/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/keys/[id]/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/keys/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/models/alias/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/models/route.js +1 -1
- package/app/.next/server/app/api/models/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/models/test/route.js +1 -1
- package/app/.next/server/app/api/models/test/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/oauth/[provider]/[action]/route.js +1 -1
- package/app/.next/server/app/api/oauth/[provider]/[action]/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/oauth/cursor/auto-import/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/oauth/cursor/import/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/oauth/iflow/cookie/route.js +1 -0
- package/app/.next/server/app/api/oauth/iflow/cookie/route.js.nft.json +1 -0
- package/app/.next/server/app/api/oauth/iflow/cookie/route_client-reference-manifest.js +1 -0
- package/app/.next/server/app/api/oauth/kiro/auto-import/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/import/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/social-authorize/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/social-exchange/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/pricing/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/provider-nodes/[id]/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/provider-nodes/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/provider-nodes/validate/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/providers/[id]/models/route.js +1 -1
- package/app/.next/server/app/api/providers/[id]/models/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/providers/[id]/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/providers/[id]/test/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/providers/[id]/test-models/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/providers/client/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/providers/route.js +1 -1
- package/app/.next/server/app/api/providers/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/providers/test-batch/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/providers/validate/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/settings/database/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/settings/proxy-test/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/settings/require-login/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/tags/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/translator/console-logs/route.js +1 -1
- package/app/.next/server/app/api/translator/console-logs/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/translator/console-logs/stream/route.js +1 -1
- package/app/.next/server/app/api/translator/console-logs/stream/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/translator/load/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/translator/save/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/translator/send/route.js +1 -1
- package/app/.next/server/app/api/translator/send/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/translator/translate/route.js +1 -1
- package/app/.next/server/app/api/translator/translate/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/tunnel/disable/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/tunnel/enable/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/tunnel/status/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/usage/[connectionId]/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/usage/chart/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/usage/history/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/usage/providers/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/usage/request-details/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/usage/request-logs/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/usage/stats/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/usage/stream/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/v1/api/chat/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/v1/chat/completions/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/v1/embeddings/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/v1/messages/count_tokens/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/v1/messages/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/v1/models/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/v1/responses/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/v1/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/v1beta/models/[...path]/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/v1beta/models/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/version/route.js +1 -1
- package/app/.next/server/app/api/version/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/callback/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/callback.html +1 -1
- package/app/.next/server/app/callback.rsc +3 -3
- package/app/.next/server/app/callback.segments/_full.segment.rsc +3 -3
- package/app/.next/server/app/callback.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/callback.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/callback.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/callback.segments/callback.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/cli-tools.html +1 -1
- package/app/.next/server/app/dashboard/cli-tools.rsc +5 -5
- package/app/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/cli-tools.segments/_full.segment.rsc +5 -5
- package/app/.next/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/cli-tools.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/combos.html +1 -1
- package/app/.next/server/app/dashboard/combos.rsc +5 -5
- package/app/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/combos.segments/_full.segment.rsc +5 -5
- package/app/.next/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/combos.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/combos.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/endpoint.html +1 -1
- package/app/.next/server/app/dashboard/endpoint.rsc +5 -5
- package/app/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/endpoint.segments/_full.segment.rsc +5 -5
- package/app/.next/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/endpoint.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/endpoint.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/mitm.html +1 -0
- package/app/.next/server/app/dashboard/mitm.meta +17 -0
- package/app/.next/server/app/dashboard/mitm.rsc +20 -0
- package/app/.next/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +6 -0
- package/app/.next/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +4 -0
- package/app/.next/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +4 -0
- package/app/.next/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +6 -0
- package/app/.next/server/app/dashboard/mitm.segments/_full.segment.rsc +20 -0
- package/app/.next/server/app/dashboard/mitm.segments/_head.segment.rsc +6 -0
- package/app/.next/server/app/dashboard/mitm.segments/_index.segment.rsc +7 -0
- package/app/.next/server/app/dashboard/mitm.segments/_tree.segment.rsc +5 -0
- package/app/.next/server/app/dashboard/profile.html +1 -1
- package/app/.next/server/app/dashboard/profile.rsc +5 -5
- package/app/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/profile.segments/_full.segment.rsc +5 -5
- package/app/.next/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/profile.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/profile.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/providers/new.html +1 -1
- package/app/.next/server/app/dashboard/providers/new.rsc +5 -5
- package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/providers/new.segments/_full.segment.rsc +5 -5
- package/app/.next/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers/new.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/providers/new.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/providers.html +1 -1
- package/app/.next/server/app/dashboard/providers.rsc +5 -5
- package/app/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/providers.segments/_full.segment.rsc +5 -5
- package/app/.next/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/providers.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/providers.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/quota.html +2 -1
- package/app/.next/server/app/dashboard/quota.rsc +6 -6
- package/app/.next/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/quota.segments/_full.segment.rsc +6 -6
- package/app/.next/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/quota.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/quota.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.html +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.rsc +3 -3
- package/app/.next/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/translator.html +1 -1
- package/app/.next/server/app/dashboard/translator.rsc +5 -5
- package/app/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/translator.segments/_full.segment.rsc +5 -5
- package/app/.next/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/translator.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/translator.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/usage.html +1 -1
- package/app/.next/server/app/dashboard/usage.rsc +5 -5
- package/app/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard/usage.segments/_full.segment.rsc +5 -5
- package/app/.next/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard/usage.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/dashboard/usage.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/dashboard.html +1 -1
- package/app/.next/server/app/dashboard.rsc +5 -5
- package/app/.next/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/app/.next/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/app/.next/server/app/dashboard.segments/_full.segment.rsc +5 -5
- package/app/.next/server/app/dashboard.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/dashboard.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/dashboard.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/index.html +1 -1
- package/app/.next/server/app/index.rsc +3 -3
- package/app/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/app/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/landing/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/landing.html +1 -1
- package/app/.next/server/app/landing.rsc +3 -3
- package/app/.next/server/app/landing.segments/_full.segment.rsc +3 -3
- package/app/.next/server/app/landing.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/landing.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/landing.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/landing.segments/landing/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/landing.segments/landing.segment.rsc +1 -1
- package/app/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/login.html +1 -1
- package/app/.next/server/app/login.rsc +4 -4
- package/app/.next/server/app/login.segments/_full.segment.rsc +4 -4
- package/app/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/app/.next/server/app/login.segments/_index.segment.rsc +3 -3
- package/app/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/app/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -1
- package/app/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app-paths-manifest.json +44 -42
- package/app/.next/server/chunks/1238.js +1 -1
- package/app/.next/server/chunks/2280.js +1 -1
- package/app/.next/server/chunks/3832.js +1 -1
- package/app/.next/server/chunks/412.js +2 -2
- package/app/.next/server/chunks/4841.js +1 -1
- package/app/.next/server/chunks/6182.js +16 -10
- package/app/.next/server/chunks/6384.js +1 -0
- package/app/.next/server/chunks/649.js +15 -0
- package/app/.next/server/chunks/7647.js +1 -1
- package/app/.next/server/chunks/8590.js +1 -1
- package/app/.next/server/chunks/8756.js +1 -1
- package/app/.next/server/pages/404.html +1 -1
- package/app/.next/server/pages/500.html +2 -2
- package/app/.next/server/server-reference-manifest.js +1 -1
- package/app/.next/server/server-reference-manifest.json +1 -1
- package/app/.next/static/24vSaT3cvf72GHKm3J7Mb/_buildManifest.js +1 -0
- package/app/.next/static/chunks/4495-97a066cea645caef.js +1 -0
- package/app/.next/static/chunks/5497-55c93d32928bd3b6.js +7 -0
- package/app/.next/static/chunks/9242-572cb7c592af9377.js +15 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/cli-tools/page-8caef34f3e144a20.js +1 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/mitm/page-7f5a8700b96d31b1.js +1 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/providers/[id]/page-d3eea801999e8eaf.js +1 -0
- package/app/.next/static/chunks/app/(dashboard)/layout-e85ef8386b3bd547.js +1 -0
- package/app/.next/static/chunks/app/_global-error/page-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/auth/login/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/auth/logout/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/alias/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/claude-settings/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/codex-settings/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/copilot-settings/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/droid-settings/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/openclaw-settings/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/opencode-settings/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/cloud/auth/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/cloud/credentials/update/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/cloud/model/resolve/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/cloud/models/alias/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/combos/[id]/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/combos/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/init/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/keys/[id]/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/keys/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/models/alias/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/models/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/models/test/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/[provider]/[action]/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/cursor/auto-import/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/cursor/import/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/iflow/cookie/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/auto-import/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/import/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/social-authorize/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/social-exchange/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/pricing/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/provider-nodes/[id]/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/provider-nodes/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/provider-nodes/validate/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/providers/[id]/models/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/providers/[id]/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/providers/[id]/test/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/providers/[id]/test-models/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/providers/client/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/providers/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/providers/test-batch/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/providers/validate/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/settings/database/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/settings/proxy-test/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/settings/require-login/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/settings/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/shutdown/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/tags/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/translator/console-logs/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/translator/console-logs/stream/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/translator/load/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/translator/save/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/translator/send/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/translator/translate/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/tunnel/disable/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/tunnel/enable/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/tunnel/status/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/usage/[connectionId]/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/usage/chart/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/usage/history/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/usage/providers/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/usage/request-details/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/usage/request-logs/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/usage/stats/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/usage/stream/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/v1/api/chat/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/v1/chat/completions/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/v1/embeddings/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/v1/messages/count_tokens/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/v1/messages/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/v1/models/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/v1/responses/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/v1/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/v1beta/models/[...path]/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/v1beta/models/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/api/version/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/{layout-75a17c7e6aea5a13.js → layout-8a56242f992801a8.js} +1 -1
- package/app/.next/static/chunks/app/manifest.webmanifest/route-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/app/page-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/next/dist/client/components/builtin/app-error-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/next/dist/client/components/builtin/forbidden-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/next/dist/client/components/builtin/not-found-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/chunks/next/dist/client/components/builtin/unauthorized-3afc9e982dbedc92.js +1 -0
- package/app/.next/static/css/fb5ab131d55b40e1.css +3 -0
- package/app/package.json +1 -1
- package/app/src/mitm/cert/generate.js +16 -5
- package/app/src/mitm/cert/install.js +7 -3
- package/app/src/mitm/dns/dnsConfig.js +79 -66
- package/app/src/mitm/manager.js +111 -177
- package/app/src/mitm/server.js +37 -44
- package/hooks/postinstall.js +73 -0
- package/package.json +2 -1
- package/app/.next/server/chunks/1164.js +0 -1
- package/app/.next/static/3zOZ19iwThxWJSFLWgyzs/_buildManifest.js +0 -1
- package/app/.next/static/chunks/4495-bc9f104bf7b22419.js +0 -1
- package/app/.next/static/chunks/5497-cb22fa6d2bb73c4a.js +0 -7
- package/app/.next/static/chunks/app/(dashboard)/dashboard/cli-tools/page-2fbd60d069c77b8f.js +0 -15
- package/app/.next/static/chunks/app/(dashboard)/dashboard/providers/[id]/page-96232c1eaa074aae.js +0 -1
- package/app/.next/static/chunks/app/(dashboard)/layout-626a5cf4ccea1e63.js +0 -1
- package/app/.next/static/chunks/app/_global-error/page-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/auth/login/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/auth/logout/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/alias/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/claude-settings/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/codex-settings/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/copilot-settings/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/droid-settings/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/openclaw-settings/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/opencode-settings/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/cloud/auth/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/cloud/credentials/update/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/cloud/model/resolve/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/cloud/models/alias/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/combos/[id]/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/combos/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/init/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/keys/[id]/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/keys/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/models/alias/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/models/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/models/test/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/[provider]/[action]/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/cursor/auto-import/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/cursor/import/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/auto-import/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/import/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/social-authorize/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/social-exchange/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/pricing/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/provider-nodes/[id]/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/provider-nodes/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/provider-nodes/validate/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/models/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/test/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/test-models/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/providers/client/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/providers/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/providers/test-batch/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/providers/validate/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/settings/database/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/settings/proxy-test/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/settings/require-login/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/settings/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/shutdown/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/tags/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/translator/console-logs/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/translator/console-logs/stream/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/translator/load/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/translator/save/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/translator/send/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/translator/translate/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/tunnel/disable/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/tunnel/enable/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/tunnel/status/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/usage/[connectionId]/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/usage/chart/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/usage/history/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/usage/providers/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/usage/request-details/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/usage/request-logs/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/usage/stats/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/usage/stream/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/v1/api/chat/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/v1/chat/completions/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/v1/embeddings/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/v1/messages/count_tokens/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/v1/messages/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/v1/models/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/v1/responses/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/v1/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/v1beta/models/[...path]/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/v1beta/models/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/api/version/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/manifest.webmanifest/route-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/app/page-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/app-error-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/forbidden-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/not-found-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/unauthorized-6094e45f32dd5e2c.js +0 -1
- package/app/.next/static/css/62123907b7f6e3ce.css +0 -3
- /package/app/.next/static/{3zOZ19iwThxWJSFLWgyzs → 24vSaT3cvf72GHKm3J7Mb}/_ssgManifest.js +0 -0
package/app/src/mitm/manager.js
CHANGED
|
@@ -5,7 +5,7 @@ const os = require("os");
|
|
|
5
5
|
const net = require("net");
|
|
6
6
|
const https = require("https");
|
|
7
7
|
const crypto = require("crypto");
|
|
8
|
-
const { addDNSEntry, removeDNSEntry,
|
|
8
|
+
const { addDNSEntry, removeDNSEntry, removeAllDNSEntries, checkAllDNSStatus } = require("./dns/dnsConfig");
|
|
9
9
|
|
|
10
10
|
const IS_WIN = process.platform === "win32";
|
|
11
11
|
const { generateCert } = require("./cert/generate");
|
|
@@ -13,45 +13,27 @@ const { installCert } = require("./cert/install");
|
|
|
13
13
|
const { MITM_DIR } = require("./paths");
|
|
14
14
|
|
|
15
15
|
const MITM_PORT = 443;
|
|
16
|
-
// Windows: node listens on 8443, netsh portproxy forwards 443→8443
|
|
17
16
|
const MITM_WIN_NODE_PORT = 8443;
|
|
18
17
|
const PID_FILE = path.join(MITM_DIR, ".mitm.pid");
|
|
19
18
|
|
|
20
|
-
// Resolve server.js path robustly:
|
|
21
|
-
// __dirname is unreliable inside Next.js bundles, so we use DATA_DIR env or
|
|
22
|
-
// fall back to locating the file relative to the app's source root.
|
|
23
19
|
function resolveServerPath() {
|
|
24
|
-
// 1. Explicit override via env (useful for packaged/standalone builds)
|
|
25
20
|
if (process.env.MITM_SERVER_PATH) return process.env.MITM_SERVER_PATH;
|
|
26
|
-
|
|
27
|
-
// 2. Try sibling of this file (works in dev where __dirname is real)
|
|
28
21
|
const sibling = path.join(__dirname, "server.js");
|
|
29
22
|
if (fs.existsSync(sibling)) return sibling;
|
|
30
|
-
|
|
31
|
-
// 3. Fallback: resolve from process.cwd() → src/mitm/server.js
|
|
32
23
|
const fromCwd = path.join(process.cwd(), "src", "mitm", "server.js");
|
|
33
24
|
if (fs.existsSync(fromCwd)) return fromCwd;
|
|
34
|
-
|
|
35
|
-
// 4. Standalone build: app root is parent of .next
|
|
36
25
|
const fromNext = path.join(process.cwd(), "..", "src", "mitm", "server.js");
|
|
37
26
|
if (fs.existsSync(fromNext)) return fromNext;
|
|
38
|
-
|
|
39
|
-
return fromCwd; // best guess
|
|
27
|
+
return fromCwd;
|
|
40
28
|
}
|
|
41
29
|
|
|
42
30
|
const SERVER_PATH = resolveServerPath();
|
|
43
|
-
|
|
44
31
|
const ENCRYPT_ALGO = "aes-256-gcm";
|
|
45
32
|
const ENCRYPT_SALT = "9router-mitm-pwd";
|
|
46
33
|
|
|
47
|
-
/**
|
|
48
|
-
* Get process name using port 443
|
|
49
|
-
* @returns {string|null} Process name or null if not found
|
|
50
|
-
*/
|
|
51
34
|
function getProcessUsingPort443() {
|
|
52
35
|
try {
|
|
53
36
|
if (IS_WIN) {
|
|
54
|
-
// Use PowerShell for precise port 443 owner lookup
|
|
55
37
|
const psCmd = `powershell -NonInteractive -WindowStyle Hidden -Command ` +
|
|
56
38
|
`"$c = Get-NetTCPConnection -LocalPort 443 -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1; if ($c) { $c.OwningProcess } else { 0 }"`;
|
|
57
39
|
const pidStr = execSync(psCmd, { encoding: "utf8", windowsHide: true }).trim();
|
|
@@ -62,31 +44,22 @@ function getProcessUsingPort443() {
|
|
|
62
44
|
if (processMatch) return processMatch[1].replace(".exe", "");
|
|
63
45
|
}
|
|
64
46
|
} else {
|
|
65
|
-
// macOS/Linux: use lsof
|
|
66
47
|
const result = execSync("lsof -i :443", { encoding: "utf8" });
|
|
67
48
|
const lines = result.trim().split("\n");
|
|
68
|
-
if (lines.length > 1)
|
|
69
|
-
const processName = lines[1].split(/\s+/)[0];
|
|
70
|
-
return processName;
|
|
71
|
-
}
|
|
49
|
+
if (lines.length > 1) return lines[1].split(/\s+/)[0];
|
|
72
50
|
}
|
|
73
|
-
} catch
|
|
51
|
+
} catch {
|
|
74
52
|
return null;
|
|
75
53
|
}
|
|
76
54
|
return null;
|
|
77
55
|
}
|
|
78
56
|
|
|
79
|
-
// Store server process in-memory
|
|
80
57
|
let serverProcess = null;
|
|
81
58
|
let serverPid = null;
|
|
82
59
|
|
|
83
|
-
// Persist sudo password across Next.js hot reloads (in-memory only)
|
|
84
60
|
function getCachedPassword() { return globalThis.__mitmSudoPassword || null; }
|
|
85
61
|
function setCachedPassword(pwd) { globalThis.__mitmSudoPassword = pwd; }
|
|
86
62
|
|
|
87
|
-
// Check if a PID is alive
|
|
88
|
-
// EACCES = process exists but no permission (e.g. root process) → still alive
|
|
89
|
-
// ESRCH = process does not exist → dead
|
|
90
63
|
function isProcessAlive(pid) {
|
|
91
64
|
try {
|
|
92
65
|
process.kill(pid, 0);
|
|
@@ -96,51 +69,41 @@ function isProcessAlive(pid) {
|
|
|
96
69
|
}
|
|
97
70
|
}
|
|
98
71
|
|
|
99
|
-
// Cross-platform process kill
|
|
100
72
|
function killProcess(pid, force = false, sudoPassword = null) {
|
|
101
73
|
if (IS_WIN) {
|
|
102
74
|
const flag = force ? "/F " : "";
|
|
103
75
|
exec(`taskkill ${flag}/PID ${pid}`, () => { });
|
|
104
76
|
} else {
|
|
105
77
|
const sig = force ? "SIGKILL" : "SIGTERM";
|
|
106
|
-
// Kill entire process group (sudo parent + child node)
|
|
107
78
|
const cmd = `pkill -${sig} -P ${pid} 2>/dev/null; kill -${sig} ${pid} 2>/dev/null`;
|
|
108
79
|
if (sudoPassword) {
|
|
109
80
|
const { execWithPassword } = require("./dns/dnsConfig");
|
|
110
|
-
execWithPassword(cmd, sudoPassword).catch(() => {
|
|
111
|
-
// Fallback without sudo
|
|
112
|
-
exec(cmd, () => { });
|
|
113
|
-
});
|
|
81
|
+
execWithPassword(cmd, sudoPassword).catch(() => exec(cmd, () => { }));
|
|
114
82
|
} else {
|
|
115
83
|
exec(cmd, () => { });
|
|
116
84
|
}
|
|
117
85
|
}
|
|
118
86
|
}
|
|
119
87
|
|
|
120
|
-
/** Derive a 32-byte encryption key from machineId */
|
|
121
88
|
function deriveKey() {
|
|
122
89
|
try {
|
|
123
90
|
const { machineIdSync } = require("node-machine-id");
|
|
124
91
|
const raw = machineIdSync();
|
|
125
92
|
return crypto.createHash("sha256").update(raw + ENCRYPT_SALT).digest();
|
|
126
93
|
} catch {
|
|
127
|
-
// Fallback: fixed key derived from salt (less secure but functional)
|
|
128
94
|
return crypto.createHash("sha256").update(ENCRYPT_SALT).digest();
|
|
129
95
|
}
|
|
130
96
|
}
|
|
131
97
|
|
|
132
|
-
/** Encrypt sudo password with AES-256-GCM */
|
|
133
98
|
function encryptPassword(plaintext) {
|
|
134
99
|
const key = deriveKey();
|
|
135
100
|
const iv = crypto.randomBytes(12);
|
|
136
101
|
const cipher = crypto.createCipheriv(ENCRYPT_ALGO, key, iv);
|
|
137
102
|
const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
138
103
|
const tag = cipher.getAuthTag();
|
|
139
|
-
// Store as hex: iv:tag:ciphertext
|
|
140
104
|
return `${iv.toString("hex")}:${tag.toString("hex")}:${encrypted.toString("hex")}`;
|
|
141
105
|
}
|
|
142
106
|
|
|
143
|
-
/** Decrypt sudo password */
|
|
144
107
|
function decryptPassword(stored) {
|
|
145
108
|
try {
|
|
146
109
|
const [ivHex, tagHex, dataHex] = stored.split(":");
|
|
@@ -154,23 +117,16 @@ function decryptPassword(stored) {
|
|
|
154
117
|
}
|
|
155
118
|
}
|
|
156
119
|
|
|
157
|
-
// DB hooks — injected from ESM context (initializeApp / route handlers)
|
|
158
|
-
// to avoid webpack bundling issues with dynamic imports in CJS modules.
|
|
159
120
|
let _getSettings = null;
|
|
160
121
|
let _updateSettings = null;
|
|
161
122
|
|
|
162
|
-
/** Called once from ESM context to inject DB access functions */
|
|
163
123
|
function initDbHooks(getSettingsFn, updateSettingsFn) {
|
|
164
124
|
_getSettings = getSettingsFn;
|
|
165
125
|
_updateSettings = updateSettingsFn;
|
|
166
126
|
}
|
|
167
127
|
|
|
168
|
-
/** Save encrypted sudo password + mitmEnabled to db */
|
|
169
128
|
async function saveMitmSettings(enabled, password) {
|
|
170
|
-
if (!_updateSettings)
|
|
171
|
-
console.log("[MITM] DB hooks not initialized, skipping save");
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
129
|
+
if (!_updateSettings) return;
|
|
174
130
|
try {
|
|
175
131
|
const updates = { mitmEnabled: enabled };
|
|
176
132
|
if (password) updates.mitmSudoEncrypted = encryptPassword(password);
|
|
@@ -180,7 +136,6 @@ async function saveMitmSettings(enabled, password) {
|
|
|
180
136
|
}
|
|
181
137
|
}
|
|
182
138
|
|
|
183
|
-
/** Load and decrypt sudo password from db */
|
|
184
139
|
async function loadEncryptedPassword() {
|
|
185
140
|
if (!_getSettings) return null;
|
|
186
141
|
try {
|
|
@@ -192,37 +147,27 @@ async function loadEncryptedPassword() {
|
|
|
192
147
|
}
|
|
193
148
|
}
|
|
194
149
|
|
|
195
|
-
/**
|
|
196
|
-
* Check if port 443 is available
|
|
197
|
-
* Returns: "free" | "in-use" | "no-permission"
|
|
198
|
-
*/
|
|
199
150
|
function checkPort443Free() {
|
|
200
151
|
return new Promise((resolve) => {
|
|
201
152
|
const tester = net.createServer();
|
|
202
153
|
tester.once("error", (err) => {
|
|
203
154
|
if (err.code === "EADDRINUSE") resolve("in-use");
|
|
204
|
-
else resolve("no-permission");
|
|
155
|
+
else resolve("no-permission");
|
|
205
156
|
});
|
|
206
157
|
tester.once("listening", () => { tester.close(() => resolve("free")); });
|
|
207
158
|
tester.listen(MITM_PORT, "127.0.0.1");
|
|
208
159
|
});
|
|
209
160
|
}
|
|
210
161
|
|
|
211
|
-
/**
|
|
212
|
-
* Get PID and process name currently holding port 443
|
|
213
|
-
* Returns { pid, name } or null if port is free / cannot determine
|
|
214
|
-
*/
|
|
215
162
|
function getPort443Owner(sudoPassword) {
|
|
216
163
|
return new Promise((resolve) => {
|
|
217
164
|
if (IS_WIN) {
|
|
218
|
-
// Use PowerShell Get-NetTCPConnection for precise port 443 owner lookup
|
|
219
165
|
const psCmd = `powershell -NonInteractive -WindowStyle Hidden -Command "` +
|
|
220
166
|
`$c = Get-NetTCPConnection -LocalPort 443 -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1; ` +
|
|
221
167
|
`if ($c) { $c.OwningProcess } else { 0 }"`;
|
|
222
168
|
exec(psCmd, { windowsHide: true }, (err, stdout) => {
|
|
223
169
|
if (err) return resolve(null);
|
|
224
170
|
const pid = parseInt(stdout.trim(), 10);
|
|
225
|
-
// 0 = no owner, <=4 = System/Idle — not real port owners
|
|
226
171
|
if (!pid || pid <= 4) return resolve(null);
|
|
227
172
|
exec(`tasklist /FI "PID eq ${pid}" /FO CSV /NH`, { windowsHide: true }, (e2, out2) => {
|
|
228
173
|
const m = out2?.match(/"([^"]+)"/);
|
|
@@ -230,7 +175,6 @@ function getPort443Owner(sudoPassword) {
|
|
|
230
175
|
});
|
|
231
176
|
});
|
|
232
177
|
} else {
|
|
233
|
-
// Use ps to find node process running server.js (no sudo needed)
|
|
234
178
|
exec(`ps aux | grep "[s]erver.js"`, (err, stdout) => {
|
|
235
179
|
if (!stdout?.trim()) return resolve(null);
|
|
236
180
|
for (const line of stdout.split("\n")) {
|
|
@@ -244,19 +188,12 @@ function getPort443Owner(sudoPassword) {
|
|
|
244
188
|
});
|
|
245
189
|
}
|
|
246
190
|
|
|
247
|
-
/**
|
|
248
|
-
* Kill any leftover MITM server process (from previous failed start)
|
|
249
|
-
* Uses sudo to kill the node process that was spawned with sudo
|
|
250
|
-
*/
|
|
251
191
|
async function killLeftoverMitm(sudoPassword) {
|
|
252
|
-
// Kill in-memory process if still alive
|
|
253
192
|
if (serverProcess && !serverProcess.killed) {
|
|
254
193
|
try { serverProcess.kill("SIGKILL"); } catch { /* ignore */ }
|
|
255
194
|
serverProcess = null;
|
|
256
195
|
serverPid = null;
|
|
257
196
|
}
|
|
258
|
-
|
|
259
|
-
// Kill from PID file
|
|
260
197
|
try {
|
|
261
198
|
if (fs.existsSync(PID_FILE)) {
|
|
262
199
|
const savedPid = parseInt(fs.readFileSync(PID_FILE, "utf-8").trim(), 10);
|
|
@@ -267,8 +204,6 @@ async function killLeftoverMitm(sudoPassword) {
|
|
|
267
204
|
fs.unlinkSync(PID_FILE);
|
|
268
205
|
}
|
|
269
206
|
} catch { /* ignore */ }
|
|
270
|
-
|
|
271
|
-
// Also kill any node process running server.js via sudo (belt-and-suspenders)
|
|
272
207
|
if (!IS_WIN && SERVER_PATH) {
|
|
273
208
|
try {
|
|
274
209
|
const escaped = SERVER_PATH.replace(/'/g, "'\\''");
|
|
@@ -283,10 +218,6 @@ async function killLeftoverMitm(sudoPassword) {
|
|
|
283
218
|
}
|
|
284
219
|
}
|
|
285
220
|
|
|
286
|
-
/**
|
|
287
|
-
* Poll MITM health endpoint until server is up or timeout.
|
|
288
|
-
* Returns { ok, pid } on success, null on timeout.
|
|
289
|
-
*/
|
|
290
221
|
function pollMitmHealth(timeoutMs, port = MITM_PORT) {
|
|
291
222
|
return new Promise((resolve) => {
|
|
292
223
|
const deadline = Date.now() + timeoutMs;
|
|
@@ -315,7 +246,38 @@ function pollMitmHealth(timeoutMs, port = MITM_PORT) {
|
|
|
315
246
|
}
|
|
316
247
|
|
|
317
248
|
/**
|
|
318
|
-
*
|
|
249
|
+
* Check which tools have their domains covered by the installed cert SAN.
|
|
250
|
+
* Uses built-in crypto.X509Certificate (Node 15.6+).
|
|
251
|
+
*/
|
|
252
|
+
function getCertToolCoverage(certPath) {
|
|
253
|
+
try {
|
|
254
|
+
const pem = fs.readFileSync(certPath, "utf8");
|
|
255
|
+
const cert = new crypto.X509Certificate(pem);
|
|
256
|
+
const san = cert.subjectAltName || "";
|
|
257
|
+
// Extract all DNS SANs
|
|
258
|
+
const sans = san.split(",").map(s => s.trim().replace(/^DNS:/, ""));
|
|
259
|
+
const matchesSan = (domain) => sans.some(s => {
|
|
260
|
+
if (s === domain) return true;
|
|
261
|
+
// Wildcard: *.foo.com matches bar.foo.com
|
|
262
|
+
if (s.startsWith("*.")) {
|
|
263
|
+
const suffix = s.slice(1); // .foo.com
|
|
264
|
+
return domain.endsWith(suffix) && !domain.slice(0, -suffix.length).includes(".");
|
|
265
|
+
}
|
|
266
|
+
return false;
|
|
267
|
+
});
|
|
268
|
+
const { TOOL_HOSTS } = require("./dns/dnsConfig");
|
|
269
|
+
const coverage = {};
|
|
270
|
+
for (const [tool, hosts] of Object.entries(TOOL_HOSTS)) {
|
|
271
|
+
coverage[tool] = hosts.every(matchesSan);
|
|
272
|
+
}
|
|
273
|
+
return coverage;
|
|
274
|
+
} catch {
|
|
275
|
+
return {};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Get full MITM status including per-tool DNS status
|
|
319
281
|
*/
|
|
320
282
|
async function getMitmStatus() {
|
|
321
283
|
let running = serverProcess !== null && !serverProcess.killed;
|
|
@@ -332,30 +294,26 @@ async function getMitmStatus() {
|
|
|
332
294
|
fs.unlinkSync(PID_FILE);
|
|
333
295
|
}
|
|
334
296
|
}
|
|
335
|
-
} catch {
|
|
336
|
-
// Ignore
|
|
337
|
-
}
|
|
297
|
+
} catch { /* ignore */ }
|
|
338
298
|
}
|
|
339
299
|
|
|
340
|
-
const
|
|
341
|
-
const
|
|
300
|
+
const dnsStatus = checkAllDNSStatus();
|
|
301
|
+
const certPath = path.join(MITM_DIR, "server.crt");
|
|
302
|
+
const certExists = fs.existsSync(certPath);
|
|
303
|
+
const certCoversTools = certExists ? getCertToolCoverage(certPath) : {};
|
|
342
304
|
|
|
343
|
-
return { running, pid,
|
|
305
|
+
return { running, pid, certExists, dnsStatus, certCoversTools };
|
|
344
306
|
}
|
|
345
307
|
|
|
346
308
|
/**
|
|
347
|
-
* Start MITM
|
|
348
|
-
* @param {string} apiKey - 9Router API key
|
|
349
|
-
* @param {string} sudoPassword - Sudo password for DNS/cert operations
|
|
309
|
+
* Start MITM server only (cert + server, no DNS)
|
|
350
310
|
*/
|
|
351
|
-
async function
|
|
352
|
-
// Check orphan process from PID file before spawning
|
|
311
|
+
async function startServer(apiKey, sudoPassword) {
|
|
353
312
|
if (!serverProcess || serverProcess.killed) {
|
|
354
313
|
try {
|
|
355
314
|
if (fs.existsSync(PID_FILE)) {
|
|
356
315
|
const savedPid = parseInt(fs.readFileSync(PID_FILE, "utf-8").trim(), 10);
|
|
357
316
|
if (savedPid && isProcessAlive(savedPid)) {
|
|
358
|
-
// Orphan MITM process still alive — reuse it
|
|
359
317
|
serverPid = savedPid;
|
|
360
318
|
console.log(`[MITM] Reusing existing process PID ${savedPid}`);
|
|
361
319
|
await saveMitmSettings(true, sudoPassword);
|
|
@@ -365,25 +323,20 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
365
323
|
fs.unlinkSync(PID_FILE);
|
|
366
324
|
}
|
|
367
325
|
}
|
|
368
|
-
} catch {
|
|
369
|
-
// Ignore stale PID file errors
|
|
370
|
-
}
|
|
326
|
+
} catch { /* ignore */ }
|
|
371
327
|
}
|
|
372
328
|
|
|
373
329
|
if (serverProcess && !serverProcess.killed) {
|
|
374
|
-
throw new Error("MITM
|
|
330
|
+
throw new Error("MITM server is already running");
|
|
375
331
|
}
|
|
376
332
|
|
|
377
|
-
// Kill any leftover MITM server from a previous failed start attempt
|
|
378
333
|
await killLeftoverMitm(sudoPassword);
|
|
379
334
|
|
|
380
335
|
if (!IS_WIN) {
|
|
381
|
-
// Check port 443 availability — Windows handles this inside elevated script
|
|
382
336
|
const portStatus = await checkPort443Free();
|
|
383
337
|
if (portStatus === "in-use" || portStatus === "no-permission") {
|
|
384
338
|
const owner = await getPort443Owner(sudoPassword);
|
|
385
339
|
if (owner && owner.name === "node") {
|
|
386
|
-
// Orphan MITM node process — kill it and continue
|
|
387
340
|
console.log(`[MITM] Killing orphan node process on port 443 (PID ${owner.pid})...`);
|
|
388
341
|
try {
|
|
389
342
|
const { execWithPassword } = require("./dns/dnsConfig");
|
|
@@ -394,76 +347,61 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
394
347
|
const shortName = owner.name.includes("/")
|
|
395
348
|
? owner.name.split("/").filter(Boolean).pop()
|
|
396
349
|
: owner.name;
|
|
397
|
-
throw new Error(
|
|
398
|
-
`Port 443 is already in use by "${shortName}" (PID ${owner.pid}). Stop that process first, then retry.`
|
|
399
|
-
);
|
|
350
|
+
throw new Error(`Port 443 is already in use by "${shortName}" (PID ${owner.pid}). Stop that process first.`);
|
|
400
351
|
}
|
|
401
352
|
}
|
|
402
353
|
}
|
|
403
354
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
// Step 1: Generate SSL certificate if not exists
|
|
355
|
+
// Step 1: Generate SSL certificate if not exists or missing domain coverage
|
|
407
356
|
const certPath = path.join(MITM_DIR, "server.crt");
|
|
357
|
+
const keyPath = path.join(MITM_DIR, "server.key");
|
|
358
|
+
let needsRegenerate = false;
|
|
359
|
+
|
|
408
360
|
if (!fs.existsSync(certPath)) {
|
|
409
361
|
console.log("[MITM] Generating SSL certificate...");
|
|
410
|
-
|
|
362
|
+
needsRegenerate = true;
|
|
363
|
+
} else {
|
|
364
|
+
// Check if cert covers all tool domains
|
|
365
|
+
const coverage = getCertToolCoverage(certPath);
|
|
366
|
+
const { TOOL_HOSTS } = require("./dns/dnsConfig");
|
|
367
|
+
const allCovered = Object.keys(TOOL_HOSTS).every(tool => coverage[tool] === true);
|
|
368
|
+
if (!allCovered) {
|
|
369
|
+
console.log("[MITM] Certificate missing domain coverage — regenerating...");
|
|
370
|
+
needsRegenerate = true;
|
|
371
|
+
try {
|
|
372
|
+
fs.unlinkSync(certPath);
|
|
373
|
+
if (fs.existsSync(keyPath)) fs.unlinkSync(keyPath);
|
|
374
|
+
} catch { /* ignore */ }
|
|
375
|
+
}
|
|
411
376
|
}
|
|
412
377
|
|
|
413
|
-
|
|
414
|
-
|
|
378
|
+
if (needsRegenerate) {
|
|
379
|
+
await generateCert();
|
|
380
|
+
}
|
|
415
381
|
|
|
382
|
+
// Step 2: Install cert + spawn server
|
|
416
383
|
if (IS_WIN) {
|
|
417
|
-
// Windows: single UAC via VBScript → elevated PowerShell script that:
|
|
418
|
-
// 1. Installs SSL cert 2. Adds DNS entries 3. Starts node server.js (elevated → can bind 443) 4. Writes flag
|
|
419
|
-
// Node polls flag file to know when server is ready, then health-checks port 443
|
|
420
384
|
const hostsFile = path.join(process.env.SystemRoot || "C:\\Windows", "System32", "drivers", "etc", "hosts");
|
|
421
|
-
const TARGET_HOSTS_WIN = ["daily-cloudcode-pa.googleapis.com", "cloudcode-pa.googleapis.com"];
|
|
422
|
-
|
|
423
|
-
// Use Chr(34) in VBScript for quotes — avoid escaping issues
|
|
424
385
|
const flagFile = path.join(os.tmpdir(), `mitm_ready_${Date.now()}.flag`);
|
|
425
|
-
|
|
426
|
-
// PowerShell uses single-quoted strings — escape single quotes only
|
|
427
386
|
const psSQ = (s) => s.replace(/'/g, "''");
|
|
428
387
|
const certPs = psSQ(certPath);
|
|
429
|
-
const hostsPs = psSQ(hostsFile);
|
|
430
388
|
const nodePs = psSQ(process.execPath);
|
|
431
389
|
const serverPs = psSQ(SERVER_PATH);
|
|
432
390
|
const flagPs = psSQ(flagFile);
|
|
433
391
|
|
|
434
|
-
const dnsLines = TARGET_HOSTS_WIN.map(h =>
|
|
435
|
-
`$hc = Get-Content -Path '${hostsPs}' -Raw -ErrorAction SilentlyContinue\n` +
|
|
436
|
-
`if ($hc -notmatch [regex]::Escape('${h}')) { Add-Content -Path '${hostsPs}' -Value '127.0.0.1 ${h}' -Encoding UTF8 }`
|
|
437
|
-
).join("\n");
|
|
438
|
-
|
|
439
392
|
const psScript = [
|
|
440
|
-
`# 0. Kill any orphan node process on port 443`,
|
|
441
393
|
`$conn = Get-NetTCPConnection -LocalPort 443 -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1`,
|
|
442
394
|
`if ($conn -and $conn.OwningProcess -gt 4) { Stop-Process -Id $conn.OwningProcess -Force -ErrorAction SilentlyContinue }`,
|
|
443
395
|
`Start-Sleep -Milliseconds 500`,
|
|
444
|
-
``,
|
|
445
|
-
`# 1. Install SSL cert to Windows Root store (always run to ensure trust)`,
|
|
446
396
|
`& certutil -addstore Root '${certPs}' | Out-Null`,
|
|
447
|
-
``,
|
|
448
|
-
`# 2. Add DNS entries to hosts file`,
|
|
449
|
-
dnsLines,
|
|
450
|
-
`& ipconfig /flushdns | Out-Null`,
|
|
451
|
-
``,
|
|
452
|
-
`# 3. Start node MITM server elevated (required to bind port 443)`,
|
|
453
|
-
`# Use cmd /c to pass env vars inline — Start-Process does not inherit current env`,
|
|
454
397
|
`$nodeCmd = 'set ROUTER_API_KEY=${psSQ(apiKey)}&& set NODE_ENV=production&& "${nodePs}" "${serverPs}"'`,
|
|
455
398
|
`Start-Process cmd -ArgumentList '/c',$nodeCmd -WindowStyle Hidden`,
|
|
456
|
-
``,
|
|
457
|
-
`# 4. Signal ready`,
|
|
458
399
|
`Start-Sleep -Milliseconds 500`,
|
|
459
400
|
`Set-Content -Path '${flagPs}' -Value 'ready' -Encoding UTF8`,
|
|
460
401
|
].join("\n");
|
|
461
402
|
|
|
462
403
|
const tmpPs1 = path.join(os.tmpdir(), `mitm_start_${Date.now()}.ps1`);
|
|
463
404
|
fs.writeFileSync(tmpPs1, psScript, "utf8");
|
|
464
|
-
|
|
465
|
-
// VBScript uses Shell.Application.ShellExecute to trigger UAC from any context
|
|
466
|
-
// Chr(34) = double-quote, avoids VBScript string escaping issues
|
|
467
405
|
const vbs = [
|
|
468
406
|
`Set oShell = CreateObject("Shell.Application")`,
|
|
469
407
|
`Dim ps`,
|
|
@@ -474,19 +412,16 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
474
412
|
].join("\r\n");
|
|
475
413
|
const tmpVbs = path.join(os.tmpdir(), `mitm_uac_${Date.now()}.vbs`);
|
|
476
414
|
fs.writeFileSync(tmpVbs, vbs, "utf8");
|
|
477
|
-
|
|
478
|
-
// Launch VBScript — shows UAC dialog, user confirms, script runs elevated
|
|
479
415
|
spawn("wscript.exe", [tmpVbs], { stdio: "ignore", windowsHide: false, detached: true }).unref();
|
|
480
416
|
|
|
481
|
-
// Poll flag file — resolves when elevated script completes
|
|
482
417
|
await new Promise((resolve, reject) => {
|
|
483
|
-
const deadline = Date.now() + 90000;
|
|
418
|
+
const deadline = Date.now() + 90000;
|
|
484
419
|
const poll = () => {
|
|
485
420
|
if (fs.existsSync(flagFile)) {
|
|
486
421
|
try { fs.unlinkSync(flagFile); fs.unlinkSync(tmpPs1); fs.unlinkSync(tmpVbs); } catch { /* ignore */ }
|
|
487
422
|
return resolve();
|
|
488
423
|
}
|
|
489
|
-
if (Date.now() > deadline) return reject(new Error("Timed out waiting for UAC confirmation.
|
|
424
|
+
if (Date.now() > deadline) return reject(new Error("Timed out waiting for UAC confirmation."));
|
|
490
425
|
setTimeout(poll, 500);
|
|
491
426
|
};
|
|
492
427
|
poll();
|
|
@@ -494,17 +429,13 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
494
429
|
|
|
495
430
|
if (_updateSettings) await _updateSettings({ mitmCertInstalled: true }).catch(() => { });
|
|
496
431
|
} else {
|
|
497
|
-
// macOS/Linux: Step 1 Cert → Step 2 Server → Step 3 DNS
|
|
498
|
-
// Cert first — no side effects on IDE if it fails
|
|
499
432
|
const { checkCertInstalled } = require("./cert/install");
|
|
500
433
|
const certTrusted = await checkCertInstalled(certPath);
|
|
501
434
|
if (!certTrusted) {
|
|
502
435
|
await installCert(sudoPassword, certPath);
|
|
503
436
|
if (_updateSettings) await _updateSettings({ mitmCertInstalled: true }).catch(() => { });
|
|
504
437
|
}
|
|
505
|
-
steps.cert = true;
|
|
506
438
|
|
|
507
|
-
// Server second — binds port 443 but DNS not yet redirected, IDE unaffected
|
|
508
439
|
const inlineCmd = `ROUTER_API_KEY='${apiKey}' NODE_ENV='production' '${process.execPath}' '${SERVER_PATH}'`;
|
|
509
440
|
serverProcess = spawn(
|
|
510
441
|
"sudo", ["-S", "-E", "sh", "-c", inlineCmd],
|
|
@@ -514,7 +445,6 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
514
445
|
serverProcess.stdin.end();
|
|
515
446
|
}
|
|
516
447
|
|
|
517
|
-
// Windows: node was started by elevated script — PID comes from health check later
|
|
518
448
|
if (!IS_WIN && serverProcess) {
|
|
519
449
|
serverPid = serverProcess.pid;
|
|
520
450
|
fs.writeFileSync(PID_FILE, String(serverPid));
|
|
@@ -527,7 +457,6 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
527
457
|
});
|
|
528
458
|
serverProcess.stderr.on("data", (data) => {
|
|
529
459
|
const msg = data.toString().trim();
|
|
530
|
-
// Capture meaningful errors (ignore sudo password prompt noise)
|
|
531
460
|
if (msg && !msg.includes("Password:") && !msg.includes("password for")) {
|
|
532
461
|
console.error(`[MITM Server Error] ${msg}`);
|
|
533
462
|
startError = msg;
|
|
@@ -541,51 +470,35 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
541
470
|
});
|
|
542
471
|
}
|
|
543
472
|
|
|
544
|
-
// Wait for server to be ready by polling health endpoint on port 443
|
|
545
473
|
const health = await pollMitmHealth(IS_WIN ? 15000 : 8000, MITM_PORT);
|
|
546
|
-
|
|
547
474
|
if (!health) {
|
|
548
475
|
if (IS_WIN) serverProcess = null;
|
|
549
476
|
const processUsing443 = getProcessUsingPort443();
|
|
550
477
|
const portInfo = processUsing443 ? ` Port 443 already in use by ${processUsing443}.` : "";
|
|
551
478
|
const reason = startError || `Check sudo password or port 443 access.${portInfo}`;
|
|
552
|
-
// Server failed — DNS was NOT added yet (new order), so IDE is unaffected
|
|
553
479
|
throw new Error(`MITM server failed to start. ${reason}`);
|
|
554
480
|
}
|
|
555
481
|
|
|
556
|
-
steps.server = true;
|
|
557
|
-
|
|
558
|
-
// On Windows, mark cert as installed after successful start
|
|
559
482
|
if (IS_WIN && _updateSettings) await _updateSettings({ mitmCertInstalled: true }).catch(() => { });
|
|
560
|
-
|
|
561
|
-
// On Windows, use real PID from health check (launcher exits immediately after UAC)
|
|
562
483
|
if (IS_WIN && health.pid) {
|
|
563
484
|
serverPid = health.pid;
|
|
564
485
|
fs.writeFileSync(PID_FILE, String(serverPid));
|
|
565
486
|
}
|
|
566
487
|
|
|
567
|
-
// Step 3: DNS last — only redirect IDE traffic after server is confirmed healthy
|
|
568
|
-
if (!IS_WIN) {
|
|
569
|
-
console.log("[MITM] Adding DNS entry...");
|
|
570
|
-
await addDNSEntry(sudoPassword);
|
|
571
|
-
steps.dns = true;
|
|
572
|
-
} else {
|
|
573
|
-
steps.cert = true;
|
|
574
|
-
steps.server = true;
|
|
575
|
-
steps.dns = true;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
488
|
await saveMitmSettings(true, sudoPassword);
|
|
579
489
|
if (sudoPassword) setCachedPassword(sudoPassword);
|
|
580
490
|
|
|
581
|
-
return { running: true, pid: serverPid
|
|
491
|
+
return { running: true, pid: serverPid };
|
|
582
492
|
}
|
|
583
493
|
|
|
584
494
|
/**
|
|
585
|
-
* Stop MITM
|
|
586
|
-
* @param {string} sudoPassword - Sudo password for DNS cleanup
|
|
495
|
+
* Stop MITM server — removes ALL tool DNS entries first, then kills server
|
|
587
496
|
*/
|
|
588
|
-
async function
|
|
497
|
+
async function stopServer(sudoPassword) {
|
|
498
|
+
// Remove all DNS entries first (before killing server)
|
|
499
|
+
console.log("[MITM] Removing all DNS entries before stopping server...");
|
|
500
|
+
await removeAllDNSEntries(sudoPassword);
|
|
501
|
+
|
|
589
502
|
const proc = serverProcess;
|
|
590
503
|
if (proc && !proc.killed) {
|
|
591
504
|
console.log("Stopping MITM server...");
|
|
@@ -611,16 +524,15 @@ async function stopMitm(sudoPassword) {
|
|
|
611
524
|
}
|
|
612
525
|
|
|
613
526
|
if (IS_WIN) {
|
|
614
|
-
// Windows stop: remove DNS entries via elevated VBScript (1 UAC)
|
|
615
527
|
const hostsFile = path.join(process.env.SystemRoot || "C:\\Windows", "System32", "drivers", "etc", "hosts");
|
|
616
|
-
const TARGET_HOSTS_WIN = ["daily-cloudcode-pa.googleapis.com", "cloudcode-pa.googleapis.com"];
|
|
617
528
|
const psSQ = (s) => s.replace(/'/g, "''");
|
|
529
|
+
const { TOOL_HOSTS } = require("./dns/dnsConfig");
|
|
530
|
+
const allHosts = Object.values(TOOL_HOSTS).flat();
|
|
618
531
|
|
|
619
|
-
// Filter hosts content in Node (read doesn't need elevation)
|
|
620
532
|
let hostsContent = "";
|
|
621
533
|
try { hostsContent = fs.readFileSync(hostsFile, "utf8"); } catch { /* ignore */ }
|
|
622
534
|
const filtered = hostsContent.split(/\r?\n/)
|
|
623
|
-
.filter(l => !
|
|
535
|
+
.filter(l => !allHosts.some(h => l.includes(h)))
|
|
624
536
|
.join("\r\n");
|
|
625
537
|
const tmpHosts = path.join(os.tmpdir(), "mitm_hosts_clean.tmp");
|
|
626
538
|
fs.writeFileSync(tmpHosts, filtered, "utf8");
|
|
@@ -645,7 +557,6 @@ async function stopMitm(sudoPassword) {
|
|
|
645
557
|
fs.writeFileSync(tmpVbs, vbs, "utf8");
|
|
646
558
|
spawn("wscript.exe", [tmpVbs], { stdio: "ignore", windowsHide: false, detached: true }).unref();
|
|
647
559
|
|
|
648
|
-
// Poll flag — best effort, don't block UI if user cancels UAC
|
|
649
560
|
await new Promise((resolve) => {
|
|
650
561
|
const deadline = Date.now() + 30000;
|
|
651
562
|
const poll = () => {
|
|
@@ -658,20 +569,43 @@ async function stopMitm(sudoPassword) {
|
|
|
658
569
|
};
|
|
659
570
|
poll();
|
|
660
571
|
});
|
|
661
|
-
} else {
|
|
662
|
-
console.log("Removing DNS entry...");
|
|
663
|
-
await removeDNSEntry(sudoPassword);
|
|
664
572
|
}
|
|
665
573
|
|
|
666
574
|
try { fs.unlinkSync(PID_FILE); } catch { /* ignore */ }
|
|
667
|
-
|
|
668
575
|
await saveMitmSettings(false, null);
|
|
669
576
|
|
|
670
577
|
return { running: false, pid: null };
|
|
671
578
|
}
|
|
672
579
|
|
|
580
|
+
/**
|
|
581
|
+
* Enable DNS for a specific tool (requires server running)
|
|
582
|
+
*/
|
|
583
|
+
async function enableToolDNS(tool, sudoPassword) {
|
|
584
|
+
const status = await getMitmStatus();
|
|
585
|
+
if (!status.running) throw new Error("MITM server is not running. Start the server first.");
|
|
586
|
+
await addDNSEntry(tool, sudoPassword);
|
|
587
|
+
return { success: true };
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Disable DNS for a specific tool
|
|
592
|
+
*/
|
|
593
|
+
async function disableToolDNS(tool, sudoPassword) {
|
|
594
|
+
await removeDNSEntry(tool, sudoPassword);
|
|
595
|
+
return { success: true };
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// Legacy aliases for backward compatibility
|
|
599
|
+
const startMitm = startServer;
|
|
600
|
+
const stopMitm = stopServer;
|
|
601
|
+
|
|
673
602
|
module.exports = {
|
|
674
603
|
getMitmStatus,
|
|
604
|
+
startServer,
|
|
605
|
+
stopServer,
|
|
606
|
+
enableToolDNS,
|
|
607
|
+
disableToolDNS,
|
|
608
|
+
// Legacy
|
|
675
609
|
startMitm,
|
|
676
610
|
stopMitm,
|
|
677
611
|
getCachedPassword,
|