Skip to content

Commit f0cfe5f

Browse files
committed
Request objects - update to consider JWT
* User request instances already have a `prepareForExecution()` method that indicates if this request can be sent yet. For example, does the onesignal ID exist to make this request. * Use this existing method to check for auth and block sending this request if auth is required but invalid, or auth is unknown, etc. * OSRequestFetchUser will have onesignalId as a property, regardless of JWT on or off. The aliasLabel and aliasId pair is already expected to be onesignal ID, so make it explicit. * Keeping the onesignal ID can be used to know if the user has actually been created on the server and to check for the post-create cool-off period. The request will be translated to use the onesignal ID or the external ID based on JWT on/off. Requests Updated: * OSRequestCreateUser * OSRequestFetchUser * OSRequestAddAliases * OSRequestRemoveAlias * OSRequestUpdateProperties Requests Not Allowed with Identity Verification: * OSRequestFetchIdentityBySubscription * OSRequestIdentifyUser
1 parent ca6b132 commit f0cfe5f

11 files changed

+101
-84
lines changed

iOS_SDK/OneSignalSDK/OneSignalUser/Source/Executors/OSUserExecutor.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ extension OSUserExecutor {
254254
let identity = request.parameters?["identity"] as? [String: String],
255255
let onesignalId = request.identityModel.onesignalId,
256256
identity[OS_EXTERNAL_ID] != nil {
257-
self.fetchUser(aliasLabel: OS_ONESIGNAL_ID, aliasId: onesignalId, identityModel: request.identityModel)
257+
self.fetchUser(onesignalId: onesignalId, identityModel: request.identityModel)
258258
} else {
259259
self.executePendingRequests()
260260
}
@@ -314,7 +314,7 @@ extension OSUserExecutor {
314314
return
315315
}
316316

317-
self.fetchUser(aliasLabel: OS_ONESIGNAL_ID, aliasId: onesignalId, identityModel: request.identityModel)
317+
self.fetchUser(onesignalId: onesignalId, identityModel: request.identityModel)
318318
}
319319
} onFailure: { error in
320320
OneSignalLog.onesignalLog(.LL_ERROR, message: "OSUserExecutor executeFetchIdentityBySubscriptionRequest failed with error: \(error.debugDescription)")
@@ -375,7 +375,7 @@ extension OSUserExecutor {
375375
if OneSignalUserManagerImpl.sharedInstance.isCurrentUser(request.identityModelToUpdate) {
376376
// Add onesignal ID to new records because an immediate fetch may not return the newly-applied external ID
377377
self.newRecordsState.add(onesignalId, true)
378-
self.fetchUser(aliasLabel: OS_ONESIGNAL_ID, aliasId: onesignalId, identityModel: request.identityModelToUpdate)
378+
self.fetchUser(onesignalId: onesignalId, identityModel: request.identityModelToUpdate)
379379
} else {
380380
self.executePendingRequests()
381381
}
@@ -417,8 +417,8 @@ extension OSUserExecutor {
417417
}
418418
}
419419

420-
func fetchUser(aliasLabel: String, aliasId: String, identityModel: OSIdentityModel, onNewSession: Bool = false) {
421-
let request = OSRequestFetchUser(identityModel: identityModel, aliasLabel: aliasLabel, aliasId: aliasId, onNewSession: onNewSession)
420+
func fetchUser(onesignalId: String, identityModel: OSIdentityModel, onNewSession: Bool = false) {
421+
let request = OSRequestFetchUser(identityModel: identityModel, onesignalId: onesignalId, onNewSession: onNewSession)
422422

423423
appendToQueue(request)
424424

iOS_SDK/OneSignalSDK/OneSignalUser/Source/OneSignalUserManagerImpl.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ extension OneSignalUserManagerImpl {
566566

567567
// Fetch the user's data if there is a onesignal_id
568568
if let onesignalId = onesignalId {
569-
userExecutor!.fetchUser(aliasLabel: OS_ONESIGNAL_ID, aliasId: onesignalId, identityModel: user.identityModel, onNewSession: true)
569+
userExecutor!.fetchUser(onesignalId: onesignalId, identityModel: user.identityModel, onNewSession: true)
570570
} else {
571571
// It is possible to init a user from cache who is missing the onesignalId
572572
// This can happen if any createUser or identifyUser requests are cached

iOS_SDK/OneSignalSDK/OneSignalUser/Source/Requests/OSRequestAddAliases.swift

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,21 @@ class OSRequestAddAliases: OneSignalRequest, OSUserRequest {
3838
var identityModel: OSIdentityModel
3939
let aliases: [String: String]
4040

41-
/// requires a `onesignal_id` to send this request
41+
/// Needs `onesignal_id` without JWT on or `external_id` with valid JWT to send this request
4242
func prepareForExecution(newRecordsState: OSNewRecordsState) -> Bool {
43-
if let onesignalId = identityModel.onesignalId,
44-
newRecordsState.canAccess(onesignalId),
45-
let appId = OneSignalConfigManager.getAppId()
46-
{
47-
self.addJWTHeader(identityModel: identityModel)
48-
self.path = "apps/\(appId)/users/by/\(OS_ONESIGNAL_ID)/\(onesignalId)/identity"
49-
return true
50-
} else {
43+
let alias = getAlias(identityModel: identityModel)
44+
guard
45+
let onesignalId = identityModel.onesignalId,
46+
newRecordsState.canAccess(onesignalId),
47+
let aliasIdToUse = alias.id,
48+
let appId = OneSignalConfigManager.getAppId(),
49+
addJWTHeaderIsValid(identityModel: identityModel)
50+
else {
5151
return false
5252
}
53+
54+
self.path = "apps/\(appId)/users/by/\(alias.label)/\(aliasIdToUse)/identity"
55+
return true
5356
}
5457

5558
init(aliases: [String: String], identityModel: OSIdentityModel) {

iOS_SDK/OneSignalSDK/OneSignalUser/Source/Requests/OSRequestCreateSubscription.swift

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,21 @@ class OSRequestCreateSubscription: OneSignalRequest, OSUserRequest {
4343
var subscriptionModel: OSSubscriptionModel
4444
var identityModel: OSIdentityModel
4545

46-
// Need the onesignal_id of the user
46+
/// Needs the `onesignal_id` without JWT on or `external_id` with valid JWT to send this request
4747
func prepareForExecution(newRecordsState: OSNewRecordsState) -> Bool {
48-
if let onesignalId = identityModel.onesignalId,
49-
newRecordsState.canAccess(onesignalId),
50-
let appId = OneSignalConfigManager.getAppId()
51-
{
52-
self.addJWTHeader(identityModel: identityModel)
53-
self.path = "apps/\(appId)/users/by/\(OS_ONESIGNAL_ID)/\(onesignalId)/subscriptions"
54-
return true
55-
} else {
48+
let alias = getAlias(identityModel: identityModel)
49+
guard
50+
let onesignalId = identityModel.onesignalId,
51+
newRecordsState.canAccess(onesignalId),
52+
let aliasIdToUse = alias.id,
53+
let appId = OneSignalConfigManager.getAppId(),
54+
addJWTHeaderIsValid(identityModel: identityModel)
55+
else {
5656
return false
5757
}
58+
59+
self.path = "apps/\(appId)/users/by/\(alias.label)/\(aliasIdToUse)/subscriptions"
60+
return true
5861
}
5962

6063
init(subscriptionModel: OSSubscriptionModel, identityModel: OSIdentityModel) {

iOS_SDK/OneSignalSDK/OneSignalUser/Source/Requests/OSRequestCreateUser.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class OSRequestCreateUser: OneSignalRequest, OSUserRequest {
4545
var pushSubscriptionModel: OSSubscriptionModel?
4646
var originalPushToken: String?
4747

48+
// TODO: JWT 🔐 confirm existence of external ID is already addressed before getting here
4849
/// Checks if the subscription ID can be accessed, if a subscription is being included in the request
4950
func prepareForExecution(newRecordsState: OSNewRecordsState) -> Bool {
5051
guard let appId = OneSignalConfigManager.getAppId() else {
@@ -59,8 +60,12 @@ class OSRequestCreateUser: OneSignalRequest, OSUserRequest {
5960
return false
6061
}
6162

63+
guard addJWTHeaderIsValid(identityModel: identityModel) else {
64+
OneSignalLog.onesignalLog(.LL_DEBUG, message: "Cannot generate the create user request yet due to auth.")
65+
return false
66+
}
67+
6268
_ = self.addPushSubscriptionIdToAdditionalHeaders()
63-
self.addJWTHeader(identityModel: identityModel)
6469
self.path = "apps/\(appId)/users"
6570
return true
6671
}

iOS_SDK/OneSignalSDK/OneSignalUser/Source/Requests/OSRequestFetchIdentityBySubscription.swift

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,19 @@ class OSRequestFetchIdentityBySubscription: OneSignalRequest, OSUserRequest {
3939
var identityModel: OSIdentityModel
4040
var pushSubscriptionModel: OSSubscriptionModel
4141

42+
/// Only send this request if Identity Verification is off.
4243
func prepareForExecution(newRecordsState: OSNewRecordsState) -> Bool {
43-
// newRecordsState is unused for this request
44-
guard let appId = OneSignalConfigManager.getAppId() else {
45-
OneSignalLog.onesignalLog(.LL_DEBUG, message: "Cannot generate the FetchIdentityBySubscription request due to null app ID.")
44+
guard
45+
let appId = OneSignalConfigManager.getAppId(),
46+
let subscriptionId = pushSubscriptionModel.subscriptionId,
47+
OneSignalUserManagerImpl.sharedInstance.jwtConfig.isRequired == false
48+
else {
49+
OneSignalLog.onesignalLog(.LL_ERROR, message: "Cannot generate the FetchIdentityBySubscription request.")
4650
return false
4751
}
4852

49-
if let subscriptionId = pushSubscriptionModel.subscriptionId {
50-
self.path = "apps/\(appId)/subscriptions/\(subscriptionId)/user/identity"
51-
return true
52-
} else {
53-
// This is an error, and should never happen
54-
OneSignalLog.onesignalLog(.LL_ERROR, message: "Cannot generate the FetchIdentityBySubscription request due to null subscriptionId.")
55-
self.path = ""
56-
return false
57-
}
53+
self.path = "apps/\(appId)/subscriptions/\(subscriptionId)/user/identity"
54+
return true
5855
}
5956

6057
init(identityModel: OSIdentityModel, pushSubscriptionModel: OSSubscriptionModel) {

iOS_SDK/OneSignalSDK/OneSignalUser/Source/Requests/OSRequestFetchUser.swift

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,35 +40,39 @@ class OSRequestFetchUser: OneSignalRequest, OSUserRequest {
4040
}
4141

4242
let identityModel: OSIdentityModel
43-
let aliasLabel: String
44-
let aliasId: String
4543
let onNewSession: Bool
4644

45+
/// This should always be `OS_ONESIGNAL_ID` even with JWT on, as a way to know if the user has been created on the server and for the post-create cool off period
46+
let onesignalId: String
47+
48+
// TODO: JWT 🔐 Is external ID already handled by this time? Or do we need to check the alias here?
49+
/// Needs `onesignal_id` without JWT on or `external_id` with valid JWT to send this request
4750
func prepareForExecution(newRecordsState: OSNewRecordsState) -> Bool {
48-
guard let appId = OneSignalConfigManager.getAppId(),
49-
newRecordsState.canAccess(aliasId)
51+
let alias = getAlias(identityModel: identityModel)
52+
guard
53+
let aliasIdToUse = alias.id,
54+
let appId = OneSignalConfigManager.getAppId(),
55+
newRecordsState.canAccess(onesignalId),
56+
addJWTHeaderIsValid( identityModel: identityModel)
5057
else {
51-
OneSignalLog.onesignalLog(.LL_DEBUG, message: "Cannot generate the fetch user request for \(aliasLabel): \(aliasId) yet.")
58+
OneSignalLog.onesignalLog(.LL_DEBUG, message: "Cannot generate the fetch user request for \(alias) yet.")
5259
return false
5360
}
54-
self.addJWTHeader(identityModel: identityModel)
55-
self.path = "apps/\(appId)/users/by/\(aliasLabel)/\(aliasId)"
61+
self.path = "apps/\(appId)/users/by/\(alias.label)/\(aliasIdToUse)"
5662
return true
5763
}
5864

59-
init(identityModel: OSIdentityModel, aliasLabel: String, aliasId: String, onNewSession: Bool) {
65+
init(identityModel: OSIdentityModel, onesignalId: String, onNewSession: Bool) {
6066
self.identityModel = identityModel
61-
self.aliasLabel = aliasLabel
62-
self.aliasId = aliasId
67+
self.onesignalId = onesignalId
6368
self.onNewSession = onNewSession
64-
self.stringDescription = "<OSRequestFetchUser with \(aliasLabel): \(aliasId)>"
69+
self.stringDescription = "<OSRequestFetchUser with \(OS_ONESIGNAL_ID): \(onesignalId)>"
6570
super.init()
6671
self.method = GET
6772
}
6873

6974
func encode(with coder: NSCoder) {
70-
coder.encode(aliasLabel, forKey: "aliasLabel")
71-
coder.encode(aliasId, forKey: "aliasId")
75+
coder.encode(onesignalId, forKey: "onesignalId")
7276
coder.encode(identityModel, forKey: "identityModel")
7377
coder.encode(onNewSession, forKey: "onNewSession")
7478
coder.encode(method.rawValue, forKey: "method") // Encodes as String
@@ -78,19 +82,17 @@ class OSRequestFetchUser: OneSignalRequest, OSUserRequest {
7882
required init?(coder: NSCoder) {
7983
guard
8084
let identityModel = coder.decodeObject(forKey: "identityModel") as? OSIdentityModel,
81-
let aliasLabel = coder.decodeObject(forKey: "aliasLabel") as? String,
82-
let aliasId = coder.decodeObject(forKey: "aliasId") as? String,
85+
let onesignalId = coder.decodeObject(forKey: "onesignalId") as? String,
8386
let rawMethod = coder.decodeObject(forKey: "method") as? UInt32,
8487
let timestamp = coder.decodeObject(forKey: "timestamp") as? Date
8588
else {
8689
// Log error
8790
return nil
8891
}
8992
self.identityModel = identityModel
90-
self.aliasLabel = aliasLabel
91-
self.aliasId = aliasId
93+
self.onesignalId = onesignalId
9294
self.onNewSession = coder.decodeBool(forKey: "onNewSession")
93-
self.stringDescription = "<OSRequestFetchUser with \(aliasLabel): \(aliasId)>"
95+
self.stringDescription = "<OSRequestFetchUser with \(OS_ONESIGNAL_ID): \(onesignalId)>"
9496
super.init()
9597
self.method = HTTPMethod(rawValue: rawMethod)
9698
self.timestamp = timestamp

iOS_SDK/OneSignalSDK/OneSignalUser/Source/Requests/OSRequestIdentifyUser.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,20 @@ class OSRequestIdentifyUser: OneSignalRequest, OSUserRequest {
4848
let aliasId: String
4949

5050
/// requires a `onesignal_id` to send this request
51+
/// Only send this request if Identity Verification is off
5152
func prepareForExecution(newRecordsState: OSNewRecordsState) -> Bool {
52-
if let onesignalId = identityModelToIdentify.onesignalId,
53-
newRecordsState.canAccess(onesignalId),
54-
let appId = OneSignalConfigManager.getAppId()
55-
{
56-
self.addJWTHeader(identityModel: identityModelToIdentify)
57-
self.path = "apps/\(appId)/users/by/\(OS_ONESIGNAL_ID)/\(onesignalId)/identity"
58-
return true
59-
} else {
60-
// self.path is non-nil, so set to empty string
61-
self.path = ""
53+
guard
54+
let onesignalId = identityModelToIdentify.onesignalId,
55+
newRecordsState.canAccess(onesignalId),
56+
let appId = OneSignalConfigManager.getAppId(),
57+
OneSignalUserManagerImpl.sharedInstance.jwtConfig.isRequired == false
58+
else {
6259
OneSignalLog.onesignalLog(.LL_DEBUG, message: "Cannot generate the Identify User request yet.")
6360
return false
6461
}
62+
63+
self.path = "apps/\(appId)/users/by/\(OS_ONESIGNAL_ID)/\(onesignalId)/identity"
64+
return true
6565
}
6666

6767
/**

iOS_SDK/OneSignalSDK/OneSignalUser/Source/Requests/OSRequestRemoveAlias.swift

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,21 @@ class OSRequestRemoveAlias: OneSignalRequest, OSUserRequest {
3838
let labelToRemove: String
3939
var identityModel: OSIdentityModel
4040

41+
/// Needs `onesignal_id` without JWT on or `external_id` with valid JWT to send this request
4142
func prepareForExecution(newRecordsState: OSNewRecordsState) -> Bool {
42-
if let onesignalId = identityModel.onesignalId,
43-
newRecordsState.canAccess(onesignalId),
44-
let appId = OneSignalConfigManager.getAppId()
45-
{
46-
self.addJWTHeader(identityModel: identityModel)
47-
self.path = "apps/\(appId)/users/by/\(OS_ONESIGNAL_ID)/\(onesignalId)/identity/\(labelToRemove)"
48-
return true
49-
} else {
43+
let alias = getAlias(identityModel: identityModel)
44+
guard
45+
let onesignalId = identityModel.onesignalId,
46+
newRecordsState.canAccess(onesignalId),
47+
let aliasIdToUse = alias.id,
48+
let appId = OneSignalConfigManager.getAppId(),
49+
addJWTHeaderIsValid(identityModel: identityModel)
50+
else {
5051
return false
5152
}
53+
54+
self.path = "apps/\(appId)/users/by/\(alias.label)/\(aliasIdToUse)/identity/\(labelToRemove)"
55+
return true
5256
}
5357

5458
init(labelToRemove: String, identityModel: OSIdentityModel) {

iOS_SDK/OneSignalSDK/OneSignalUser/Source/Requests/OSRequestUpdateProperties.swift

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,22 @@ class OSRequestUpdateProperties: OneSignalRequest, OSUserRequest {
3737

3838
var identityModel: OSIdentityModel
3939

40-
// TODO: Decide if addPushSubscriptionIdToAdditionalHeadersIfNeeded should block.
41-
// Note Android adds it to requests, if the push sub ID exists
40+
/// Needs `onesignal_id` without JWT on or `external_id` with valid JWT to send this request
4241
func prepareForExecution(newRecordsState: OSNewRecordsState) -> Bool {
43-
if let onesignalId = identityModel.onesignalId,
44-
newRecordsState.canAccess(onesignalId),
45-
let appId = OneSignalConfigManager.getAppId()
46-
{
47-
_ = self.addPushSubscriptionIdToAdditionalHeaders()
48-
self.addJWTHeader(identityModel: identityModel)
49-
self.path = "apps/\(appId)/users/by/\(OS_ONESIGNAL_ID)/\(onesignalId)"
50-
return true
51-
} else {
42+
let alias = getAlias(identityModel: identityModel)
43+
guard
44+
let onesignalId = identityModel.onesignalId,
45+
newRecordsState.canAccess(onesignalId),
46+
let aliasIdToUse = alias.id,
47+
let appId = OneSignalConfigManager.getAppId(),
48+
addJWTHeaderIsValid(identityModel: identityModel)
49+
else {
5250
return false
5351
}
52+
53+
_ = self.addPushSubscriptionIdToAdditionalHeaders()
54+
self.path = "apps/\(appId)/users/by/\(alias.label)/\(aliasIdToUse)"
55+
return true
5456
}
5557

5658
init(params: [String: Any], identityModel: OSIdentityModel) {

0 commit comments

Comments
 (0)