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
- 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.
47 lines
1.7 KiB
Go
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...)))
|
|
}
|