9router 0.2.71 → 0.2.73
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 +42 -40
- package/app/.next/build-manifest.json +2 -2
- package/app/.next/prerender-manifest.json +3 -3
- package/app/.next/routes-manifest.json +12 -0
- 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_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page.js +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_client-reference-manifest.js +1 -1
- package/app/.next/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +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 +2 -2
- 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.js +1 -1
- 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.js +2 -2
- 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 +4 -5
- 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.js +2 -2
- 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.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/droid-settings/route.js +2 -2
- 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.js +2 -2
- package/app/.next/server/app/api/cli-tools/openclaw-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.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.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.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.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.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.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_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.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/kiro/auto-import/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/oauth/kiro/import/route.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.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.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.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.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/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/validate/route.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/require-login/route.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.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/sync/cloud/route.js +1 -1
- package/app/.next/server/app/api/sync/cloud/route_client-reference-manifest.js +1 -1
- package/app/.next/server/app/api/sync/initialize/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/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.js.nft.json +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/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/history/route.js +1 -2
- package/app/.next/server/app/api/usage/history/route.js.nft.json +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.js +45 -0
- package/app/.next/server/app/api/usage/providers/route.js.nft.json +1 -0
- package/app/.next/server/app/api/usage/providers/route_client-reference-manifest.js +1 -0
- package/app/.next/server/app/api/usage/request-details/route.js +1 -0
- package/app/.next/server/app/api/usage/request-details/route.js.nft.json +1 -0
- package/app/.next/server/app/api/usage/request-details/route_client-reference-manifest.js +1 -0
- package/app/.next/server/app/api/usage/request-logs/route.js +1 -2
- package/app/.next/server/app/api/usage/request-logs/route.js.nft.json +1 -1
- package/app/.next/server/app/api/usage/request-logs/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/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.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.js +1 -1
- package/app/.next/server/app/api/v1beta/models/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/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/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/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app-paths-manifest.json +42 -40
- package/app/.next/server/chunks/3110.js +2 -2
- package/app/.next/server/chunks/3990.js +41 -0
- package/app/.next/server/chunks/412.js +4 -4
- package/app/.next/server/chunks/5330.js +2 -3
- package/app/.next/server/chunks/7647.js +1 -0
- package/app/.next/server/chunks/8152.js +1 -1
- package/app/.next/server/chunks/8954.js +1 -1
- package/app/.next/server/chunks/9718.js +1 -1
- package/app/.next/server/chunks/9862.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/chunks/1393-ec22348a03d98802.js +1 -0
- package/app/.next/static/chunks/8729-30cb66f318ac2d23.js +1 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/profile/page-738071ba2546b274.js +1 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/providers/[id]/page-d48c3e28182c53fd.js +1 -0
- package/app/.next/static/chunks/app/(dashboard)/dashboard/usage/page-874d3494c011eaf2.js +1 -0
- package/app/.next/static/chunks/app/_global-error/page-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/auth/login/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/auth/logout/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/alias/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/claude-settings/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/codex-settings/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/droid-settings/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/cli-tools/openclaw-settings/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/cloud/auth/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/cloud/credentials/update/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/cloud/model/resolve/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/cloud/models/alias/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/combos/[id]/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/combos/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/init/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/keys/[id]/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/keys/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/models/alias/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/models/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/[provider]/[action]/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/cursor/auto-import/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/cursor/import/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/auto-import/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/import/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/social-authorize/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/oauth/kiro/social-exchange/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/pricing/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/provider-nodes/[id]/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/provider-nodes/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/provider-nodes/validate/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/providers/[id]/models/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/providers/[id]/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/providers/[id]/test/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/providers/client/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/providers/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/providers/validate/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/settings/require-login/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/settings/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/shutdown/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/sync/cloud/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/sync/initialize/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/tags/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/translator/load/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/translator/save/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/translator/send/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/translator/translate/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/usage/[connectionId]/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/usage/history/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/usage/providers/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/usage/request-details/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/usage/request-logs/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/v1/api/chat/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/v1/chat/completions/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/v1/messages/count_tokens/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/v1/messages/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/v1/models/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/v1/responses/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/v1/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/v1beta/models/[...path]/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/api/v1beta/models/route-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/app/page-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/next/dist/client/components/builtin/app-error-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/next/dist/client/components/builtin/forbidden-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/next/dist/client/components/builtin/not-found-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/chunks/next/dist/client/components/builtin/unauthorized-1968aadfb379c0a3.js +1 -0
- package/app/.next/static/css/e4a2c774b676c378.css +3 -0
- package/app/.next/static/jnuJ7xmQaeiHg9oUUDqGs/_buildManifest.js +1 -0
- package/app/package.json +1 -1
- package/app/public/providers/glm-cn.png +0 -0
- package/app/src/mitm/cert/generate.js +44 -0
- package/app/src/mitm/cert/install.js +136 -0
- package/app/src/mitm/dns/dnsConfig.js +130 -0
- package/app/src/mitm/manager.js +227 -0
- package/cli.js +110 -144
- package/package.json +1 -1
- package/src/cli/utils/input.js +7 -1
- package/src/cli/utils/menuHelper.js +2 -1
- package/app/.next/server/chunks/9707.js +0 -1
- package/app/.next/static/FcGNHUA9390qBi1g02a_v/_buildManifest.js +0 -1
- package/app/.next/static/chunks/1393-3fdad0258c0b525c.js +0 -1
- package/app/.next/static/chunks/8729-9d273189141eb6fb.js +0 -1
- package/app/.next/static/chunks/app/(dashboard)/dashboard/profile/page-b61f704bc7de9783.js +0 -1
- package/app/.next/static/chunks/app/(dashboard)/dashboard/providers/[id]/page-e8509c35110f8541.js +0 -1
- package/app/.next/static/chunks/app/(dashboard)/dashboard/usage/page-15eac98ba6db9df4.js +0 -1
- package/app/.next/static/chunks/app/_global-error/page-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/auth/login/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/auth/logout/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/alias/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/claude-settings/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/codex-settings/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/droid-settings/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/cli-tools/openclaw-settings/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/cloud/auth/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/cloud/credentials/update/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/cloud/model/resolve/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/cloud/models/alias/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/combos/[id]/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/combos/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/init/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/keys/[id]/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/keys/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/models/alias/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/models/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/[provider]/[action]/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/cursor/auto-import/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/cursor/import/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/auto-import/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/import/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/social-authorize/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/oauth/kiro/social-exchange/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/pricing/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/provider-nodes/[id]/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/provider-nodes/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/provider-nodes/validate/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/models/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/providers/[id]/test/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/providers/client/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/providers/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/providers/validate/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/settings/require-login/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/settings/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/shutdown/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/sync/cloud/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/sync/initialize/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/tags/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/translator/load/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/translator/save/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/translator/send/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/translator/translate/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/usage/[connectionId]/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/usage/history/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/usage/request-logs/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/v1/api/chat/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/v1/chat/completions/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/v1/messages/count_tokens/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/v1/messages/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/v1/models/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/v1/responses/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/v1/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/v1beta/models/[...path]/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/api/v1beta/models/route-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/app/page-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/app-error-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/forbidden-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/not-found-901ec69b71429e39.js +0 -1
- package/app/.next/static/chunks/next/dist/client/components/builtin/unauthorized-901ec69b71429e39.js +0 -1
- package/app/.next/static/css/69b23ffd995e0cf4.css +0 -3
- /package/app/.next/static/{FcGNHUA9390qBi1g02a_v → jnuJ7xmQaeiHg9oUUDqGs}/_ssgManifest.js +0 -0
package/app/package.json
CHANGED
|
Binary file
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const os = require("os");
|
|
4
|
+
|
|
5
|
+
const TARGET_HOST = "daily-cloudcode-pa.googleapis.com";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generate self-signed SSL certificate using selfsigned (pure JS, no openssl needed)
|
|
9
|
+
*/
|
|
10
|
+
async function generateCert() {
|
|
11
|
+
const certDir = path.join(os.homedir(), ".9router", "mitm");
|
|
12
|
+
const keyPath = path.join(certDir, "server.key");
|
|
13
|
+
const certPath = path.join(certDir, "server.crt");
|
|
14
|
+
|
|
15
|
+
if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
|
|
16
|
+
console.log("✅ SSL certificate already exists");
|
|
17
|
+
return { key: keyPath, cert: certPath };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!fs.existsSync(certDir)) {
|
|
21
|
+
fs.mkdirSync(certDir, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const selfsigned = require("selfsigned");
|
|
25
|
+
const attrs = [{ name: "commonName", value: TARGET_HOST }];
|
|
26
|
+
const notAfter = new Date();
|
|
27
|
+
notAfter.setFullYear(notAfter.getFullYear() + 1);
|
|
28
|
+
const pems = await selfsigned.generate(attrs, {
|
|
29
|
+
keySize: 2048,
|
|
30
|
+
algorithm: "sha256",
|
|
31
|
+
notAfterDate: notAfter,
|
|
32
|
+
extensions: [
|
|
33
|
+
{ name: "subjectAltName", altNames: [{ type: 2, value: TARGET_HOST }] }
|
|
34
|
+
]
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
fs.writeFileSync(keyPath, pems.private);
|
|
38
|
+
fs.writeFileSync(certPath, pems.cert);
|
|
39
|
+
|
|
40
|
+
console.log(`✅ Generated SSL certificate for ${TARGET_HOST}`);
|
|
41
|
+
return { key: keyPath, cert: certPath };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = { generateCert };
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const crypto = require("crypto");
|
|
3
|
+
const { exec } = require("child_process");
|
|
4
|
+
const { execWithPassword } = require("../dns/dnsConfig.js");
|
|
5
|
+
|
|
6
|
+
const IS_WIN = process.platform === "win32";
|
|
7
|
+
|
|
8
|
+
// Get SHA1 fingerprint from cert file using Node.js crypto
|
|
9
|
+
function getCertFingerprint(certPath) {
|
|
10
|
+
const pem = fs.readFileSync(certPath, "utf-8");
|
|
11
|
+
const der = Buffer.from(pem.replace(/-----[^-]+-----/g, "").replace(/\s/g, ""), "base64");
|
|
12
|
+
return crypto.createHash("sha1").update(der).digest("hex").toUpperCase().match(/.{2}/g).join(":");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Check if certificate is already installed in system store
|
|
17
|
+
*/
|
|
18
|
+
async function checkCertInstalled(certPath) {
|
|
19
|
+
if (IS_WIN) {
|
|
20
|
+
return checkCertInstalledWindows(certPath);
|
|
21
|
+
}
|
|
22
|
+
return checkCertInstalledMac(certPath);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function checkCertInstalledMac(certPath) {
|
|
26
|
+
return new Promise((resolve) => {
|
|
27
|
+
try {
|
|
28
|
+
const fingerprint = getCertFingerprint(certPath);
|
|
29
|
+
exec(`security find-certificate -a -Z /Library/Keychains/System.keychain | grep -i "${fingerprint}"`, (error) => {
|
|
30
|
+
resolve(!error);
|
|
31
|
+
});
|
|
32
|
+
} catch {
|
|
33
|
+
resolve(false);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function checkCertInstalledWindows(certPath) {
|
|
39
|
+
return new Promise((resolve) => {
|
|
40
|
+
// Check Root store for our cert by subject name
|
|
41
|
+
exec("certutil -store Root daily-cloudcode-pa.googleapis.com", (error) => {
|
|
42
|
+
resolve(!error);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Install SSL certificate to system trust store
|
|
49
|
+
*/
|
|
50
|
+
async function installCert(sudoPassword, certPath) {
|
|
51
|
+
if (!fs.existsSync(certPath)) {
|
|
52
|
+
throw new Error(`Certificate file not found: ${certPath}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const isInstalled = await checkCertInstalled(certPath);
|
|
56
|
+
if (isInstalled) {
|
|
57
|
+
console.log("✅ Certificate already installed");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (IS_WIN) {
|
|
62
|
+
await installCertWindows(certPath);
|
|
63
|
+
} else {
|
|
64
|
+
await installCertMac(sudoPassword, certPath);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function installCertMac(sudoPassword, certPath) {
|
|
69
|
+
const command = `security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "${certPath}"`;
|
|
70
|
+
try {
|
|
71
|
+
await execWithPassword(command, sudoPassword);
|
|
72
|
+
console.log(`✅ Installed certificate to system keychain: ${certPath}`);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
const msg = error.message?.includes("canceled") ? "User canceled authorization" : "Certificate install failed";
|
|
75
|
+
throw new Error(msg);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function installCertWindows(certPath) {
|
|
80
|
+
// Use PowerShell elevated to add cert to Root store
|
|
81
|
+
const psCommand = `Start-Process certutil -ArgumentList '-addstore','Root','${certPath.replace(/'/g, "''")}' -Verb RunAs -Wait`;
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
exec(`powershell -Command "${psCommand}"`, (error) => {
|
|
84
|
+
if (error) {
|
|
85
|
+
reject(new Error(`Failed to install certificate: ${error.message}`));
|
|
86
|
+
} else {
|
|
87
|
+
console.log(`✅ Installed certificate to Windows Root store`);
|
|
88
|
+
resolve();
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Uninstall SSL certificate from system store
|
|
96
|
+
*/
|
|
97
|
+
async function uninstallCert(sudoPassword, certPath) {
|
|
98
|
+
const isInstalled = await checkCertInstalled(certPath);
|
|
99
|
+
if (!isInstalled) {
|
|
100
|
+
console.log("Certificate not found in system store");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (IS_WIN) {
|
|
105
|
+
await uninstallCertWindows();
|
|
106
|
+
} else {
|
|
107
|
+
await uninstallCertMac(sudoPassword, certPath);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async function uninstallCertMac(sudoPassword, certPath) {
|
|
112
|
+
const fingerprint = getCertFingerprint(certPath).replace(/:/g, "");
|
|
113
|
+
const command = `security delete-certificate -Z "${fingerprint}" /Library/Keychains/System.keychain`;
|
|
114
|
+
try {
|
|
115
|
+
await execWithPassword(command, sudoPassword);
|
|
116
|
+
console.log("✅ Uninstalled certificate from system keychain");
|
|
117
|
+
} catch (err) {
|
|
118
|
+
throw new Error("Failed to uninstall certificate");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function uninstallCertWindows() {
|
|
123
|
+
const psCommand = `Start-Process certutil -ArgumentList '-delstore','Root','daily-cloudcode-pa.googleapis.com' -Verb RunAs -Wait`;
|
|
124
|
+
return new Promise((resolve, reject) => {
|
|
125
|
+
exec(`powershell -Command "${psCommand}"`, (error) => {
|
|
126
|
+
if (error) {
|
|
127
|
+
reject(new Error(`Failed to uninstall certificate: ${error.message}`));
|
|
128
|
+
} else {
|
|
129
|
+
console.log("✅ Uninstalled certificate from Windows Root store");
|
|
130
|
+
resolve();
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
module.exports = { installCert, uninstallCert, checkCertInstalled };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
const { exec, spawn } = require("child_process");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
|
|
5
|
+
const TARGET_HOST = "daily-cloudcode-pa.googleapis.com";
|
|
6
|
+
const IS_WIN = process.platform === "win32";
|
|
7
|
+
const HOSTS_FILE = IS_WIN
|
|
8
|
+
? path.join(process.env.SystemRoot || "C:\\Windows", "System32", "drivers", "etc", "hosts")
|
|
9
|
+
: "/etc/hosts";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Execute command with sudo password via stdin (macOS/Linux only)
|
|
13
|
+
*/
|
|
14
|
+
function execWithPassword(command, password) {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const child = spawn("sudo", ["-S", "sh", "-c", command], {
|
|
17
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
let stdout = "";
|
|
21
|
+
let stderr = "";
|
|
22
|
+
child.stdout.on("data", (d) => { stdout += d; });
|
|
23
|
+
child.stderr.on("data", (d) => { stderr += d; });
|
|
24
|
+
|
|
25
|
+
child.on("close", (code) => {
|
|
26
|
+
if (code === 0) resolve(stdout);
|
|
27
|
+
else reject(new Error(stderr || `Exit code ${code}`));
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
child.stdin.write(`${password}\n`);
|
|
31
|
+
child.stdin.end();
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Execute elevated command on Windows via PowerShell RunAs
|
|
37
|
+
*/
|
|
38
|
+
function execElevatedWindows(command) {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const psCommand = `Start-Process cmd -ArgumentList '/c','${command.replace(/'/g, "''")}' -Verb RunAs -Wait`;
|
|
41
|
+
exec(`powershell -Command "${psCommand}"`, (error, stdout, stderr) => {
|
|
42
|
+
if (error) {
|
|
43
|
+
reject(new Error(`Elevated command failed: ${error.message}\n${stderr}`));
|
|
44
|
+
} else {
|
|
45
|
+
resolve(stdout);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Check if DNS entry already exists
|
|
53
|
+
*/
|
|
54
|
+
function checkDNSEntry() {
|
|
55
|
+
try {
|
|
56
|
+
const hostsContent = fs.readFileSync(HOSTS_FILE, "utf8");
|
|
57
|
+
return hostsContent.includes(TARGET_HOST);
|
|
58
|
+
} catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Add DNS entry to hosts file
|
|
65
|
+
*/
|
|
66
|
+
async function addDNSEntry(sudoPassword) {
|
|
67
|
+
if (checkDNSEntry()) {
|
|
68
|
+
console.log(`DNS entry for ${TARGET_HOST} already exists`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const entry = `127.0.0.1 ${TARGET_HOST}`;
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
if (IS_WIN) {
|
|
76
|
+
// Windows: use elevated echo >> hosts
|
|
77
|
+
await execElevatedWindows(`echo ${entry} >> "${HOSTS_FILE}"`);
|
|
78
|
+
} else {
|
|
79
|
+
await execWithPassword(`echo "${entry}" >> ${HOSTS_FILE}`, sudoPassword);
|
|
80
|
+
}
|
|
81
|
+
// Flush DNS cache
|
|
82
|
+
if (IS_WIN) {
|
|
83
|
+
await execElevatedWindows("ipconfig /flushdns");
|
|
84
|
+
} else {
|
|
85
|
+
await execWithPassword("dscacheutil -flushcache && killall -HUP mDNSResponder", sudoPassword);
|
|
86
|
+
}
|
|
87
|
+
console.log(`✅ Added DNS entry: ${entry}`);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
const msg = error.message?.includes("incorrect password") ? "Wrong sudo password" : "Failed to add DNS entry";
|
|
90
|
+
throw new Error(msg);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Remove DNS entry from hosts file
|
|
96
|
+
*/
|
|
97
|
+
async function removeDNSEntry(sudoPassword) {
|
|
98
|
+
if (!checkDNSEntry()) {
|
|
99
|
+
console.log(`DNS entry for ${TARGET_HOST} does not exist`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
if (IS_WIN) {
|
|
105
|
+
// Windows: read, filter, write back via elevated PowerShell
|
|
106
|
+
const psScript = `(Get-Content '${HOSTS_FILE}') | Where-Object { $_ -notmatch '${TARGET_HOST}' } | Set-Content '${HOSTS_FILE}'`;
|
|
107
|
+
const psCommand = `Start-Process powershell -ArgumentList '-Command','${psScript.replace(/'/g, "''")}' -Verb RunAs -Wait`;
|
|
108
|
+
await new Promise((resolve, reject) => {
|
|
109
|
+
exec(`powershell -Command "${psCommand}"`, (error) => {
|
|
110
|
+
if (error) reject(new Error(`Failed to remove DNS entry: ${error.message}`));
|
|
111
|
+
else resolve();
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
} else {
|
|
115
|
+
await execWithPassword(`sed -i '' '/${TARGET_HOST}/d' ${HOSTS_FILE}`, sudoPassword);
|
|
116
|
+
}
|
|
117
|
+
// Flush DNS cache
|
|
118
|
+
if (IS_WIN) {
|
|
119
|
+
await execElevatedWindows("ipconfig /flushdns");
|
|
120
|
+
} else {
|
|
121
|
+
await execWithPassword("dscacheutil -flushcache && killall -HUP mDNSResponder", sudoPassword);
|
|
122
|
+
}
|
|
123
|
+
console.log(`✅ Removed DNS entry for ${TARGET_HOST}`);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
const msg = error.message?.includes("incorrect password") ? "Wrong sudo password" : "Failed to remove DNS entry";
|
|
126
|
+
throw new Error(msg);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
module.exports = { addDNSEntry, removeDNSEntry, execWithPassword, checkDNSEntry };
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
const { spawn } = require("child_process");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const os = require("os");
|
|
5
|
+
const { addDNSEntry, removeDNSEntry } = require("./dns/dnsConfig");
|
|
6
|
+
const { generateCert } = require("./cert/generate");
|
|
7
|
+
const { installCert } = require("./cert/install");
|
|
8
|
+
|
|
9
|
+
// Store server process
|
|
10
|
+
let serverProcess = null;
|
|
11
|
+
let serverPid = null;
|
|
12
|
+
// Persist across Next.js hot reloads
|
|
13
|
+
function getCachedPassword() { return globalThis.__mitmSudoPassword || null; }
|
|
14
|
+
function setCachedPassword(pwd) { globalThis.__mitmSudoPassword = pwd; }
|
|
15
|
+
|
|
16
|
+
// server.js is in same directory as this file
|
|
17
|
+
const PID_FILE = path.join(os.homedir(), ".9router", "mitm", ".mitm.pid");
|
|
18
|
+
|
|
19
|
+
// Check if a PID is alive
|
|
20
|
+
function isProcessAlive(pid) {
|
|
21
|
+
try {
|
|
22
|
+
process.kill(pid, 0);
|
|
23
|
+
return true;
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get MITM status
|
|
31
|
+
*/
|
|
32
|
+
async function getMitmStatus() {
|
|
33
|
+
// Check in-memory process first, then fallback to PID file
|
|
34
|
+
let running = serverProcess !== null && !serverProcess.killed;
|
|
35
|
+
let pid = serverPid;
|
|
36
|
+
|
|
37
|
+
if (!running) {
|
|
38
|
+
try {
|
|
39
|
+
if (fs.existsSync(PID_FILE)) {
|
|
40
|
+
const savedPid = parseInt(fs.readFileSync(PID_FILE, "utf-8").trim(), 10);
|
|
41
|
+
if (savedPid && isProcessAlive(savedPid)) {
|
|
42
|
+
running = true;
|
|
43
|
+
pid = savedPid;
|
|
44
|
+
} else {
|
|
45
|
+
// Stale PID file, clean up
|
|
46
|
+
fs.unlinkSync(PID_FILE);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
} catch {
|
|
50
|
+
// Ignore
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Check DNS configuration
|
|
55
|
+
let dnsConfigured = false;
|
|
56
|
+
try {
|
|
57
|
+
const hostsContent = fs.readFileSync("/etc/hosts", "utf-8");
|
|
58
|
+
dnsConfigured = hostsContent.includes("daily-cloudcode-pa.googleapis.com");
|
|
59
|
+
} catch {
|
|
60
|
+
// Ignore
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Check cert
|
|
64
|
+
const certDir = path.join(os.homedir(), ".9router", "mitm");
|
|
65
|
+
const certExists = fs.existsSync(path.join(certDir, "server.crt"));
|
|
66
|
+
|
|
67
|
+
return { running, pid, dnsConfigured, certExists };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Start MITM proxy
|
|
72
|
+
* @param {string} apiKey - 9Router API key
|
|
73
|
+
* @param {string} sudoPassword - Sudo password for DNS/cert operations
|
|
74
|
+
*/
|
|
75
|
+
async function startMitm(apiKey, sudoPassword) {
|
|
76
|
+
// Check if already running
|
|
77
|
+
if (serverProcess && !serverProcess.killed) {
|
|
78
|
+
throw new Error("MITM proxy is already running");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// 1. Generate SSL certificate if not exists
|
|
82
|
+
const certPath = path.join(os.homedir(), ".9router", "mitm", "server.crt");
|
|
83
|
+
if (!fs.existsSync(certPath)) {
|
|
84
|
+
console.log("Generating SSL certificate...");
|
|
85
|
+
await generateCert();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 2. Install certificate to system keychain
|
|
89
|
+
await installCert(sudoPassword, certPath);
|
|
90
|
+
|
|
91
|
+
// 3. Add DNS entry
|
|
92
|
+
console.log("Adding DNS entry...");
|
|
93
|
+
await addDNSEntry(sudoPassword);
|
|
94
|
+
|
|
95
|
+
// 4. Start MITM server
|
|
96
|
+
console.log("Starting MITM server...");
|
|
97
|
+
const serverPath = path.join(process.cwd(), "src/mitm/server.js");
|
|
98
|
+
serverProcess = spawn("node", [serverPath], {
|
|
99
|
+
env: {
|
|
100
|
+
...process.env,
|
|
101
|
+
ROUTER_API_KEY: apiKey,
|
|
102
|
+
NODE_ENV: "production"
|
|
103
|
+
},
|
|
104
|
+
detached: false,
|
|
105
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
serverPid = serverProcess.pid;
|
|
109
|
+
|
|
110
|
+
// Save PID to file
|
|
111
|
+
fs.writeFileSync(PID_FILE, String(serverPid));
|
|
112
|
+
|
|
113
|
+
// Log server output
|
|
114
|
+
serverProcess.stdout.on("data", (data) => {
|
|
115
|
+
console.log(`[MITM Server] ${data.toString().trim()}`);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
serverProcess.stderr.on("data", (data) => {
|
|
119
|
+
console.error(`[MITM Server Error] ${data.toString().trim()}`);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
serverProcess.on("exit", (code) => {
|
|
123
|
+
console.log(`MITM server exited with code ${code}`);
|
|
124
|
+
serverProcess = null;
|
|
125
|
+
serverPid = null;
|
|
126
|
+
|
|
127
|
+
// Remove PID file
|
|
128
|
+
try {
|
|
129
|
+
fs.unlinkSync(PID_FILE);
|
|
130
|
+
} catch (error) {
|
|
131
|
+
// Ignore
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Wait and verify server actually started
|
|
136
|
+
const started = await new Promise((resolve) => {
|
|
137
|
+
let resolved = false;
|
|
138
|
+
const timeout = setTimeout(() => {
|
|
139
|
+
if (!resolved) { resolved = true; resolve(true); }
|
|
140
|
+
}, 2000);
|
|
141
|
+
|
|
142
|
+
serverProcess.on("exit", (code) => {
|
|
143
|
+
clearTimeout(timeout);
|
|
144
|
+
if (!resolved) { resolved = true; resolve(false); }
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Check stderr for error messages
|
|
148
|
+
serverProcess.stderr.on("data", (data) => {
|
|
149
|
+
const msg = data.toString().trim();
|
|
150
|
+
if (msg.includes("Port") && msg.includes("already in use")) {
|
|
151
|
+
clearTimeout(timeout);
|
|
152
|
+
if (!resolved) { resolved = true; resolve(false); }
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
if (!started) {
|
|
158
|
+
throw new Error("MITM server failed to start (port 443 may be in use)");
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
running: true,
|
|
163
|
+
pid: serverPid
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Stop MITM proxy
|
|
169
|
+
* @param {string} sudoPassword - Sudo password for DNS cleanup
|
|
170
|
+
*/
|
|
171
|
+
async function stopMitm(sudoPassword) {
|
|
172
|
+
// 1. Kill server process (in-memory or from PID file)
|
|
173
|
+
const proc = serverProcess;
|
|
174
|
+
if (proc && !proc.killed) {
|
|
175
|
+
console.log("Stopping MITM server...");
|
|
176
|
+
proc.kill("SIGTERM");
|
|
177
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
178
|
+
if (!proc.killed) {
|
|
179
|
+
proc.kill("SIGKILL");
|
|
180
|
+
}
|
|
181
|
+
serverProcess = null;
|
|
182
|
+
serverPid = null;
|
|
183
|
+
} else {
|
|
184
|
+
// Fallback: kill by PID file
|
|
185
|
+
try {
|
|
186
|
+
if (fs.existsSync(PID_FILE)) {
|
|
187
|
+
const savedPid = parseInt(fs.readFileSync(PID_FILE, "utf-8").trim(), 10);
|
|
188
|
+
if (savedPid && isProcessAlive(savedPid)) {
|
|
189
|
+
console.log(`Killing MITM server (PID: ${savedPid})...`);
|
|
190
|
+
process.kill(savedPid, "SIGTERM");
|
|
191
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
192
|
+
if (isProcessAlive(savedPid)) {
|
|
193
|
+
process.kill(savedPid, "SIGKILL");
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
} catch {
|
|
198
|
+
// Ignore
|
|
199
|
+
}
|
|
200
|
+
serverProcess = null;
|
|
201
|
+
serverPid = null;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// 2. Remove DNS entry
|
|
205
|
+
console.log("Removing DNS entry...");
|
|
206
|
+
await removeDNSEntry(sudoPassword);
|
|
207
|
+
|
|
208
|
+
// 3. Remove PID file
|
|
209
|
+
try {
|
|
210
|
+
fs.unlinkSync(PID_FILE);
|
|
211
|
+
} catch (error) {
|
|
212
|
+
// Ignore
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
running: false,
|
|
217
|
+
pid: null
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
module.exports = {
|
|
222
|
+
getMitmStatus,
|
|
223
|
+
startMitm,
|
|
224
|
+
stopMitm,
|
|
225
|
+
getCachedPassword,
|
|
226
|
+
setCachedPassword
|
|
227
|
+
};
|