Skip to content

Commit bc2347b

Browse files
authored
feat(auth): deprecate AWSAuthSignInOptions.validationData (#2955)
1 parent 0f508b3 commit bc2347b

File tree

6 files changed

+237
-29
lines changed

6 files changed

+237
-29
lines changed

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Models/Options/AWSAuthSignInOptions.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,21 @@ public struct AWSAuthSignInOptions {
1111

1212
public let authFlowType: AuthFlowType?
1313

14-
/// You can pass data to your Lambda function using validation data during sign in
15-
public let validationData: [String: String]?
16-
1714
public let metadata: [String: String]?
1815

16+
public init(
17+
metadata: [String: String]? = nil,
18+
authFlowType: AuthFlowType? = nil
19+
) {
20+
self.metadata = metadata
21+
self.authFlowType = authFlowType
22+
}
23+
24+
/// You can pass data to your Lambda function using validation data during sign in
25+
@available(*, deprecated, renamed: "metadata")
26+
public var validationData: [String: String]?
27+
28+
@available(*, deprecated, renamed: "init(metadata:authFlowType:)")
1929
public init(validationData: [String: String]? = nil,
2030
metadata: [String: String]? = nil,
2131
authFlowType: AuthFlowType? = nil) {

AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/AWSAuthSignInTask.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,16 @@ class AWSAuthSignInTask: AuthSignInTask, DefaultLogger {
158158

159159
// Since InitiateAuth API explicitly doesn't accept validationData,
160160
// we can pass this data to the Lambda function by using the ClientMetadata parameter
161-
var clientMetadata = pluginOptions?.metadata ?? [:]
162-
for (key, value) in pluginOptions?.validationData ?? [:] {
163-
clientMetadata[key] = value
164-
}
161+
162+
let clientMetadata = (pluginOptions?.metadata ?? [:]).merging(
163+
// we're adding `validationData` to the `clientMetadata` here
164+
// to prevent breaking behavioral changes.
165+
// in vNext, the `validationData` property will be removed
166+
// and we'll use only the `metadata` property.
167+
pluginOptions?.validationData ?? [:],
168+
uniquingKeysWith: { _, new in new }
169+
)
170+
165171
return clientMetadata
166172
}
167173
}

AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/HubEventTests/AuthHubEventHandlerTests.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ class AuthHubEventHandlerTests: XCTestCase {
2929

3030
configurePluginForSignInEvent()
3131

32-
let pluginOptions = AWSAuthSignInOptions(validationData: ["somekey": "somevalue"],
33-
metadata: ["somekey": "somevalue"])
32+
let pluginOptions = AWSAuthSignInOptions(metadata: ["somekey": "somevalue"])
3433
let options = AuthSignInRequest.Options(pluginOptions: pluginOptions)
3534

3635
let hubEventExpectation = expectation(description: "Should receive the hub event")
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
//
2+
// Copyright Amazon.com Inc. or its affiliates.
3+
// All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
import XCTest
9+
import AWSCognitoIdentity
10+
@testable import Amplify
11+
@testable import AWSCognitoAuthPlugin
12+
import AWSCognitoIdentityProvider
13+
import ClientRuntime
14+
15+
class AWSAuthSignInOptionsTestCase: BasePluginTest {
16+
override var initialState: AuthState {
17+
AuthState.configured(.signedOut(.init(lastKnownUserName: nil)), .configured)
18+
}
19+
20+
override func setUp() {
21+
super.setUp()
22+
mockIdentityProvider = MockIdentityProvider(mockInitiateAuthResponse: { _ in
23+
InitiateAuthOutputResponse(
24+
authenticationResult: .none,
25+
challengeName: .passwordVerifier,
26+
challengeParameters: InitiateAuthOutputResponse.validChalengeParams,
27+
session: "someSession")
28+
}, mockRespondToAuthChallengeResponse: { _ in
29+
RespondToAuthChallengeOutputResponse(
30+
authenticationResult: .init(
31+
accessToken: Defaults.validAccessToken,
32+
expiresIn: 300,
33+
idToken: "idToken",
34+
newDeviceMetadata: nil,
35+
refreshToken: "refreshToken",
36+
tokenType: ""),
37+
challengeName: .none,
38+
challengeParameters: [:],
39+
session: "session")
40+
})
41+
}
42+
43+
/// - Given: A sign in task
44+
/// - When: `metadata` is included in the `AWSAuthSignInOptions`
45+
/// - Then: That `metadata` should be included in the event's `clientMetadata`
46+
func test_clientMetadata_noValidationData() async throws {
47+
let signInOptions = AWSAuthSignInOptions(
48+
metadata: ["someKey": "metadataValue"]
49+
)
50+
let options = AuthSignInRequest.Options(pluginOptions: signInOptions)
51+
let request = AuthSignInRequest(username: "username", password: "password", options: options)
52+
53+
let stateMachine = try XCTUnwrap(plugin.authStateMachine)
54+
let signInTask = AWSAuthSignInTask(
55+
request,
56+
authStateMachine: stateMachine,
57+
configuration: plugin.authConfiguration
58+
)
59+
60+
let states = await stateMachine.listen()
61+
_ = try await signInTask.execute()
62+
63+
let clientMetadata = await states
64+
.compactMap(\.authenticationState)
65+
.compactMap(\.signInEvent)
66+
.first(where: { _ in true })?
67+
.clientMetadata
68+
69+
XCTAssertEqual(clientMetadata, ["someKey": "metadataValue"])
70+
}
71+
72+
/// - Given: A sign in task
73+
/// - When: Deprecated `validationData` is included in the `AWSAuthSignInOptions`
74+
/// - Then: That `validationData` should be included in the event's `clientMetadata`
75+
@available(*, deprecated)
76+
func test_clientMetadata_noMetadata() async throws {
77+
let signInOptions = AWSAuthSignInOptions(
78+
validationData: ["someKey": "validationValue"]
79+
)
80+
let options = AuthSignInRequest.Options(pluginOptions: signInOptions)
81+
let request = AuthSignInRequest(username: "username", password: "password", options: options)
82+
83+
let stateMachine = try XCTUnwrap(plugin.authStateMachine)
84+
let signInTask = AWSAuthSignInTask(
85+
request,
86+
authStateMachine: stateMachine,
87+
configuration: plugin.authConfiguration
88+
)
89+
90+
let states = await stateMachine.listen()
91+
_ = try await signInTask.execute()
92+
93+
let clientMetadata = await states
94+
.compactMap(\.authenticationState)
95+
.compactMap(\.signInEvent)
96+
.first(where: { _ in true })?
97+
.clientMetadata
98+
99+
XCTAssertEqual(clientMetadata, ["someKey": "validationValue"])
100+
}
101+
102+
/// - Given: A sign in task
103+
/// - When: `metadata` and deprecated `validationData` is included in the `AWSAuthSignInOptions`
104+
/// with the same key.
105+
/// - Then: The value from `metadata` should be included in the event's `validationData`
106+
///
107+
/// - Note:`validationData` overriding `metadata` seems a bit counterintuintive because
108+
/// `validationData` is now deprecated. However this is necessary to ensure we don't break the implicit
109+
/// contract consumers may be (knowlingly or unknowlingly) depending on.
110+
@available(*, deprecated)
111+
func test_clientMetadata_sameKey() async throws {
112+
let signInOptions = AWSAuthSignInOptions(
113+
validationData: ["someKey": "validationValue"],
114+
metadata: ["someKey": "metadataValue"]
115+
)
116+
let options = AuthSignInRequest.Options(pluginOptions: signInOptions)
117+
let request = AuthSignInRequest(username: "username", password: "password", options: options)
118+
119+
let stateMachine = try XCTUnwrap(plugin.authStateMachine)
120+
let signInTask = AWSAuthSignInTask(
121+
request,
122+
authStateMachine: stateMachine,
123+
configuration: plugin.authConfiguration
124+
)
125+
126+
let states = await stateMachine.listen()
127+
_ = try await signInTask.execute()
128+
129+
let clientMetadata = await states
130+
.compactMap(\.authenticationState)
131+
.compactMap(\.signInEvent)
132+
.first(where: { _ in true })?
133+
.clientMetadata
134+
135+
XCTAssertEqual(clientMetadata, ["someKey": "validationValue"])
136+
}
137+
138+
/// - Given: A sign in task
139+
/// - When: `metadata` and deprecated `validationData` is included in the `AWSAuthSignInOptions`
140+
/// with the different keys.
141+
/// - Then: The values from `metadata` and the deprecated `validationData` should be included in the event's `clientMetadata`
142+
@available(*, deprecated)
143+
func test_clientMetadata_differentKeys() async throws {
144+
let signInOptions = AWSAuthSignInOptions(
145+
validationData: ["validationKey": "validationValue"],
146+
metadata: ["metadataKey": "metadataValue"]
147+
)
148+
let options = AuthSignInRequest.Options(pluginOptions: signInOptions)
149+
let request = AuthSignInRequest(username: "username", password: "password", options: options)
150+
151+
let stateMachine = try XCTUnwrap(plugin.authStateMachine)
152+
let signInTask = AWSAuthSignInTask(
153+
request,
154+
authStateMachine: stateMachine,
155+
configuration: plugin.authConfiguration
156+
)
157+
158+
let states = await stateMachine.listen()
159+
_ = try await signInTask.execute()
160+
161+
let clientMetadata = await states
162+
.compactMap(\.authenticationState)
163+
.compactMap(\.signInEvent)
164+
.first(where: { _ in true })?
165+
.clientMetadata
166+
167+
XCTAssertEqual(
168+
clientMetadata,
169+
[
170+
"validationKey": "validationValue",
171+
"metadataKey": "metadataValue"
172+
]
173+
)
174+
}
175+
}
176+
177+
fileprivate extension AuthState {
178+
var authenticationState: AuthenticationState? {
179+
if case .configured(let authenticationState, _) = self {
180+
return authenticationState
181+
}
182+
return nil
183+
}
184+
}
185+
186+
fileprivate extension AuthenticationState {
187+
var signInEvent: SignInEventData? {
188+
if case .signingIn(.signingInWithSRP(_, let eventData)) = self {
189+
return eventData
190+
}
191+
return nil
192+
}
193+
}

AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/AWSAuthSignInPluginTests.swift

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ class AWSAuthSignInPluginTests: BasePluginTest {
4949
session: "session")
5050
})
5151

52-
let pluginOptions = AWSAuthSignInOptions(validationData: ["somekey": "somevalue"],
53-
metadata: ["somekey": "somevalue"])
52+
let pluginOptions = AWSAuthSignInOptions(metadata: ["somekey": "somevalue"])
5453
let options = AuthSignInRequest.Options(pluginOptions: pluginOptions)
5554

5655
do {
@@ -96,9 +95,10 @@ class AWSAuthSignInPluginTests: BasePluginTest {
9695
session: "session")
9796
})
9897

