git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/otp/example/main.go (about)

     1  package main
     2  
     3  import (
     4  	"git.sr.ht/~pingoo/stdx/otp"
     5  	"git.sr.ht/~pingoo/stdx/otp/totp"
     6  
     7  	"bufio"
     8  	"bytes"
     9  	"encoding/base32"
    10  	"fmt"
    11  	"image/png"
    12  	"io/ioutil"
    13  	"os"
    14  	"time"
    15  )
    16  
    17  func display(key *otp.Key, data []byte) {
    18  	fmt.Printf("Issuer:       %s\n", key.Issuer())
    19  	fmt.Printf("Account Name: %s\n", key.AccountName())
    20  	fmt.Printf("Secret:       %s\n", key.Secret())
    21  	fmt.Println("Writing PNG to qr-code.png....")
    22  	ioutil.WriteFile("qr-code.png", data, 0644)
    23  	fmt.Println("")
    24  	fmt.Println("Please add your TOTP to your OTP Application now!")
    25  	fmt.Println("")
    26  }
    27  
    28  func promptForPasscode() string {
    29  	reader := bufio.NewReader(os.Stdin)
    30  	fmt.Print("Enter Passcode: ")
    31  	text, _ := reader.ReadString('\n')
    32  	return text
    33  }
    34  
    35  // Demo function, not used in main
    36  // Generates Passcode using a UTF-8 (not base32) secret and custom parameters
    37  func GeneratePassCode(utf8string string) string {
    38  	secret := base32.StdEncoding.EncodeToString([]byte(utf8string))
    39  	passcode, err := totp.GenerateCodeCustom(secret, time.Now(), totp.ValidateOpts{
    40  		Period:    30,
    41  		Skew:      1,
    42  		Digits:    otp.DigitsSix,
    43  		Algorithm: otp.AlgorithmSHA512,
    44  	})
    45  	if err != nil {
    46  		panic(err)
    47  	}
    48  	return passcode
    49  }
    50  
    51  func main() {
    52  	key, err := totp.Generate(totp.GenerateOpts{
    53  		Issuer:      "Example.com",
    54  		AccountName: "alice@example.com",
    55  	})
    56  	if err != nil {
    57  		panic(err)
    58  	}
    59  	// Convert TOTP key into a PNG
    60  	var buf bytes.Buffer
    61  	img, err := key.QrCode(200, 200)
    62  	if err != nil {
    63  		panic(err)
    64  	}
    65  	png.Encode(&buf, img)
    66  
    67  	// display the QR code to the user.
    68  	display(key, buf.Bytes())
    69  
    70  	// Now Validate that the user's successfully added the passcode.
    71  	fmt.Println("Validating TOTP...")
    72  	passcode := promptForPasscode()
    73  	valid := totp.Validate(passcode, key.Secret())
    74  	if valid {
    75  		println("Valid passcode!")
    76  		os.Exit(0)
    77  	} else {
    78  		println("Invalid passcode!")
    79  		os.Exit(1)
    80  	}
    81  }