diff --git a/clip/arguments.go b/clip/arguments.go index db70050..bcb3456 100644 --- a/clip/arguments.go +++ b/clip/arguments.go @@ -35,7 +35,7 @@ func CopyShortcut(realPath string, field int, rcwPassword []byte) error { if field == 2 { // TOTP mode fmt.Println(back.AnsiWarning + "[Starting]" + back.AnsiReset + " TOTP clipboard refresher") - errorChan := make(chan error) + errorChan := make(chan error, 1) go TOTPCopier(decSlice[2], errorChan, nil) // "done" is not needed because the process runs until the program is killed if err = <-errorChan; err != nil { // handle error from first copy return errors.New("error encountered in TOTP refresh process: " + err.Error()) diff --git a/clip/totp.go b/clip/totp.go index e067e5c..528e836 100644 --- a/clip/totp.go +++ b/clip/totp.go @@ -10,19 +10,32 @@ import ( // TOTPCopier is meant to be run as a goroutine to keep // the clipboard up-to-date with the latest TOTP token. +// +// Note that errorChan should be buffered with capacity 1. +// This is because TOTPCopier only returns errors on the first +// iteration, as subsequent errors are highly unlikely to occur +// and allowing the caller to move on from error-checking is beneficial. func TOTPCopier(secret string, errorChan chan<- error, done <-chan bool) { + var firstRun = true + var currentTime time.Time + var token string + var err error for { - currentTime := time.Now() - token, err := core.GenTOTP(secret, currentTime) - if err != nil { + currentTime = time.Now() + token, err = core.GenTOTP(secret, currentTime) + if firstRun && err != nil { errorChan <- err } - if err = CopyString(false, token); err != nil { - errorChan <- err + err = CopyString(false, token) + if firstRun { + if err != nil { + errorChan <- err + } else { + errorChan <- nil // indicate that first copy was successful + } + firstRun = false } - errorChan <- nil // indicate that first copy was successful - // sleep till next 30-second interval time.Sleep(time.Duration(30-(currentTime.Second()%30)) * time.Second)