99-
let pluginOptions = AWSAuthSignInOptions(validationData: ["somekey": "somevalue"],
100-
metadata: ["somekey": "somevalue"],
101-
authFlowType: .userSRP)
98+
let pluginOptions = AWSAuthSignInOptions(
99+
metadata: ["somekey": "somevalue"],
100+
authFlowType: .userSRP
101+
)
102102
let options = AuthSignInRequest.Options(pluginOptions: pluginOptions)
103103

104104
do {
@@ -324,9 +324,10 @@ class AWSAuthSignInPluginTests: BasePluginTest {
324324
session: "session")
325325
})
326326

327-
let pluginOptions = AWSAuthSignInOptions(validationData: ["somekey": "somevalue"],
328-
metadata: ["somekey": "somevalue"],
329-
authFlowType: .customWithSRP)
327+
let pluginOptions = AWSAuthSignInOptions(
328+
metadata: ["somekey": "somevalue"],
329+
authFlowType: .customWithSRP
330+
)
330331
let options = AuthSignInRequest.Options(pluginOptions: pluginOptions)
331332
do {
332333
let result = try await plugin.signIn(username: "username", password: "password", options: options)
@@ -571,9 +572,10 @@ class AWSAuthSignInPluginTests: BasePluginTest {
571572
session: "session")
572573
})
573574

