Skip to content

Commit b029886

Browse files
authored
Merge pull request #2196 from OneSignal/identity-verification-implementation
Feature - Identity verification implementation
2 parents 3b7e5d6 + 48f4c9a commit b029886

File tree

49 files changed

+831
-146
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+831
-146
lines changed

Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/application/MainApplication.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
import androidx.annotation.NonNull;
77
import androidx.annotation.Nullable;
88
import androidx.multidex.MultiDexApplication;
9-
109
import com.onesignal.Continue;
10+
import com.onesignal.IUserJwtInvalidatedListener;
1111
import com.onesignal.OneSignal;
12+
import com.onesignal.UserJwtInvalidatedEvent;
1213
import com.onesignal.inAppMessages.IInAppMessageClickListener;
1314
import com.onesignal.inAppMessages.IInAppMessageClickEvent;
1415
import com.onesignal.inAppMessages.IInAppMessageDidDismissEvent;
@@ -140,6 +141,13 @@ public void onUserStateChange(@NonNull UserChangedState state) {
140141
}
141142
});
142143

144+
OneSignal.addUserJwtInvalidatedListner(new IUserJwtInvalidatedListener() {
145+
@Override
146+
public void onUserJwtInvalidated(@NonNull UserJwtInvalidatedEvent event) {
147+
Log.v(Tag.LOG_TAG, "onUserJwtInvalidated fired with ID:" + event.getExternalId());
148+
}
149+
});
150+
143151
OneSignal.getInAppMessages().setPaused(true);
144152
OneSignal.getLocation().setShared(false);
145153

Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/MainActivityViewModel.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import android.view.View;
1919
import android.view.ViewTreeObserver;
2020
import android.widget.Button;
21+
import android.widget.EditText;
2122
import android.widget.LinearLayout;
2223
import android.widget.RelativeLayout;
2324
import android.widget.Switch;
@@ -83,6 +84,10 @@ public class MainActivityViewModel implements ActivityViewModel, IPushSubscripti
8384
private Button loginUserButton;
8485
private Button logoutUserButton;
8586

