Skip to content

Commit 3e45b5a

Browse files
ekurutepegrdsdev
andauthored
fix(auth): prevent from requesting login keychain password os macOS (#455)
* fix macOS behavior * fix failing auth tests --------- Co-authored-by: Guilherme Souza <[email protected]>
1 parent 2db52ae commit 3e45b5a

File tree

2 files changed

+47
-44
lines changed

2 files changed

+47
-44
lines changed

Sources/Auth/Internal/Keychain.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@
6767
query[kSecAttrAccessGroup as String] = accessGroup
6868
}
6969

70+
// this is highly recommended for all keychain operations and makes the
71+
// macOS keychain item behave like an iOS keychain item
72+
// https://developer.apple.com/documentation/security/ksecusedataprotectionkeychain
73+
query[kSecUseDataProtectionKeychain as String] = kCFBooleanTrue
74+
7075
return query
7176
}
7277

Tests/AuthTests/SessionManagerTests.swift

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,6 @@ final class SessionManagerTests: XCTestCase {
4141
)
4242
}
4343

44-
override func invokeTest() {
45-
withMainSerialExecutor {
46-
super.invokeTest()
47-
}
48-
}
49-
5044
func testSession_shouldFailWithSessionNotFound() async {
5145
do {
5246
_ = try await sut.session()
@@ -58,53 +52,57 @@ final class SessionManagerTests: XCTestCase {
5852
}
5953

6054
func testSession_shouldReturnValidSession() async throws {
61-
let session = Session.validSession
62-
try Dependencies[clientID].sessionStorage.store(session)
55+
try await withMainSerialExecutor {
56+
let session = Session.validSession
57+
try Dependencies[clientID].sessionStorage.store(session)
6358

64-
let returnedSession = try await sut.session()
65-
XCTAssertNoDifference(returnedSession, session)
59+
let returnedSession = try await sut.session()
60+
XCTAssertNoDifference(returnedSession, session)
61+
}
6662
}
6763

6864
func testSession_shouldRefreshSession_whenCurrentSessionExpired() async throws {
69-
let currentSession = Session.expiredSession
70-
try Dependencies[clientID].sessionStorage.store(currentSession)
71-
72-
let validSession = Session.validSession
73-
74-
let refreshSessionCallCount = LockIsolated(0)
75-
76-
let (refreshSessionStream, refreshSessionContinuation) = AsyncStream<Session>.makeStream()
77-
78-
http.when(
79-
{ $0.url.path.contains("/token") },
80-
return: { _ in
81-
refreshSessionCallCount.withValue { $0 += 1 }
82-
let session = await refreshSessionStream.first(where: { _ in true })!
83-
return .stub(session)
65+
try await withMainSerialExecutor {
66+
let currentSession = Session.expiredSession
67+
try Dependencies[clientID].sessionStorage.store(currentSession)
68+
69+
let validSession = Session.validSession
70+
71+
let refreshSessionCallCount = LockIsolated(0)
72+
73+
let (refreshSessionStream, refreshSessionContinuation) = AsyncStream<Session>.makeStream()
74+
75+
http.when(
76+
{ $0.url.path.contains("/token") },
77+
return: { _ in
78+
refreshSessionCallCount.withValue { $0 += 1 }
79+
let session = await refreshSessionStream.first(where: { _ in true })!
80+
return .stub(session)
81+
}
82+
)
83+
84+
// Fire N tasks and call sut.session()
85+
let tasks = (0 ..< 10).map { _ in
86+
Task.detached { [weak self] in
87+
try await self?.sut.session()
88+
}
8489
}
85-
)
8690

87-
// Fire N tasks and call sut.session()
88-
let tasks = (0 ..< 10).map { _ in
89-
Task.detached { [weak self] in
90-
try await self?.sut.session()
91-
}
92-
}
91+
await Task.yield()
9392

94-
await Task.megaYield()
93+
refreshSessionContinuation.yield(validSession)
94+
refreshSessionContinuation.finish()
9595

96-
refreshSessionContinuation.yield(validSession)
97-
refreshSessionContinuation.finish()
96+
// Await for all tasks to complete.
97+
var result: [Result<Session?, Error>] = []
98+
for task in tasks {
99+
let value = await task.result
100+
result.append(value)
101+
}
98102

99-
// Await for all tasks to complete.
100-
var result: [Result<Session?, Error>] = []
101-
for task in tasks {
102-
let value = await task.result
103-
result.append(value)
103+
// Verify that refresher and storage was called only once.
104+
XCTAssertEqual(refreshSessionCallCount.value, 1)
105+
XCTAssertEqual(try result.map { try $0.get() }, (0 ..< 10).map { _ in validSession })
104106
}
105-
106-
// Verify that refresher and storage was called only once.
107-
XCTAssertEqual(refreshSessionCallCount.value, 1)
108-
XCTAssertEqual(try result.map { try $0.get() }, (0 ..< 10).map { _ in validSession })
109107
}
110108
}

0 commit comments

Comments
 (0)