9router 0.3.28 → 0.3.30
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 +46 -43
- package/app/.next/build-manifest.json +2 -2
- package/app/.next/prerender-manifest.json +24 -0
- package/app/.next/routes-manifest.json +18 -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.js.nft.json +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.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.js.nft.json +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.js +1 -1
- package/app/.next/server/app/api/usage/[connectionId]/route.js.nft.json +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.js +1 -0
- package/app/.next/server/app/api/usage/stats/route.js.nft.json +1 -0
- package/app/.next/server/app/api/usage/stats/route_client-reference-manifest.js +1 -0
- 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.js +1 -1
- package/app/.next/server/app/api/v1/api/chat/route.js.nft.json +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.js +1 -1
- package/app/.next/server/app/api/v1/chat/completions/route.js.nft.json +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.js +1 -1
- package/app/.next/server/app/api/v1/embeddings/route.js.nft.json +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.js +1 -1
- package/app/.next/server/app/api/v1/messages/route.js.nft.json +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.js +1 -1
- package/app/.next/server/app/api/v1/responses/route.js.nft.json +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.js +1 -1
- package/app/.next/server/app/api/v1beta/models/[...path]/route.js.nft.json +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 +46 -43
- package/app/.next/server/chunks/1238.js +2 -2
- package/app/.next/server/chunks/1424.js +1 -1
- package/app/.next/server/chunks/2280.js +1 -1
- package/app/.next/server/chunks/3245.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 +12 -0
- package/app/.next/server/chunks/4989.js +2 -2
- 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/chunks/8895.js +2 -2
- 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/chunks/4495-97a066cea645caef.js +1 -0
- package/app/.next/static/chunks/5497-87f1cb95ee622c7b.js +7 -0
- package/app/.next/static/chunks/9242-3524e9de7ad33a19.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-cbe799ec784651ca.js → layout-f9f92a7880a478f2.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/.next/static/k3zp-r_EpPiF5lcYQ24hp/_buildManifest.js +1 -0
- package/app/package.json +1 -1
- package/app/src/mitm/cert/generate.js +16 -5
- package/app/src/mitm/cert/install.js +8 -3
- package/app/src/mitm/dns/dnsConfig.js +79 -66
- package/app/src/mitm/manager.js +126 -169
- 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/server/chunks/3110.js +0 -12
- package/app/.next/static/7sCSr7yWSqEyoyOGqrYLA/_buildManifest.js +0 -1
- package/app/.next/static/chunks/4495-bc9f104bf7b22419.js +0 -1
- package/app/.next/static/chunks/5497-9aeee36152b1d579.js +0 -7
- package/app/.next/static/chunks/app/(dashboard)/dashboard/cli-tools/page-4cc436d49f7e7638.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-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/auth/login/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/auth/logout/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/alias/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/claude-settings/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/codex-settings/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/copilot-settings/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/droid-settings/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/openclaw-settings/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/opencode-settings/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/cloud/auth/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/cloud/credentials/update/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/cloud/model/resolve/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/cloud/models/alias/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/combos/[id]/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/combos/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/init/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/keys/[id]/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/keys/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/models/alias/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/models/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/models/test/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/[provider]/[action]/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/cursor/auto-import/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/cursor/import/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/auto-import/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/import/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/social-authorize/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/social-exchange/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/pricing/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/provider-nodes/[id]/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/provider-nodes/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/provider-nodes/validate/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/models/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/test/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/test-models/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/providers/client/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/providers/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/providers/test-batch/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/providers/validate/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/settings/database/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/settings/proxy-test/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/settings/require-login/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/settings/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/shutdown/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/tags/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/translator/console-logs/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/translator/console-logs/stream/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/translator/load/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/translator/save/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/translator/send/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/translator/translate/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/tunnel/disable/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/tunnel/enable/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/tunnel/status/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/usage/[connectionId]/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/usage/chart/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/usage/history/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/usage/providers/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/usage/request-details/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/usage/request-logs/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/usage/stream/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/v1/api/chat/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/v1/chat/completions/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/v1/embeddings/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/v1/messages/count_tokens/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/v1/messages/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/v1/models/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/v1/responses/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/v1/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/v1beta/models/[...path]/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/v1beta/models/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/api/version/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/manifest.webmanifest/route-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/app/page-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/app-error-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/forbidden-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/not-found-dc114b2367afe467.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/unauthorized-dc114b2367afe467.js +0 -1
- package/app/.next/static/css/544a28fc50711a49.css +0 -3
- /package/app/.next/static/{7sCSr7yWSqEyoyOGqrYLA → k3zp-r_EpPiF5lcYQ24hp}/_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,42 +69,41 @@ function isProcessAlive(pid) {
|
|
|
96
69
|
}
|
|
97
70
|
}
|
|
98
71
|
|
|
99
|
-
|
|
100
|
-
function killProcess(pid, force = false) {
|
|
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
|
-
// Use pkill to kill entire process group (catches sudo + child node process)
|
|
106
77
|
const sig = force ? "SIGKILL" : "SIGTERM";
|
|
107
|
-
|
|
78
|
+
const cmd = `pkill -${sig} -P ${pid} 2>/dev/null; kill -${sig} ${pid} 2>/dev/null`;
|
|
79
|
+
if (sudoPassword) {
|
|
80
|
+
const { execWithPassword } = require("./dns/dnsConfig");
|
|
81
|
+
execWithPassword(cmd, sudoPassword).catch(() => exec(cmd, () => { }));
|
|
82
|
+
} else {
|
|
83
|
+
exec(cmd, () => { });
|
|
84
|
+
}
|
|
108
85
|
}
|
|
109
86
|
}
|
|
110
87
|
|
|
111
|
-
/** Derive a 32-byte encryption key from machineId */
|
|
112
88
|
function deriveKey() {
|
|
113
89
|
try {
|
|
114
90
|
const { machineIdSync } = require("node-machine-id");
|
|
115
91
|
const raw = machineIdSync();
|
|
116
92
|
return crypto.createHash("sha256").update(raw + ENCRYPT_SALT).digest();
|
|
117
93
|
} catch {
|
|
118
|
-
// Fallback: fixed key derived from salt (less secure but functional)
|
|
119
94
|
return crypto.createHash("sha256").update(ENCRYPT_SALT).digest();
|
|
120
95
|
}
|
|
121
96
|
}
|
|
122
97
|
|
|
123
|
-
/** Encrypt sudo password with AES-256-GCM */
|
|
124
98
|
function encryptPassword(plaintext) {
|
|
125
99
|
const key = deriveKey();
|
|
126
100
|
const iv = crypto.randomBytes(12);
|
|
127
101
|
const cipher = crypto.createCipheriv(ENCRYPT_ALGO, key, iv);
|
|
128
102
|
const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
129
103
|
const tag = cipher.getAuthTag();
|
|
130
|
-
// Store as hex: iv:tag:ciphertext
|
|
131
104
|
return `${iv.toString("hex")}:${tag.toString("hex")}:${encrypted.toString("hex")}`;
|
|
132
105
|
}
|
|
133
106
|
|
|
134
|
-
/** Decrypt sudo password */
|
|
135
107
|
function decryptPassword(stored) {
|
|
136
108
|
try {
|
|
137
109
|
const [ivHex, tagHex, dataHex] = stored.split(":");
|
|
@@ -145,23 +117,16 @@ function decryptPassword(stored) {
|
|
|
145
117
|
}
|
|
146
118
|
}
|
|
147
119
|
|
|
148
|
-
// DB hooks — injected from ESM context (initializeApp / route handlers)
|
|
149
|
-
// to avoid webpack bundling issues with dynamic imports in CJS modules.
|
|
150
120
|
let _getSettings = null;
|
|
151
121
|
let _updateSettings = null;
|
|
152
122
|
|
|
153
|
-
/** Called once from ESM context to inject DB access functions */
|
|
154
123
|
function initDbHooks(getSettingsFn, updateSettingsFn) {
|
|
155
124
|
_getSettings = getSettingsFn;
|
|
156
125
|
_updateSettings = updateSettingsFn;
|
|
157
126
|
}
|
|
158
127
|
|
|
159
|
-
/** Save encrypted sudo password + mitmEnabled to db */
|
|
160
128
|
async function saveMitmSettings(enabled, password) {
|
|
161
|
-
if (!_updateSettings)
|
|
162
|
-
console.log("[MITM] DB hooks not initialized, skipping save");
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
129
|
+
if (!_updateSettings) return;
|
|
165
130
|
try {
|
|
166
131
|
const updates = { mitmEnabled: enabled };
|
|
167
132
|
if (password) updates.mitmSudoEncrypted = encryptPassword(password);
|
|
@@ -171,7 +136,6 @@ async function saveMitmSettings(enabled, password) {
|
|
|
171
136
|
}
|
|
172
137
|
}
|
|
173
138
|
|
|
174
|
-
/** Load and decrypt sudo password from db */
|
|
175
139
|
async function loadEncryptedPassword() {
|
|
176
140
|
if (!_getSettings) return null;
|
|
177
141
|
try {
|
|
@@ -183,37 +147,27 @@ async function loadEncryptedPassword() {
|
|
|
183
147
|
}
|
|
184
148
|
}
|
|
185
149
|
|
|
186
|
-
/**
|
|
187
|
-
* Check if port 443 is available
|
|
188
|
-
* Returns: "free" | "in-use" | "no-permission"
|
|
189
|
-
*/
|
|
190
150
|
function checkPort443Free() {
|
|
191
151
|
return new Promise((resolve) => {
|
|
192
152
|
const tester = net.createServer();
|
|
193
153
|
tester.once("error", (err) => {
|
|
194
154
|
if (err.code === "EADDRINUSE") resolve("in-use");
|
|
195
|
-
else resolve("no-permission");
|
|
155
|
+
else resolve("no-permission");
|
|
196
156
|
});
|
|
197
157
|
tester.once("listening", () => { tester.close(() => resolve("free")); });
|
|
198
158
|
tester.listen(MITM_PORT, "127.0.0.1");
|
|
199
159
|
});
|
|
200
160
|
}
|
|
201
161
|
|
|
202
|
-
/**
|
|
203
|
-
* Get PID and process name currently holding port 443
|
|
204
|
-
* Returns { pid, name } or null if port is free / cannot determine
|
|
205
|
-
*/
|
|
206
162
|
function getPort443Owner(sudoPassword) {
|
|
207
163
|
return new Promise((resolve) => {
|
|
208
164
|
if (IS_WIN) {
|
|
209
|
-
// Use PowerShell Get-NetTCPConnection for precise port 443 owner lookup
|
|
210
165
|
const psCmd = `powershell -NonInteractive -WindowStyle Hidden -Command "` +
|
|
211
166
|
`$c = Get-NetTCPConnection -LocalPort 443 -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1; ` +
|
|
212
167
|
`if ($c) { $c.OwningProcess } else { 0 }"`;
|
|
213
168
|
exec(psCmd, { windowsHide: true }, (err, stdout) => {
|
|
214
169
|
if (err) return resolve(null);
|
|
215
170
|
const pid = parseInt(stdout.trim(), 10);
|
|
216
|
-
// 0 = no owner, <=4 = System/Idle — not real port owners
|
|
217
171
|
if (!pid || pid <= 4) return resolve(null);
|
|
218
172
|
exec(`tasklist /FI "PID eq ${pid}" /FO CSV /NH`, { windowsHide: true }, (e2, out2) => {
|
|
219
173
|
const m = out2?.match(/"([^"]+)"/);
|
|
@@ -221,7 +175,6 @@ function getPort443Owner(sudoPassword) {
|
|
|
221
175
|
});
|
|
222
176
|
});
|
|
223
177
|
} else {
|
|
224
|
-
// Use ps to find node process running server.js (no sudo needed)
|
|
225
178
|
exec(`ps aux | grep "[s]erver.js"`, (err, stdout) => {
|
|
226
179
|
if (!stdout?.trim()) return resolve(null);
|
|
227
180
|
for (const line of stdout.split("\n")) {
|
|
@@ -235,31 +188,22 @@ function getPort443Owner(sudoPassword) {
|
|
|
235
188
|
});
|
|
236
189
|
}
|
|
237
190
|
|
|
238
|
-
/**
|
|
239
|
-
* Kill any leftover MITM server process (from previous failed start)
|
|
240
|
-
* Uses sudo to kill the node process that was spawned with sudo
|
|
241
|
-
*/
|
|
242
191
|
async function killLeftoverMitm(sudoPassword) {
|
|
243
|
-
// Kill in-memory process if still alive
|
|
244
192
|
if (serverProcess && !serverProcess.killed) {
|
|
245
193
|
try { serverProcess.kill("SIGKILL"); } catch { /* ignore */ }
|
|
246
194
|
serverProcess = null;
|
|
247
195
|
serverPid = null;
|
|
248
196
|
}
|
|
249
|
-
|
|
250
|
-
// Kill from PID file
|
|
251
197
|
try {
|
|
252
198
|
if (fs.existsSync(PID_FILE)) {
|
|
253
199
|
const savedPid = parseInt(fs.readFileSync(PID_FILE, "utf-8").trim(), 10);
|
|
254
200
|
if (savedPid && isProcessAlive(savedPid)) {
|
|
255
|
-
killProcess(savedPid, true);
|
|
201
|
+
killProcess(savedPid, true, sudoPassword);
|
|
256
202
|
await new Promise(r => setTimeout(r, 500));
|
|
257
203
|
}
|
|
258
204
|
fs.unlinkSync(PID_FILE);
|
|
259
205
|
}
|
|
260
206
|
} catch { /* ignore */ }
|
|
261
|
-
|
|
262
|
-
// Also kill any node process running server.js via sudo (belt-and-suspenders)
|
|
263
207
|
if (!IS_WIN && SERVER_PATH) {
|
|
264
208
|
try {
|
|
265
209
|
const escaped = SERVER_PATH.replace(/'/g, "'\\''");
|
|
@@ -274,10 +218,6 @@ async function killLeftoverMitm(sudoPassword) {
|
|
|
274
218
|
}
|
|
275
219
|
}
|
|
276
220
|
|
|
277
|
-
/**
|
|
278
|
-
* Poll MITM health endpoint until server is up or timeout.
|
|
279
|
-
* Returns { ok, pid } on success, null on timeout.
|
|
280
|
-
*/
|
|
281
221
|
function pollMitmHealth(timeoutMs, port = MITM_PORT) {
|
|
282
222
|
return new Promise((resolve) => {
|
|
283
223
|
const deadline = Date.now() + timeoutMs;
|
|
@@ -306,7 +246,38 @@ function pollMitmHealth(timeoutMs, port = MITM_PORT) {
|
|
|
306
246
|
}
|
|
307
247
|
|
|
308
248
|
/**
|
|
309
|
-
*
|
|
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
|
|
310
281
|
*/
|
|
311
282
|
async function getMitmStatus() {
|
|
312
283
|
let running = serverProcess !== null && !serverProcess.killed;
|
|
@@ -323,30 +294,26 @@ async function getMitmStatus() {
|
|
|
323
294
|
fs.unlinkSync(PID_FILE);
|
|
324
295
|
}
|
|
325
296
|
}
|
|
326
|
-
} catch {
|
|
327
|
-
// Ignore
|
|
328
|
-
}
|
|
297
|
+
} catch { /* ignore */ }
|
|
329
298
|
}
|
|
330
299
|
|
|
331
|
-
const
|
|
332
|
-
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) : {};
|
|
333
304
|
|
|
334
|
-
return { running, pid,
|
|
305
|
+
return { running, pid, certExists, dnsStatus, certCoversTools };
|
|
335
306
|
}
|
|
336
307
|
|
|
337
308
|
/**
|
|
338
|
-
* Start MITM
|
|
339
|
-
* @param {string} apiKey - 9Router API key
|
|
340
|
-
* @param {string} sudoPassword - Sudo password for DNS/cert operations
|
|
309
|
+
* Start MITM server only (cert + server, no DNS)
|
|
341
310
|
*/
|
|
342
|
-
async function
|
|
343
|
-
// Check orphan process from PID file before spawning
|
|
311
|
+
async function startServer(apiKey, sudoPassword) {
|
|
344
312
|
if (!serverProcess || serverProcess.killed) {
|
|
345
313
|
try {
|
|
346
314
|
if (fs.existsSync(PID_FILE)) {
|
|
347
315
|
const savedPid = parseInt(fs.readFileSync(PID_FILE, "utf-8").trim(), 10);
|
|
348
316
|
if (savedPid && isProcessAlive(savedPid)) {
|
|
349
|
-
// Orphan MITM process still alive — reuse it
|
|
350
317
|
serverPid = savedPid;
|
|
351
318
|
console.log(`[MITM] Reusing existing process PID ${savedPid}`);
|
|
352
319
|
await saveMitmSettings(true, sudoPassword);
|
|
@@ -356,25 +323,20 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
356
323
|
fs.unlinkSync(PID_FILE);
|
|
357
324
|
}
|
|
358
325
|
}
|
|
359
|
-
} catch {
|
|
360
|
-
// Ignore stale PID file errors
|
|
361
|
-
}
|
|
326
|
+
} catch { /* ignore */ }
|
|
362
327
|
}
|
|
363
328
|
|
|
364
329
|
if (serverProcess && !serverProcess.killed) {
|
|
365
|
-
throw new Error("MITM
|
|
330
|
+
throw new Error("MITM server is already running");
|
|
366
331
|
}
|
|
367
332
|
|
|
368
|
-
// Kill any leftover MITM server from a previous failed start attempt
|
|
369
333
|
await killLeftoverMitm(sudoPassword);
|
|
370
334
|
|
|
371
335
|
if (!IS_WIN) {
|
|
372
|
-
// Check port 443 availability — Windows handles this inside elevated script
|
|
373
336
|
const portStatus = await checkPort443Free();
|
|
374
337
|
if (portStatus === "in-use" || portStatus === "no-permission") {
|
|
375
338
|
const owner = await getPort443Owner(sudoPassword);
|
|
376
339
|
if (owner && owner.name === "node") {
|
|
377
|
-
// Orphan MITM node process — kill it and continue
|
|
378
340
|
console.log(`[MITM] Killing orphan node process on port 443 (PID ${owner.pid})...`);
|
|
379
341
|
try {
|
|
380
342
|
const { execWithPassword } = require("./dns/dnsConfig");
|
|
@@ -385,74 +347,61 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
385
347
|
const shortName = owner.name.includes("/")
|
|
386
348
|
? owner.name.split("/").filter(Boolean).pop()
|
|
387
349
|
: owner.name;
|
|
388
|
-
throw new Error(
|
|
389
|
-
`Port 443 is already in use by "${shortName}" (PID ${owner.pid}). Stop that process first, then retry.`
|
|
390
|
-
);
|
|
350
|
+
throw new Error(`Port 443 is already in use by "${shortName}" (PID ${owner.pid}). Stop that process first.`);
|
|
391
351
|
}
|
|
392
352
|
}
|
|
393
353
|
}
|
|
394
354
|
|
|
395
|
-
// 1
|
|
355
|
+
// Step 1: Generate SSL certificate if not exists or missing domain coverage
|
|
396
356
|
const certPath = path.join(MITM_DIR, "server.crt");
|
|
357
|
+
const keyPath = path.join(MITM_DIR, "server.key");
|
|
358
|
+
let needsRegenerate = false;
|
|
359
|
+
|
|
397
360
|
if (!fs.existsSync(certPath)) {
|
|
398
|
-
console.log("Generating SSL certificate...");
|
|
399
|
-
|
|
361
|
+
console.log("[MITM] Generating SSL certificate...");
|
|
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
|
+
}
|
|
400
376
|
}
|
|
401
377
|
|
|
402
|
-
|
|
403
|
-
|
|
378
|
+
if (needsRegenerate) {
|
|
379
|
+
await generateCert();
|
|
380
|
+
}
|
|
404
381
|
|
|
382
|
+
// Step 2: Install cert + spawn server
|
|
405
383
|
if (IS_WIN) {
|
|
406
|
-
// Windows: single UAC via VBScript → elevated PowerShell script that:
|
|
407
|
-
// 1. Installs SSL cert 2. Adds DNS entries 3. Starts node server.js (elevated → can bind 443) 4. Writes flag
|
|
408
|
-
// Node polls flag file to know when server is ready, then health-checks port 443
|
|
409
384
|
const hostsFile = path.join(process.env.SystemRoot || "C:\\Windows", "System32", "drivers", "etc", "hosts");
|
|
410
|
-
const TARGET_HOSTS_WIN = ["daily-cloudcode-pa.googleapis.com", "cloudcode-pa.googleapis.com"];
|
|
411
|
-
|
|
412
|
-
// Use Chr(34) in VBScript for quotes — avoid escaping issues
|
|
413
385
|
const flagFile = path.join(os.tmpdir(), `mitm_ready_${Date.now()}.flag`);
|
|
414
|
-
|
|
415
|
-
// PowerShell uses single-quoted strings — escape single quotes only
|
|
416
386
|
const psSQ = (s) => s.replace(/'/g, "''");
|
|
417
387
|
const certPs = psSQ(certPath);
|
|
418
|
-
const hostsPs = psSQ(hostsFile);
|
|
419
388
|
const nodePs = psSQ(process.execPath);
|
|
420
389
|
const serverPs = psSQ(SERVER_PATH);
|
|
421
390
|
const flagPs = psSQ(flagFile);
|
|
422
391
|
|
|
423
|
-
const dnsLines = TARGET_HOSTS_WIN.map(h =>
|
|
424
|
-
`$hc = Get-Content -Path '${hostsPs}' -Raw -ErrorAction SilentlyContinue\n` +
|
|
425
|
-
`if ($hc -notmatch [regex]::Escape('${h}')) { Add-Content -Path '${hostsPs}' -Value '127.0.0.1 ${h}' -Encoding UTF8 }`
|
|
426
|
-
).join("\n");
|
|
427
|
-
|
|
428
392
|
const psScript = [
|
|
429
|
-
`# 0. Kill any orphan node process on port 443`,
|
|
430
393
|
`$conn = Get-NetTCPConnection -LocalPort 443 -State Listen -ErrorAction SilentlyContinue | Select-Object -First 1`,
|
|
431
394
|
`if ($conn -and $conn.OwningProcess -gt 4) { Stop-Process -Id $conn.OwningProcess -Force -ErrorAction SilentlyContinue }`,
|
|
432
395
|
`Start-Sleep -Milliseconds 500`,
|
|
433
|
-
``,
|
|
434
|
-
`# 1. Install SSL cert to Windows Root store (always run to ensure trust)`,
|
|
435
396
|
`& certutil -addstore Root '${certPs}' | Out-Null`,
|
|
436
|
-
``,
|
|
437
|
-
`# 2. Add DNS entries to hosts file`,
|
|
438
|
-
dnsLines,
|
|
439
|
-
`& ipconfig /flushdns | Out-Null`,
|
|
440
|
-
``,
|
|
441
|
-
`# 3. Start node MITM server elevated (required to bind port 443)`,
|
|
442
|
-
`# Use cmd /c to pass env vars inline — Start-Process does not inherit current env`,
|
|
443
397
|
`$nodeCmd = 'set ROUTER_API_KEY=${psSQ(apiKey)}&& set NODE_ENV=production&& "${nodePs}" "${serverPs}"'`,
|
|
444
398
|
`Start-Process cmd -ArgumentList '/c',$nodeCmd -WindowStyle Hidden`,
|
|
445
|
-
``,
|
|
446
|
-
`# 4. Signal ready`,
|
|
447
399
|
`Start-Sleep -Milliseconds 500`,
|
|
448
400
|
`Set-Content -Path '${flagPs}' -Value 'ready' -Encoding UTF8`,
|
|
449
401
|
].join("\n");
|
|
450
402
|
|
|
451
403
|
const tmpPs1 = path.join(os.tmpdir(), `mitm_start_${Date.now()}.ps1`);
|
|
452
404
|
fs.writeFileSync(tmpPs1, psScript, "utf8");
|
|
453
|
-
|
|
454
|
-
// VBScript uses Shell.Application.ShellExecute to trigger UAC from any context
|
|
455
|
-
// Chr(34) = double-quote, avoids VBScript string escaping issues
|
|
456
405
|
const vbs = [
|
|
457
406
|
`Set oShell = CreateObject("Shell.Application")`,
|
|
458
407
|
`Dim ps`,
|
|
@@ -463,19 +412,16 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
463
412
|
].join("\r\n");
|
|
464
413
|
const tmpVbs = path.join(os.tmpdir(), `mitm_uac_${Date.now()}.vbs`);
|
|
465
414
|
fs.writeFileSync(tmpVbs, vbs, "utf8");
|
|
466
|
-
|
|
467
|
-
// Launch VBScript — shows UAC dialog, user confirms, script runs elevated
|
|
468
415
|
spawn("wscript.exe", [tmpVbs], { stdio: "ignore", windowsHide: false, detached: true }).unref();
|
|
469
416
|
|
|
470
|
-
// Poll flag file — resolves when elevated script completes
|
|
471
417
|
await new Promise((resolve, reject) => {
|
|
472
|
-
const deadline = Date.now() + 90000;
|
|
418
|
+
const deadline = Date.now() + 90000;
|
|
473
419
|
const poll = () => {
|
|
474
420
|
if (fs.existsSync(flagFile)) {
|
|
475
421
|
try { fs.unlinkSync(flagFile); fs.unlinkSync(tmpPs1); fs.unlinkSync(tmpVbs); } catch { /* ignore */ }
|
|
476
422
|
return resolve();
|
|
477
423
|
}
|
|
478
|
-
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."));
|
|
479
425
|
setTimeout(poll, 500);
|
|
480
426
|
};
|
|
481
427
|
poll();
|
|
@@ -483,28 +429,22 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
483
429
|
|
|
484
430
|
if (_updateSettings) await _updateSettings({ mitmCertInstalled: true }).catch(() => { });
|
|
485
431
|
} else {
|
|
486
|
-
|
|
487
|
-
const
|
|
488
|
-
|
|
489
|
-
if (!certAlreadyInstalled) {
|
|
432
|
+
const { checkCertInstalled } = require("./cert/install");
|
|
433
|
+
const certTrusted = await checkCertInstalled(certPath);
|
|
434
|
+
if (!certTrusted) {
|
|
490
435
|
await installCert(sudoPassword, certPath);
|
|
491
436
|
if (_updateSettings) await _updateSettings({ mitmCertInstalled: true }).catch(() => { });
|
|
492
437
|
}
|
|
493
|
-
console.log("Adding DNS entry...");
|
|
494
|
-
await addDNSEntry(sudoPassword);
|
|
495
438
|
|
|
496
|
-
// sudo -S: read password from stdin, -E: preserve env vars
|
|
497
439
|
const inlineCmd = `ROUTER_API_KEY='${apiKey}' NODE_ENV='production' '${process.execPath}' '${SERVER_PATH}'`;
|
|
498
440
|
serverProcess = spawn(
|
|
499
441
|
"sudo", ["-S", "-E", "sh", "-c", inlineCmd],
|
|
500
442
|
{ detached: false, stdio: ["pipe", "pipe", "pipe"] }
|
|
501
443
|
);
|
|
502
|
-
// Write password then close stdin so sudo proceeds
|
|
503
444
|
serverProcess.stdin.write(`${sudoPassword}\n`);
|
|
504
445
|
serverProcess.stdin.end();
|
|
505
446
|
}
|
|
506
447
|
|
|
507
|
-
// Windows: node was started by elevated script — PID comes from health check later
|
|
508
448
|
if (!IS_WIN && serverProcess) {
|
|
509
449
|
serverPid = serverProcess.pid;
|
|
510
450
|
fs.writeFileSync(PID_FILE, String(serverPid));
|
|
@@ -517,7 +457,6 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
517
457
|
});
|
|
518
458
|
serverProcess.stderr.on("data", (data) => {
|
|
519
459
|
const msg = data.toString().trim();
|
|
520
|
-
// Capture meaningful errors (ignore sudo password prompt noise)
|
|
521
460
|
if (msg && !msg.includes("Password:") && !msg.includes("password for")) {
|
|
522
461
|
console.error(`[MITM Server Error] ${msg}`);
|
|
523
462
|
startError = msg;
|
|
@@ -531,22 +470,16 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
531
470
|
});
|
|
532
471
|
}
|
|
533
472
|
|
|
534
|
-
// Wait for server to be ready by polling health endpoint on port 443
|
|
535
473
|
const health = await pollMitmHealth(IS_WIN ? 15000 : 8000, MITM_PORT);
|
|
536
|
-
|
|
537
474
|
if (!health) {
|
|
538
475
|
if (IS_WIN) serverProcess = null;
|
|
539
|
-
try { await removeDNSEntry(sudoPassword); } catch { /* best effort */ }
|
|
540
476
|
const processUsing443 = getProcessUsingPort443();
|
|
541
477
|
const portInfo = processUsing443 ? ` Port 443 already in use by ${processUsing443}.` : "";
|
|
542
478
|
const reason = startError || `Check sudo password or port 443 access.${portInfo}`;
|
|
543
479
|
throw new Error(`MITM server failed to start. ${reason}`);
|
|
544
480
|
}
|
|
545
481
|
|
|
546
|
-
// On Windows, mark cert as installed after successful start
|
|
547
482
|
if (IS_WIN && _updateSettings) await _updateSettings({ mitmCertInstalled: true }).catch(() => { });
|
|
548
|
-
|
|
549
|
-
// On Windows, use real PID from health check (launcher exits immediately after UAC)
|
|
550
483
|
if (IS_WIN && health.pid) {
|
|
551
484
|
serverPid = health.pid;
|
|
552
485
|
fs.writeFileSync(PID_FILE, String(serverPid));
|
|
@@ -559,16 +492,19 @@ async function startMitm(apiKey, sudoPassword) {
|
|
|
559
492
|
}
|
|
560
493
|
|
|
561
494
|
/**
|
|
562
|
-
* Stop MITM
|
|
563
|
-
* @param {string} sudoPassword - Sudo password for DNS cleanup
|
|
495
|
+
* Stop MITM server — removes ALL tool DNS entries first, then kills server
|
|
564
496
|
*/
|
|
565
|
-
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
|
+
|
|
566
502
|
const proc = serverProcess;
|
|
567
503
|
if (proc && !proc.killed) {
|
|
568
504
|
console.log("Stopping MITM server...");
|
|
569
|
-
killProcess(proc.pid, false);
|
|
505
|
+
killProcess(proc.pid, false, sudoPassword);
|
|
570
506
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
571
|
-
if (isProcessAlive(proc.pid)) killProcess(proc.pid, true);
|
|
507
|
+
if (isProcessAlive(proc.pid)) killProcess(proc.pid, true, sudoPassword);
|
|
572
508
|
serverProcess = null;
|
|
573
509
|
serverPid = null;
|
|
574
510
|
} else {
|
|
@@ -577,9 +513,9 @@ async function stopMitm(sudoPassword) {
|
|
|
577
513
|
const savedPid = parseInt(fs.readFileSync(PID_FILE, "utf-8").trim(), 10);
|
|
578
514
|
if (savedPid && isProcessAlive(savedPid)) {
|
|
579
515
|
console.log(`Killing MITM server (PID: ${savedPid})...`);
|
|
580
|
-
killProcess(savedPid, false);
|
|
516
|
+
killProcess(savedPid, false, sudoPassword);
|
|
581
517
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
582
|
-
if (isProcessAlive(savedPid)) killProcess(savedPid, true);
|
|
518
|
+
if (isProcessAlive(savedPid)) killProcess(savedPid, true, sudoPassword);
|
|
583
519
|
}
|
|
584
520
|
}
|
|
585
521
|
} catch { /* ignore */ }
|
|
@@ -588,16 +524,15 @@ async function stopMitm(sudoPassword) {
|
|
|
588
524
|
}
|
|
589
525
|
|
|
590
526
|
if (IS_WIN) {
|
|
591
|
-
// Windows stop: remove DNS entries via elevated VBScript (1 UAC)
|
|
592
527
|
const hostsFile = path.join(process.env.SystemRoot || "C:\\Windows", "System32", "drivers", "etc", "hosts");
|
|
593
|
-
const TARGET_HOSTS_WIN = ["daily-cloudcode-pa.googleapis.com", "cloudcode-pa.googleapis.com"];
|
|
594
528
|
const psSQ = (s) => s.replace(/'/g, "''");
|
|
529
|
+
const { TOOL_HOSTS } = require("./dns/dnsConfig");
|
|
530
|
+
const allHosts = Object.values(TOOL_HOSTS).flat();
|
|
595
531
|
|
|
596
|
-
// Filter hosts content in Node (read doesn't need elevation)
|
|
597
532
|
let hostsContent = "";
|
|
598
533
|
try { hostsContent = fs.readFileSync(hostsFile, "utf8"); } catch { /* ignore */ }
|
|
599
534
|
const filtered = hostsContent.split(/\r?\n/)
|
|
600
|
-
.filter(l => !
|
|
535
|
+
.filter(l => !allHosts.some(h => l.includes(h)))
|
|
601
536
|
.join("\r\n");
|
|
602
537
|
const tmpHosts = path.join(os.tmpdir(), "mitm_hosts_clean.tmp");
|
|
603
538
|
fs.writeFileSync(tmpHosts, filtered, "utf8");
|
|
@@ -622,7 +557,6 @@ async function stopMitm(sudoPassword) {
|
|
|
622
557
|
fs.writeFileSync(tmpVbs, vbs, "utf8");
|
|
623
558
|
spawn("wscript.exe", [tmpVbs], { stdio: "ignore", windowsHide: false, detached: true }).unref();
|
|
624
559
|
|
|
625
|
-
// Poll flag — best effort, don't block UI if user cancels UAC
|
|
626
560
|
await new Promise((resolve) => {
|
|
627
561
|
const deadline = Date.now() + 30000;
|
|
628
562
|
const poll = () => {
|
|
@@ -635,20 +569,43 @@ async function stopMitm(sudoPassword) {
|
|
|
635
569
|
};
|
|
636
570
|
poll();
|
|
637
571
|
});
|
|
638
|
-
} else {
|
|
639
|
-
console.log("Removing DNS entry...");
|
|
640
|
-
await removeDNSEntry(sudoPassword);
|
|
641
572
|
}
|
|
642
573
|
|
|
643
574
|
try { fs.unlinkSync(PID_FILE); } catch { /* ignore */ }
|
|
644
|
-
|
|
645
575
|
await saveMitmSettings(false, null);
|
|
646
576
|
|
|
647
577
|
return { running: false, pid: null };
|
|
648
578
|
}
|
|
649
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
|
+
|
|
650
602
|
module.exports = {
|
|
651
603
|
getMitmStatus,
|
|
604
|
+
startServer,
|
|
605
|
+
stopServer,
|
|
606
|
+
enableToolDNS,
|
|
607
|
+
disableToolDNS,
|
|
608
|
+
// Legacy
|
|
652
609
|
startMitm,
|
|
653
610
|
stopMitm,
|
|
654
611
|
getCachedPassword,
|