mirror of
https://github.com/sstent/go-garminconnect.git
synced 2025-12-06 08:02:02 +00:00
82 lines
1.7 KiB
Go
82 lines
1.7 KiB
Go
package auth
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
"sync"
|
|
)
|
|
|
|
// MFAState represents the state of an MFA verification session
|
|
type MFAState struct {
|
|
VerificationURL string `json:"verification_url"`
|
|
SessionToken string `json:"session_token"`
|
|
MFACode string `json:"mfa_code"`
|
|
ExpiresAt time.Time `json:"expires_at"`
|
|
}
|
|
|
|
// MFAStorage handles persistence of MFA state
|
|
type MFAStorage interface {
|
|
Store(state MFAState) error
|
|
Get() (MFAState, error)
|
|
Clear() error
|
|
}
|
|
|
|
// FileMFAStorage implements MFAStorage using a JSON file
|
|
type FileMFAStorage struct {
|
|
filePath string
|
|
mutex sync.RWMutex
|
|
}
|
|
|
|
// NewFileMFAStorage creates a new file-based MFA storage
|
|
func NewFileMFAStorage() *FileMFAStorage {
|
|
home, _ := os.UserHomeDir()
|
|
return &FileMFAStorage{
|
|
filePath: filepath.Join(home, ".garminconnect", "mfa_state.json"),
|
|
}
|
|
}
|
|
|
|
// Store saves MFA state to file
|
|
func (s *FileMFAStorage) Store(state MFAState) error {
|
|
s.mutex.Lock()
|
|
defer s.mutex.Unlock()
|
|
|
|
// Create directory if needed
|
|
dir := filepath.Dir(s.filePath)
|
|
if err := os.MkdirAll(dir, 0700); err != nil {
|
|
return err
|
|
}
|
|
|
|
data, err := json.MarshalIndent(state, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return os.WriteFile(s.filePath, data, 0600)
|
|
}
|
|
|
|
// Get retrieves MFA state from file
|
|
func (s *FileMFAStorage) Get() (MFAState, error) {
|
|
s.mutex.RLock()
|
|
defer s.mutex.RUnlock()
|
|
|
|
data, err := os.ReadFile(s.filePath)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return MFAState{}, nil
|
|
}
|
|
return MFAState{}, err
|
|
}
|
|
|
|
var state MFAState
|
|
err = json.Unmarshal(data, &state)
|
|
return state, err
|
|
}
|
|
|
|
// Clear removes the MFA state file
|
|
func (s *FileMFAStorage) Clear() error {
|
|
s.mutex.Lock()
|
|
defer s.mutex.Unlock()
|
|
return os.Remove(s.filePath)
|
|
}
|