diff --git a/application/src/main/java/org/thingsboard/server/controller/MobileApplicationController.java b/application/src/main/java/org/thingsboard/server/controller/MobileApplicationController.java index 77e34fc18c..0e12ddb273 100644 --- a/application/src/main/java/org/thingsboard/server/controller/MobileApplicationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/MobileApplicationController.java @@ -16,6 +16,7 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import io.swagger.v3.oas.annotations.Parameter; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; @@ -47,6 +48,7 @@ import org.thingsboard.server.service.security.system.SystemSecurityService; import java.net.URI; import java.net.URISyntaxException; +import java.util.Optional; import static org.thingsboard.server.controller.ControllerConstants.AVAILABLE_FOR_ANY_AUTHORIZED_USER; import static org.thingsboard.server.controller.ControllerConstants.SYSTEM_AUTHORITY_PARAGRAPH; @@ -81,8 +83,8 @@ public class MobileApplicationController extends BaseController { " }\n" + "}"; - public static final String ANDROID_APPLICATION_STORE_LINK = "https://play.google.com/store/apps/details?id=org.thingsboard.demo.app"; - public static final String APPLE_APPLICATION_STORE_LINK = "https://apps.apple.com/us/app/thingsboard-live/id1594355695"; + public static final String DEFAULT_GOOGLE_APP_STORE_LINK = "https://play.google.com/store/apps/details?id=org.thingsboard.demo.app"; + public static final String DEFAULT_APPLE_APP_STORE_LINK = "https://apps.apple.com/us/app/thingsboard-live/id1594355695"; public static final String SECRET = "secret"; public static final String SECRET_PARAM_DESCRIPTION = "A string value representing short-lived secret key"; public static final String DEFAULT_APP_DOMAIN = "demo.thingsboard.io"; @@ -171,13 +173,14 @@ public class MobileApplicationController extends BaseController { @GetMapping(value = "/api/noauth/qr") public ResponseEntity getApplicationRedirect(@RequestHeader(value = "User-Agent") String userAgent) { + MobileAppSettings mobileAppSettings = mobileAppSettingsService.getMobileAppSettings(TenantId.SYS_TENANT_ID); if (userAgent.contains("Android")) { return ResponseEntity.status(HttpStatus.FOUND) - .header("Location", ANDROID_APPLICATION_STORE_LINK) + .header("Location", getGoogleStoreLink(mobileAppSettings)) .build(); } else if (userAgent.contains("iPhone") || userAgent.contains("iPad")) { return ResponseEntity.status(HttpStatus.FOUND) - .header("Location", APPLE_APPLICATION_STORE_LINK) + .header("Location", getAppleStoreLink(mobileAppSettings)) .build(); } else { return ResponseEntity.status(HttpStatus.NOT_FOUND) @@ -185,4 +188,26 @@ public class MobileApplicationController extends BaseController { } } + @ApiOperation(value = "Get Mobile application store link (getMobileAppStoreLinks)", + notes = "The response payload contains links to google play and apple store." + AVAILABLE_FOR_ANY_AUTHORIZED_USER) + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") + @GetMapping(value = "/api/mobile/app/storeLinks") + public JsonNode getMobileAppStoreLinks() { + MobileAppSettings mobileAppSettings = mobileAppSettingsService.getMobileAppSettings(TenantId.SYS_TENANT_ID); + ObjectNode infoObject = JacksonUtil.newObjectNode(); + infoObject.put("googlePlayLink", getGoogleStoreLink(mobileAppSettings)); + infoObject.put("appStoreLink", getAppleStoreLink(mobileAppSettings)); + return infoObject; + } + + private String getGoogleStoreLink(MobileAppSettings mobileAppSettings) { + return mobileAppSettings.isUseDefaultApp() ? DEFAULT_GOOGLE_APP_STORE_LINK : + Optional.ofNullable(mobileAppSettings.getAndroidConfig().getStoreLink()).orElse(DEFAULT_GOOGLE_APP_STORE_LINK); + } + + private String getAppleStoreLink(MobileAppSettings mobileAppSettings) { + return mobileAppSettings.isUseDefaultApp() ? DEFAULT_APPLE_APP_STORE_LINK : + Optional.ofNullable(mobileAppSettings.getIosConfig().getStoreLink()).orElse(DEFAULT_APPLE_APP_STORE_LINK); + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/AndroidConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/AndroidConfig.java index e1fb5056fc..d670382462 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/AndroidConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/AndroidConfig.java @@ -34,5 +34,7 @@ public class AndroidConfig { private String appPackage; @NoXss private String sha256CertFingerprints; + @NoXss + private String storeLink; } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/IosConfig.java b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/IosConfig.java index f03b446b3b..7d40dfe805 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/mobile/IosConfig.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/mobile/IosConfig.java @@ -32,5 +32,7 @@ public class IosConfig { private boolean enabled; @NoXss private String appId; + @NoXss + private String storeLink; }