Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[User Model] Add validation logic to add/remove email & sms subscriptions #1729

Merged
merged 1 commit into from
Jan 30, 2023
Merged
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
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
}
}