574-
let pluginOptions = AWSAuthSignInOptions(validationData: ["somekey": "somevalue"],
575-
metadata: ["somekey": "somevalue"],
576-
authFlowType: .userPassword)
575+
let pluginOptions = AWSAuthSignInOptions(
576+
metadata: ["somekey": "somevalue"],
577+
authFlowType: .userPassword
578+
)
577579
let options = AuthSignInRequest.Options(pluginOptions: pluginOptions)
578580
do {
579581
let result = try await plugin.signIn(
@@ -614,9 +616,10 @@ class AWSAuthSignInPluginTests: BasePluginTest {
614616
session: "session")
615617
})
616618

617-
let pluginOptions = AWSAuthSignInOptions(validationData: ["somekey": "somevalue"],
618-
metadata: ["somekey": "somevalue"],
619-
authFlowType: .customWithoutSRP)
619+
let pluginOptions = AWSAuthSignInOptions(
620+
metadata: ["somekey": "somevalue"],
621+
authFlowType: .customWithoutSRP
622+
)
620623
let options = AuthSignInRequest.Options(pluginOptions: pluginOptions)
621624
do {
622625
let result = try await plugin.signIn(
@@ -1144,8 +1147,7 @@ class AWSAuthSignInPluginTests: BasePluginTest {
11441147
session: "session")
11451148
})
11461149

1147-
let pluginOptions = AWSAuthSignInOptions(validationData: ["somekey": "somevalue"],
1148-
metadata: ["somekey": "somevalue"])
1150+
let pluginOptions = AWSAuthSignInOptions(metadata: ["somekey": "somevalue"])
11491151
let options = AuthSignInRequest.Options(pluginOptions: pluginOptions)
11501152

11511153
do {
@@ -1226,8 +1228,7 @@ class AWSAuthSignInPluginTests: BasePluginTest {
12261228
session: "session")
12271229
})
12281230

1229-
let pluginOptions = AWSAuthSignInOptions(validationData: ["somekey": "somevalue"],
1230-
metadata: ["somekey": "somevalue"])
1231+
let pluginOptions = AWSAuthSignInOptions(metadata: ["somekey": "somevalue"])
12311232
let options = AuthSignInRequest.Options(pluginOptions: pluginOptions)
12321233

12331234
do {

AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/HostedUITests/AWSAuthHostedUISignInTests.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,7 @@ class AWSAuthHostedUISignInTests: XCTestCase {
257257
session: "session")
258258
})
259259

260-
let pluginOptions = AWSAuthSignInOptions(validationData: ["somekey": "somevalue"],
261-
metadata: ["somekey": "somevalue"])
260+
let pluginOptions = AWSAuthSignInOptions(metadata: ["somekey": "somevalue"])
262261
let options = AuthSignInRequest.Options(pluginOptions: pluginOptions)
263262

264263
do {

0 commit comments

Comments
 (0)