Skip to content

Commit

Permalink
Merge pull request #1729 from OneSignal/user-model/email-sms-validation
Browse files Browse the repository at this point in the history
[User Model] Add validation logic to add/remove email & sms subscriptions
  • Loading branch information
brismithers authored and jinliu9508 committed Feb 6, 2024
2 parents e82fc07 + de584d5 commit ef0339a
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ private void setupEmailLayout() {
@Override
public void onSuccess(String value) {
if (value != null && !value.isEmpty()) {
OneSignal.getUser().addEmailSubscription(value);
OneSignal.getUser().addEmail(value);
emailArrayList.add(new DummySubscription(value));
toaster.makeCustomViewToast("Added email " + value, ToastType.SUCCESS);
}
Expand All @@ -549,7 +549,7 @@ private void setupSMSLayout() {
@Override
public void onSuccess(String value) {
if (value != null && !value.isEmpty()) {
OneSignal.getUser().addSmsSubscription(value);
OneSignal.getUser().addSms(value);
smsArrayList.add(new DummySubscription(value));
toaster.makeCustomViewToast("Added SMS " + value, ToastType.SUCCESS);
}
Expand Down Expand Up @@ -630,7 +630,7 @@ private void setupEmailRecyclerView() {
emailsRecyclerView.setLayoutManager(linearLayoutManager);
emailsRecyclerViewAdapter = new SubscriptionRecyclerViewAdapter(context, emailArrayList, value -> {
String email = ((DummySubscription)value).getId();
OneSignal.getUser().removeEmailSubscription(email);
OneSignal.getUser().removeEmail(email);
emailArrayList.remove(value);
refreshEmailRecyclerView();
toaster.makeCustomViewToast("Deleted email " + email, ToastType.SUCCESS);
Expand All @@ -656,7 +656,7 @@ private void setupSMSRecyclerView() {
smssRecyclerView.setLayoutManager(linearLayoutManager);
smssRecyclerViewAdapter = new SubscriptionRecyclerViewAdapter(context, smsArrayList, value -> {
String number = ((DummySubscription)value).getId();
OneSignal.getUser().removeSmsSubscription(number);
OneSignal.getUser().removeSms(number);
smsArrayList.remove(value);
refreshSMSRecyclerView();
toaster.makeCustomViewToast("Deleted SMS " + number, ToastType.SUCCESS);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
package com.onesignal.common

import java.util.regex.Pattern

object OneSignalUtils {
@JvmStatic
var sdkType = "native"

@JvmStatic
val sdkVersion: String = "050000"

fun isValidEmail(email: String): Boolean {
if (email.isEmpty())
return false

val emRegex = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$"
val pattern: Pattern = Pattern.compile(emRegex)
return pattern.matcher(email).matches()
}

fun isValidPhoneNumber(number: String): Boolean {
if (number.isEmpty())
return false

val emRegex = "^\\+?[1-9]\\d{1,14}\$"
val pattern: Pattern = Pattern.compile(emRegex)
return pattern.matcher(number).matches()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,28 +70,28 @@ interface IUserManager {
*
* @param email The email address that the current user has subscribed for.
*/
fun addEmailSubscription(email: String)
fun addEmail(email: String)

/**
* Remove an email subscription from the current user.
*
* @param email The email address that the current user was subscribed for, and should no longer be.
*/
fun removeEmailSubscription(email: String)
fun removeEmail(email: String)

/**
* Add a new SMS subscription to the current user.
*
* @param sms The phone number that the current user has subscribed for, in [E.164](https://documentation.onesignal.com/docs/sms-faq#what-is-the-e164-format) format.
*/
fun addSmsSubscription(sms: String)
fun addSms(sms: String)

/**
* Remove an SMS subscription from the current user.
*
* @param sms The sms address that the current user was subscribed for, and should no longer be.
*/
fun removeSmsSubscription(sms: String)
fun removeSms(sms: String)

/**
* Add a tag for the current user. Tags are key:value pairs used as building blocks
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.onesignal.user.internal

import com.onesignal.common.OneSignalUtils
import com.onesignal.core.internal.language.ILanguageContext
import com.onesignal.debug.LogLevel
import com.onesignal.debug.internal.logging.Logging
Expand Down Expand Up @@ -48,8 +49,12 @@ internal open class UserManager(
override fun addAlias(label: String, id: String) {
Logging.log(LogLevel.DEBUG, "setAlias(label: $label, id: $id)")

if(label.isEmpty()) {
throw Exception("Cannot add empty alias")
}

if (label == IdentityConstants.ONESIGNAL_ID) {
throw Exception("Cannot remove '${IdentityConstants.ONESIGNAL_ID}' alias")
throw Exception("Cannot add '${IdentityConstants.ONESIGNAL_ID}' alias")
}

_identityModel[label] = id
Expand All @@ -58,8 +63,14 @@ internal open class UserManager(
override fun addAliases(aliases: Map<String, String>) {
Logging.log(LogLevel.DEBUG, "addAliases(aliases: $aliases")

if (aliases.keys.any { it == IdentityConstants.ONESIGNAL_ID }) {
throw Exception("Cannot remove '${IdentityConstants.ONESIGNAL_ID}' alias")
aliases.forEach {
if(it.key.isEmpty()) {
throw Exception("Cannot add empty alias")
}

if (it.key == IdentityConstants.ONESIGNAL_ID) {
throw Exception("Cannot add '${IdentityConstants.ONESIGNAL_ID}' alias")
}
}

aliases.forEach {
Expand All @@ -70,6 +81,10 @@ internal open class UserManager(
override fun removeAlias(label: String) {
Logging.log(LogLevel.DEBUG, "removeAlias(label: $label)")

if(label.isEmpty()) {
throw Exception("Cannot remove empty alias")
}

if (label == IdentityConstants.ONESIGNAL_ID) {
throw Exception("Cannot remove '${IdentityConstants.ONESIGNAL_ID}' alias")
}
Expand All @@ -80,52 +95,104 @@ internal open class UserManager(
override fun removeAliases(labels: Collection<String>) {
Logging.log(LogLevel.DEBUG, "removeAliases(labels: $labels)")

labels.forEach {
if(it.isEmpty()) {
throw Exception("Cannot remove empty alias")
}

if (it == IdentityConstants.ONESIGNAL_ID) {
throw Exception("Cannot remove '${IdentityConstants.ONESIGNAL_ID}' alias")
}
}

labels.forEach {
_identityModel.remove(it)
}
}

override fun addEmailSubscription(email: String) {
Logging.log(LogLevel.DEBUG, "addEmailSubscription(email: $email)")
override fun addEmail(email: String) {
Logging.log(LogLevel.DEBUG, "addEmail(email: $email)")

if(!OneSignalUtils.isValidEmail(email)) {
throw Exception("Cannot add invalid email address as subscription: $email")
}

_subscriptionManager.addEmailSubscription(email)
}

override fun removeEmailSubscription(email: String) {
Logging.log(LogLevel.DEBUG, "removeEmailSubscription(email: $email)")
override fun removeEmail(email: String) {
Logging.log(LogLevel.DEBUG, "removeEmail(email: $email)")

if(!OneSignalUtils.isValidEmail(email)) {
throw Exception("Cannot remove invalid email address as subscription: $email")
}

_subscriptionManager.removeEmailSubscription(email)
}

override fun addSmsSubscription(sms: String) {
Logging.log(LogLevel.DEBUG, "addSmsSubscription(sms: $sms)")
override fun addSms(sms: String) {
Logging.log(LogLevel.DEBUG, "addSms(sms: $sms)")

if(!OneSignalUtils.isValidPhoneNumber(sms)) {
throw Exception("Cannot add invalid sms number as subscription: $sms")
}

_subscriptionManager.addSmsSubscription(sms)
}

override fun removeSmsSubscription(sms: String) {
Logging.log(LogLevel.DEBUG, "removeSmsSubscription(sms: $sms)")
override fun removeSms(sms: String) {
Logging.log(LogLevel.DEBUG, "removeSms(sms: $sms)")

if(!OneSignalUtils.isValidPhoneNumber(sms)) {
throw Exception("Cannot remove invalid sms number as subscription: $sms")
}

_subscriptionManager.removeSmsSubscription(sms)
}

override fun addTag(key: String, value: String) {
Logging.log(LogLevel.DEBUG, "setTag(key: $key, value: $value)")

if(key.isEmpty()) {
throw Exception("Cannot add tag with empty key")
}

_propertiesModel.tags[key] = value
}

override fun addTags(tags: Map<String, String>) {
Logging.log(LogLevel.DEBUG, "setTags(tags: $tags)")

tags.forEach {
if(it.key.isEmpty()) {
throw Exception("Cannot add tag with empty key")
}
}

tags.forEach {
_propertiesModel.tags[it.key] = it.value
}
}

override fun removeTag(key: String) {
Logging.log(LogLevel.DEBUG, "removeTag(key: $key)")

if(key.isEmpty()) {
throw Exception("Cannot remove tag with empty key")
}

_propertiesModel.tags.remove(key)
}

override fun removeTags(keys: Collection<String>) {
Logging.log(LogLevel.DEBUG, "removeTags(keys: $keys)")

keys.forEach {
if(it.isEmpty()) {
throw Exception("Cannot remove tag with empty key")
}
}

keys.forEach {
_propertiesModel.tags.remove(it)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ class LoginUserFromSubscriptionOperation() : Operation(LoginUserFromSubscription
override val groupComparisonType: GroupComparisonType = GroupComparisonType.NONE
override val canStartExecute: Boolean = true

constructor(appId: String, onesignalId: String, playerId: String) : this() {
constructor(appId: String, onesignalId: String, subscriptionId: String) : this() {
this.appId = appId
this.onesignalId = onesignalId
this.subscriptionId = playerId
this.subscriptionId = subscriptionId
}
}

0 comments on commit ef0339a

Please sign in to comment.