@@ -52,13 +52,25 @@ import org.mongodb.kbson.serialization.EJson
5252public interface AppConfiguration {
5353
5454 public val appId: String
55+
5556 // TODO Consider replacing with URL type, but didn't want to include io.ktor.http.Url as it
5657 // requires ktor as api dependency
5758 public val baseUrl: String
5859 public val encryptionKey: ByteArray?
5960 public val metadataMode: MetadataMode
6061 public val syncRootDirectory: String
6162
63+ /* *
64+ * Authorization header name used for Atlas App services requests.
65+ */
66+ public val authorizationHeaderName: String
67+
68+ /* *
69+ * Custom configured headers that will be sent alongside other headers when
70+ * making network requests towards Atlas App services.
71+ */
72+ public val customRequestHeaders: Map <String , String >
73+
6274 /* *
6375 * The name of app. This is only used for debugging.
6476 *
@@ -119,7 +131,7 @@ public interface AppConfiguration {
119131 * @param appId the application id of the App Services Application.
120132 */
121133 public class Builder (
122- private val appId : String
134+ private val appId : String ,
123135 ) {
124136
125137 private var baseUrl: String = DEFAULT_BASE_URL
@@ -131,9 +143,12 @@ public interface AppConfiguration {
131143 private var networkTransport: NetworkTransport ? = null
132144 private var appName: String? = null
133145 private var appVersion: String? = null
146+
134147 @OptIn(ExperimentalKBsonSerializerApi ::class )
135148 private var ejson: EJson = EJson
136149 private var httpLogObfuscator: HttpLogObfuscator ? = LogObfuscatorImpl
150+ private val customRequestHeaders = mutableMapOf<String , String >()
151+ private var authorizationHeaderName: String = DEFAULT_AUTHORIZATION_HEADER_NAME
137152
138153 /* *
139154 * Sets the encryption key used to encrypt the user metadata Realm only. Individual
@@ -179,7 +194,10 @@ public interface AppConfiguration {
179194 * @return the Builder instance used.
180195 */
181196 @Deprecated(" Use io.realm.kotlin.log.RealmLog instead." )
182- public fun log (level : LogLevel = LogLevel .WARN , customLoggers : List <RealmLogger > = emptyList()): Builder =
197+ public fun log (
198+ level : LogLevel = LogLevel .WARN ,
199+ customLoggers : List <RealmLogger > = emptyList(),
200+ ): Builder =
183201 apply {
184202 this .logLevel = level
185203 this .userLoggers = customLoggers
@@ -268,6 +286,34 @@ public interface AppConfiguration {
268286 this .httpLogObfuscator = httpLogObfuscator
269287 }
270288
289+ /* *
290+ * Sets the name of the HTTP header used to send authorization data in when making requests to
291+ * Atlas App Services. The Atlas App or firewall must have been configured to expect a
292+ * custom authorization header.
293+ *
294+ * The default authorization header is named [DEFAULT_AUTHORIZATION_HEADER_NAME].
295+ *
296+ * @param name name of the header.
297+ * @throws IllegalArgumentException if an empty [name] is provided.
298+ */
299+ public fun authorizationHeaderName (name : String ): Builder = apply {
300+ require(name.isNotEmpty()) { " Non-empty 'name' required." }
301+ authorizationHeaderName = name
302+ }
303+
304+ /* *
305+ * Update the custom headers that would be appended to every request to an Atlas App Services Application.
306+ *
307+ * @param block lambda with the the custom header map update instructions.
308+ * @throws IllegalArgumentException if an empty header name is provided.
309+ */
310+ public fun customRequestHeaders (
311+ block : MutableMap <String , String >.() -> Unit ,
312+ ): Builder = apply {
313+ customRequestHeaders.block()
314+ require(! customRequestHeaders.containsKey(" " )) { " Non-empty custom header name required." }
315+ }
316+
271317 /* *
272318 * Sets the default EJson decoder that would be use to encode and decode arguments and results
273319 * when calling remote Atlas [Functions], authenticating with a [customFunction], and retrieving
@@ -327,22 +373,25 @@ public interface AppConfiguration {
327373 }
328374
329375 val appLogger = ContextLogger (" Sdk" )
330- val networkTransport: (dispatcher: DispatcherHolder ) -> NetworkTransport = { dispatcherHolder ->
331- val logger: Logger = object : Logger {
332- override fun log (message : String ) {
333- val obfuscatedMessage = httpLogObfuscator?.obfuscate(message)
334- appLogger.debug(obfuscatedMessage ? : message)
376+ val networkTransport: (dispatcher: DispatcherHolder ) -> NetworkTransport =
377+ { dispatcherHolder ->
378+ val logger: Logger = object : Logger {
379+ override fun log (message : String ) {
380+ val obfuscatedMessage = httpLogObfuscator?.obfuscate(message)
381+ appLogger.debug(obfuscatedMessage ? : message)
382+ }
335383 }
384+ networkTransport ? : KtorNetworkTransport (
385+ // FIXME Add AppConfiguration.Builder option to set timeout as a Duration with default \
386+ // constant in AppConfiguration.Companion
387+ // https://github.com/realm/realm-kotlin/issues/408
388+ timeoutMs = 60000 ,
389+ dispatcherHolder = dispatcherHolder,
390+ logger = logger,
391+ customHeaders = customRequestHeaders,
392+ authorizationHeaderName = authorizationHeaderName
393+ )
336394 }
337- networkTransport ? : KtorNetworkTransport (
338- // FIXME Add AppConfiguration.Builder option to set timeout as a Duration with default \
339- // constant in AppConfiguration.Companion
340- // https://github.com/realm/realm-kotlin/issues/408
341- timeoutMs = 60000 ,
342- dispatcherHolder = dispatcherHolder,
343- logger = logger
344- )
345- }
346395
347396 return AppConfigurationImpl (
348397 appId = appId,
@@ -359,7 +408,9 @@ public interface AppConfiguration {
359408 appVersion = appVersion,
360409 bundleId = bundleId,
361410 ejson = ejson,
362- httpLogObfuscator = httpLogObfuscator
411+ httpLogObfuscator = httpLogObfuscator,
412+ customRequestHeaders = customRequestHeaders,
413+ authorizationHeaderName = authorizationHeaderName,
363414 )
364415 }
365416 }
0 commit comments