package lkgateway import ( "time" "git.zetit.ru/zuevav/Bridge-and-Join-s/internal/license" ) // DefaultLicensePublicKey — публичный ключ лицензий, зашитый в релиз. // Пустой в исходниках; подставляется при официальной сборке. Если задан в // настройках (LicenseSettings.PublicKey) — приоритет у настроек. var DefaultLicensePublicKey = "" // LicenseStatus — сводка состояния лицензии для UI и гейтов. type LicenseStatus struct { Present bool // ключ введён Valid bool // подпись верна и срок не истёк Tenant string Plan string ExpiresAt time.Time DaysLeft int AllowsUpdates bool Message string } // licensingEnabled — включено ли лицензирование (есть публичный ключ для // проверки). Если ключа нет вовсе — продукт в открытом режиме, гейты не // действуют (удобно для разработки и бесплатной редакции). func licensingEnabled(rc *RuntimeConfig) bool { return rc.Snapshot().License.PublicKey != "" || DefaultLicensePublicKey != "" } // licenseStatus разбирает и проверяет лицензию из настроек. func licenseStatus(rc *RuntimeConfig) LicenseStatus { s := rc.Snapshot().License st := LicenseStatus{} if s.Key == "" { st.Message = "лицензионный ключ не введён" return st } st.Present = true pubB64 := s.PublicKey if pubB64 == "" { pubB64 = DefaultLicensePublicKey } if pubB64 == "" { st.Message = "нет публичного ключа для проверки лицензии" return st } pub, err := license.ParsePublicKey(pubB64) if err != nil { st.Message = "неверный публичный ключ: " + err.Error() return st } tok, err := license.DecodeToken(s.Key) if err != nil { st.Message = "неверный формат ключа: " + err.Error() return st } lic, err := license.Verify(tok, pub) if err != nil { st.Message = "подпись лицензии недействительна" return st } now := time.Now().UTC() st.Tenant = lic.Tenant st.Plan = string(lic.Plan) st.ExpiresAt = lic.ExpiresAt st.DaysLeft = lic.DaysLeft(now) st.AllowsUpdates = lic.AllowsUpdates() if err := lic.Valid(now); err != nil { st.Message = err.Error() return st } st.Valid = true st.Message = "активна до " + lic.ExpiresAt.Format("02.01.2006") return st }