diff --git a/email.go b/email.go index 8e25f91..b3c4683 100755 --- a/email.go +++ b/email.go @@ -1,18 +1,22 @@ package contact import ( + "bytes" "context" "crypto/sha256" "crypto/tls" "encoding/base64" "encoding/json" "fmt" + "io" "log" + "net/http" "net/mail" "net/smtp" "net/url" "os" "strings" + "time" "github.com/bytbox/go-pop3" "github.com/emersion/go-imap" @@ -97,12 +101,44 @@ func (e *Emailer) oauthThenReadIMAP() (chan *mail.Message, error) { os.WriteFile(e.OAuth+".token", tokenFileJSON, os.ModePerm) log.Printf("%s", tokenFileJSON) } - token, _ := os.ReadFile(e.OAuth + ".token") var tokenStruct struct { - AccessToken string `json:"access_token"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + Expiry time.Time `json:"expiry"` + ExpiresIn int `json:"expires_in"` } + token, _ := os.ReadFile(e.OAuth + ".token") json.Unmarshal(token, &tokenStruct) - log.Println(e.From, tokenStruct.AccessToken) + if time.Until(tokenStruct.Expiry) < time.Minute*5 { + var appStruct struct { + Installed struct { + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + GrantType string `json:"grant_type"` + RefreshToken string `json:"refresh_token"` + } `json:"installed"` + } + json.Unmarshal([]byte(configJSON), &appStruct) + appStruct.Installed.GrantType = "refresh_token" + appStruct.Installed.RefreshToken = tokenStruct.RefreshToken + b, _ := json.Marshal(appStruct.Installed) + resp, err := http.Post(`https://oauth2.googleapis.com/token`, `application/json`, bytes.NewReader(b)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + b, _ = io.ReadAll(resp.Body) + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("(%d) %s", resp.StatusCode, b) + } + tokenStruct.Expiry = time.Time{} + json.Unmarshal(b, &tokenStruct) + tokenStruct.Expiry = time.Now().Add(time.Duration(tokenStruct.ExpiresIn) * time.Second) + tokenStruct.RefreshToken = appStruct.Installed.RefreshToken + b, _ = json.Marshal(tokenStruct) + os.WriteFile(e.OAuth+".token", b, os.ModePerm) + } + log.Println("OAUTH", e.From, time.Until(tokenStruct.Expiry), tokenStruct.AccessToken) return e.readIMAP(e.From, tokenStruct.AccessToken) }