Files
minstrel/internal/api/stream_token.go
T
bvandeusenandClaude Opus 5.5 08a2c06b85 docs: api comments say what the endpoints do, not how they came to be (#6277)
Rewrites the internal/api comment blocks to rule 32: task, milestone and
rule ids gone, the stories behind them restated as the constraint they
left, stale references corrected (the stream secret is wired from config,
the timezone handler already refreshes the scheduler, the Android app is
the native client, the design docs cited are not in the repo). Also
rewraps comment lines over 80 columns left by the earlier batches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 12:23:58 -04:00

39 lines
1.4 KiB
Go

package api
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"time"
)
// SignStreamToken returns the HMAC-SHA256 hex of "<trackID>|<exp>" keyed
// by secret. The token is constant-time-comparable via VerifyStreamToken
// so it's safe to expose the verification function in handlers.
//
// trackID is the canonical track UUID. exp is the Unix time after which
// the token is invalid; the handler checks exp before serving.
//
// The secret comes from MINSTREL_STREAM_SECRET, or its auto-generated
// fallback persisted under the data directory. This file is the primitive
// the token endpoint and the stream handler share.
func SignStreamToken(secret []byte, trackID string, exp int64) string {
mac := hmac.New(sha256.New, secret)
// hash.Hash.Write is documented as never returning an error.
_, _ = fmt.Fprintf(mac, "%s|%d", trackID, exp)
return hex.EncodeToString(mac.Sum(nil))
}
// VerifyStreamToken returns true iff token is a valid HMAC for
// (trackID, exp) AND exp has not yet passed. Wall-clock comparison —
// callers must trust the server's clock. Uses hmac.Equal for
// constant-time compare so a timing oracle can't bias token guessing.
func VerifyStreamToken(secret []byte, trackID string, exp int64, token string) bool {
if time.Now().Unix() > exp {
return false
}
expected := SignStreamToken(secret, trackID, exp)
return hmac.Equal([]byte(expected), []byte(token))
}