package app import ( "crypto/hmac" "crypto/rand" "crypto/sha256" "encoding/base32" "encoding/base64" "encoding/hex" "errors" "strings" ) var codeEncoding = base32.NewEncoding("0123456789ABCDEFGHJKMNPQRSTVWXYZ"). WithPadding(base32.NoPadding) func randomBytes(size int) ([]byte, error) { value := make([]byte, size) if _, err := rand.Read(value); err != nil { return nil, err } return value, nil } func randomToken(size int) (string, error) { value, err := randomBytes(size) if err != nil { return "", err } return base64.RawURLEncoding.EncodeToString(value), nil } func deploymentCode() (string, error) { value, err := randomBytes(7) if err != nil { return "", err } encoded := codeEncoding.EncodeToString(value) if len(encoded) < 10 { return "", errors.New("generated deployment code is too short") } return "TAPM-" + encoded[:5] + "-" + encoded[5:10], nil } func normalizeCode(value string) string { return strings.ToUpper(strings.ReplaceAll(strings.TrimSpace(value), " ", "")) } func hashValue(value string) [32]byte { return sha256.Sum256([]byte(value)) } func hashHex(value string) string { sum := hashValue(value) return hex.EncodeToString(sum[:]) } func signValue(secret []byte, value string) string { mac := hmac.New(sha256.New, secret) _, _ = mac.Write([]byte(value)) return base64.RawURLEncoding.EncodeToString(mac.Sum(nil)) } func verifySignature(secret []byte, value, signature string) bool { expected := signValue(secret, value) return hmac.Equal([]byte(expected), []byte(signature)) }