Files
t5de-catalog/internal/token/tokentest/tokentest.go
T
dhkatzandClaude Opus 5.5 8742829e77
CI / build (push) Successful in 54s
t5de-catalog: store and serve community product files
A Go server that takes product uploads with hub upload tokens, checks them by
t5de-api's pack rules, stores files by sha256, registers revisions with the hub
(POST /api/v1/catalog/revisions), and serves files with immutable caching;
files used only by adult revisions need an adult access token. Contract:
t5de-hub's docs/products.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 18:59:16 -07:00

61 lines
1.6 KiB
Go

// Package tokentest signs tokens the way the hub does, for tests.
package tokentest
import (
"crypto/ed25519"
"crypto/rand"
"encoding/base64"
"encoding/json"
)
// Key is a test signing key.
type Key struct {
ID string
Private ed25519.PrivateKey
Public ed25519.PublicKey
}
// NewKey makes a key with ID kid.
func NewKey(kid string) *Key {
pub, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
panic(err)
}
return &Key{ID: kid, Private: priv, Public: pub}
}
// Sign returns a compact EdDSA JWT with these claims, with the header the hub sends.
func (k *Key) Sign(claims map[string]any) string {
return k.SignWithHeader(map[string]any{"alg": "EdDSA", "kid": k.ID, "typ": "JWT"}, claims)
}
// SignWithHeader signs claims with any header.
func (k *Key) SignWithHeader(header, claims map[string]any) string {
input := part(header) + "." + part(claims)
return input + "." + base64.RawURLEncoding.EncodeToString(ed25519.Sign(k.Private, []byte(input)))
}
func part(v any) string {
data, err := json.Marshal(v)
if err != nil {
panic(err)
}
return base64.RawURLEncoding.EncodeToString(data)
}
// JWKS returns a key set holding these keys, as the hub serves it.
func JWKS(keys ...*Key) []byte {
var set struct {
Keys []map[string]string `json:"keys"`
}
set.Keys = []map[string]string{}
for _, k := range keys {
set.Keys = append(set.Keys, map[string]string{
"kty": "OKP", "crv": "Ed25519", "x": base64.RawURLEncoding.EncodeToString(k.Public),
"kid": k.ID, "alg": "EdDSA", "use": "sig",
})
}
data, _ := json.Marshal(set)
return data
}