diff --git a/overleaf.go b/overleaf.go index 08933ac..e9a874f 100644 --- a/overleaf.go +++ b/overleaf.go @@ -2,10 +2,11 @@ package main import ( "bytes" - "errors" "fmt" "io" + "log" "net/http" + "net/http/cookiejar" "net/url" "strings" @@ -18,11 +19,16 @@ type Overleaf struct { CSRF string } -// NewOverleaf initializes a new Overleaf instance func NewOverleaf(baseURL string) *Overleaf { + // Create a new HTTP client with a cookie jar + jar, _ := cookiejar.New(nil) + client := &http.Client{ + Jar: jar, + } + return &Overleaf{ BaseURL: strings.TrimSuffix(baseURL, "/"), - Client: &http.Client{}, + Client: client, } } @@ -65,42 +71,57 @@ func (o *Overleaf) post(endpoint string, data map[string]string) (*http.Response return resp, nil } -// obtainCSRF retrieves the CSRF token func (o *Overleaf) obtainCSRF() error { + // Perform a GET request to retrieve the login page resp, err := o.get("/login") if err != nil { - return err + return fmt.Errorf("failed to load login page: %v", err) } defer resp.Body.Close() + // Parse the HTML to find the CSRF token doc, err := goquery.NewDocumentFromReader(resp.Body) if err != nil { - return fmt.Errorf("failed to parse HTML document: %w", err) + return fmt.Errorf("failed to parse login page HTML: %v", err) } csrf, exists := doc.Find(`meta[name="ol-csrfToken"]`).Attr("content") if !exists { - return errors.New("CSRF token not found in the login page") + return fmt.Errorf("CSRF token not found in login page") } + o.CSRF = csrf return nil } -// Login logs in as the admin user func (o *Overleaf) Login(email, password string) error { + // Retrieve CSRF token + if err := o.obtainCSRF(); err != nil { + return fmt.Errorf("failed to obtain CSRF token: %v", err) + } + + // Log the CSRF token for debugging + log.Printf("Obtained CSRF token: %s", o.CSRF) + + // Create the login request resp, err := o.post("/login", map[string]string{ "email": email, "password": password, + "_csrf": o.CSRF, // Include the CSRF token }) if err != nil { - return fmt.Errorf("admin login failed: %w", err) + return fmt.Errorf("failed to send login request: %v", err) } defer resp.Body.Close() + // Log response for debugging + body, _ := io.ReadAll(resp.Body) if resp.StatusCode != http.StatusOK { - body, _ := io.ReadAll(resp.Body) + log.Printf("Login response: %s", string(body)) return fmt.Errorf("admin login returned status %d: %s", resp.StatusCode, string(body)) } + + log.Println("Admin login successful.") return nil }