Ispravka QR koda za 2FA — generisanje na serveru kao base64 PNG
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"image/png"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pquerna/otp/totp"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
const bcryptCost = 12
|
||||
|
||||
// HashujLozinku kreira bcrypt heš lozinke
|
||||
func HashujLozinku(lozinka string) (string, error) {
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(lozinka), bcryptCost)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("ntech: auth.HashujLozinku: %w", err)
|
||||
}
|
||||
return string(hash), nil
|
||||
}
|
||||
|
||||
// ProveriLozinku proverava da li lozinka odgovara heš vrednosti
|
||||
func ProveriLozinku(hash, lozinka string) bool {
|
||||
return bcrypt.CompareHashAndPassword([]byte(hash), []byte(lozinka)) == nil
|
||||
}
|
||||
|
||||
// GenerisiToken generiše nasumičan UUID token za sesiju
|
||||
func GenerisiToken() string {
|
||||
return uuid.New().String()
|
||||
}
|
||||
|
||||
// TotpPodaci sadrži tajnu, URI i base64-enkodiran QR kod za prikaz
|
||||
type TotpPodaci struct {
|
||||
Tajna string
|
||||
URI string
|
||||
QRBase64 string
|
||||
}
|
||||
|
||||
// GenerisuTotpTajnu generiše novu TOTP tajnu za korisnika
|
||||
func GenerisuTotpTajnu(korisnickoIme, nazivFirme string) (*TotpPodaci, error) {
|
||||
if nazivFirme == "" {
|
||||
nazivFirme = "NTech"
|
||||
}
|
||||
kljuc, err := totp.Generate(totp.GenerateOpts{
|
||||
Issuer: nazivFirme,
|
||||
AccountName: korisnickoIme,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ntech: auth.GenerisuTotpTajnu: %w", err)
|
||||
}
|
||||
img, err := kljuc.Image(200, 200)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ntech: auth.GenerisuTotpTajnu: qr: %w", err)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := png.Encode(&buf, img); err != nil {
|
||||
return nil, fmt.Errorf("ntech: auth.GenerisuTotpTajnu: png: %w", err)
|
||||
}
|
||||
return &TotpPodaci{
|
||||
Tajna: kljuc.Secret(),
|
||||
URI: kljuc.URL(),
|
||||
QRBase64: base64.StdEncoding.EncodeToString(buf.Bytes()),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RegenerisiTotpQR vraća URI i base64 QR sliku za već postojeću TOTP tajnu
|
||||
func RegenerisiTotpQR(tajna, korisnickoIme, nazivFirme string) (uri, qrBase64 string) {
|
||||
kljuc, err := totp.Generate(totp.GenerateOpts{
|
||||
Issuer: nazivFirme,
|
||||
AccountName: korisnickoIme,
|
||||
Secret: []byte(tajna),
|
||||
})
|
||||
if err != nil {
|
||||
return "", ""
|
||||
}
|
||||
img, err := kljuc.Image(200, 200)
|
||||
if err != nil {
|
||||
return kljuc.URL(), ""
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := png.Encode(&buf, img); err != nil {
|
||||
return kljuc.URL(), ""
|
||||
}
|
||||
return kljuc.URL(), base64.StdEncoding.EncodeToString(buf.Bytes())
|
||||
}
|
||||
|
||||
// VerifikujTotpKod proverava TOTP kod korisnika
|
||||
func VerifikujTotpKod(kod, tajna string) bool {
|
||||
return totp.Validate(kod, tajna)
|
||||
}
|
||||
Reference in New Issue
Block a user