1package backend
2
3import (
4 "crypto/rand"
5 "crypto/sha256"
6 "encoding/hex"
7
8 "github.com/charmbracelet/log/v2"
9 "golang.org/x/crypto/bcrypt"
10)
11
12const saltySalt = "salty-soft-serve"
13
14// HashPassword hashes the password using bcrypt.
15func HashPassword(password string) (string, error) {
16 crypt, err := bcrypt.GenerateFromPassword([]byte(password+saltySalt), bcrypt.DefaultCost)
17 if err != nil {
18 return "", err //nolint:wrapcheck
19 }
20
21 return string(crypt), nil
22}
23
24// VerifyPassword verifies the password against the hash.
25func VerifyPassword(password, hash string) bool {
26 err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password+saltySalt))
27 return err == nil
28}
29
30// GenerateToken returns a random unique token.
31func GenerateToken() string {
32 buf := make([]byte, 20)
33 if _, err := rand.Read(buf); err != nil {
34 log.Error("unable to generate access token")
35 return ""
36 }
37
38 return "ss_" + hex.EncodeToString(buf)
39}
40
41// HashToken hashes the token using sha256.
42func HashToken(token string) string {
43 sum := sha256.Sum256([]byte(token + saltySalt))
44 return hex.EncodeToString(sum[:])
45}