87+
// JWT
88+
private Button invalidateJwtButton;
89+
private Button updateJwtButton;
90+
8691
// Alias
8792
private TextView aliasTitleTextView;
8893
private RecyclerView aliasesRecyclerView;
@@ -211,6 +216,9 @@ public ActivityViewModel onActivityCreated(Context context) {
211216
loginUserButton = getActivity().findViewById(R.id.main_activity_login_user_button);
212217
logoutUserButton = getActivity().findViewById(R.id.main_activity_logout_user_button);
213218

219+
invalidateJwtButton = getActivity().findViewById(R.id.main_activity_invalidate_jwt_button);
220+
updateJwtButton = getActivity().findViewById(R.id.main_activity_update_jwt_button);
221+
214222
aliasTitleTextView = getActivity().findViewById(R.id.main_activity_aliases_title_text_view);
215223
noAliasesTextView = getActivity().findViewById(R.id.main_activity_aliases_no_aliases_text_view);
216224
addAliasButton = getActivity().findViewById(R.id.main_activity_add_alias_button);
@@ -422,6 +430,7 @@ public void onFailure() {
422430
}
423431

424432
private void setupUserLayout() {
433+
setupJWTLayout();
425434
setupAliasLayout();
426435
setupEmailLayout();
427436
setupSMSLayout();
@@ -430,6 +439,28 @@ private void setupUserLayout() {
430439
setupTriggersLayout();
431440
}
432441

442+
private void setupJWTLayout() {
443+
invalidateJwtButton.setOnClickListener(v -> {
444+
OneSignal.updateUserJwt(OneSignal.getUser().getExternalId(), "");
445+
});
446+
updateJwtButton.setOnClickListener(v -> {
447+
dialog.createUpdateAlertDialog("", Dialog.DialogAction.UPDATE, ProfileUtil.FieldType.JWT, new UpdateAlertDialogCallback() {
448+
@Override
449+
public void onSuccess(String update) {
450+
if (update != null && !update.isEmpty()) {
451+
OneSignal.updateUserJwt(OneSignal.getUser().getExternalId(), update);
452+
refreshState();
453+
}
454+
}
455+
456+
@Override
457+
public void onFailure() {
458+
459+
}
460+
});
461+
});
462+
}
463+
433464
private void setupAliasLayout() {
434465
setupAliasesRecyclerView();
435466
addAliasButton.setOnClickListener(v -> dialog.createAddPairAlertDialog("Add Alias", ProfileUtil.FieldType.ALIAS, new AddPairAlertDialogCallback() {

Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/util/ProfileUtil.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public enum FieldType {
1313
ALIAS("Alias"),
1414
EMAIL("Email"),
1515
SMS("SMS"),
16+
JWT("JWT"),
1617
EXTERNAL_USER_ID("External User Id"),
1718

1819
TAG("Tags"),
@@ -97,6 +98,10 @@ public static boolean isSMSValid(TextInputLayout smsTextInputLayout) {
9798
return true;
9899
}
99100

101+
private static boolean isJWTValid(TextInputLayout jwtTextInputLayout) {
102+
return !jwtTextInputLayout.getEditText().toString().isEmpty();
103+
}
104+
100105
private static boolean isExternalUserIdValid(TextInputLayout externalUserIdTextInputLayout) {
101106
externalUserIdTextInputLayout.setErrorEnabled(false);
102107
if (externalUserIdTextInputLayout.getEditText() != null) {
@@ -137,6 +142,8 @@ static boolean isContentValid(FieldType field, TextInputLayout alertDialogTextIn
137142
return isEmailValid(alertDialogTextInputLayout);
138143
case SMS:
139144
return isSMSValid(alertDialogTextInputLayout);
145+
case JWT:
146+
return isJWTValid(alertDialogTextInputLayout);
140147
case EXTERNAL_USER_ID:
141148
return isExternalUserIdValid(alertDialogTextInputLayout);
142149
case TAG:

Examples/OneSignalDemo/app/src/main/res/layout/main_activity_layout.xml

Lines changed: 99 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -152,20 +152,20 @@
152152
android:layout_width="wrap_content"
153153
android:layout_height="wrap_content"
154154
android:layout_gravity="start|center_vertical"
155-
android:gravity="start|center_vertical"
156-
android:layout_marginBottom="4dp"
157155
android:layout_marginStart="12dp"
158156
android:layout_marginLeft="12dp"
157+
android:layout_marginBottom="4dp"
158+
android:gravity="start|center_vertical"
159159
android:text="@string/app"
160160
android:textColor="@color/colorDarkText" />
161161

162162
<androidx.cardview.widget.CardView
163163
android:layout_width="match_parent"
164164
android:layout_height="wrap_content"
165-
android:layout_marginTop="4dp"
166-
android:layout_marginBottom="12dp"
167165
android:layout_marginStart="12dp"
166+
android:layout_marginTop="4dp"
168167
android:layout_marginEnd="12dp"
168+
android:layout_marginBottom="12dp"
169169
app:cardCornerRadius="6dp"
170170
app:cardElevation="4dp">
171171

@@ -226,23 +226,23 @@
226226
android:layout_width="match_parent"
227227
android:layout_height="56dp"
228228
android:layout_gravity="center"
229-
android:gravity="center"
230229
android:layout_marginStart="12dp"
231230
android:layout_marginTop="4dp"
232231
android:layout_marginEnd="12dp"
233232
android:layout_marginBottom="12dp"
234-
android:orientation="vertical"
235-
android:background="@color/colorPrimary">
233+
android:background="@color/colorPrimary"
234+
android:gravity="center"
235+
android:orientation="vertical">
236236

237237
<Button
238238
android:id="@+id/main_activity_app_revoke_consent_button"
239239
android:layout_width="match_parent"
240240
android:layout_height="match_parent"
241+
android:background="@drawable/ripple_selector_white_red"
241242
android:text="@string/revoke_consent"
242-
android:textSize="19sp"
243243
android:textColor="@android:color/white"
244-
android:background="@drawable/ripple_selector_white_red"
245-
android:visibility="visible"/>
244+
android:textSize="19sp"
245+
android:visibility="visible" />
246246

247247
</LinearLayout>
248248

@@ -263,11 +263,11 @@
263263
android:id="@+id/main_activity_login_user_button"
264264
android:layout_width="match_parent"
265265
android:layout_height="match_parent"
266+
android:background="@drawable/ripple_selector_white_red"
266267
android:text="@string/login_user"
267-
android:textSize="19sp"
268268
android:textColor="@android:color/white"
269-
android:background="@drawable/ripple_selector_white_red"
270-
android:visibility="visible"/>
269+
android:textSize="19sp"
270+
android:visibility="visible" />
271271

272272
</LinearLayout>
273273

@@ -288,14 +288,97 @@
288288
android:id="@+id/main_activity_logout_user_button"
289289
android:layout_width="match_parent"
290290
android:layout_height="match_parent"
291+
android:background="@drawable/ripple_selector_white_red"
291292
android:text="@string/logout_user"
292-
android:textSize="19sp"
293293
android:textColor="@android:color/white"
294-
android:background="@drawable/ripple_selector_white_red"
295-
android:visibility="visible"/>
294+
android:textSize="19sp"
295+
android:visibility="visible" />
296296
</LinearLayout>
297297
</LinearLayout>
298298

299+
<LinearLayout
300+
android:id="@+id/main_activity_jwt_linear_layout"
301+
android:layout_width="match_parent"
302+
android:layout_height="match_parent"
303+
android:clipChildren="false"
304+
android:clipToPadding="false"
305+
android:orientation="vertical">
306+
307+
<TextView
308+
android:id="@+id/main_activity_jwt_title_text_view"
309+
android:layout_width="wrap_content"
310+
android:layout_height="wrap_content"
311+
android:layout_gravity="start|center_vertical"
312+
android:layout_marginStart="12dp"
313+
android:layout_marginLeft="12dp"
314+
android:layout_marginBottom="4dp"
315+
android:gravity="start|center_vertical"
316+
android:text="@string/JWT"
317+
android:textColor="@color/colorDarkText" />
318+
319+
<androidx.cardview.widget.CardView
320+
android:layout_width="match_parent"
321+
android:layout_height="wrap_content"
322+
android:layout_marginStart="12dp"
323+
android:layout_marginTop="4dp"
324+
android:layout_marginEnd="12dp"
325+
android:layout_marginBottom="12dp"
326+
app:cardCornerRadius="6dp"
327+
app:cardElevation="4dp">
328+
329+
<LinearLayout
330+
android:id="@+id/main_activity_jwt_details_linear_layout"
331+
android:layout_width="match_parent"
332+
android:layout_height="wrap_content"
333+
android:orientation="vertical">
334+
335+
<LinearLayout
336+
android:layout_width="match_parent"
337+
android:layout_height="match_parent"
338+
android:layout_gravity="center"
339+
android:layout_marginTop="4dp"
340+
android:background="@color/colorPrimary"
341+
android:gravity="center"
342+
android:orientation="vertical">
343+
344+
<Button
345+
android:id="@+id/main_activity_invalidate_jwt_button"
346+
android:layout_width="match_parent"
347+
android:layout_height="match_parent"
348+
android:background="@drawable/ripple_selector_white_red"
349+
android:text="@string/invalidate_JWT"
350+
android:textColor="@android:color/white"
351+
android:textSize="19sp"
352+
android:visibility="visible" />
353+
354+
</LinearLayout>
355+
356+
<LinearLayout
357+
android:layout_width="match_parent"
358+
android:layout_height="match_parent"
359+
android:layout_gravity="center"
360+
android:layout_marginTop="4dp"
361+
android:background="@color/colorPrimary"
362+
android:gravity="center"
363+
android:orientation="vertical">
364+
365+
<Button
366+
android:id="@+id/main_activity_update_jwt_button"
367+
android:layout_width="match_parent"
368+
android:layout_height="match_parent"
369+
android:background="@drawable/ripple_selector_white_red"
370+
android:text="@string/update_JWT"
371+
android:textColor="@android:color/white"
372+
android:textSize="19sp"
373+
android:visibility="visible" />
374+
</LinearLayout>
375+
376+
</LinearLayout>
377+
378+
</androidx.cardview.widget.CardView>
379+
380+
</LinearLayout>
381+
299382
<!-- Aliases -->
300383
<LinearLayout
301384
android:id="@+id/main_activity_aliases_linear_layout"

Examples/OneSignalDemo/app/src/main/res/values/strings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
<string name="login_user">Login User</string>
1010
<string name="logout_user">Logout User</string>
1111

12+
<string name="JWT">JWT</string>
13+
<string name="invalidate_JWT">Invalidate JWT</string>
14+
<string name="update_JWT">Update JWT</string>
15+
<string name="no_jwt_added">No JWT Added</string>
16+
1217
<string name="aliases">Aliases</string>
1318
<string name="external_user_id_colon">EUID:</string>
1419
<string name="no_aliases_added">No Aliases Added</string>

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/IOneSignal.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,16 @@ interface IOneSignal {
123123
* data is not cleared.
124124
*/
125125
fun logout()
126+
127+
/**
128+
* Update JWT token for a user
129+
*/
130+
fun updateUserJwt(
131+
externalId: String,
132+
token: String,
133+
)
134+
135+
fun addUserJwtInvalidatedListener(listener: IUserJwtInvalidatedListener)
136+
137+
fun removeUserJwtInvalidatedListener(listener: IUserJwtInvalidatedListener)
126138
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.onesignal
2+
3+
/**
4+
* Implement this interface and provide an instance to [OneSignal.addUserJwtInvalidatedListner]
5+
* in order to receive control when the JWT for the current user is invalidated.
6+
*
7+
* @see [User JWT Invalidated Event | OneSignal Docs](https://documentation.onesignal.com/docs/identity-verification)
8+
*/
9+
interface IUserJwtInvalidatedListener {
10+
/**
11+
* Called when the JWT is invalidated
12+
*
13+
* @param event The user JWT that expired.
14+
*/
15+
fun onUserJwtInvalidated(event: UserJwtInvalidatedEvent)
16+
}

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/OneSignal.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,24 @@ object OneSignal {
192192
@JvmStatic
193193
fun logout() = oneSignal.logout()
194194

195+
@JvmStatic
196+
fun updateUserJwt(
197+
externalId: String,
198+
token: String,
199+
) {
200+
oneSignal.updateUserJwt(externalId, token)
201+
}
202+
203+
@JvmStatic
204+
fun addUserJwtInvalidatedListner(listener: IUserJwtInvalidatedListener) {
205+
oneSignal.addUserJwtInvalidatedListener(listener)
206+
}
207+
208+
@JvmStatic
209+
fun removeUserJwtInvalidatedListner(listener: IUserJwtInvalidatedListener) {
210+
oneSignal.removeUserJwtInvalidatedListener(listener)
211+
}
212+
195213
private val oneSignal: IOneSignal by lazy {
196214
OneSignalImp()
197215
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.onesignal
2+
3+
/**
4+
* The event passed into [IUserJwtInvalidatedListener.onUserJwtInvalidated], it provides access
5+
* to the external ID whose JWT has just been invalidated.
6+
*
7+
* For more information https://documentation.onesignal.com/docs/identity-verification#4-handle-jwt-lifecycle-events
8+
*/
9+
class UserJwtInvalidatedEvent(
10+
val externalId: String,
11+
)

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/CoreModule.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import com.onesignal.core.internal.preferences.IPreferencesService
3131
import com.onesignal.core.internal.preferences.impl.PreferencesService
3232
import com.onesignal.core.internal.purchases.impl.TrackAmazonPurchase
3333
import com.onesignal.core.internal.purchases.impl.TrackGooglePurchase
34+
import com.onesignal.core.internal.startup.IBootstrapService
3435
import com.onesignal.core.internal.startup.IStartableService
3536
import com.onesignal.core.internal.time.ITime
3637
import com.onesignal.core.internal.time.impl.Time
@@ -40,6 +41,7 @@ import com.onesignal.location.ILocationManager
4041
import com.onesignal.location.internal.MisconfiguredLocationManager
4142
import com.onesignal.notifications.INotificationsManager
4243
import com.onesignal.notifications.internal.MisconfiguredNotificationsManager
44+
import com.onesignal.user.internal.service.IdentityVerificationService
4345

4446
internal class CoreModule : IModule {
4547
override fun register(builder: ServiceBuilder) {
@@ -59,6 +61,7 @@ internal class CoreModule : IModule {
5961
builder.register<ConfigModelStore>().provides<ConfigModelStore>()
6062
builder.register<ParamsBackendService>().provides<IParamsBackendService>()
6163
builder.register<ConfigModelStoreListener>().provides<IStartableService>()
64+
builder.register<IdentityVerificationService>().provides<IBootstrapService>()
6265

6366
// Operations
6467
builder.register<OperationModelStore>().provides<OperationModelStore>()

0 commit comments

Comments
 (0)