Skip to content

Commit

Permalink
fixup: identity verification improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
jinliu9508 committed Nov 14, 2024
1 parent db78c39 commit bd8b6b2
Show file tree
Hide file tree
Showing 13 changed files with 44 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public void onCreate() {
// This will reproduce result similar to Kotlin CouroutineScope.launch{}, which may potentially crash the app
ExecutorService executor = Executors.newSingleThreadExecutor();
@SuppressLint({"NewApi", "LocalSuppress"}) CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
//OneSignal.getNotifications().requestPermission(true, Continue.none());
OneSignal.getNotifications().requestPermission(true, Continue.none());
}, executor);
future.join(); // Waits for the task to complete
executor.shutdown();
Expand Down Expand Up @@ -144,9 +144,6 @@ public void onUserStateChange(@NonNull UserChangedState state) {
OneSignal.addUserJwtInvalidatedListner(new IUserJwtInvalidatedListener() {
@Override
public void onUserJwtInvalidated(@NonNull UserJwtInvalidatedEvent event) {
// !!! For manual testing only
String jwt = "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIwMTM5YmQ2Zi00NTFmLTQzOGMtODg4Ni00ZTBmMGZlM2EwODUiLCJleHAiOjE3MjczNjkyMjIsImlkZW50aXR5Ijp7ImV4dGVybmFsX2lkIjoiamluIn0sInN1YnNjcmlwdGlvbnMiOlt7InR5cGUiOiJFbWFpbCIsInRva2VuIjoidGVzdEBkb21haW4uY29tIn0seyJ0eXBlIjoiU01TIiwidG9rZW4iOiIrMTIzNDU2NzgifSx7InR5cGUiOiJBbmRyb2lkUHVzaCIsImlkIjoiMTIzZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjE0MTc0MDAwIn1dfQ.6XF7wRF4lLOvKr5Gd3MHv9j7U151hcBjmqSyk6nI6JVYUgt6q0YRp2j1aSJcg8VmaejzP1DouN1DpWUT_JTRXA";
OneSignal.updateUserJwt(event.getExternalId(), jwt);
Log.v(Tag.LOG_TAG, "onUserJwtInvalidated fired with ID:" + event.getExternalId());
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,7 @@ private void setupAppLayout() {
@Override
public void onSuccess(String update) {
if (update != null && !update.isEmpty()) {
String jwt = "InitialJWT";
OneSignal.login(update, jwt);
OneSignal.login(update);
refreshState();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static boolean exists(Context context, String key) {
}

public static String getOneSignalAppId(Context context) {
return getSharedPreference(context).getString(OS_APP_ID_SHARED_PREF, "0139bd6f-451f-438c-8886-4e0f0fe3a085");
return getSharedPreference(context).getString(OS_APP_ID_SHARED_PREF, "77e32082-ea27-42e3-a898-c72e141824ef");
}

public static boolean getUserPrivacyConsent(Context context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ interface IOneSignal {
*/
val isInitialized: Boolean

/**
* Whether the security feature to authenticate your external user ids is enabled
*/
val useIdentityVerification: Boolean

/**
* The user manager for accessing user-scoped
* management.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.onesignal

/** TODO: complete the comment part for this listener
/**
* Implement this interface and provide an instance to [OneSignal.addUserJwtInvalidatedListner]
* in order to receive control when the JWT for the current user is invalidated.
*
* @see [User JWT Invalidated Event | OneSignal Docs](https://documentation.onesignal.com/docs/)
* @see [User JWT Invalidated Event | OneSignal Docs](https://documentation.onesignal.com/docs/identity-verification)
*/
interface IUserJwtInvalidatedListener {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,6 @@ object OneSignal {
val isInitialized: Boolean
get() = oneSignal.isInitialized

/**
* Whether the security feature to authenticate your external user ids is enabled
*/
@JvmStatic
val useIdentityVerification: Boolean
get() = oneSignal.useIdentityVerification

/**
* The current SDK version as a string.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.onesignal

/** TODO: jwt documentation
/**
* The event passed into [IUserJwtInvalidatedListener.onUserJwtInvalidated], it provides access
* to the external ID whose JWT has just been invalidated.
*
* For more information https://documentation.onesignal.com/docs/identity-verification#4-handle-jwt-lifecycle-events
*/
class UserJwtInvalidatedEvent(
val externalId: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,39 +46,29 @@ internal class HttpClient(
url: String,
body: JSONObject,
headers: OptionalHeaders?,
): HttpResponse {
return makeRequest(url, "POST", body, _configModelStore.model.httpTimeout, headers)
}
): HttpResponse = makeRequest(url, "POST", body, _configModelStore.model.httpTimeout, headers)

override suspend fun get(
url: String,
headers: OptionalHeaders?,
): HttpResponse {
return makeRequest(url, null, null, _configModelStore.model.httpGetTimeout, headers)
}
): HttpResponse = makeRequest(url, null, null, _configModelStore.model.httpGetTimeout, headers)

override suspend fun put(
url: String,
body: JSONObject,
headers: OptionalHeaders?,
): HttpResponse {
return makeRequest(url, "PUT", body, _configModelStore.model.httpTimeout, headers)
}
): HttpResponse = makeRequest(url, "PUT", body, _configModelStore.model.httpTimeout, headers)

override suspend fun patch(
url: String,
body: JSONObject,
headers: OptionalHeaders?,
): HttpResponse {
return makeRequest(url, "PATCH", body, _configModelStore.model.httpTimeout, headers)
}
): HttpResponse = makeRequest(url, "PATCH", body, _configModelStore.model.httpTimeout, headers)

override suspend fun delete(
url: String,
headers: OptionalHeaders?,
): HttpResponse {
return makeRequest(url, "DELETE", null, _configModelStore.model.httpTimeout, headers)
}
): HttpResponse = makeRequest(url, "DELETE", null, _configModelStore.model.httpTimeout, headers)

private suspend fun makeRequest(
url: String,
Expand Down Expand Up @@ -151,7 +141,7 @@ internal class HttpClient(
con.setRequestProperty("SDK-Version", "onesignal/android/" + OneSignalUtils.SDK_VERSION)

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ internal class HttpConnectionFactory(
) : IHttpConnectionFactory {
@Throws(IOException::class)
override fun newHttpURLConnection(url: String): HttpURLConnection {
return URL("https://staging.onesignal.com/api/v1/" + url).openConnection() as HttpURLConnection
return URL(_configModelStore.model.apiUrl + url).openConnection() as HttpURLConnection
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ internal class OperationRepo(

// Ensure the operation does not have empty JWT if identity verification is on
if (_configModelStore.model.useIdentityVerification &&
_identityModelStore.model.jwtToken.isNullOrEmpty()
_identityModelStore.model.jwtToken != null
) {
continue
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ import org.json.JSONObject
internal class OneSignalImp : IOneSignal, IServiceProvider {
override val sdkVersion: String = OneSignalUtils.SDK_VERSION
override var isInitialized: Boolean = false
override val useIdentityVerification: Boolean
get() = configModel?.useIdentityVerification ?: true

override var consentRequired: Boolean
get() = configModel?.consentRequired ?: (_consentRequired == true)
Expand Down Expand Up @@ -153,6 +151,8 @@ internal class OneSignalImp : IOneSignal, IServiceProvider {
private var _disableGMSMissingPrompt: Boolean? = null
private val initLock: Any = Any()
private val loginLock: Any = Any()
private val useIdentityVerification: Boolean
get() = configModel?.useIdentityVerification ?: true

private val listOfModules =
listOf(
Expand Down Expand Up @@ -365,7 +365,6 @@ internal class OneSignalImp : IOneSignal, IServiceProvider {
return
}

// TODO: Set JWT Token for all future requests.
createAndSwitchToNewUser(suppressBackendOperation = false) { identityModel, _ ->
identityModel.externalId = externalId
identityModel.jwtToken = jwtBearerToken
Expand All @@ -383,30 +382,16 @@ internal class OneSignalImp : IOneSignal, IServiceProvider {
// provide a callback to the caller when we can absolutely say the user is logged
// in, so they may take action on their own backend.

val result =
when (useIdentityVerification) {
true -> {
operationRepo!!.enqueue(
LoginUserOperation(
configModel!!.appId,
identityModelStore!!.model.onesignalId,
identityModelStore!!.model.externalId,
),
)
}
else -> {
operationRepo!!.enqueueAndWait(
LoginUserOperation(
configModel!!.appId,
newIdentityOneSignalId,
externalId,
if (currentIdentityExternalId == null) currentIdentityOneSignalId else null,
),
)
}
}
val operation =
LoginUserOperation(
configModel!!.appId,
identityModelStore?.model?.onesignalId ?: newIdentityOneSignalId,
identityModelStore?.model?.externalId ?: externalId,
if (!useIdentityVerification && currentIdentityExternalId == null) currentIdentityOneSignalId else null,
)

if (result == false) {
val result = operationRepo!!.enqueueAndWait(operation)
if (!result) {
Logging.log(LogLevel.ERROR, "Could not login user")
}
}
Expand Down Expand Up @@ -492,7 +477,7 @@ internal class OneSignalImp : IOneSignal, IServiceProvider {
modify(identityModel, propertiesModel)
}

if (!identityModel.jwtToken.isNullOrEmpty()) {
if (identityModel.jwtToken != null) {
setupNewSubscription(identityModel, propertiesModel, suppressBackendOperation, sdkId)
}

Expand Down Expand Up @@ -560,18 +545,19 @@ internal class OneSignalImp : IOneSignal, IServiceProvider {
configModel.addFetchParamsObserver(
object : FetchParamsObserver {
override fun onParamsFetched(params: ParamsObject) {
// resume operations if identity verification is turned off or a jwt is cached
if (params.useIdentityVerification == false || identityModelStore!!.model.jwtToken != null) {
operationRepo!!.enqueue(
LoginUserOperation(
configModel!!.appId,
identityModelStore!!.model.onesignalId,
identityModelStore!!.model.externalId,
),
)
} else {
Logging.log(LogLevel.ERROR, "A valid JWT is required for user ${identityModelStore!!.model.externalId}.")
if (params.useIdentityVerification == true && identityModelStore.model.jwtToken == null) {
Logging.log(LogLevel.INFO, "A valid JWT is required for user ${identityModelStore!!.model.externalId}.")
return
}

// resume operations either identity verification is turned off or a jwt is cached
operationRepo!!.enqueue(
LoginUserOperation(
configModel!!.appId,
identityModelStore!!.model.onesignalId,
identityModelStore!!.model.externalId,
),
)
}
},
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.onesignal.user.internal

import com.onesignal.IUserJwtInvalidatedListener
import com.onesignal.OneSignal
import com.onesignal.UserJwtInvalidatedEvent
import com.onesignal.common.IDManager
import com.onesignal.common.OneSignalUtils
Expand Down Expand Up @@ -252,12 +251,12 @@ internal open class UserManager(
}

override fun addUserJwtInvalidatedListener(listener: IUserJwtInvalidatedListener) {
Logging.debug("OneSignal.addClickListener(listener: $listener)")
Logging.debug("OneSignal.addUserJwtInvalidatedListener(listener: $listener)")
jwtInvalidatedCallback.subscribe(listener)
}

override fun removeUserJwtInvalidatedListener(listener: IUserJwtInvalidatedListener) {
Logging.debug("OneSignal.removeClickListener(listener: $listener)")
Logging.debug("OneSignal.removeUserJwtInvalidatedListener(listener: $listener)")
jwtInvalidatedCallback.unsubscribe(listener)
}

Expand All @@ -283,7 +282,7 @@ internal open class UserManager(
val newJwt = args.newValue.toString()

// prevent same JWT from being invalidated twice in a row
if (OneSignal.useIdentityVerification && jwtTokenInvalidated != oldJwt && newJwt.isEmpty()) {
if (jwtTokenInvalidated != oldJwt && newJwt == null) {
jwtInvalidatedCallback.fire {
it.onUserJwtInvalidated(UserJwtInvalidatedEvent(externalId))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ open class IdentityModelStore(prefs: IPreferencesService) : SingletonModelStore<
SimpleModelStore({ IdentityModel() }, "identity", prefs),
) {
fun invalidateJwt() {
model.jwtToken = ""
model.jwtToken = null
}

// Use externalId instead of onesignalId when a jwt is present
fun getIdentityAlias(): Pair<String, String> {
if (model.jwtToken.isNullOrEmpty()) {
if (model.jwtToken == null) {
return Pair(IdentityConstants.ONESIGNAL_ID, model.onesignalId)
}

Expand Down

0 comments on commit bd8b6b2

Please sign in to comment.