Skip to content

Commit 0c5d4db

Browse files
nan-liclaude
andcommitted
fix(iv): suppress anonymous ops at enqueue under IV-required
Add shouldSuppressAnonymousOp from reference branch #2599: any non- LoginUserOperation enqueued without an externalId is dropped at the enqueue boundary when useIdentityVerification == REQUIRED, since it can't authenticate and would otherwise sit in the queue forever blocked by hasValidJwtIfRequired. LoginUserOperation is exempt — it's enqueued intentionally during logout and purged later by removeOperationsWithoutExternalId if needed. Outer-gated on _identityVerificationService.newCodePathsRun so Phase 1 customers stay byte-for-byte on the legacy enqueue path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent c61a077 commit 0c5d4db

1 file changed

Lines changed: 24 additions & 0 deletions

File tree

  • OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl

OneSignalSDK/onesignal/core/src/main/java/com/onesignal/core/internal/operations/impl/OperationRepo.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ internal class OperationRepo(
135135
operation: Operation,
136136
flush: Boolean,
137137
) {
138+
if (shouldSuppressAnonymousOp(operation)) return
139+
138140
Logging.log(LogLevel.DEBUG, "OperationRepo.enqueue(operation: $operation, flush: $flush)")
139141

140142
operation.id = UUID.randomUUID().toString()
@@ -147,6 +149,8 @@ internal class OperationRepo(
147149
operation: Operation,
148150
flush: Boolean,
149151
): Boolean {
152+
if (shouldSuppressAnonymousOp(operation)) return false
153+
150154
Logging.log(LogLevel.DEBUG, "OperationRepo.enqueueAndWait(operation: $operation, force: $flush)")
151155

152156
operation.id = UUID.randomUUID().toString()
@@ -157,6 +161,26 @@ internal class OperationRepo(
157161
return waiter.waitForWake()
158162
}
159163

164+
/**
165+
* Drop anonymous (externalId == null) operations at enqueue time when IV is required —
166+
* they cannot be authenticated and would otherwise sit in the queue forever, blocked by
167+
* `hasValidJwtIfRequired`. LoginUserOperation is exempt because it's enqueued
168+
* intentionally during logout and purged later by [removeOperationsWithoutExternalId]
169+
* if needed. Outer-gated on `newCodePathsRun` so Phase 1 customers stay byte-for-byte
170+
* on the legacy enqueue path.
171+
*/
172+
private fun shouldSuppressAnonymousOp(op: Operation): Boolean {
173+
if (!_identityVerificationService.newCodePathsRun) return false
174+
if (op is LoginUserOperation) return false
175+
val suppress =
176+
_configModelStore.model.useIdentityVerification == JwtRequirement.REQUIRED &&
177+
op.externalId == null
178+
if (suppress) {
179+
Logging.debug("OperationRepo: suppressing anonymous op under IV-required: $op")
180+
}
181+
return suppress
182+
}
183+
160184
/**
161185
* Only used inside this class, adds OperationQueueItem to queue
162186
* WARNING: Never set flush=true until budget rules are added, even for internal use!

0 commit comments

Comments
 (0)