mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-11-07 09:45:36 +00:00
feat(stockbit): print the ssh forward when the shell is remote
The login page listens on 127.0.0.1, so a browser on the Mac driving a VM could never reach it. Over SSH, idx now picks port 7878, skips opening a browser on the VM, and prints the exact ssh -L to run where the browser is.
This commit is contained in:
parent
00c59ad9c9
commit
cb532b670b
3 changed files with 54 additions and 8 deletions
|
|
@ -57,7 +57,7 @@ pub fn handle(cmd: &StockbitCmd, format: &OutputFormat) -> Result<(), IdxError>
|
|||
match &cmd.command {
|
||||
StockbitSubcommand::Login { no_browser, port } => {
|
||||
let status = if std::io::stdin().is_terminal() {
|
||||
match login_in_browser(port.unwrap_or(0), !no_browser) {
|
||||
match login_in_browser(*port, !no_browser) {
|
||||
Ok(()) => stockbit::session_status()?,
|
||||
Err(err) => {
|
||||
runtime::warn(format!("browser login unavailable ({err}); paste instead"));
|
||||
|
|
@ -105,11 +105,24 @@ pub fn handle(cmd: &StockbitCmd, format: &OutputFormat) -> Result<(), IdxError>
|
|||
}
|
||||
|
||||
/// Serves the local login page and waits for a session it can verify.
|
||||
fn login_in_browser(port: u16, open: bool) -> Result<(), IdxError> {
|
||||
let page = stockbit::loopback::LoginPage::bind(port)?;
|
||||
///
|
||||
/// The page is only reachable from this machine. Over SSH the browser is
|
||||
/// usually somewhere else, so idx picks a stable port, skips opening a
|
||||
/// browser here, and prints the forward to run on the machine with the
|
||||
/// browser.
|
||||
fn login_in_browser(port: Option<u16>, open: bool) -> Result<(), IdxError> {
|
||||
let ssh = std::env::var("SSH_CONNECTION").ok();
|
||||
// A stable port makes the printed `ssh -L` match what the page serves.
|
||||
let page = stockbit::loopback::LoginPage::bind(port.unwrap_or(if ssh.is_some() {
|
||||
DEFAULT_SSH_PORT
|
||||
} else {
|
||||
0
|
||||
}))?;
|
||||
println!("Open this page to connect Stockbit: {}", page.url());
|
||||
if open {
|
||||
open_in_browser(&page.url());
|
||||
match &ssh {
|
||||
Some(connection) => print_ssh_hint(connection, page.port()),
|
||||
None if open => open_in_browser(&page.url()),
|
||||
None => {}
|
||||
}
|
||||
page.wait(LOGIN_TIMEOUT, |pasted| {
|
||||
stockbit::login(pasted)
|
||||
|
|
@ -118,6 +131,29 @@ fn login_in_browser(port: u16, open: bool) -> Result<(), IdxError> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Port the page uses over SSH, so `ssh -L 7878:…:7878` matches it.
|
||||
const DEFAULT_SSH_PORT: u16 = 7878;
|
||||
|
||||
/// The forward to run where the browser is, from `SSH_CONNECTION`
|
||||
/// (`client_ip client_port server_ip server_port`).
|
||||
fn print_ssh_hint(connection: &str, port: u16) {
|
||||
let fields: Vec<&str> = connection.split_whitespace().collect();
|
||||
let target = match (std::env::var("USER").ok(), fields.get(2)) {
|
||||
(Some(user), Some(server)) => format!("{user}@{server}"),
|
||||
(None, Some(server)) => (*server).to_string(),
|
||||
_ => "<this host>".to_string(),
|
||||
};
|
||||
runtime::warn(
|
||||
"this shell is over SSH: the page listens on the remote machine, so open it from the \
|
||||
machine with your browser",
|
||||
);
|
||||
println!(
|
||||
"\nFrom the machine you are sitting at, run (and keep it open):\n \
|
||||
ssh -L {port}:127.0.0.1:{port} {target}\n\
|
||||
then open the URL above there.\n"
|
||||
);
|
||||
}
|
||||
|
||||
/// Opens `url` with the desktop's default browser, best effort.
|
||||
fn open_in_browser(url: &str) {
|
||||
#[cfg(target_os = "macos")]
|
||||
|
|
|
|||
|
|
@ -62,6 +62,11 @@ impl LoginPage {
|
|||
format!("http://127.0.0.1:{}/login/{}", self.port, self.secret)
|
||||
}
|
||||
|
||||
/// The port the page listens on.
|
||||
pub fn port(&self) -> u16 {
|
||||
self.port
|
||||
}
|
||||
|
||||
/// Serves until `verify` accepts a paste or `timeout` passes. `verify`
|
||||
/// returns the error text to show on the page when the paste is refused.
|
||||
///
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue