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]>
This commit is contained in:
commit
8742829e77
20 files changed
+2348
No files matched your search
@@ -0,0 +1,60 @@
|
||||
// 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
|
||||
}
|
||||
Reference in new issue
Block a user