posthog_cli/
login.rs

1use anyhow::Error;
2use inquire::Text;
3use tracing::info;
4
5use crate::{
6    invocation_context::{context, init_context},
7    utils::auth::{host_validator, token_validator, CredentialProvider, HomeDirProvider, Token},
8};
9
10pub fn login() -> Result<(), Error> {
11    let host = Text::new("Enter the PostHog host URL")
12        .with_default("https://us.posthog.com")
13        .with_validator(host_validator)
14        .prompt()?;
15
16    let env_id =
17        Text::new("Enter your project ID (the number in your posthog homepage url)").prompt()?;
18
19    let token = Text::new(
20        "Enter your personal API token (see posthog.com/docs/api#private-endpoint-authentication)",
21    )
22    .with_validator(token_validator)
23    .prompt()?;
24
25    let token = Token {
26        host: Some(host),
27        token,
28        env_id,
29    };
30    let provider = HomeDirProvider;
31    provider.store_credentials(token)?;
32    info!("Token saved to: {}", provider.report_location());
33
34    // Login is the only command that doesn't have a context coming in - because it modifies the context
35    init_context(None, false)?;
36    context().capture_command_invoked("interactive_login");
37
38    Ok(())
39}