func (o *OTP) QRImage(width, height int) (image.Image, error) { key, err := otp.NewKeyFromURL(o.URI) if err != nil { return nil, err } return key.Image(width, height) }
func (o *OTP) Validate(password string) error { key, err := otp.NewKeyFromURL(o.URI) if err != nil { return err } if !totp.Validate(password, key.Secret()) { return ErrAccessDenied } return nil }
// Generate a new TOTP Key. func Generate(opts GenerateOpts) (*otp.Key, error) { // url encode the Issuer/AccountName if opts.Issuer == "" { return nil, otp.ErrGenerateMissingIssuer } if opts.AccountName == "" { return nil, otp.ErrGenerateMissingAccountName } if opts.Period == 0 { opts.Period = 30 } if opts.SecretSize == 0 { opts.SecretSize = 10 } // otpauth://totp/Example:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=Example v := url.Values{} secret := make([]byte, opts.SecretSize) _, err := rand.Read(secret) if err != nil { return nil, err } v.Set("secret", base32.StdEncoding.EncodeToString(secret)) v.Set("issuer", opts.Issuer) v.Set("period", strconv.FormatUint(uint64(opts.Period), 10)) v.Set("algorithm", opts.Algorithm.String()) v.Set("digits", opts.Digits.String()) u := url.URL{ Scheme: "otpauth", Host: "totp", Path: "/" + opts.Issuer + ":" + opts.AccountName, RawQuery: v.Encode(), } return otp.NewKeyFromURL(u.String()) }