Skip to content

Commit 3542d34

Browse files
committed
Adding work in progress Subscription executor auth pends
adds handling for pending unauthorized subscription executor requests. Doesn't yet handle prepare for execution properly No unit tests yet
1 parent 1ae0deb commit 3542d34

File tree

1 file changed

+73
-4
lines changed

1 file changed

+73
-4
lines changed

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

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class OSSubscriptionOperationExecutor: OSOperationExecutor {
3535
var addRequestQueue: [OSRequestCreateSubscription] = []
3636
var removeRequestQueue: [OSRequestDeleteSubscription] = []
3737
var updateRequestQueue: [OSRequestUpdateSubscription] = []
38+
var pendingAuthRequests: [String: [OSUserRequest]] = [String:[OSUserRequest]]()
3839
var subscriptionModels: [String: OSSubscriptionModel] = [:]
3940
let newRecordsState: OSNewRecordsState
4041
let jwtConfig: OSUserJwtConfig
@@ -279,16 +280,40 @@ class OSSubscriptionOperationExecutor: OSOperationExecutor {
279280
}
280281
}
281282

282-
func handleUnauthorizedError(externalId: String, error: NSError) {
283+
func handleUnauthorizedError(externalId: String, error: NSError, request: OSUserRequest) {
283284
if (jwtConfig.isRequired ?? false) {
285+
self.pendRequestUntilAuthUpdated(request, externalId: externalId)
284286
OneSignalUserManagerImpl.sharedInstance.invalidateJwtForExternalId(externalId: externalId, error: error)
285287
}
286288
}
289+
290+
291+
func pendRequestUntilAuthUpdated(_ request: OSUserRequest, externalId: String?) {
292+
self.dispatchQueue.async {
293+
self.addRequestQueue.removeAll(where: { $0 == request})
294+
self.removeRequestQueue.removeAll(where: { $0 == request})
295+
self.updateRequestQueue.removeAll(where: { $0 == request})
296+
guard let externalId = externalId else {
297+
return
298+
}
299+
var requests = self.pendingAuthRequests[externalId] ?? []
300+
let inQueue = requests.contains(where: {$0 == request})
301+
guard !inQueue else {
302+
return
303+
}
304+
requests.append(request)
305+
self.pendingAuthRequests[externalId] = requests
306+
}
307+
}
287308

288309
func executeCreateSubscriptionRequest(_ request: OSRequestCreateSubscription, inBackground: Bool) {
289310
guard !request.sentToClient else {
290311
return
291312
}
313+
guard request.addJWTHeaderIsValid(identityModel: request.identityModel) else {
314+
pendRequestUntilAuthUpdated(request, externalId:request.identityModel.externalId)
315+
return
316+
}
292317
guard request.prepareForExecution(newRecordsState: newRecordsState) else {
293318
return
294319
}
@@ -339,7 +364,7 @@ class OSSubscriptionOperationExecutor: OSOperationExecutor {
339364
OneSignalUserManagerImpl.sharedInstance._logout()
340365
} else if responseType == .unauthorized && (self.jwtConfig.isRequired ?? false) {
341366
if let externalId = request.identityModel.externalId {
342-
self.handleUnauthorizedError(externalId: externalId, error: nsError)
367+
self.handleUnauthorizedError(externalId: externalId, error: nsError, request: request)
343368
}
344369
request.sentToClient = false
345370
} else if responseType != .retryable {
@@ -359,6 +384,11 @@ class OSSubscriptionOperationExecutor: OSOperationExecutor {
359384
guard !request.sentToClient else {
360385
return
361386
}
387+
// ECM TODO
388+
// guard request.addJWTHeaderIsValid(identityModel: request.identityModel) else {
389+
// pendRequestUntilAuthUpdated(request, externalId:request.identityModel.externalId)
390+
// return
391+
// }
362392
guard request.prepareForExecution(newRecordsState: newRecordsState) else {
363393
return
364394
}
@@ -389,7 +419,7 @@ class OSSubscriptionOperationExecutor: OSOperationExecutor {
389419
if responseType == .unauthorized && (self.jwtConfig.isRequired ?? false) {
390420
// ECM The delete subscription request doesn't have an identity model?
391421
if let externalId = OneSignalUserManagerImpl.sharedInstance.user.identityModel.externalId {
392-
self.handleUnauthorizedError(externalId: externalId, error: nsError)
422+
self.handleUnauthorizedError(externalId: externalId, error: nsError, request: request)
393423
}
394424
request.sentToClient = false
395425
} else if responseType != .retryable {
@@ -410,6 +440,11 @@ class OSSubscriptionOperationExecutor: OSOperationExecutor {
410440
guard !request.sentToClient else {
411441
return
412442
}
443+
// ECM TODO
444+
// guard request.addJWTHeaderIsValid(identityModel: request.identityModel) else {
445+
// pendRequestUntilAuthUpdated(request, externalId:request.identityModel.externalId)
446+
// return
447+
// }
413448
guard request.prepareForExecution(newRecordsState: newRecordsState) else {
414449
return
415450
}
@@ -437,7 +472,7 @@ class OSSubscriptionOperationExecutor: OSOperationExecutor {
437472
if responseType == .unauthorized && (self.jwtConfig.isRequired ?? false) {
438473
// ECM The update subscription request doesn't have an identity model?
439474
if let externalId = OneSignalUserManagerImpl.sharedInstance.user.identityModel.externalId {
440-
self.handleUnauthorizedError(externalId: externalId, error: nsError)
475+
self.handleUnauthorizedError(externalId: externalId, error: nsError, request: request)
441476
}
442477
request.sentToClient = false
443478
} else if responseType != .retryable {
@@ -454,6 +489,40 @@ class OSSubscriptionOperationExecutor: OSOperationExecutor {
454489
}
455490
}
456491

492+
extension OSSubscriptionOperationExecutor: OSUserJwtConfigListener {
493+
func onRequiresUserAuthChanged(from: OneSignalOSCore.OSRequiresUserAuth, to: OneSignalOSCore.OSRequiresUserAuth) {
494+
print("❌ OSSubscriptionOperationExecutor onUserAuthChanged from \(String(describing: from)) to \(String(describing: to))")
495+
// ECM TODO If auth changed from false or unknown to true, process requests
496+
}
497+
498+
func onJwtUpdated(externalId: String, token: String?) {
499+
print("❌ OSSubscriptionOperationExecutor onJwtUpdated for \(externalId) to \(String(describing: token))")
500+
reQueuePendingRequestsForExternalId(externalId: externalId)
501+
}
502+
503+
private func reQueuePendingRequestsForExternalId(externalId: String) {
504+
self.dispatchQueue.async {
505+
guard let requests = self.pendingAuthRequests[externalId] else {
506+
return
507+
}
508+
for request in requests {
509+
if let addRequest = request as? OSRequestCreateSubscription {
510+
self.addRequestQueue.append(addRequest)
511+
} else if let removeRequest = request as? OSRequestDeleteSubscription {
512+
self.removeRequestQueue.append(removeRequest)
513+
} else if let updateRequest = request as? OSRequestUpdateSubscription {
514+
self.updateRequestQueue.append(updateRequest)
515+
}
516+
}
517+
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_SUBSCRIPTION_EXECUTOR_ADD_REQUEST_QUEUE_KEY, withValue: self.addRequestQueue)
518+
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_SUBSCRIPTION_EXECUTOR_REMOVE_REQUEST_QUEUE_KEY, withValue: self.removeRequestQueue)
519+
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_SUBSCRIPTION_EXECUTOR_UPDATE_REQUEST_QUEUE_KEY, withValue: self.updateRequestQueue)
520+
self.pendingAuthRequests[externalId] = nil
521+
self.processRequestQueue(inBackground: false)
522+
}
523+
}
524+
}
525+
457526
extension OSSubscriptionOperationExecutor: OSLoggable {
458527
func logSelf() {
459528
print(

0 commit comments

Comments
 (0)