mirror of
https://github.com/rwinkhart/libmutton.git
synced 2026-08-27 20:36:29 -04:00
60 lines
1.4 KiB
Go
60 lines
1.4 KiB
Go
//go:build (!android && !ios) || termux
|
|
|
|
package clip
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/pquerna/otp"
|
|
"github.com/pquerna/otp/totp"
|
|
)
|
|
|
|
// GenTOTP generates a TOTP token from a secret.
|
|
// Prefix `secret` with "steam@" for Steam TOTP format.
|
|
func GenTOTP(secret string, time time.Time) (string, error) {
|
|
var totpToken string
|
|
var err error
|
|
|
|
if strings.HasPrefix(secret, "steam@") {
|
|
totpToken, err = totp.GenerateCodeCustom(secret[6:], time, totp.ValidateOpts{Period: 30, Digits: 5, Encoder: otp.EncoderSteam})
|
|
} else {
|
|
totpToken, err = totp.GenerateCode(secret, time)
|
|
}
|
|
|
|
if err != nil {
|
|
return "", errors.New("unable to generate TOTP token: " + err.Error())
|
|
}
|
|
|
|
return totpToken, nil
|
|
}
|
|
|
|
// TOTPCopier is meant to be run as a goroutine to keep
|
|
// the clipboard up-to-date with the latest TOTP token.
|
|
func TOTPCopier(secret string, errorChan chan<- error, done <-chan bool) {
|
|
for {
|
|
currentTime := time.Now()
|
|
token, err := GenTOTP(secret, currentTime)
|
|
if err != nil {
|
|
errorChan <- err
|
|
}
|
|
err = CopyString(false, token)
|
|
if err != nil {
|
|
errorChan <- err
|
|
}
|
|
|
|
errorChan <- nil // indicate that first copy was successful
|
|
|
|
// sleep till next 30-second interval
|
|
time.Sleep(time.Duration(30-(currentTime.Second()%30)) * time.Second)
|
|
|
|
// exit after sleep if indicated (will not update clipboard again)
|
|
select {
|
|
case <-done:
|
|
return
|
|
default:
|
|
}
|
|
}
|
|
}
|