...

Source file src/edge-infra.dev/pkg/edge/api/totp/totp.go

Documentation: edge-infra.dev/pkg/edge/api/totp

     1  package totp
     2  
     3  import (
     4  	"encoding/base32"
     5  	"errors"
     6  	"fmt"
     7  	"time"
     8  
     9  	"edge-infra.dev/pkg/edge/api/graph/model"
    10  
    11  	"github.com/pquerna/otp"
    12  	"github.com/pquerna/otp/totp"
    13  )
    14  
    15  const (
    16  	// DefaultTokenDuration is the default time in seconds
    17  	// a totp token will be valid for
    18  	DefaultTokenDuration = 600
    19  	// DefaultOtpLength is the default length of
    20  	// the totp token
    21  	DefaultOtpLength = 6
    22  	// InvalidTOTPToken message for invalid totp token
    23  	InvalidTOTPToken = "invalid totp token/secret"
    24  )
    25  
    26  var (
    27  	ErrInvalidTOTPToken = errors.New(InvalidTOTPToken)
    28  )
    29  
    30  // GenerateTotp generates a totp token with the provided secret
    31  func GenerateTotp(totpSecret string) (*model.Totp, error) {
    32  	secret := base32.StdEncoding.EncodeToString([]byte(totpSecret))
    33  	currentTime := time.Now().UTC()
    34  	expiryTime := currentTime.Add(DefaultTokenDuration * time.Second)
    35  	passcode, err := totp.GenerateCodeCustom(secret, currentTime, totp.ValidateOpts{
    36  		Period: DefaultTokenDuration,
    37  		Digits: otp.Digits(DefaultOtpLength),
    38  	})
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	response := &model.Totp{
    43  		Code:      passcode,
    44  		CreatedAt: currentTime.String(),
    45  		ExpiresAt: expiryTime.String(),
    46  		Duration:  DefaultTokenDuration,
    47  	}
    48  	return response, nil
    49  }
    50  
    51  // ValidateTotpToken validates that a totp token is valid and has not be tampered with or expired
    52  func ValidateTotpToken(token string, totpSecret string) error {
    53  	secret := base32.StdEncoding.EncodeToString([]byte(totpSecret))
    54  	currentTime := time.Now().UTC()
    55  	valid, err := totp.ValidateCustom(token, secret, currentTime, totp.ValidateOpts{
    56  		Period: DefaultTokenDuration,
    57  		Digits: otp.Digits(DefaultOtpLength),
    58  	})
    59  	if err != nil {
    60  		return fmt.Errorf("%s: %v", InvalidTOTPToken, err)
    61  	}
    62  	if !valid {
    63  		return ErrInvalidTOTPToken
    64  	}
    65  	return nil
    66  }
    67  

View as plain text