diff --git a/app/shared/src/commonMain/kotlin/ru/fromchat/api/ApiClient.kt b/app/shared/src/commonMain/kotlin/ru/fromchat/api/ApiClient.kt index 6a9c546..137976e 100644 --- a/app/shared/src/commonMain/kotlin/ru/fromchat/api/ApiClient.kt +++ b/app/shared/src/commonMain/kotlin/ru/fromchat/api/ApiClient.kt @@ -854,16 +854,19 @@ object ApiClient { } /** - * Fetch encrypted file bytes. Path is e.g. "/uploads/files/encrypted/xxx.jpg" or "/api/uploads/files/encrypted/xxx.jpg". - * Backend may return path with /api prefix; apiBaseUrl already includes /api, so we avoid double /api. + * Fetch encrypted file bytes. Path examples: + * - absolute URL like "http://..." -> returned as-is + * - "/uploads/files/encrypted/xxx.jpg" -> returned as /uploads/... + * - "/api/uploads/..." -> strip legacy `/api` prefix, then combine with apiBaseUrl */ - fun encryptedFileUrl(path: String): String = when { - path.startsWith("http") -> path - path.startsWith("/api") -> { - val serverBase = ServerConfig.apiBaseUrl.removeSuffix("/api") - "$serverBase$path" + fun encryptedFileUrl(path: String): String { + if (path.startsWith("http")) return path + val base = ServerConfig.apiBaseUrl.trimEnd('/') + var p = if (path.startsWith("/")) path else "/$path" + if (p.startsWith("/api/") || p == "/api") { + p = p.removePrefix("/api").ifEmpty { "/" } } - else -> "${ServerConfig.apiBaseUrl}$path" + return base + p } /** Plain public-chat attachment URL (same path resolution as [encryptedFileUrl]). */ @@ -1357,7 +1360,7 @@ object ApiClient { suspend fun validateToken(): Boolean { try { http - .get("${ServerConfig.apiBaseUrl}/api/user/profile") + .get("${ServerConfig.apiBaseUrl}/user/profile") return true // Token is valid if no exception thrown } catch (e: ClientRequestException) { if (e.response.status.value == 401 || e.response.status.value == 403) { diff --git a/app/shared/src/commonMain/kotlin/ru/fromchat/api/instance/InstanceIdResolve.kt b/app/shared/src/commonMain/kotlin/ru/fromchat/api/instance/InstanceIdResolve.kt index fd12434..3b92d28 100644 --- a/app/shared/src/commonMain/kotlin/ru/fromchat/api/instance/InstanceIdResolve.kt +++ b/app/shared/src/commonMain/kotlin/ru/fromchat/api/instance/InstanceIdResolve.kt @@ -73,7 +73,7 @@ suspend fun resolveInstanceId( fun apiBaseUrlFor(config: ServerConfigData): String { val scheme = if (config.httpsEnabled) "https" else "http" - return "$scheme://${config.serverIp}:${config.apiPort}/api" + return "$scheme://${config.serverIp}:${config.apiPort}" } private fun networkFailureToResolveResult( diff --git a/app/shared/src/commonMain/kotlin/ru/fromchat/config/ServerConfig.kt b/app/shared/src/commonMain/kotlin/ru/fromchat/config/ServerConfig.kt index f426412..cb990b3 100644 --- a/app/shared/src/commonMain/kotlin/ru/fromchat/config/ServerConfig.kt +++ b/app/shared/src/commonMain/kotlin/ru/fromchat/config/ServerConfig.kt @@ -50,12 +50,12 @@ object ServerConfig { } /** - * LiveKit signaling WebSocket URL: same host and API port as HTTPS reverse proxy (`/api/livekit/rtc`). + * LiveKit signaling WebSocket URL: same host and API port as HTTPS reverse proxy (`/livekit/rtc`). * WebRTC media uses the configured calls port on the server (e.g. HAProxy in front of LiveKit). */ fun liveKitSignalingWsUrl(): String { val scheme = if (config.httpsEnabled) "wss" else "ws" - return "$scheme://${config.serverIp}:${config.apiPort}/api/livekit/rtc" + return "$scheme://${config.serverIp}:${config.apiPort}/livekit/rtc" } /** @@ -64,7 +64,7 @@ object ServerConfig { val apiBaseUrl: String get() { val scheme = if (config.httpsEnabled) "https" else "http" - return "$scheme://${config.serverIp}:${config.apiPort}/api" + return "$scheme://${config.serverIp}:${config.apiPort}" } /** @@ -73,7 +73,7 @@ object ServerConfig { val webSocketUrl: String get() { val scheme = if (config.httpsEnabled) "wss" else "ws" - return "$scheme://${config.serverIp}:${config.apiPort}/api/chat/ws" + return "$scheme://${config.serverIp}:${config.apiPort}/chat/ws" } } diff --git a/app/shared/src/commonMain/kotlin/ru/fromchat/ui/chat/Avatar.kt b/app/shared/src/commonMain/kotlin/ru/fromchat/ui/chat/Avatar.kt index 52f8443..3ea9ec9 100644 --- a/app/shared/src/commonMain/kotlin/ru/fromchat/ui/chat/Avatar.kt +++ b/app/shared/src/commonMain/kotlin/ru/fromchat/ui/chat/Avatar.kt @@ -76,7 +76,10 @@ fun Avatar( val fullUrl = if (profilePictureUrl.startsWith("http")) { profilePictureUrl } else { - "${ServerConfig.apiBaseUrl}$profilePictureUrl" + val path = profilePictureUrl + .removePrefix("/api") + .let { if (it.startsWith("/")) it else "/$it" } + "${ServerConfig.apiBaseUrl}$path" } AsyncImage(