package license // Совместимость формата лицензии между bj (проверяет токены) и сервером лицензий // lic_Bridge-and-Join-s (выпускает их). Пакет лежит копией в обоих репозиториях; // этот тест с одинаковым ожидаемым токеном есть в обоих — если формат разойдётся, // упадёт тот, где пакет изменили. Подпись Ed25519 детерминирована. import ( "crypto/ed25519" "testing" "time" ) const compatToken = "eyJzY2hlbWEiOjEsImlkIjoiMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1NTU1NTU1NTU1IiwidGVuYW50Ijoi0J7QntCeIMKr0J/RgNC+0LLQtdGA0LrQsMK7IiwicHJvZHVjdCI6ImJqLXNlcnZlciIsInBsYW4iOiJwcm8iLCJpc3N1ZWRfYXQiOiIyMDI2LTA5LTAxVDAwOjAwOjAwWiIsImV4cGlyZXNfYXQiOiIyMDI2LTExLTAxVDAwOjAwOjAwWiIsImZlYXR1cmVzIjpbInVwZGF0ZXMiLCJucHIiXSwibWF4X25vZGVzIjoyLCJpbnN0YWxsX2lkIjoiYWFhYWFhYWEtYmJiYi1jY2NjLWRkZGQtZWVlZWVlZWVlZWVlIiwiY29udHJhY3RfdW50aWwiOiIyMDI3LTA5LTAxVDAwOjAwOjAwWiJ9.VIKhe7NZxwvTQfCNCNMwrADvlWd/izmzZrE2h1rkwliOBHQd5rGU00/v/V8uArkw4YShc5NW4BLY35wIPQ3GDg==.main" func TestTokenCompat(t *testing.T) { seed := make([]byte, ed25519.SeedSize) for i := range seed { seed[i] = byte(i + 1) } priv := ed25519.NewKeyFromSeed(seed) l := &License{ ID: "11111111-2222-3333-4444-555555555555", Tenant: "ООО «Проверка»", Product: "bj-server", Plan: PlanPro, IssuedAt: time.Date(2026, 9, 1, 0, 0, 0, 0, time.UTC), ExpiresAt: time.Date(2026, 11, 1, 0, 0, 0, 0, time.UTC), Features: []string{"updates", "npr"}, MaxNodes: 2, InstallID: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", ContractUntil: time.Date(2027, 9, 1, 0, 0, 0, 0, time.UTC), } tok, err := Sign(l, priv, "main") if err != nil { t.Fatal(err) } if got := tok.Encode(); got != compatToken { t.Fatalf("формат токена изменился — синхронизируйте internal/license в bj и сервере лицензий\nполучено: %s", got) } back, err := DecodeToken(compatToken) if err != nil { t.Fatal(err) } v, err := Verify(back, priv.Public().(ed25519.PublicKey)) if err != nil || v.InstallID != l.InstallID || !v.ContractUntil.Equal(l.ContractUntil) || v.Tenant != l.Tenant { t.Fatalf("проверка токена: %v %+v", err, v) } }