Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.github.jan.supabase

import io.ktor.http.Headers
import io.ktor.http.Url
import io.ktor.util.toMap

internal fun maskString(value: String, visibleCharacters: Int = 2, showLength: Boolean = false): String {
if(value.isBlank()) return value;
return value.take(visibleCharacters) + "..." + if(showLength) " (len=${value.length})" else ""
}

internal fun maskUrl(value: Url, visibleCharacters: Int = 2): String {
return buildUrl(value) {
host = "${host.take(visibleCharacters)}..."
}
}

private val SENSITIVE_HEADERS = listOf("apikey", "Authorization")

internal fun maskHeaders(headers: Headers): String = headers.toMap().mapValues { (key, value) ->
if(key in SENSITIVE_HEADERS) {
value.firstOrNull()?.let {
listOf(if(key == "Authorization") "Bearer ${maskString(it.drop(7), showLength = true)}" else maskString(it, showLength = true))
}
} else value
}.toString()
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.github.jan.supabase

import io.github.jan.supabase.annotations.SupabaseInternal
import io.ktor.http.URLBuilder
import io.ktor.http.Url

@SupabaseInternal
inline fun buildUrl(baseUrl: String, init: URLBuilder.() -> Unit): String {
val builder = URLBuilder(baseUrl)
builder.init()
return builder.buildString()
}

@SupabaseInternal
inline fun buildUrl(baseUrl: Url, init: URLBuilder.() -> Unit): String {
val builder = URLBuilder(baseUrl)
builder.init()
return builder.buildString()
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import io.github.jan.supabase.exceptions.SupabaseEncodingException
import io.github.jan.supabase.logging.i
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.bodyAsText
import io.ktor.http.URLBuilder
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.MissingFieldException
import kotlinx.serialization.SerializationException
Expand All @@ -32,13 +31,6 @@ suspend inline fun <reified T> HttpResponse.safeBody(context: String? = null): T
}
}

@SupabaseInternal
inline fun buildUrl(baseUrl: String, init: URLBuilder.() -> Unit): String {
val builder = URLBuilder(baseUrl)
builder.init()
return builder.buildString()
}

@SupabaseInternal
fun String.toJsonObject(): JsonObject = supabaseJson.decodeFromString(this)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.github.jan.supabase.exceptions

import io.github.jan.supabase.maskHeaders
import io.github.jan.supabase.maskUrl
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.request

Expand All @@ -17,8 +19,8 @@ import io.ktor.client.statement.request
*/
open class RestException(val error: String, val description: String?, val response: HttpResponse): Exception("""
$error${description?.let { "\n$it" } ?: ""}
URL: ${response.request.url}
Headers: ${response.request.headers.entries()}
URL: ${maskUrl(response.request.url)}
Headers: ${maskHeaders(response.request.headers)}
Http Method: ${response.request.method.value}
""".trimIndent()) {

Expand Down
46 changes: 46 additions & 0 deletions Supabase/src/commonTest/kotlin/StringMaskingTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import io.github.jan.supabase.maskHeaders
import io.github.jan.supabase.maskString
import io.github.jan.supabase.maskUrl
import io.ktor.http.Url
import io.ktor.http.headers
import kotlin.test.Test
import kotlin.test.assertEquals

class StringMaskingTest {

@Test
fun testEmptyString() {
assertEquals("", maskString(""))
}

@Test
fun testString() {
assertEquals("ab...", maskString("abcdefghi"))
}

@Test
fun testStringWithLength() {
assertEquals("ab... (len=5)", maskString("abcde", showLength = true))
}

@Test
fun testUrl() {
assertEquals("https://ab.../test?parameter=true", maskUrl(Url("https://abcdefg.supabase.co/test?parameter=true")))
}

@Test
fun testHeaderMasking() {
val headers = headers {
set("aa", "bb")
set("another", "one")
set("apikey", "areallylongkey")
set("Authorization", "Bearer thisisasecretkey")
}
val maskedString = maskHeaders(headers)
assertEquals(
"{aa=[bb], another=[one], apikey=[ar... (len=14)], Authorization=[Bearer th... (len=16)]}",
maskedString
)
}

}
Loading