Files
pop/cmd/auth.go
Michael Freno 691a2acdad feat: implement automatic auth token refresh on 401 with context support (FRE-4763)
- Add SessionRefresher interface for token refresh abstraction
- Update ProtonMailClient to auto-refresh on 401 responses
- Add DoWithContext method for context-aware HTTP requests
- Update SessionManager with RefreshTokenWithContext method
- Update LoginWithCredentials and LoginInteractive to accept context
- Add checkAuthenticatedWithManager helper for commands needing session manager
- All API methods now support proper cancellation via context.Context

Files changed:
- internal/api/client.go - Auto-refresh on 401, context support
- internal/auth/session.go - Context-aware refresh and login methods
- internal/auth/interface.go - SessionRefresher interface
- cmd/mail.go, cmd/draft.go, cmd/folders.go - Updated to use new helpers
- cmd/auth.go - Context support for login commands

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-09 21:46:03 -04:00

75 lines
1.7 KiB
Go

package cmd
import (
"context"
"fmt"
"os"
"github.com/frenocorp/pop/internal/auth"
"github.com/frenocorp/pop/internal/config"
"github.com/spf13/cobra"
)
func loginCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "login",
Short: "Log in to ProtonMail",
Long: `Authenticate with ProtonMail API and store session credentials.`,
RunE: func(cmd *cobra.Command, args []string) error {
cfgMgr := config.NewConfigManager()
cfg, err := cfgMgr.Load()
if err != nil {
return fmt.Errorf("failed to load config: %w", err)
}
manager, err := auth.NewSessionManager()
if err != nil {
return fmt.Errorf("failed to create session manager: %w", err)
}
return manager.LoginInteractive(context.Background(), cfg.APIBaseURL)
},
}
return cmd
}
func logoutCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "logout",
Short: "Log out from ProtonMail",
Long: `Clear stored session credentials.`,
RunE: func(cmd *cobra.Command, args []string) error {
manager, err := auth.NewSessionManager()
if err != nil {
return fmt.Errorf("failed to create session manager: %w", err)
}
return manager.Logout()
},
}
return cmd
}
func sessionCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "session",
Short: "Show current session info",
Long: `Display current authentication session details.`,
RunE: func(cmd *cobra.Command, args []string) error {
manager, err := auth.NewSessionManager()
if err != nil {
return fmt.Errorf("failed to create session manager: %w", err)
}
session, err := manager.GetSession()
if err != nil {
return fmt.Errorf("no active session: %w", err)
}
fmt.Fprintf(os.Stdout, "Session: %s\n", session.UID)
return nil
},
}
return cmd
}