mirror of
https://github.com/yattee/yattee.git
synced 2026-10-23 13:12:53 +00:00
Refuse a login whose Apple identity moved under it
Storing checked that the identity scope was resolved, but not that it was still the one the login was made under. Credentials are filed per identity, and the round trip leaves room for the scope to move — the account obtained here would then be written into somebody else's namespace and synced to their Keychain. Only a move between two named identities counts. Unresolved at either end is left to the storing side, which already refuses to write under a scope it cannot name; rejecting it here as well would turn an ordinary sign-in that began before iCloud settled — or a tokenless scope revalidating on activation, which it does every time — into a failed login.
This commit is contained in:
@@ -153,6 +153,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"accounts.signIn.identityChanged" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Your iCloud account changed while signing in. Try again."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"accounts.signIn.identityUnresolved" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
|
||||
@@ -153,11 +153,31 @@ struct InstanceLoginView: View {
|
||||
isLoading = true
|
||||
errorMessage = nil
|
||||
|
||||
// Which Apple identity this login is being made under. Credentials are
|
||||
// filed per identity, and the round trip below leaves room for the
|
||||
// scope to move — storing afterwards would file the account obtained
|
||||
// here in somebody else's namespace, and sync it to their Keychain.
|
||||
let scopeAtStart = appEnvironment.credentialIdentityScope.current
|
||||
|
||||
Task {
|
||||
do {
|
||||
let credential = try await performLogin(appEnvironment: appEnvironment)
|
||||
|
||||
await MainActor.run {
|
||||
// Only a move between two *named* identities is a mismatch.
|
||||
// Unresolved at either end is left to `storeLogin`, which
|
||||
// already refuses to write under a scope it cannot name —
|
||||
// rejecting here as well would turn an ordinary sign-in
|
||||
// that began before iCloud settled, or a tokenless scope
|
||||
// revalidating on activation, into a failed login.
|
||||
if let scopeAtStart,
|
||||
let scopeNow = appEnvironment.credentialIdentityScope.current,
|
||||
scopeNow != scopeAtStart {
|
||||
errorMessage = String(localized: "accounts.signIn.identityChanged")
|
||||
isLoading = false
|
||||
return
|
||||
}
|
||||
|
||||
guard onLoginSuccess(credential, username) else {
|
||||
// The failure is reported by a toast from the storing
|
||||
// side; staying open keeps the form filled in so the
|
||||
|
||||
Reference in New Issue
Block a user