Files
pipu-music/services/api/internal/platform/sign/sign.go
T
mrleo1nid 1e3b350dfc
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m1s
ci / db / db (push) Successful in 1m16s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m12s
ci / api / api (push) Successful in 45s
ci / recommender / recommender (push) Successful in 1m50s
ci / ts / ts (packages + web) (push) Failing after 6m53s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m13s
feat(upload): enhance audio upload handling and user feedback
- Introduced a new warning for users uploading non-FLAC or WAV formats, indicating that these formats should only be used as a last resort.
- Added functionality to highlight files needing format attention in the upload queue.
- Updated the UI to provide clearer guidance on acceptable audio formats during uploads.
- Improved documentation to reflect changes in upload requirements and user interface updates.
2026-10-21 10:07:43 +03:00

47 lines
1.7 KiB
Go

// Package sign — HMAC-подписи ссылок, которые клиент открывает без заголовка Authorization
// (обложки в <img>, стрим в <audio>).
package sign
import (
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"fmt"
"strings"
)
// Signer подписывает наборы строк ключом сервера.
type Signer struct{ key []byte }
// New создаёт Signer. Пустой ключ — случайный: ссылки перестанут действовать после перезапуска.
func New(keyBase64 string) (*Signer, error) {
if strings.TrimSpace(keyBase64) == "" {
key := make([]byte, 32)
if _, err := rand.Read(key); err != nil {
return nil, err
}
return &Signer{key: key}, nil
}
key, err := base64.StdEncoding.DecodeString(strings.TrimSpace(keyBase64))
if err != nil || len(key) < 16 {
return nil, fmt.Errorf("sign: key must be base64 of at least 16 bytes")
}
return &Signer{key: key}, nil
}
// Sign возвращает подпись частей (base64url, 22 символа — первые 16 байт HMAC-SHA256).
func (s *Signer) Sign(parts ...string) string {
m := hmac.New(sha256.New, s.key)
for _, p := range parts {
_, _ = m.Write([]byte(p))
_, _ = m.Write([]byte{0}) // разделитель: ("ab","c") и ("a","bc") подписываются по-разному
}
return base64.RawURLEncoding.EncodeToString(m.Sum(nil)[:16])
}
// Verify проверяет подпись за постоянное время.
func (s *Signer) Verify(sig string, parts ...string) bool {
return hmac.Equal([]byte(sig), []byte(s.Sign(parts...)))
}