Skip to content
Open
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
39 changes: 26 additions & 13 deletions OneSignalSDK/detekt/detekt-baseline-core.xml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,10 @@ internal class HttpClient(
con.doOutput = true
}

logHTTPSent(con.requestMethod, con.url, jsonBody, con.requestProperties)

if (jsonBody != null) {
val strJsonBody = JSONUtils.toUnescapedEUIDString(jsonBody)
val sendBytes = strJsonBody.toByteArray(charset("UTF-8"))
con.setFixedLengthStreamingMode(sendBytes.size)
val outputStream = con.outputStream
outputStream.write(sendBytes)
}

// H E A D E R S
// H E A D E R S — must be set before any body write below. `getOutputStream()`
// (and `setFixedLengthStreamingMode`) commit the request line + headers to the
// wire; `setRequestProperty` after that point either throws IllegalStateException
// or is silently dropped, depending on the HttpURLConnection implementation.

if (headers?.cacheKey != null) {
val eTag =
Expand All @@ -195,6 +188,20 @@ internal class HttpClient(
con.setRequestProperty("OneSignal-Session-Duration", headers.sessionDuration.toString())
}

if (headers?.jwt != null) {
con.setRequestProperty("Authorization", "Bearer ${headers.jwt}")
}

logHTTPSent(con.requestMethod, con.url, jsonBody, con.requestProperties)
Comment thread
nan-li marked this conversation as resolved.

if (jsonBody != null) {
val strJsonBody = JSONUtils.toUnescapedEUIDString(jsonBody)
val sendBytes = strJsonBody.toByteArray(charset("UTF-8"))
con.setFixedLengthStreamingMode(sendBytes.size)
val outputStream = con.outputStream
outputStream.write(sendBytes)
}

// Network request is made from getResponseCode()
httpResponse = con.responseCode

Comment thread
claude[bot] marked this conversation as resolved.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ data class OptionalHeaders(
* Used to track delay between session start and request
*/
val sessionDuration: Long? = null,
/**
* JWT bearer token for identity verification. When non-null, sent as
* `Authorization: Bearer <jwt>` on the request.
*/
val jwt: String? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ interface IIdentityBackendService {
aliasLabel: String,
aliasValue: String,
identities: Map<String, String>,
jwt: String? = null,
): Map<String, String>

/**
Expand All @@ -35,6 +36,7 @@ interface IIdentityBackendService {
aliasLabel: String,
aliasValue: String,
aliasLabelToDelete: String,
jwt: String? = null,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ interface ISubscriptionBackendService {
aliasLabel: String,
aliasValue: String,
subscription: SubscriptionObject,
jwt: String? = null,
): Pair<String, RywData?>?

/**
Expand All @@ -35,6 +36,7 @@ interface ISubscriptionBackendService {
appId: String,
subscriptionId: String,
subscription: SubscriptionObject,
jwt: String? = null,
): RywData?

/**
Expand All @@ -46,6 +48,7 @@ interface ISubscriptionBackendService {
suspend fun deleteSubscription(
appId: String,
subscriptionId: String,
jwt: String? = null,
)

/**
Expand All @@ -61,11 +64,15 @@ interface ISubscriptionBackendService {
subscriptionId: String,
aliasLabel: String,
aliasValue: String,
jwt: String? = null,
)

/**
* Given an existing subscription, retrieve all identities associated to it.
*
* Note: this endpoint is not used when `jwt_required == true`; the v4→v5 migration path it
* supports is explicitly blocked under IV. See [LoginUserFromSubscriptionOperationExecutor].
*
* @param appId The ID of the OneSignal application this subscription exists under.
* @param subscriptionId The ID of the subscription to retrieve identities for.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ interface IUserBackendService {
identities: Map<String, String>,
subscriptions: List<SubscriptionObject>,
properties: Map<String, String>,
jwt: String? = null,
): CreateUserResponse
// TODO: Change to send only the push subscription, optimally

Expand All @@ -48,6 +49,7 @@ interface IUserBackendService {
properties: PropertiesObject,
refreshDeviceMetadata: Boolean,
propertyiesDelta: PropertiesDeltasObject,
jwt: String? = null,
): RywData?

/**
Expand All @@ -65,6 +67,7 @@ interface IUserBackendService {
appId: String,
aliasLabel: String,
aliasValue: String,
jwt: String? = null,
): CreateUserResponse
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.onesignal.common.exceptions.BackendException
import com.onesignal.common.putMap
import com.onesignal.common.toMap
import com.onesignal.core.internal.http.IHttpClient
import com.onesignal.core.internal.http.impl.OptionalHeaders
import com.onesignal.user.internal.backend.IIdentityBackendService
import org.json.JSONObject

Expand All @@ -15,12 +16,14 @@ internal class IdentityBackendService(
aliasLabel: String,
aliasValue: String,
identities: Map<String, String>,
jwt: String?,
): Map<String, String> {
val requestJSONObject =
JSONObject()
.put("identity", JSONObject().putMap(identities))

val response = _httpClient.patch("apps/$appId/users/by/$aliasLabel/$aliasValue/identity", requestJSONObject)
val response =
_httpClient.patch("apps/$appId/users/by/$aliasLabel/$aliasValue/identity", requestJSONObject, OptionalHeaders(jwt = jwt))

if (!response.isSuccess) {
throw BackendException(response.statusCode, response.payload, response.retryAfterSeconds)
Expand All @@ -36,8 +39,10 @@ internal class IdentityBackendService(
aliasLabel: String,
aliasValue: String,
aliasLabelToDelete: String,
jwt: String?,
) {
val response = _httpClient.delete("apps/$appId/users/by/$aliasLabel/$aliasValue/identity/$aliasLabelToDelete")
val response =
_httpClient.delete("apps/$appId/users/by/$aliasLabel/$aliasValue/identity/$aliasLabelToDelete", OptionalHeaders(jwt = jwt))

if (!response.isSuccess) {
throw BackendException(response.statusCode, response.payload, response.retryAfterSeconds)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.onesignal.common.safeLong
import com.onesignal.common.safeString
import com.onesignal.common.toMap
import com.onesignal.core.internal.http.IHttpClient
import com.onesignal.core.internal.http.impl.OptionalHeaders
import com.onesignal.user.internal.backend.ISubscriptionBackendService
import com.onesignal.user.internal.backend.SubscriptionObject
import org.json.JSONObject
Expand All @@ -19,11 +20,13 @@ internal class SubscriptionBackendService(
aliasLabel: String,
aliasValue: String,
subscription: SubscriptionObject,
jwt: String?,
): Pair<String, RywData?>? {
val jsonSubscription = JSONConverter.convertToJSON(subscription)
val requestJSON = JSONObject().put("subscription", jsonSubscription)

val response = _httpClient.post("apps/$appId/users/by/$aliasLabel/$aliasValue/subscriptions", requestJSON)
val response =
_httpClient.post("apps/$appId/users/by/$aliasLabel/$aliasValue/subscriptions", requestJSON, OptionalHeaders(jwt = jwt))

if (!response.isSuccess) {
throw BackendException(response.statusCode, response.payload, response.retryAfterSeconds)
Expand All @@ -50,12 +53,13 @@ internal class SubscriptionBackendService(
appId: String,
subscriptionId: String,
subscription: SubscriptionObject,
jwt: String?,
): RywData? {
val requestJSON =
JSONObject()
.put("subscription", JSONConverter.convertToJSON(subscription))

val response = _httpClient.patch("apps/$appId/subscriptions/$subscriptionId", requestJSON)
val response = _httpClient.patch("apps/$appId/subscriptions/$subscriptionId", requestJSON, OptionalHeaders(jwt = jwt))

if (!response.isSuccess) {
throw BackendException(response.statusCode, response.payload, response.retryAfterSeconds)
Expand All @@ -76,8 +80,9 @@ internal class SubscriptionBackendService(
override suspend fun deleteSubscription(
appId: String,
subscriptionId: String,
jwt: String?,
) {
val response = _httpClient.delete("apps/$appId/subscriptions/$subscriptionId")
val response = _httpClient.delete("apps/$appId/subscriptions/$subscriptionId", OptionalHeaders(jwt = jwt))

if (!response.isSuccess) {
throw BackendException(response.statusCode, response.payload, response.retryAfterSeconds)
Expand All @@ -89,12 +94,13 @@ internal class SubscriptionBackendService(
subscriptionId: String,
aliasLabel: String,
aliasValue: String,
jwt: String?,
) {
val requestJSON =
JSONObject()
.put("identity", JSONObject().put(aliasLabel, aliasValue))

val response = _httpClient.patch("apps/$appId/subscriptions/$subscriptionId/owner", requestJSON)
val response = _httpClient.patch("apps/$appId/subscriptions/$subscriptionId/owner", requestJSON, OptionalHeaders(jwt = jwt))

if (!response.isSuccess) {
throw BackendException(response.statusCode, response.payload, response.retryAfterSeconds)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.onesignal.common.putMap
import com.onesignal.common.safeLong
import com.onesignal.common.safeString
import com.onesignal.core.internal.http.IHttpClient
import com.onesignal.core.internal.http.impl.OptionalHeaders
import com.onesignal.user.internal.backend.CreateUserResponse
import com.onesignal.user.internal.backend.IUserBackendService
import com.onesignal.user.internal.backend.PropertiesDeltasObject
Expand All @@ -21,6 +22,7 @@ internal class UserBackendService(
identities: Map<String, String>,
subscriptions: List<SubscriptionObject>,
properties: Map<String, String>,
jwt: String?,
): CreateUserResponse {
val requestJSON = JSONObject()

Expand All @@ -39,7 +41,7 @@ internal class UserBackendService(

requestJSON.put("refresh_device_metadata", true)

val response = _httpClient.post("apps/$appId/users", requestJSON)
val response = _httpClient.post("apps/$appId/users", requestJSON, OptionalHeaders(jwt = jwt))

if (!response.isSuccess) {
throw BackendException(response.statusCode, response.payload, response.retryAfterSeconds)
Expand All @@ -55,6 +57,7 @@ internal class UserBackendService(
properties: PropertiesObject,
refreshDeviceMetadata: Boolean,
propertyiesDelta: PropertiesDeltasObject,
jwt: String?,
): RywData? {
val jsonObject =
JSONObject()
Expand All @@ -68,7 +71,7 @@ internal class UserBackendService(
jsonObject.put("deltas", JSONConverter.convertToJSON(propertyiesDelta))
}

val response = _httpClient.patch("apps/$appId/users/by/$aliasLabel/$aliasValue", jsonObject)
val response = _httpClient.patch("apps/$appId/users/by/$aliasLabel/$aliasValue", jsonObject, OptionalHeaders(jwt = jwt))

if (!response.isSuccess) {
throw BackendException(response.statusCode, response.payload, response.retryAfterSeconds)
Expand All @@ -90,8 +93,9 @@ internal class UserBackendService(
appId: String,
aliasLabel: String,
aliasValue: String,
jwt: String?,
): CreateUserResponse {
val response = _httpClient.get("apps/$appId/users/by/$aliasLabel/$aliasValue")
val response = _httpClient.get("apps/$appId/users/by/$aliasLabel/$aliasValue", OptionalHeaders(jwt = jwt))

if (!response.isSuccess) {
throw BackendException(response.statusCode, response.payload, response.retryAfterSeconds)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ interface ICustomEventBackendService {
eventName: String,
eventProperties: String?,
metadata: CustomEventMetadata,
jwt: String? = null,
): ExecutionResponse
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.onesignal.user.internal.customEvents.impl
import com.onesignal.common.DateUtils
import com.onesignal.common.exceptions.BackendException
import com.onesignal.core.internal.http.IHttpClient
import com.onesignal.core.internal.http.impl.OptionalHeaders
import com.onesignal.core.internal.operations.ExecutionResponse
import com.onesignal.core.internal.operations.ExecutionResult
import com.onesignal.user.internal.customEvents.ICustomEventBackendService
Expand All @@ -21,6 +22,7 @@ internal class CustomEventBackendService(
eventName: String,
eventProperties: String?,
metadata: CustomEventMetadata,
jwt: String?,
): ExecutionResponse {
val body = JSONObject()
body.put("name", eventName)
Expand All @@ -42,7 +44,7 @@ internal class CustomEventBackendService(
body.put("payload", payload)
val jsonObject = JSONObject().put("events", JSONArray().put(body))

val response = httpClient.post("apps/$appId/custom_events", jsonObject)
val response = httpClient.post("apps/$appId/custom_events", jsonObject, OptionalHeaders(jwt = jwt))

if (!response.isSuccess) {
throw BackendException(response.statusCode, response.payload, response.retryAfterSeconds)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@ import com.onesignal.common.NetworkUtils
import com.onesignal.common.OneSignalUtils
import com.onesignal.common.exceptions.BackendException
import com.onesignal.core.internal.application.IApplicationService
import com.onesignal.core.internal.config.impl.IdentityVerificationService
import com.onesignal.core.internal.device.IDeviceService
import com.onesignal.core.internal.operations.ExecutionResponse
import com.onesignal.core.internal.operations.ExecutionResult
import com.onesignal.core.internal.operations.IOperationExecutor
import com.onesignal.core.internal.operations.Operation
import com.onesignal.user.internal.customEvents.ICustomEventBackendService
import com.onesignal.user.internal.customEvents.impl.CustomEventMetadata
import com.onesignal.user.internal.jwt.JwtTokenStore
import com.onesignal.user.internal.operations.TrackCustomEventOperation

internal class CustomEventOperationExecutor(
private val customEventBackendService: ICustomEventBackendService,
private val applicationService: IApplicationService,
private val deviceService: IDeviceService,
private val jwtTokenStore: JwtTokenStore,
private val identityVerificationService: IdentityVerificationService,
) : IOperationExecutor {
override val operations: List<String>
get() = listOf(CUSTOM_EVENT)
Expand All @@ -40,6 +44,7 @@ internal class CustomEventOperationExecutor(
try {
when (operation) {
is TrackCustomEventOperation -> {
val jwt = resolveJwt(operation, jwtTokenStore, identityVerificationService)
customEventBackendService.sendCustomEvent(
operation.appId,
operation.onesignalId,
Comment thread
claude[bot] marked this conversation as resolved.
Expand All @@ -48,6 +53,7 @@ internal class CustomEventOperationExecutor(
operation.eventName,
operation.eventProperties,
eventMetadataJson,
jwt,
)
}
}
Expand All @@ -57,6 +63,8 @@ internal class CustomEventOperationExecutor(
return when (responseType) {
NetworkUtils.ResponseStatusType.RETRYABLE ->
ExecutionResponse(ExecutionResult.FAIL_RETRY, retryAfterSeconds = ex.retryAfterSeconds)
NetworkUtils.ResponseStatusType.UNAUTHORIZED ->
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED, retryAfterSeconds = ex.retryAfterSeconds)
else ->
ExecutionResponse(ExecutionResult.FAIL_NORETRY)
}
Expand Down
Loading
Loading