ProtonMail / go-proton-api

Proton API library used by Go-based clients and tools
MIT License
122 stars 16 forks source link

Where are the docs on how to use this library? #139

Open tristan957 opened 9 months ago

tristan957 commented 9 months ago

I am trying to create a little command line client for getting my contact email addresses. Here is my code so far:

package main

import (
    "context"
    "fmt"
    "os"
    "os/signal"
    "syscall"

    "github.com/ProtonMail/go-proton-api"
    "golang.org/x/term"
)

func fatal(err error) {
    fmt.Fprintf(os.Stderr, "%v\n", err)
    os.Exit(1)
}

func main() {
    ctx := context.Background()

    // Create context that becomes done when various signals are received
    ctx, fn := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
    defer fn()

    // How da fuck do you get a valid app version...
    manager := proton.New(proton.WithAppVersion("web-mail@5.0.33.6"), proton.WithDebug(true))
    defer manager.Close()

    client, auth, err := manager.NewClientWithLogin(ctx, "email", []byte("password"))
    if err != nil {
        fatal(err)
    }
    defer client.Close()

    if auth.TwoFA.Enabled&proton.HasTOTP != 0 {
        if term.IsTerminal(syscall.Stdin) {
            fmt.Print("TOTP: ")
        }

        code, err := term.ReadPassword(syscall.Stdin)
        if err != nil {
            fatal(err)
        }

        if err := client.Auth2FA(ctx, proton.Auth2FAReq{TwoFactorCode: string(code)}); err != nil {
            panic(err)
        }
    }

    contacts, err := client.GetAllContacts(ctx)
    if err != nil {
        fatal(err)
    }

    for _, contact := range contacts {
        fmt.Println(contact.Name)
    }
}

I have two questions:

  1. What should I put for the app version? Impersonating the web client seems stupid to me, but gets me past the first hurdle.
  2. This gets me to the CAPTCHA which I then need to complete. Is this avoidable? This program would be called tens of times a day. If I had to complete CAPTCHAs all day everyday, I would die. I am assuming I can complete it once, and get a token which I can then login with in subsequent program invocations. Is there an example of some go code which handles this flow?

The interface seems fairly easy to deal with except for the lacking documentation on completing the auth flow.

tristan957 commented 9 months ago

Or if there is a Proton CLI in the works, I will stop my efforts :). I really just want to be able to autocomplete email addresses in my terminal email client :).

crazy-matt commented 8 months ago

@tristan957 You might be looking for the number displayed at the bottom left corner of your web browser mailbox, see below:

screenshot

I was thinking wrapping this API myself to automate labels injection with a CLI and found your issue. I searched for some info around how to get the API creds GO_PROTON_API_TEST_USERNAME/GO_PROTON_API_TEST_PASSWORD mentioned in their readme but it's still a mistery to me how to generate those if they can help bypassing the 2FA/security key/captcha.