Files
ai_site/platform/internal/yuhticket/ticket_test.go
whm e571e98387 feat: Z34b restore-by-host + harden web nginx DNS race
Add HMAC restore-by-host for phone-less rebind; resolve gateway at request time and recreate web after stack up.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 00:16:08 +08:00

89 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package yuhticket
import (
"testing"
"time"
)
func TestSignVerifyRoundTrip(t *testing.T) {
secret := "test-secret"
now := time.Unix(1_700_000_000, 0).UTC()
c := Claims{
Iss: "yuheng", Aud: "aijianzhan", Phone: "13531041944",
HostKey: "host-1", Exp: now.Add(90 * time.Second).Unix(), JTI: "jti-ok", Scope: "sync_bind",
}
tok, err := Sign(secret, c)
if err != nil {
t.Fatal(err)
}
got, err := Verify(tok, VerifyOpts{Secret: secret, Now: now})
if err != nil {
t.Fatal(err)
}
if got.Phone != c.Phone || got.HostKey != c.HostKey {
t.Fatalf("claims mismatch: %+v", got)
}
}
func TestVerifyBadSig(t *testing.T) {
now := time.Unix(1_700_000_000, 0).UTC()
tok, _ := Sign("a", Claims{
Phone: "13800000001", HostKey: "h", Exp: now.Add(60 * time.Second).Unix(), JTI: "j1",
})
if _, err := Verify(tok, VerifyOpts{Secret: "b", Now: now}); err == nil {
t.Fatal("expected bad sig")
}
}
func TestSignVerifyRestoreNoPhone(t *testing.T) {
secret := "test-secret"
now := time.Unix(1_700_000_000, 0).UTC()
c := Claims{
Iss: "yuheng", Aud: "aijianzhan", HostKey: "6655aabbccddeeff00112233",
Exp: now.Add(90 * time.Second).Unix(), JTI: "jti-restore", Scope: "sync_restore",
YuhengUserID: "6655aabbccddeeff00112233",
}
tok, err := Sign(secret, c)
if err != nil {
t.Fatal(err)
}
got, err := Verify(tok, VerifyOpts{
Secret: secret, Now: now, AllowEmptyPhone: true,
AllowedScopes: []string{"sync_bind", "sync_restore"},
})
if err != nil {
t.Fatal(err)
}
if got.HostKey != c.HostKey || got.Phone != "" {
t.Fatalf("claims mismatch: %+v", got)
}
// 默认 Verify须 phone应拒绝无 phone 的 sync_bindsync_restore 在默认 scopes 外也应拒绝
if _, err := Verify(tok, VerifyOpts{Secret: secret, Now: now}); err == nil {
t.Fatal("expected scope reject without AllowedScopes")
}
}
func TestSignRequiresPhoneForSyncBind(t *testing.T) {
_, err := Sign("s", Claims{
HostKey: "h", Exp: time.Now().Add(time.Minute).Unix(), JTI: "j", Scope: "sync_bind",
})
if err == nil {
t.Fatal("expected phone required for sync_bind")
}
}
func TestJTIConsume(t *testing.T) {
dir := t.TempDir()
st, err := NewJTIStore(dir)
if err != nil {
t.Fatal(err)
}
exp := time.Now().Add(time.Minute).Unix()
if err := st.Consume("x", exp); err != nil {
t.Fatal(err)
}
if err := st.Consume("x", exp); err == nil {
t.Fatal("expected replay")
}
}