-
Notifications
You must be signed in to change notification settings - Fork 292
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
[PoC]: disallow sharing anonymous app store account #3778
base: main
Are you sure you want to change the base?
[PoC]: disallow sharing anonymous app store account #3778
Conversation
…ctions but storekit doesn't have transactions
if self.currentUserIsAnonymous | ||
&& !systemInfo.dangerousSettings.disallowSharingAppStoreAccountsForAnonymousIDs { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logOut on anonymous user would normally fail, this enables it for the dangerous setting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i assume the state is correct but "not disallow sharing" sounds like it should be "allowing sharing". Am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you asking about the flag name or the behavior?
I mean, my brain was fried when writing and this might not be a good flag name, but conceptually this says "on logout, if the user is anonymous and you want to allow for sharing between anonymous ids (so, not disallow), error out", which basically maps to existing default behavior.
If the user is anonymous and you don't want to alias anonymous IDs, then we allow logOut to proceed.
I think this is correct?
let newAppUserID = Self.generateRandomID() | ||
self.resetCacheAndSave(newUserID: newAppUserID) | ||
Logger.info(Strings.identity.log_out_success(newAppUserID: newAppUserID)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only change here is to make it easier to see in logs what the new user is
case .app_store_logout_detected_anonymous_id_not_sharing: | ||
return "The current user doesn't have transactions in their App Store Account, " + | ||
"but their corresponding CustomerInfo does. \n " + | ||
"The user will be reset under assumption that they've logged out of their App Store Account " + | ||
"\n becuase of the disallowSharingAppStoreAccountsForAnonymousIDs dangerousSetting" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my brain is fried, this copy can probably be cleaned up for readability
*/ | ||
private extension Purchases { | ||
|
||
func resetUserIfPurchaseHistoryIsEmptyIfNeeded() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here's where the magic lives:
- check if the current customer info has any purchases. If they don't, then no-op, so that we're not creating new anonymous users all the time.
- If the customer info has any purchases, but the app store account doesn't have, then assume that this is a log out. This is only valid for anonymous users, since identified users could have purchases from a different store.
.with(dangerousSettings: .init(autoSyncPurchases: true, | ||
internalSettings: DangerousSettings.Internal(usesStoreKit2JWS: useStoreKit2), | ||
disallowSharingAppStoreAccountsForAnonymousIDs: true)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
example usage, but this can be removed before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note that it needs to be used alongside SK2 + SK2 JWTs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MarkVillacampa there isn't a way to force SK2 JWT before iOS v5, right? If so I'll have to rebase this PR on that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not an easy way to force SK2 JWT before v5, no. But do we have to check that flag to use SK2 for this very specific dangerous setting? I'd assume if somebody enables it they know what they're doing :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I mean, you can't use the flag in any case because it's internal, so they wouldn't be able to access it unless they do @testable
(what this sample app is doing) or otherwise fork the SDK, right?
This adds a new
dangerousSetting
that allows the SDK to detect when the user has logged out of their App Store account on an anonymous ID, and reset the user cache in order to revoke access.This is very much a draft, but I tested this locally by:
Notes:
dangerousSetting
, and will likely not be a behavior most developers would want to have enabled. But it might be useful for some developers, as a way to prevent account sharing as an exploit.