zevairouter 1.0.53 → 1.0.55
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/CHANGELOG.md +10 -0
- package/cli/app/.next-cli-build/BUILD_ID +1 -1
- package/cli/app/.next-cli-build/app-path-routes-manifest.json +19 -19
- package/cli/app/.next-cli-build/build-manifest.json +2 -2
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/automation/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/context/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/playground/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/terminal/page.js +3 -3
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/terminal/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.html +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.html +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/api/models/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/models/test/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/providers/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/input/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/resize/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/stream/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/version/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/callback.html +1 -1
- package/cli/app/.next-cli-build/server/app/callback.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/quota.rsc +6 -6
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +6 -6
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/index.html +1 -1
- package/cli/app/.next-cli-build/server/app/index.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/landing.html +1 -1
- package/cli/app/.next-cli-build/server/app/landing.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/login.html +1 -1
- package/cli/app/.next-cli-build/server/app/login.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app-paths-manifest.json +19 -19
- package/cli/app/.next-cli-build/server/chunks/3407.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/4746.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/6896.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/7276.js +1 -1
- package/cli/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/pages/404.html +1 -1
- package/cli/app/.next-cli-build/server/pages/500.html +1 -1
- package/cli/app/.next-cli-build/static/chunks/{3702-f8a85fe02d121762.js → 3702-24070e27997eb07a.js} +1 -1
- package/cli/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/terminal/page-1f6733fa5712fc3d.js +4 -0
- package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
- package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
- package/cli/app/package.json +1 -1
- package/cli/package.json +1 -1
- package/cli/src/cli/menus/settings.js +87 -0
- package/package.json +1 -1
- package/src/app/(dashboard)/dashboard/terminal/TerminalPageClient.js +10 -9
- package/cli/app/.next-cli-build/static/chunks/app/(dashboard)/dashboard/terminal/page-72854e35a9d5f79d.js +0 -4
- /package/cli/app/.next-cli-build/static/{KZ2mKpiM-80Yd5c6nmIun → XIBKxMKXhvuza8tkgLUjP}/_buildManifest.js +0 -0
- /package/cli/app/.next-cli-build/static/{KZ2mKpiM-80Yd5c6nmIun → XIBKxMKXhvuza8tkgLUjP}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3570],{63133:(e,t,r)=>{Promise.resolve().then(r.bind(r,92072))},82407:()=>{},92072:(e,t,r)=>{"use strict";r.d(t,{default:()=>h});var n=r(95155),s=r(12115),a=r(8422),i=class{activate(e){this._terminal=e}dispose(){}fit(){let e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;let t=this._terminal._core;(this._terminal.rows!==e.rows||this._terminal.cols!==e.cols)&&(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal||!this._terminal.element||!this._terminal.element.parentElement)return;let e=this._terminal._core._renderService.dimensions;if(0===e.css.cell.width||0===e.css.cell.height)return;let t=0===this._terminal.options.scrollback?0:this._terminal.options.overviewRuler?.width||14,r=window.getComputedStyle(this._terminal.element.parentElement),n=parseInt(r.getPropertyValue("height")),s=Math.max(0,parseInt(r.getPropertyValue("width"))),a=window.getComputedStyle(this._terminal.element),i={top:parseInt(a.getPropertyValue("padding-top")),bottom:parseInt(a.getPropertyValue("padding-bottom")),right:parseInt(a.getPropertyValue("padding-right")),left:parseInt(a.getPropertyValue("padding-left"))},l=i.top+i.bottom;return{cols:Math.max(2,Math.floor((s-(i.right+i.left)-t)/e.css.cell.width)),rows:Math.max(1,Math.floor((n-l)/e.css.cell.height))}}},l=class{constructor(e,t,r,n={}){this._terminal=e,this._regex=t,this._handler=r,this._options=n}provideLinks(e,t){let r=o.computeLink(e,this._regex,this._terminal,this._handler);t(this._addCallbacks(r))}_addCallbacks(e){return e.map(e=>(e.leave=this._options.leave,e.hover=(t,r)=>{if(this._options.hover){let{range:n}=e;this._options.hover(t,r,n)}},e))}},o=class e{static computeLink(t,r,n,s){let a=RegExp(r.source,(r.flags||"")+"g"),[i,l]=e._getWindowedLineStrings(t-1,n),o=i.join(""),c,d=[];for(;c=a.exec(o);){let t=c[0];if(!function(e){try{let t=new URL(e),r=t.password&&t.username?`${t.protocol}//${t.username}:${t.password}@${t.host}`:t.username?`${t.protocol}//${t.username}@${t.host}`:`${t.protocol}//${t.host}`;return e.toLocaleLowerCase().startsWith(r.toLocaleLowerCase())}catch{return!1}}(t))continue;let[r,a]=e._mapStrIdx(n,l,0,c.index),[i,o]=e._mapStrIdx(n,r,a,t.length);if(-1===r||-1===a||-1===i||-1===o)continue;let u={start:{x:a+1,y:r+1},end:{x:o,y:i+1}};d.push({range:u,text:t,activate:s})}return d}static _getWindowedLineStrings(e,t){let r,n=e,s=e,a=0,i="",l=[];if(r=t.buffer.active.getLine(e)){let e=r.translateToString(!0);if(r.isWrapped&&" "!==e[0]){for(a=0;(r=t.buffer.active.getLine(--n))&&a<2048&&(a+=(i=r.translateToString(!0)).length,l.push(i),!(!r.isWrapped||-1!==i.indexOf(" "))););l.reverse()}for(l.push(e),a=0;(r=t.buffer.active.getLine(++s))&&r.isWrapped&&a<2048&&(a+=(i=r.translateToString(!0)).length,l.push(i),-1===i.indexOf(" ")););}return[l,n]}static _mapStrIdx(e,t,r,n){let s=e.buffer.active,a=s.getNullCell(),i=r;for(;n;){let e=s.getLine(t);if(!e)return[-1,-1];for(let r=i;r<e.length;++r){e.getCell(r,a);let i=a.getChars();if(a.getWidth()&&(n-=i.length||1,r===e.length-1&&""===i)){let e=s.getLine(t+1);e&&e.isWrapped&&(e.getCell(0,a),2===a.getWidth()&&(n+=1))}if(n<0)return[t,r]}t++,i=0}return[t,i]}},c=/(https?|HTTPS?):[/]{2}[^\s"'!*(){}|\\\^<>`]*[^\s"':,.!?{}|\\\^~\[\]`()<>]/;function d(e,t){let r=window.open();if(r){try{r.opener=null}catch{}r.location.href=t}else console.warn("Opening link blocked as opener could not be cleared")}var u=class{constructor(e=d,t={}){this._handler=e,this._options=t}activate(e){this._terminal=e;let t=this._options,r=t.urlRegex||c;this._linkProvider=this._terminal.registerLinkProvider(new l(this._terminal,r,this._handler,t))}dispose(){this._linkProvider?.dispose()}};function h(){let e=(0,s.useRef)(null),t=(0,s.useRef)(null),r=(0,s.useRef)(null),l=(0,s.useRef)(""),o=(0,s.useRef)(""),c=(0,s.useRef)(null),d=(0,s.useRef)([]),h=(0,s.useRef)(null),m=(0,s.useRef)(!1),p=(0,s.useRef)(""),[f,b]=(0,s.useState)("checking"),[x,g]=(0,s.useState)(""),[w,y]=(0,s.useState)(!1),[k,v]=(0,s.useState)(""),[j,N]=(0,s.useState)(""),[_,S]=(0,s.useState)("connecting"),[C,E]=(0,s.useState)("Starting shell…"),[L,A]=(0,s.useState)({shell:"",mode:""}),T=(0,s.useCallback)(async()=>{g("");try{let e=await fetch("/api/terminal/auth/status",{cache:"no-store",credentials:"same-origin"}),t=await e.json().catch(()=>({}));if(403===e.status){g(t?.error||"Access forbidden."),b("unlock");return}if(401===e.status){g("Log in to the dashboard first."),b("unlock");return}if(!t.configured)return void b("setup");if(t.unlocked)return void b("open");b("unlock")}catch(e){g(e?.message||"Failed to check terminal lock"),b("unlock")}},[]);(0,s.useEffect)(()=>{T()},[T]);let $=async e=>{e.preventDefault(),y(!0),g("");try{let e=await fetch("/api/terminal/auth/setup",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"same-origin",body:JSON.stringify({password:k,confirm:j})}),t=await e.json().catch(()=>({}));if(!e.ok)return void g(t.error||"Setup failed");v(""),N(""),b("open")}catch(e){g(e?.message||"Setup failed")}finally{y(!1)}},R=async e=>{e.preventDefault(),y(!0),g("");try{let e=await fetch("/api/terminal/auth/unlock",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"same-origin",body:JSON.stringify({password:k})}),t=await e.json().catch(()=>({}));if(!e.ok)return void g(t.error||"Unlock failed");v(""),b("open")}catch(e){g(e?.message||"Unlock failed")}finally{y(!1)}},P=async()=>{try{await fetch("/api/terminal/auth/unlock",{method:"DELETE",credentials:"same-origin"})}catch{}let e=l.current;if(l.current="",e&&fetch(`/api/terminal/session/${e}`,{method:"DELETE",credentials:"same-origin",keepalive:!0}).catch(()=>{}),c.current){try{c.current.close()}catch{}c.current=null}v(""),b("unlock")},O=(0,s.useCallback)(async()=>{let e=l.current;if(!e||0===d.current.length)return;let r=d.current.join("");d.current=[];try{let n=await fetch(`/api/terminal/session/${e}/input`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:r}),cache:"no-store",credentials:"same-origin"});!n.ok&&t.current&&(423===n.status?(t.current.write("\r\n\x1b[31m[terminal locked]\x1b[0m\r\n"),b("unlock")):(403===n.status||401===n.status)&&t.current.write(`\r
|
|
2
|
+
\x1b[31m[input blocked: ${n.status}]\x1b[0m\r
|
|
3
|
+
`))}catch{}},[]),F=(0,s.useCallback)(e=>{e&&l.current&&(d.current.push(e),h.current||(h.current=setTimeout(()=>{h.current=null,O()},8)))},[O]),M=(0,s.useCallback)(e=>{let r=t.current;if(!r)return;let n=o.current;if(!("pipe"===n||!n))return void F(e);if("\x03"===e){p.current="",r.write("^C\r\n"),F("\x03\n");return}if("\r"===e||"\n"===e||"\r\n"===e){let e=p.current;p.current="",r.write("\r\n"),F(`${e}
|
|
4
|
+
`);return}if(""===e||"\b"===e){p.current.length>0&&(p.current=p.current.slice(0,-1),r.write("\b \b"));return}32>e.charCodeAt(0)||e.startsWith("\x1b")||(p.current+=e,r.write(e))},[F]),D=(0,s.useCallback)(async()=>{let e=l.current,r=t.current;if(e&&r)try{await fetch(`/api/terminal/session/${e}/resize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cols:r.cols,rows:r.rows}),cache:"no-store",credentials:"same-origin"})}catch{}},[]),I=(0,s.useCallback)(()=>{try{t.current?.focus()}catch{}},[]),z=(0,s.useCallback)((e,t)=>{if(c.current)try{c.current.close()}catch{}let r=new EventSource(`/api/terminal/session/${e}/stream`,{withCredentials:!0});c.current=r,r.onopen=()=>{m.current||(S("ready"),E("Connected — click terminal & type"),I())},r.onmessage=e=>{let r;if(!m.current){try{r=JSON.parse(e.data)}catch{return}"data"===r.type&&"string"==typeof r.data?t.write(r.data):"ready"===r.type?(o.current=r.mode||o.current,A({shell:r.shell||"",mode:r.mode||""}),S(!1===r.alive?"closed":"ready"),E(!1===r.alive?"Shell exited":"Connected — click terminal & type"),I()):"exit"===r.type&&(S("closed"),E("Shell exited"),t.write("\r\n\x1b[90m[session ended]\x1b[0m\r\n"))}},r.onerror=()=>{m.current||(S(e=>"ready"===e?"connecting":e),E("Reconnecting…"))}},[I]),W=(0,s.useCallback)(async(e,t)=>{let r;S("connecting"),E("Starting shell…"),p.current="";try{t.fit()}catch{}let n=e.cols||120,s=e.rows||40;try{r=await fetch("/api/terminal/session",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cols:n,rows:s}),cache:"no-store",credentials:"same-origin"})}catch(t){S("error"),E(t?.message||"Failed to reach server"),e.writeln(`\x1b[31mFailed to create session: ${t?.message||"network error"}\x1b[0m`);return}if(403===r.status){S("forbidden"),E("Forbidden"),e.writeln("\x1b[33mTerminal access forbidden.\x1b[0m");return}if(401===r.status){S("error"),E("Unauthorized"),e.writeln("\x1b[31mUnauthorized — log in to the dashboard first.\x1b[0m");return}if(423===r.status){S("error"),E("Locked"),b("unlock");return}let a=await r.json().catch(()=>({}));if(!r.ok||!a?.session?.id){S("error"),E(a?.error||"Create failed"),e.writeln(`\x1b[31m${a?.error||"Failed to create terminal session"}\x1b[0m`);return}l.current=a.session.id,o.current=a.session.mode||"pipe",A({shell:a.session.shell||"",mode:a.session.mode||""}),z(a.session.id,e),I()},[z,I]),U=(0,s.useCallback)(async()=>{let e=l.current;if(l.current="",o.current="",p.current="",d.current=[],c.current){try{c.current.close()}catch{}c.current=null}e&&fetch(`/api/terminal/session/${e}`,{method:"DELETE",credentials:"same-origin"}).catch(()=>{});let n=t.current,s=r.current;n&&s&&(n.reset(),n.clear(),await W(n,s))},[W]);if((0,s.useEffect)(()=>{if("open"!==f)return;m.current=!1;let n=e.current;if(!n)return;let s=new a.B({cursorBlink:!0,cursorStyle:"bar",fontSize:13,fontFamily:'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',lineHeight:1.25,scrollback:5e3,allowProposedApi:!0,disableStdin:!1,theme:{background:"#0d0d0d",foreground:"#e8e8e8",cursor:"#E56A4A",cursorAccent:"#0d0d0d",selectionBackground:"rgba(229, 106, 74, 0.35)",black:"#1a1a1a",red:"#f87171",green:"#4ade80",yellow:"#fbbf24",blue:"#60a5fa",magenta:"#c084fc",cyan:"#22d3ee",white:"#e5e5e5",brightBlack:"#737373",brightRed:"#fca5a5",brightGreen:"#86efac",brightYellow:"#fde68a",brightBlue:"#93c5fd",brightMagenta:"#d8b4fe",brightCyan:"#67e8f9",brightWhite:"#fafafa"}}),o=new i,d=new u;s.loadAddon(o),s.loadAddon(d),s.open(n);try{n.tabIndex=0;let e=n.querySelector("textarea");e&&(e.tabIndex=0,e.setAttribute("autocomplete","off"),e.setAttribute("spellcheck","false"))}catch{}t.current=s,r.current=o;try{o.fit()}catch{}let p=s.onData(e=>M(e)),b=()=>{try{o.fit(),D()}catch{}},x=()=>I();n.addEventListener("mousedown",x),n.addEventListener("click",x),n.addEventListener("focus",I);let g="u">typeof ResizeObserver?new ResizeObserver(b):null;return g?.observe(n),window.addEventListener("resize",b),requestAnimationFrame(()=>{try{o.fit()}catch{}I()}),W(s,o),()=>{m.current=!0,g?.disconnect(),window.removeEventListener("resize",b),n.removeEventListener("mousedown",x),n.removeEventListener("click",x),n.removeEventListener("focus",I);try{p.dispose()}catch{}if(h.current&&(clearTimeout(h.current),h.current=null),c.current){try{c.current.close()}catch{}c.current=null}let e=l.current;l.current="",e&&fetch(`/api/terminal/session/${e}`,{method:"DELETE",keepalive:!0,credentials:"same-origin"}).catch(()=>{});try{s.dispose()}catch{}t.current=null,r.current=null}},[f,M,D,W,I]),"checking"===f)return(0,n.jsx)("div",{className:"flex h-full min-h-0 w-full items-center justify-center bg-[#0d0d0d] text-sm text-white/50",children:"Checking terminal lock…"});if("setup"===f||"unlock"===f){let e="setup"===f;return(0,n.jsx)("div",{className:"flex h-full min-h-0 w-full flex-col items-center justify-center bg-[#0d0d0d] px-4",children:(0,n.jsxs)("div",{className:"w-full max-w-md rounded-2xl border border-white/10 bg-white/[0.03] p-6 shadow-xl",children:[(0,n.jsxs)("div",{className:"mb-4 flex items-center gap-3",children:[(0,n.jsx)("div",{className:"flex size-10 items-center justify-center rounded-xl bg-[color:var(--brand,#E56A4A)]/15 text-[color:var(--brand,#E56A4A)]",children:(0,n.jsx)("span",{className:"material-symbols-outlined text-[22px]",children:e?"key":"lock"})}),(0,n.jsxs)("div",{children:[(0,n.jsx)("h1",{className:"text-base font-semibold text-white/95",children:e?"Set terminal password":"Unlock terminal"}),(0,n.jsx)("p",{className:"text-xs text-white/45",children:e?"First time — pick a password different from dashboard login.":"Dashboard login is not enough. Enter your terminal password."})]})]}),(0,n.jsxs)("form",{onSubmit:e?$:R,className:"space-y-3",children:[e?(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)("label",{className:"block space-y-1",children:[(0,n.jsx)("span",{className:"text-[11px] font-medium uppercase tracking-wide text-white/40",children:"New terminal password"}),(0,n.jsx)("input",{type:"password",autoFocus:!0,autoComplete:"new-password",value:k,onChange:e=>v(e.target.value),className:"w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2.5 text-sm text-white outline-none focus:border-[color:var(--brand,#E56A4A)]/60",placeholder:"Min 6 characters",required:!0,minLength:6})]}),(0,n.jsxs)("label",{className:"block space-y-1",children:[(0,n.jsx)("span",{className:"text-[11px] font-medium uppercase tracking-wide text-white/40",children:"Confirm"}),(0,n.jsx)("input",{type:"password",autoComplete:"new-password",value:j,onChange:e=>N(e.target.value),className:"w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2.5 text-sm text-white outline-none focus:border-[color:var(--brand,#E56A4A)]/60",placeholder:"Repeat password",required:!0,minLength:6})]}),(0,n.jsxs)("p",{className:"text-[11px] leading-relaxed text-white/35",children:["Must ",(0,n.jsx)("strong",{className:"text-white/55",children:"not"})," match the dashboard password. Unlock lasts ~4 hours on this browser."]})]}):(0,n.jsxs)("label",{className:"block space-y-1",children:[(0,n.jsx)("span",{className:"text-[11px] font-medium uppercase tracking-wide text-white/40",children:"Terminal password"}),(0,n.jsx)("input",{type:"password",autoFocus:!0,autoComplete:"current-password",value:k,onChange:e=>v(e.target.value),className:"w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2.5 text-sm text-white outline-none focus:border-[color:var(--brand,#E56A4A)]/60",placeholder:"••••••••",required:!0})]}),x?(0,n.jsx)("p",{className:"rounded-lg border border-red-500/30 bg-red-500/10 px-3 py-2 text-xs text-red-300",children:x}):null,(0,n.jsx)("button",{type:"submit",disabled:w,className:"w-full rounded-lg bg-[color:var(--brand,#E56A4A)] px-3 py-2.5 text-sm font-semibold text-white transition hover:brightness-110 disabled:opacity-50",children:w?"Please wait…":e?"Save & open terminal":"Unlock"})]}),"unlock"===f?(0,n.jsxs)("p",{className:"mt-3 text-center text-[11px] leading-relaxed text-white/35",children:["Forgot terminal password? On the host run CLI →"," ",(0,n.jsx)("code",{className:"text-white/55",children:"Settings → Clear Terminal Password"})," ","then set a new one here. Reset is not available in the browser."]}):null,(0,n.jsx)("p",{className:"mt-4 text-center text-[11px] text-white/30",children:"Protected by dashboard login + terminal password"})]})})}return(0,n.jsxs)("div",{className:"flex h-full min-h-0 w-full flex-col bg-[#0d0d0d]",children:[(0,n.jsxs)("div",{className:"flex shrink-0 items-center justify-between gap-3 border-b border-white/10 px-4 py-2.5",children:[(0,n.jsxs)("div",{className:"flex min-w-0 items-center gap-3",children:[(0,n.jsxs)("div",{className:"flex items-center gap-2",children:[(0,n.jsx)("span",{className:`inline-block size-2 rounded-full ${"ready"===_?"bg-emerald-500":"connecting"===_?"bg-amber-400 animate-pulse":"forbidden"===_?"bg-amber-500":"bg-red-500"}`}),(0,n.jsx)("span",{className:"text-sm font-semibold text-white/90",children:"Terminal"})]}),(0,n.jsxs)("span",{className:"truncate text-xs text-white/45",children:[C,L.shell?` \xb7 ${L.shell}`:"",L.mode?` \xb7 ${L.mode}`:""]})]}),(0,n.jsxs)("div",{className:"flex items-center gap-2",children:[(0,n.jsx)("button",{type:"button",onClick:P,className:"rounded-lg border border-white/10 bg-white/5 px-3 py-1.5 text-xs font-medium text-white/70 transition hover:border-white/20 hover:text-white",title:"Lock terminal (require password again)",children:"Lock"}),(0,n.jsx)("button",{type:"button",onClick:U,className:"rounded-lg border border-white/10 bg-white/5 px-3 py-1.5 text-xs font-medium text-white/80 transition hover:border-[color:var(--brand,#E56A4A)]/50 hover:bg-white/10 hover:text-white",children:"New session"})]})]}),(0,n.jsx)("div",{className:"relative min-h-0 flex-1",onMouseDown:I,children:(0,n.jsx)("div",{ref:e,className:"absolute inset-0 px-2 py-2 outline-none"})}),(0,n.jsx)("div",{className:"shrink-0 border-t border-white/10 px-4 py-1.5 text-[11px] text-white/35",children:"Dashboard login + terminal password \xb7 click the black area then type \xb7 idle sessions close after 30m"})]})}r(82407)}},e=>{e.O(0,[1838,1507,8441,3794,7358],()=>e(e.s=63133)),_N_E=e.O()}]);
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Minimal PTY bridge for ZevaiRouter web terminal.
|
|
4
|
+
|
|
5
|
+
stdin -> PTY master (keystrokes)
|
|
6
|
+
stdout <- PTY master (shell output), raw binary
|
|
7
|
+
stderr = control / errors (utf-8 text lines)
|
|
8
|
+
|
|
9
|
+
Optional control on a side channel is not needed: resize arrives as
|
|
10
|
+
OSC-like escape on stdin: \\x1b]9999;<cols>;<rows>\\x07
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import errno
|
|
15
|
+
import fcntl
|
|
16
|
+
import os
|
|
17
|
+
import select
|
|
18
|
+
import signal
|
|
19
|
+
import struct
|
|
20
|
+
import sys
|
|
21
|
+
import termios
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def set_winsize(fd: int, rows: int, cols: int) -> None:
|
|
25
|
+
try:
|
|
26
|
+
packed = struct.pack("HHHH", max(5, rows), max(20, cols), 0, 0)
|
|
27
|
+
fcntl.ioctl(fd, termios.TIOCSWINSZ, packed)
|
|
28
|
+
except Exception:
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def main() -> int:
|
|
33
|
+
cols = int(sys.argv[1]) if len(sys.argv) > 1 else 120
|
|
34
|
+
rows = int(sys.argv[2]) if len(sys.argv) > 2 else 40
|
|
35
|
+
shell = os.environ.get("SHELL") or ("/bin/bash" if os.path.exists("/bin/bash") else "/bin/sh")
|
|
36
|
+
cwd = os.path.expanduser("~")
|
|
37
|
+
|
|
38
|
+
pid, master = pty_fork = _fork_pty()
|
|
39
|
+
if pid == 0:
|
|
40
|
+
# child
|
|
41
|
+
try:
|
|
42
|
+
os.chdir(cwd)
|
|
43
|
+
except Exception:
|
|
44
|
+
pass
|
|
45
|
+
os.environ.setdefault("TERM", "xterm-256color")
|
|
46
|
+
os.environ.setdefault("COLORTERM", "truecolor")
|
|
47
|
+
os.environ.setdefault("FORCE_COLOR", "1")
|
|
48
|
+
try:
|
|
49
|
+
os.execv(shell, [shell, "-il"])
|
|
50
|
+
except Exception:
|
|
51
|
+
os.execv("/bin/sh", ["/bin/sh", "-i"])
|
|
52
|
+
return 1
|
|
53
|
+
|
|
54
|
+
set_winsize(master, rows, cols)
|
|
55
|
+
|
|
56
|
+
# Non-blocking master + stdin
|
|
57
|
+
for fd in (master, sys.stdin.fileno()):
|
|
58
|
+
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
|
|
59
|
+
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
|
|
60
|
+
|
|
61
|
+
# Binary stdout
|
|
62
|
+
stdout = sys.stdout.buffer
|
|
63
|
+
stdin = sys.stdin.buffer
|
|
64
|
+
|
|
65
|
+
resize_buf = b""
|
|
66
|
+
|
|
67
|
+
def handle_resize_escape(chunk: bytes) -> bytes:
|
|
68
|
+
"""Strip and apply embedded resize escapes, return remaining bytes."""
|
|
69
|
+
nonlocal resize_buf
|
|
70
|
+
data = resize_buf + chunk
|
|
71
|
+
out = bytearray()
|
|
72
|
+
i = 0
|
|
73
|
+
while i < len(data):
|
|
74
|
+
# ESC ] 9999 ; cols ; rows BEL
|
|
75
|
+
if data[i] == 0x1B and data[i : i + 6] == b"\x1b]9999;":
|
|
76
|
+
end = data.find(b"\x07", i + 6)
|
|
77
|
+
if end < 0:
|
|
78
|
+
resize_buf = data[i:]
|
|
79
|
+
return bytes(out)
|
|
80
|
+
payload = data[i + 6 : end].decode("ascii", "ignore")
|
|
81
|
+
try:
|
|
82
|
+
c_s, r_s = payload.split(";", 1)
|
|
83
|
+
set_winsize(master, int(r_s), int(c_s))
|
|
84
|
+
except Exception:
|
|
85
|
+
pass
|
|
86
|
+
i = end + 1
|
|
87
|
+
resize_buf = b""
|
|
88
|
+
continue
|
|
89
|
+
out.append(data[i])
|
|
90
|
+
i += 1
|
|
91
|
+
resize_buf = b""
|
|
92
|
+
return bytes(out)
|
|
93
|
+
|
|
94
|
+
alive = True
|
|
95
|
+
|
|
96
|
+
def on_chld(signum, frame): # noqa: ARG001
|
|
97
|
+
nonlocal alive
|
|
98
|
+
alive = False
|
|
99
|
+
|
|
100
|
+
signal.signal(signal.SIGCHLD, on_chld)
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
while alive:
|
|
104
|
+
try:
|
|
105
|
+
r, _, _ = select.select([master, sys.stdin.fileno()], [], [], 0.25)
|
|
106
|
+
except InterruptedError:
|
|
107
|
+
continue
|
|
108
|
+
|
|
109
|
+
if master in r:
|
|
110
|
+
try:
|
|
111
|
+
data = os.read(master, 8192)
|
|
112
|
+
except OSError as e:
|
|
113
|
+
if e.errno in (errno.EIO, errno.EAGAIN, errno.EWOULDBLOCK):
|
|
114
|
+
data = b""
|
|
115
|
+
else:
|
|
116
|
+
break
|
|
117
|
+
if not data:
|
|
118
|
+
# EIO often means child exited
|
|
119
|
+
if not alive:
|
|
120
|
+
break
|
|
121
|
+
else:
|
|
122
|
+
stdout.write(data)
|
|
123
|
+
stdout.flush()
|
|
124
|
+
|
|
125
|
+
if sys.stdin.fileno() in r:
|
|
126
|
+
try:
|
|
127
|
+
data = stdin.read(8192)
|
|
128
|
+
except Exception:
|
|
129
|
+
data = b""
|
|
130
|
+
if data is None:
|
|
131
|
+
data = b""
|
|
132
|
+
if data == b"" and not alive:
|
|
133
|
+
break
|
|
134
|
+
if data:
|
|
135
|
+
cleaned = handle_resize_escape(data)
|
|
136
|
+
if cleaned:
|
|
137
|
+
try:
|
|
138
|
+
os.write(master, cleaned)
|
|
139
|
+
except OSError:
|
|
140
|
+
break
|
|
141
|
+
finally:
|
|
142
|
+
try:
|
|
143
|
+
os.close(master)
|
|
144
|
+
except Exception:
|
|
145
|
+
pass
|
|
146
|
+
try:
|
|
147
|
+
os.waitpid(pid, 0)
|
|
148
|
+
except Exception:
|
|
149
|
+
pass
|
|
150
|
+
return 0
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _fork_pty():
|
|
154
|
+
import pty
|
|
155
|
+
|
|
156
|
+
return pty.fork()
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
if __name__ == "__main__":
|
|
160
|
+
try:
|
|
161
|
+
raise SystemExit(main())
|
|
162
|
+
except KeyboardInterrupt:
|
|
163
|
+
raise SystemExit(0)
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Minimal PTY bridge for ZevaiRouter web terminal.
|
|
4
|
+
|
|
5
|
+
stdin -> PTY master (keystrokes)
|
|
6
|
+
stdout <- PTY master (shell output), raw binary
|
|
7
|
+
stderr = control / errors (utf-8 text lines)
|
|
8
|
+
|
|
9
|
+
Optional control on a side channel is not needed: resize arrives as
|
|
10
|
+
OSC-like escape on stdin: \\x1b]9999;<cols>;<rows>\\x07
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import errno
|
|
15
|
+
import fcntl
|
|
16
|
+
import os
|
|
17
|
+
import select
|
|
18
|
+
import signal
|
|
19
|
+
import struct
|
|
20
|
+
import sys
|
|
21
|
+
import termios
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def set_winsize(fd: int, rows: int, cols: int) -> None:
|
|
25
|
+
try:
|
|
26
|
+
packed = struct.pack("HHHH", max(5, rows), max(20, cols), 0, 0)
|
|
27
|
+
fcntl.ioctl(fd, termios.TIOCSWINSZ, packed)
|
|
28
|
+
except Exception:
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def main() -> int:
|
|
33
|
+
cols = int(sys.argv[1]) if len(sys.argv) > 1 else 120
|
|
34
|
+
rows = int(sys.argv[2]) if len(sys.argv) > 2 else 40
|
|
35
|
+
shell = os.environ.get("SHELL") or ("/bin/bash" if os.path.exists("/bin/bash") else "/bin/sh")
|
|
36
|
+
cwd = os.path.expanduser("~")
|
|
37
|
+
|
|
38
|
+
pid, master = pty_fork = _fork_pty()
|
|
39
|
+
if pid == 0:
|
|
40
|
+
# child
|
|
41
|
+
try:
|
|
42
|
+
os.chdir(cwd)
|
|
43
|
+
except Exception:
|
|
44
|
+
pass
|
|
45
|
+
os.environ.setdefault("TERM", "xterm-256color")
|
|
46
|
+
os.environ.setdefault("COLORTERM", "truecolor")
|
|
47
|
+
os.environ.setdefault("FORCE_COLOR", "1")
|
|
48
|
+
try:
|
|
49
|
+
os.execv(shell, [shell, "-il"])
|
|
50
|
+
except Exception:
|
|
51
|
+
os.execv("/bin/sh", ["/bin/sh", "-i"])
|
|
52
|
+
return 1
|
|
53
|
+
|
|
54
|
+
set_winsize(master, rows, cols)
|
|
55
|
+
|
|
56
|
+
# Non-blocking master + stdin
|
|
57
|
+
for fd in (master, sys.stdin.fileno()):
|
|
58
|
+
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
|
|
59
|
+
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
|
|
60
|
+
|
|
61
|
+
# Binary stdout
|
|
62
|
+
stdout = sys.stdout.buffer
|
|
63
|
+
stdin = sys.stdin.buffer
|
|
64
|
+
|
|
65
|
+
resize_buf = b""
|
|
66
|
+
|
|
67
|
+
def handle_resize_escape(chunk: bytes) -> bytes:
|
|
68
|
+
"""Strip and apply embedded resize escapes, return remaining bytes."""
|
|
69
|
+
nonlocal resize_buf
|
|
70
|
+
data = resize_buf + chunk
|
|
71
|
+
out = bytearray()
|
|
72
|
+
i = 0
|
|
73
|
+
while i < len(data):
|
|
74
|
+
# ESC ] 9999 ; cols ; rows BEL
|
|
75
|
+
if data[i] == 0x1B and data[i : i + 6] == b"\x1b]9999;":
|
|
76
|
+
end = data.find(b"\x07", i + 6)
|
|
77
|
+
if end < 0:
|
|
78
|
+
resize_buf = data[i:]
|
|
79
|
+
return bytes(out)
|
|
80
|
+
payload = data[i + 6 : end].decode("ascii", "ignore")
|
|
81
|
+
try:
|
|
82
|
+
c_s, r_s = payload.split(";", 1)
|
|
83
|
+
set_winsize(master, int(r_s), int(c_s))
|
|
84
|
+
except Exception:
|
|
85
|
+
pass
|
|
86
|
+
i = end + 1
|
|
87
|
+
resize_buf = b""
|
|
88
|
+
continue
|
|
89
|
+
out.append(data[i])
|
|
90
|
+
i += 1
|
|
91
|
+
resize_buf = b""
|
|
92
|
+
return bytes(out)
|
|
93
|
+
|
|
94
|
+
alive = True
|
|
95
|
+
|
|
96
|
+
def on_chld(signum, frame): # noqa: ARG001
|
|
97
|
+
nonlocal alive
|
|
98
|
+
alive = False
|
|
99
|
+
|
|
100
|
+
signal.signal(signal.SIGCHLD, on_chld)
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
while alive:
|
|
104
|
+
try:
|
|
105
|
+
r, _, _ = select.select([master, sys.stdin.fileno()], [], [], 0.25)
|
|
106
|
+
except InterruptedError:
|
|
107
|
+
continue
|
|
108
|
+
|
|
109
|
+
if master in r:
|
|
110
|
+
try:
|
|
111
|
+
data = os.read(master, 8192)
|
|
112
|
+
except OSError as e:
|
|
113
|
+
if e.errno in (errno.EIO, errno.EAGAIN, errno.EWOULDBLOCK):
|
|
114
|
+
data = b""
|
|
115
|
+
else:
|
|
116
|
+
break
|
|
117
|
+
if not data:
|
|
118
|
+
# EIO often means child exited
|
|
119
|
+
if not alive:
|
|
120
|
+
break
|
|
121
|
+
else:
|
|
122
|
+
stdout.write(data)
|
|
123
|
+
stdout.flush()
|
|
124
|
+
|
|
125
|
+
if sys.stdin.fileno() in r:
|
|
126
|
+
try:
|
|
127
|
+
data = stdin.read(8192)
|
|
128
|
+
except Exception:
|
|
129
|
+
data = b""
|
|
130
|
+
if data is None:
|
|
131
|
+
data = b""
|
|
132
|
+
if data == b"" and not alive:
|
|
133
|
+
break
|
|
134
|
+
if data:
|
|
135
|
+
cleaned = handle_resize_escape(data)
|
|
136
|
+
if cleaned:
|
|
137
|
+
try:
|
|
138
|
+
os.write(master, cleaned)
|
|
139
|
+
except OSError:
|
|
140
|
+
break
|
|
141
|
+
finally:
|
|
142
|
+
try:
|
|
143
|
+
os.close(master)
|
|
144
|
+
except Exception:
|
|
145
|
+
pass
|
|
146
|
+
try:
|
|
147
|
+
os.waitpid(pid, 0)
|
|
148
|
+
except Exception:
|
|
149
|
+
pass
|
|
150
|
+
return 0
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _fork_pty():
|
|
154
|
+
import pty
|
|
155
|
+
|
|
156
|
+
return pty.fork()
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
if __name__ == "__main__":
|
|
160
|
+
try:
|
|
161
|
+
raise SystemExit(main())
|
|
162
|
+
except KeyboardInterrupt:
|
|
163
|
+
raise SystemExit(0)
|
package/cli/app/package.json
CHANGED
package/cli/package.json
CHANGED
|
@@ -87,6 +87,10 @@ async function showSettingsMenu(breadcrumb = []) {
|
|
|
87
87
|
label: "🔑 Reset Password to Default",
|
|
88
88
|
action: async () => { await resetPassword(); return true; }
|
|
89
89
|
},
|
|
90
|
+
{
|
|
91
|
+
label: "🖥️ Clear Terminal Password",
|
|
92
|
+
action: async () => { await clearTerminalPassword(); return true; }
|
|
93
|
+
},
|
|
90
94
|
{
|
|
91
95
|
label: (d) => {
|
|
92
96
|
const mode = d?.settings?.authMode || "password";
|
|
@@ -204,4 +208,87 @@ async function resetPassword() {
|
|
|
204
208
|
await pause();
|
|
205
209
|
}
|
|
206
210
|
|
|
211
|
+
function getDataDir() {
|
|
212
|
+
if (process.env.DATA_DIR) return process.env.DATA_DIR;
|
|
213
|
+
return process.platform === "win32"
|
|
214
|
+
? path.join(process.env.APPDATA || "", "zevai")
|
|
215
|
+
: path.join(os.homedir(), ".zevai");
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Clear web-shell secondary password. Host-only via CLI (not over HTTP) so
|
|
220
|
+
* remote dashboard users cannot reset the terminal lock.
|
|
221
|
+
*/
|
|
222
|
+
async function clearTerminalPassword() {
|
|
223
|
+
const ok = await confirm(
|
|
224
|
+
"Clear terminal password? Next Terminal open will ask to set a new one."
|
|
225
|
+
);
|
|
226
|
+
if (!ok) {
|
|
227
|
+
showStatus("Cancelled", "info");
|
|
228
|
+
await pause();
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
try {
|
|
233
|
+
const cleared = clearTerminalPasswordFromStore();
|
|
234
|
+
if (cleared) {
|
|
235
|
+
showStatus("Terminal password cleared. Open Terminal to set a new one.", "success");
|
|
236
|
+
} else {
|
|
237
|
+
showStatus("No terminal password was set (already clear).", "info");
|
|
238
|
+
}
|
|
239
|
+
} catch (err) {
|
|
240
|
+
showStatus(`Failed to clear terminal password: ${err.message}`, "error");
|
|
241
|
+
}
|
|
242
|
+
await pause();
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function clearTerminalPasswordFromStore() {
|
|
246
|
+
// Primary: SQLite settings used by the running app
|
|
247
|
+
const sqlitePath = path.join(getDataDir(), "db", "data.sqlite");
|
|
248
|
+
if (fs.existsSync(sqlitePath)) {
|
|
249
|
+
let DatabaseSync;
|
|
250
|
+
try {
|
|
251
|
+
({ DatabaseSync } = require("node:sqlite"));
|
|
252
|
+
} catch {
|
|
253
|
+
DatabaseSync = null;
|
|
254
|
+
}
|
|
255
|
+
if (DatabaseSync) {
|
|
256
|
+
const db = new DatabaseSync(sqlitePath);
|
|
257
|
+
try {
|
|
258
|
+
const row = db.prepare("SELECT data FROM settings WHERE id = 1").get();
|
|
259
|
+
if (!row?.data) return false;
|
|
260
|
+
const data = typeof row.data === "string" ? JSON.parse(row.data) : row.data;
|
|
261
|
+
if (!data || !Object.prototype.hasOwnProperty.call(data, "terminalPassword")) {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
if (!data.terminalPassword) {
|
|
265
|
+
delete data.terminalPassword;
|
|
266
|
+
db.prepare("UPDATE settings SET data = ? WHERE id = 1").run(JSON.stringify(data));
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
delete data.terminalPassword;
|
|
270
|
+
db.prepare("UPDATE settings SET data = ? WHERE id = 1").run(JSON.stringify(data));
|
|
271
|
+
return true;
|
|
272
|
+
} finally {
|
|
273
|
+
try { db.close(); } catch { /* ignore */ }
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Legacy fallback: db.json
|
|
279
|
+
const dbPath = getDbPath();
|
|
280
|
+
if (!fs.existsSync(dbPath)) {
|
|
281
|
+
throw new Error(`Settings DB not found (${sqlitePath} or ${dbPath})`);
|
|
282
|
+
}
|
|
283
|
+
const raw = fs.readFileSync(dbPath, "utf-8");
|
|
284
|
+
const db = JSON.parse(raw);
|
|
285
|
+
if (!db.settings || !Object.prototype.hasOwnProperty.call(db.settings, "terminalPassword")) {
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
const had = !!db.settings.terminalPassword;
|
|
289
|
+
delete db.settings.terminalPassword;
|
|
290
|
+
fs.writeFileSync(dbPath, JSON.stringify(db, null, 2));
|
|
291
|
+
return had;
|
|
292
|
+
}
|
|
293
|
+
|
|
207
294
|
module.exports = { showSettingsMenu };
|
package/package.json
CHANGED
|
@@ -26,7 +26,6 @@ export default function TerminalPageClient() {
|
|
|
26
26
|
const [gateBusy, setGateBusy] = useState(false);
|
|
27
27
|
const [password, setPassword] = useState("");
|
|
28
28
|
const [confirm, setConfirm] = useState("");
|
|
29
|
-
const [currentTerminalPassword, setCurrentTerminalPassword] = useState("");
|
|
30
29
|
|
|
31
30
|
const [status, setStatus] = useState("connecting");
|
|
32
31
|
const [statusText, setStatusText] = useState("Starting shell…");
|
|
@@ -81,7 +80,6 @@ export default function TerminalPageClient() {
|
|
|
81
80
|
body: JSON.stringify({
|
|
82
81
|
password,
|
|
83
82
|
confirm,
|
|
84
|
-
currentTerminalPassword: currentTerminalPassword || undefined,
|
|
85
83
|
}),
|
|
86
84
|
});
|
|
87
85
|
const data = await res.json().catch(() => ({}));
|
|
@@ -91,7 +89,6 @@ export default function TerminalPageClient() {
|
|
|
91
89
|
}
|
|
92
90
|
setPassword("");
|
|
93
91
|
setConfirm("");
|
|
94
|
-
setCurrentTerminalPassword("");
|
|
95
92
|
setGate("open");
|
|
96
93
|
} catch (error) {
|
|
97
94
|
setGateError(error?.message || "Setup failed");
|
|
@@ -585,17 +582,13 @@ export default function TerminalPageClient() {
|
|
|
585
582
|
</h1>
|
|
586
583
|
<p className="text-xs text-white/45">
|
|
587
584
|
{isSetup
|
|
588
|
-
? "
|
|
585
|
+
? "First time — pick a password different from dashboard login."
|
|
589
586
|
: "Dashboard login is not enough. Enter your terminal password."}
|
|
590
587
|
</p>
|
|
591
588
|
</div>
|
|
592
589
|
</div>
|
|
593
590
|
|
|
594
591
|
<form onSubmit={isSetup ? handleSetup : handleUnlock} className="space-y-3">
|
|
595
|
-
{isSetup && currentTerminalPassword !== undefined && (
|
|
596
|
-
// current only needed when rotating — hide on first setup (no configured pw)
|
|
597
|
-
null
|
|
598
|
-
)}
|
|
599
592
|
{isSetup ? (
|
|
600
593
|
<>
|
|
601
594
|
<label className="block space-y-1">
|
|
@@ -631,7 +624,7 @@ export default function TerminalPageClient() {
|
|
|
631
624
|
</label>
|
|
632
625
|
<p className="text-[11px] leading-relaxed text-white/35">
|
|
633
626
|
Must <strong className="text-white/55">not</strong> match the dashboard password.
|
|
634
|
-
|
|
627
|
+
Unlock lasts ~4 hours on this browser.
|
|
635
628
|
</p>
|
|
636
629
|
</>
|
|
637
630
|
) : (
|
|
@@ -667,6 +660,14 @@ export default function TerminalPageClient() {
|
|
|
667
660
|
</button>
|
|
668
661
|
</form>
|
|
669
662
|
|
|
663
|
+
{gate === "unlock" ? (
|
|
664
|
+
<p className="mt-3 text-center text-[11px] leading-relaxed text-white/35">
|
|
665
|
+
Forgot terminal password? On the host run CLI →{" "}
|
|
666
|
+
<code className="text-white/55">Settings → Clear Terminal Password</code>
|
|
667
|
+
{" "}then set a new one here. Reset is not available in the browser.
|
|
668
|
+
</p>
|
|
669
|
+
) : null}
|
|
670
|
+
|
|
670
671
|
<p className="mt-4 text-center text-[11px] text-white/30">
|
|
671
672
|
Protected by dashboard login + terminal password
|
|
672
673
|
</p>
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3570],{63133:(e,t,r)=>{Promise.resolve().then(r.bind(r,92072))},82407:()=>{},92072:(e,t,r)=>{"use strict";r.d(t,{default:()=>h});var n=r(95155),s=r(12115),a=r(8422),i=class{activate(e){this._terminal=e}dispose(){}fit(){let e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;let t=this._terminal._core;(this._terminal.rows!==e.rows||this._terminal.cols!==e.cols)&&(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal||!this._terminal.element||!this._terminal.element.parentElement)return;let e=this._terminal._core._renderService.dimensions;if(0===e.css.cell.width||0===e.css.cell.height)return;let t=0===this._terminal.options.scrollback?0:this._terminal.options.overviewRuler?.width||14,r=window.getComputedStyle(this._terminal.element.parentElement),n=parseInt(r.getPropertyValue("height")),s=Math.max(0,parseInt(r.getPropertyValue("width"))),a=window.getComputedStyle(this._terminal.element),i={top:parseInt(a.getPropertyValue("padding-top")),bottom:parseInt(a.getPropertyValue("padding-bottom")),right:parseInt(a.getPropertyValue("padding-right")),left:parseInt(a.getPropertyValue("padding-left"))},l=i.top+i.bottom;return{cols:Math.max(2,Math.floor((s-(i.right+i.left)-t)/e.css.cell.width)),rows:Math.max(1,Math.floor((n-l)/e.css.cell.height))}}},l=class{constructor(e,t,r,n={}){this._terminal=e,this._regex=t,this._handler=r,this._options=n}provideLinks(e,t){let r=o.computeLink(e,this._regex,this._terminal,this._handler);t(this._addCallbacks(r))}_addCallbacks(e){return e.map(e=>(e.leave=this._options.leave,e.hover=(t,r)=>{if(this._options.hover){let{range:n}=e;this._options.hover(t,r,n)}},e))}},o=class e{static computeLink(t,r,n,s){let a=RegExp(r.source,(r.flags||"")+"g"),[i,l]=e._getWindowedLineStrings(t-1,n),o=i.join(""),c,d=[];for(;c=a.exec(o);){let t=c[0];if(!function(e){try{let t=new URL(e),r=t.password&&t.username?`${t.protocol}//${t.username}:${t.password}@${t.host}`:t.username?`${t.protocol}//${t.username}@${t.host}`:`${t.protocol}//${t.host}`;return e.toLocaleLowerCase().startsWith(r.toLocaleLowerCase())}catch{return!1}}(t))continue;let[r,a]=e._mapStrIdx(n,l,0,c.index),[i,o]=e._mapStrIdx(n,r,a,t.length);if(-1===r||-1===a||-1===i||-1===o)continue;let u={start:{x:a+1,y:r+1},end:{x:o,y:i+1}};d.push({range:u,text:t,activate:s})}return d}static _getWindowedLineStrings(e,t){let r,n=e,s=e,a=0,i="",l=[];if(r=t.buffer.active.getLine(e)){let e=r.translateToString(!0);if(r.isWrapped&&" "!==e[0]){for(a=0;(r=t.buffer.active.getLine(--n))&&a<2048&&(a+=(i=r.translateToString(!0)).length,l.push(i),!(!r.isWrapped||-1!==i.indexOf(" "))););l.reverse()}for(l.push(e),a=0;(r=t.buffer.active.getLine(++s))&&r.isWrapped&&a<2048&&(a+=(i=r.translateToString(!0)).length,l.push(i),-1===i.indexOf(" ")););}return[l,n]}static _mapStrIdx(e,t,r,n){let s=e.buffer.active,a=s.getNullCell(),i=r;for(;n;){let e=s.getLine(t);if(!e)return[-1,-1];for(let r=i;r<e.length;++r){e.getCell(r,a);let i=a.getChars();if(a.getWidth()&&(n-=i.length||1,r===e.length-1&&""===i)){let e=s.getLine(t+1);e&&e.isWrapped&&(e.getCell(0,a),2===a.getWidth()&&(n+=1))}if(n<0)return[t,r]}t++,i=0}return[t,i]}},c=/(https?|HTTPS?):[/]{2}[^\s"'!*(){}|\\\^<>`]*[^\s"':,.!?{}|\\\^~\[\]`()<>]/;function d(e,t){let r=window.open();if(r){try{r.opener=null}catch{}r.location.href=t}else console.warn("Opening link blocked as opener could not be cleared")}var u=class{constructor(e=d,t={}){this._handler=e,this._options=t}activate(e){this._terminal=e;let t=this._options,r=t.urlRegex||c;this._linkProvider=this._terminal.registerLinkProvider(new l(this._terminal,r,this._handler,t))}dispose(){this._linkProvider?.dispose()}};function h(){let e=(0,s.useRef)(null),t=(0,s.useRef)(null),r=(0,s.useRef)(null),l=(0,s.useRef)(""),o=(0,s.useRef)(""),c=(0,s.useRef)(null),d=(0,s.useRef)([]),h=(0,s.useRef)(null),m=(0,s.useRef)(!1),p=(0,s.useRef)(""),[f,b]=(0,s.useState)("checking"),[x,g]=(0,s.useState)(""),[w,y]=(0,s.useState)(!1),[v,k]=(0,s.useState)(""),[j,N]=(0,s.useState)(""),[_,S]=(0,s.useState)(""),[C,E]=(0,s.useState)("connecting"),[L,A]=(0,s.useState)("Starting shell…"),[T,$]=(0,s.useState)({shell:"",mode:""}),P=(0,s.useCallback)(async()=>{g("");try{let e=await fetch("/api/terminal/auth/status",{cache:"no-store",credentials:"same-origin"}),t=await e.json().catch(()=>({}));if(403===e.status){g(t?.error||"Access forbidden."),b("unlock");return}if(401===e.status){g("Log in to the dashboard first."),b("unlock");return}if(!t.configured)return void b("setup");if(t.unlocked)return void b("open");b("unlock")}catch(e){g(e?.message||"Failed to check terminal lock"),b("unlock")}},[]);(0,s.useEffect)(()=>{P()},[P]);let R=async e=>{e.preventDefault(),y(!0),g("");try{let e=await fetch("/api/terminal/auth/setup",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"same-origin",body:JSON.stringify({password:v,confirm:j,currentTerminalPassword:_||void 0})}),t=await e.json().catch(()=>({}));if(!e.ok)return void g(t.error||"Setup failed");k(""),N(""),S(""),b("open")}catch(e){g(e?.message||"Setup failed")}finally{y(!1)}},O=async e=>{e.preventDefault(),y(!0),g("");try{let e=await fetch("/api/terminal/auth/unlock",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"same-origin",body:JSON.stringify({password:v})}),t=await e.json().catch(()=>({}));if(!e.ok)return void g(t.error||"Unlock failed");k(""),b("open")}catch(e){g(e?.message||"Unlock failed")}finally{y(!1)}},M=async()=>{try{await fetch("/api/terminal/auth/unlock",{method:"DELETE",credentials:"same-origin"})}catch{}let e=l.current;if(l.current="",e&&fetch(`/api/terminal/session/${e}`,{method:"DELETE",credentials:"same-origin",keepalive:!0}).catch(()=>{}),c.current){try{c.current.close()}catch{}c.current=null}k(""),b("unlock")},D=(0,s.useCallback)(async()=>{let e=l.current;if(!e||0===d.current.length)return;let r=d.current.join("");d.current=[];try{let n=await fetch(`/api/terminal/session/${e}/input`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({data:r}),cache:"no-store",credentials:"same-origin"});!n.ok&&t.current&&(423===n.status?(t.current.write("\r\n\x1b[31m[terminal locked]\x1b[0m\r\n"),b("unlock")):(403===n.status||401===n.status)&&t.current.write(`\r
|
|
2
|
-
\x1b[31m[input blocked: ${n.status}]\x1b[0m\r
|
|
3
|
-
`))}catch{}},[]),z=(0,s.useCallback)(e=>{e&&l.current&&(d.current.push(e),h.current||(h.current=setTimeout(()=>{h.current=null,D()},8)))},[D]),F=(0,s.useCallback)(e=>{let r=t.current;if(!r)return;let n=o.current;if(!("pipe"===n||!n))return void z(e);if("\x03"===e){p.current="",r.write("^C\r\n"),z("\x03\n");return}if("\r"===e||"\n"===e||"\r\n"===e){let e=p.current;p.current="",r.write("\r\n"),z(`${e}
|
|
4
|
-
`);return}if(""===e||"\b"===e){p.current.length>0&&(p.current=p.current.slice(0,-1),r.write("\b \b"));return}32>e.charCodeAt(0)||e.startsWith("\x1b")||(p.current+=e,r.write(e))},[z]),I=(0,s.useCallback)(async()=>{let e=l.current,r=t.current;if(e&&r)try{await fetch(`/api/terminal/session/${e}/resize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cols:r.cols,rows:r.rows}),cache:"no-store",credentials:"same-origin"})}catch{}},[]),W=(0,s.useCallback)(()=>{try{t.current?.focus()}catch{}},[]),U=(0,s.useCallback)((e,t)=>{if(c.current)try{c.current.close()}catch{}let r=new EventSource(`/api/terminal/session/${e}/stream`,{withCredentials:!0});c.current=r,r.onopen=()=>{m.current||(E("ready"),A("Connected — click terminal & type"),W())},r.onmessage=e=>{let r;if(!m.current){try{r=JSON.parse(e.data)}catch{return}"data"===r.type&&"string"==typeof r.data?t.write(r.data):"ready"===r.type?(o.current=r.mode||o.current,$({shell:r.shell||"",mode:r.mode||""}),E(!1===r.alive?"closed":"ready"),A(!1===r.alive?"Shell exited":"Connected — click terminal & type"),W()):"exit"===r.type&&(E("closed"),A("Shell exited"),t.write("\r\n\x1b[90m[session ended]\x1b[0m\r\n"))}},r.onerror=()=>{m.current||(E(e=>"ready"===e?"connecting":e),A("Reconnecting…"))}},[W]),q=(0,s.useCallback)(async(e,t)=>{let r;E("connecting"),A("Starting shell…"),p.current="";try{t.fit()}catch{}let n=e.cols||120,s=e.rows||40;try{r=await fetch("/api/terminal/session",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cols:n,rows:s}),cache:"no-store",credentials:"same-origin"})}catch(t){E("error"),A(t?.message||"Failed to reach server"),e.writeln(`\x1b[31mFailed to create session: ${t?.message||"network error"}\x1b[0m`);return}if(403===r.status){E("forbidden"),A("Forbidden"),e.writeln("\x1b[33mTerminal access forbidden.\x1b[0m");return}if(401===r.status){E("error"),A("Unauthorized"),e.writeln("\x1b[31mUnauthorized — log in to the dashboard first.\x1b[0m");return}if(423===r.status){E("error"),A("Locked"),b("unlock");return}let a=await r.json().catch(()=>({}));if(!r.ok||!a?.session?.id){E("error"),A(a?.error||"Create failed"),e.writeln(`\x1b[31m${a?.error||"Failed to create terminal session"}\x1b[0m`);return}l.current=a.session.id,o.current=a.session.mode||"pipe",$({shell:a.session.shell||"",mode:a.session.mode||""}),U(a.session.id,e),W()},[U,W]),J=(0,s.useCallback)(async()=>{let e=l.current;if(l.current="",o.current="",p.current="",d.current=[],c.current){try{c.current.close()}catch{}c.current=null}e&&fetch(`/api/terminal/session/${e}`,{method:"DELETE",credentials:"same-origin"}).catch(()=>{});let n=t.current,s=r.current;n&&s&&(n.reset(),n.clear(),await q(n,s))},[q]);if((0,s.useEffect)(()=>{if("open"!==f)return;m.current=!1;let n=e.current;if(!n)return;let s=new a.B({cursorBlink:!0,cursorStyle:"bar",fontSize:13,fontFamily:'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',lineHeight:1.25,scrollback:5e3,allowProposedApi:!0,disableStdin:!1,theme:{background:"#0d0d0d",foreground:"#e8e8e8",cursor:"#E56A4A",cursorAccent:"#0d0d0d",selectionBackground:"rgba(229, 106, 74, 0.35)",black:"#1a1a1a",red:"#f87171",green:"#4ade80",yellow:"#fbbf24",blue:"#60a5fa",magenta:"#c084fc",cyan:"#22d3ee",white:"#e5e5e5",brightBlack:"#737373",brightRed:"#fca5a5",brightGreen:"#86efac",brightYellow:"#fde68a",brightBlue:"#93c5fd",brightMagenta:"#d8b4fe",brightCyan:"#67e8f9",brightWhite:"#fafafa"}}),o=new i,d=new u;s.loadAddon(o),s.loadAddon(d),s.open(n);try{n.tabIndex=0;let e=n.querySelector("textarea");e&&(e.tabIndex=0,e.setAttribute("autocomplete","off"),e.setAttribute("spellcheck","false"))}catch{}t.current=s,r.current=o;try{o.fit()}catch{}let p=s.onData(e=>F(e)),b=()=>{try{o.fit(),I()}catch{}},x=()=>W();n.addEventListener("mousedown",x),n.addEventListener("click",x),n.addEventListener("focus",W);let g="u">typeof ResizeObserver?new ResizeObserver(b):null;return g?.observe(n),window.addEventListener("resize",b),requestAnimationFrame(()=>{try{o.fit()}catch{}W()}),q(s,o),()=>{m.current=!0,g?.disconnect(),window.removeEventListener("resize",b),n.removeEventListener("mousedown",x),n.removeEventListener("click",x),n.removeEventListener("focus",W);try{p.dispose()}catch{}if(h.current&&(clearTimeout(h.current),h.current=null),c.current){try{c.current.close()}catch{}c.current=null}let e=l.current;l.current="",e&&fetch(`/api/terminal/session/${e}`,{method:"DELETE",keepalive:!0,credentials:"same-origin"}).catch(()=>{});try{s.dispose()}catch{}t.current=null,r.current=null}},[f,F,I,q,W]),"checking"===f)return(0,n.jsx)("div",{className:"flex h-full min-h-0 w-full items-center justify-center bg-[#0d0d0d] text-sm text-white/50",children:"Checking terminal lock…"});if("setup"===f||"unlock"===f){let e="setup"===f;return(0,n.jsx)("div",{className:"flex h-full min-h-0 w-full flex-col items-center justify-center bg-[#0d0d0d] px-4",children:(0,n.jsxs)("div",{className:"w-full max-w-md rounded-2xl border border-white/10 bg-white/[0.03] p-6 shadow-xl",children:[(0,n.jsxs)("div",{className:"mb-4 flex items-center gap-3",children:[(0,n.jsx)("div",{className:"flex size-10 items-center justify-center rounded-xl bg-[color:var(--brand,#E56A4A)]/15 text-[color:var(--brand,#E56A4A)]",children:(0,n.jsx)("span",{className:"material-symbols-outlined text-[22px]",children:e?"key":"lock"})}),(0,n.jsxs)("div",{children:[(0,n.jsx)("h1",{className:"text-base font-semibold text-white/95",children:e?"Set terminal password":"Unlock terminal"}),(0,n.jsx)("p",{className:"text-xs text-white/45",children:e?"Separate from dashboard password — double protection for the host shell.":"Dashboard login is not enough. Enter your terminal password."})]})]}),(0,n.jsxs)("form",{onSubmit:e?R:O,className:"space-y-3",children:[e&&void 0!==_&&null,e?(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)("label",{className:"block space-y-1",children:[(0,n.jsx)("span",{className:"text-[11px] font-medium uppercase tracking-wide text-white/40",children:"New terminal password"}),(0,n.jsx)("input",{type:"password",autoFocus:!0,autoComplete:"new-password",value:v,onChange:e=>k(e.target.value),className:"w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2.5 text-sm text-white outline-none focus:border-[color:var(--brand,#E56A4A)]/60",placeholder:"Min 6 characters",required:!0,minLength:6})]}),(0,n.jsxs)("label",{className:"block space-y-1",children:[(0,n.jsx)("span",{className:"text-[11px] font-medium uppercase tracking-wide text-white/40",children:"Confirm"}),(0,n.jsx)("input",{type:"password",autoComplete:"new-password",value:j,onChange:e=>N(e.target.value),className:"w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2.5 text-sm text-white outline-none focus:border-[color:var(--brand,#E56A4A)]/60",placeholder:"Repeat password",required:!0,minLength:6})]}),(0,n.jsxs)("p",{className:"text-[11px] leading-relaxed text-white/35",children:["Must ",(0,n.jsx)("strong",{className:"text-white/55",children:"not"})," match the dashboard password. Cookie unlock lasts ~4 hours on this browser."]})]}):(0,n.jsxs)("label",{className:"block space-y-1",children:[(0,n.jsx)("span",{className:"text-[11px] font-medium uppercase tracking-wide text-white/40",children:"Terminal password"}),(0,n.jsx)("input",{type:"password",autoFocus:!0,autoComplete:"current-password",value:v,onChange:e=>k(e.target.value),className:"w-full rounded-lg border border-white/10 bg-black/40 px-3 py-2.5 text-sm text-white outline-none focus:border-[color:var(--brand,#E56A4A)]/60",placeholder:"••••••••",required:!0})]}),x?(0,n.jsx)("p",{className:"rounded-lg border border-red-500/30 bg-red-500/10 px-3 py-2 text-xs text-red-300",children:x}):null,(0,n.jsx)("button",{type:"submit",disabled:w,className:"w-full rounded-lg bg-[color:var(--brand,#E56A4A)] px-3 py-2.5 text-sm font-semibold text-white transition hover:brightness-110 disabled:opacity-50",children:w?"Please wait…":e?"Save & open terminal":"Unlock"})]}),(0,n.jsx)("p",{className:"mt-4 text-center text-[11px] text-white/30",children:"Protected by dashboard login + terminal password"})]})})}return(0,n.jsxs)("div",{className:"flex h-full min-h-0 w-full flex-col bg-[#0d0d0d]",children:[(0,n.jsxs)("div",{className:"flex shrink-0 items-center justify-between gap-3 border-b border-white/10 px-4 py-2.5",children:[(0,n.jsxs)("div",{className:"flex min-w-0 items-center gap-3",children:[(0,n.jsxs)("div",{className:"flex items-center gap-2",children:[(0,n.jsx)("span",{className:`inline-block size-2 rounded-full ${"ready"===C?"bg-emerald-500":"connecting"===C?"bg-amber-400 animate-pulse":"forbidden"===C?"bg-amber-500":"bg-red-500"}`}),(0,n.jsx)("span",{className:"text-sm font-semibold text-white/90",children:"Terminal"})]}),(0,n.jsxs)("span",{className:"truncate text-xs text-white/45",children:[L,T.shell?` \xb7 ${T.shell}`:"",T.mode?` \xb7 ${T.mode}`:""]})]}),(0,n.jsxs)("div",{className:"flex items-center gap-2",children:[(0,n.jsx)("button",{type:"button",onClick:M,className:"rounded-lg border border-white/10 bg-white/5 px-3 py-1.5 text-xs font-medium text-white/70 transition hover:border-white/20 hover:text-white",title:"Lock terminal (require password again)",children:"Lock"}),(0,n.jsx)("button",{type:"button",onClick:J,className:"rounded-lg border border-white/10 bg-white/5 px-3 py-1.5 text-xs font-medium text-white/80 transition hover:border-[color:var(--brand,#E56A4A)]/50 hover:bg-white/10 hover:text-white",children:"New session"})]})]}),(0,n.jsx)("div",{className:"relative min-h-0 flex-1",onMouseDown:W,children:(0,n.jsx)("div",{ref:e,className:"absolute inset-0 px-2 py-2 outline-none"})}),(0,n.jsx)("div",{className:"shrink-0 border-t border-white/10 px-4 py-1.5 text-[11px] text-white/35",children:"Dashboard login + terminal password \xb7 click the black area then type \xb7 idle sessions close after 30m"})]})}r(82407)}},e=>{e.O(0,[1838,1507,8441,3794,7358],()=>e(e.s=63133)),_N_E=e.O()}]);
|
|
File without changes
|
|
File without changes
|