feat: centralize app release configuration
This commit is contained in:
+73
-8
@@ -3215,12 +3215,9 @@ func serveIMAppReleaseLatest(wrt http.ResponseWriter, req *http.Request) {
|
||||
writeIMError(wrt, req, http.StatusMethodNotAllowed, 30002, imReasonMethodNotAllowed, "method not allowed", nil)
|
||||
return
|
||||
}
|
||||
tenant, ok := resolveIMHTTPTenant(wrt, req, "default")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
platform := strings.ToLower(strings.TrimSpace(req.URL.Query().Get("platform")))
|
||||
channel := strings.ToLower(strings.TrimSpace(req.URL.Query().Get("channel")))
|
||||
currentVersion := strings.TrimSpace(req.URL.Query().Get("current_version"))
|
||||
if channel == "" {
|
||||
channel = "stable"
|
||||
}
|
||||
@@ -3228,12 +3225,34 @@ func serveIMAppReleaseLatest(wrt http.ResponseWriter, req *http.Request) {
|
||||
writeIMError(wrt, req, http.StatusBadRequest, 30000, imReasonMalformedRequest, "malformed request", map[string]any{"field": "platform"})
|
||||
return
|
||||
}
|
||||
release, err := store.AppReleases.Latest(tenant.ID, platform, channel)
|
||||
currentParts, err := parseNumericAppVersion(currentVersion)
|
||||
if err != nil {
|
||||
writeIMError(wrt, req, http.StatusBadRequest, 30000, imReasonMalformedRequest, "malformed request", map[string]any{"field": "current_version"})
|
||||
return
|
||||
}
|
||||
release, err := store.AppReleases.Latest(platform, channel)
|
||||
if err != nil {
|
||||
writeIMRelationError(wrt, req, err)
|
||||
return
|
||||
}
|
||||
writeIMSuccess(wrt, req, appReleasePayload(release))
|
||||
latestParts, latestErr := parseNumericAppVersion(release.LatestVersion)
|
||||
minimumParts, minimumErr := parseNumericAppVersion(release.MinSupportedVersion)
|
||||
if latestErr != nil || minimumErr != nil {
|
||||
writeIMError(wrt, req, http.StatusInternalServerError, 50000, imReasonInternal, "invalid app release configuration", nil)
|
||||
return
|
||||
}
|
||||
hasUpdate := compareNumericAppVersion(currentParts, latestParts) < 0
|
||||
updateType := "none"
|
||||
if hasUpdate {
|
||||
updateType = strings.ToLower(strings.TrimSpace(release.UpdateType))
|
||||
if compareNumericAppVersion(currentParts, minimumParts) < 0 {
|
||||
updateType = "force"
|
||||
}
|
||||
if updateType != "force" && updateType != "recommended" {
|
||||
updateType = "none"
|
||||
}
|
||||
}
|
||||
writeIMSuccess(wrt, req, appReleasePayload(release, currentVersion, hasUpdate, updateType))
|
||||
}
|
||||
|
||||
func serveIMYouthMode(wrt http.ResponseWriter, req *http.Request) {
|
||||
@@ -9315,13 +9334,16 @@ func imCanViewLastSeen(tenantID types.TenantID, viewer, target types.Uid) bool {
|
||||
}
|
||||
}
|
||||
|
||||
func appReleasePayload(release *types.AppRelease) map[string]any {
|
||||
func appReleasePayload(release *types.AppRelease, currentVersion string, hasUpdate bool, updateType string) map[string]any {
|
||||
return map[string]any{
|
||||
"current_version": currentVersion,
|
||||
"has_update": hasUpdate,
|
||||
"force_update": hasUpdate && updateType == "force",
|
||||
"platform": release.Platform,
|
||||
"channel": release.Channel,
|
||||
"latest_version": release.LatestVersion,
|
||||
"min_supported_version": release.MinSupportedVersion,
|
||||
"update_type": release.UpdateType,
|
||||
"update_type": updateType,
|
||||
"release_notes": release.ReleaseNotes,
|
||||
"store_url": release.StoreURL,
|
||||
"package_url": release.PackageURL,
|
||||
@@ -9331,6 +9353,49 @@ func appReleasePayload(release *types.AppRelease) map[string]any {
|
||||
}
|
||||
}
|
||||
|
||||
func parseNumericAppVersion(raw string) ([]uint64, error) {
|
||||
raw = strings.TrimPrefix(strings.ToLower(strings.TrimSpace(raw)), "v")
|
||||
parts := strings.Split(raw, ".")
|
||||
if len(parts) == 0 || len(parts) > 8 {
|
||||
return nil, types.ErrMalformed
|
||||
}
|
||||
parsed := make([]uint64, len(parts))
|
||||
for i, part := range parts {
|
||||
if part == "" {
|
||||
return nil, types.ErrMalformed
|
||||
}
|
||||
value, err := strconv.ParseUint(part, 10, 32)
|
||||
if err != nil {
|
||||
return nil, types.ErrMalformed
|
||||
}
|
||||
parsed[i] = value
|
||||
}
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
func compareNumericAppVersion(left, right []uint64) int {
|
||||
length := len(left)
|
||||
if len(right) > length {
|
||||
length = len(right)
|
||||
}
|
||||
for i := 0; i < length; i++ {
|
||||
var leftPart, rightPart uint64
|
||||
if i < len(left) {
|
||||
leftPart = left[i]
|
||||
}
|
||||
if i < len(right) {
|
||||
rightPart = right[i]
|
||||
}
|
||||
if leftPart < rightPart {
|
||||
return -1
|
||||
}
|
||||
if leftPart > rightPart {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func youthModePayload(settings *types.YouthModeSettings) map[string]any {
|
||||
data := map[string]any{
|
||||
"enabled": settings.Enabled,
|
||||
|
||||
Reference in New Issue
Block a user