Skip to content

Commit 803136c

Browse files
authored
chore: kickoff v1 release
2 parents 719d670 + 27acb46 commit 803136c

32 files changed

+922
-525
lines changed

AWSPluginsCore.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
$AMPLIFY_VERSION = '1.29.3'
1111
$AMPLIFY_RELEASE_TAG = "#{$AMPLIFY_VERSION}"
1212

13-
$AWS_SDK_VERSION = '2.30.1'
13+
$AWS_SDK_VERSION = '2.31.0'
1414
$OPTIMISTIC_AWS_SDK_VERSION = "~> #{$AWS_SDK_VERSION}"
1515

1616
Pod::Spec.new do |s|

AWSPredictionsPlugin.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
$AMPLIFY_VERSION = '1.29.3'
33
$AMPLIFY_RELEASE_TAG = "#{$AMPLIFY_VERSION}"
44

5-
$AWS_SDK_VERSION = '2.30.1'
5+
$AWS_SDK_VERSION = '2.31.0'
66
$OPTIMISTIC_AWS_SDK_VERSION = "~> #{$AWS_SDK_VERSION}"
77

88
Pod::Spec.new do |s|

Amplify/Categories/API/AuthProvider/APIAuthProviderFactory.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,20 @@ open class APIAuthProviderFactory {
2525
}
2626

2727
public protocol AmplifyAuthTokenProvider {
28+
2829
typealias AuthToken = String
30+
2931
func getLatestAuthToken() -> Result<AuthToken, Error>
32+
33+
func getLatestAuthToken(completion: @escaping (Result<AuthToken, Error>) -> Void)
34+
}
35+
36+
public extension AmplifyAuthTokenProvider {
37+
38+
func getLatestAuthToken(completion: @escaping (Result<AuthToken, Error>) -> Void) {
39+
let result = getLatestAuthToken()
40+
completion(result)
41+
}
3042
}
3143

3244
/// Amplify OIDC Auth Provider

Amplify/Categories/API/Interceptor/URLRequestInterceptor.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,25 @@ import Foundation
1919
/// plugin.
2020
public protocol URLRequestInterceptor {
2121

22-
// swiftlint:disable:next todo
23-
// TODO: turn async https://github.com/aws-amplify/amplify-ios/issues/73
2422
/// Inspect and optionally modify the request, returning either the original
2523
/// unmodified request or a modified copy.
2624
/// - Parameter request: The URLRequest
2725
func intercept(_ request: URLRequest) throws -> URLRequest
26+
27+
/// Inspect and optionally modify the request, returning either the original
28+
/// unmodified request or a modified copy in the completion handler.
29+
/// - Parameter request: The URLRequest
30+
func intercept(_ request: URLRequest, completion: @escaping (Result<URLRequest, Error>) -> Void)
31+
}
32+
33+
public extension URLRequestInterceptor {
34+
35+
func intercept(_ request: URLRequest, completion: (Result<URLRequest, Error>) -> Void) {
36+
do {
37+
let interceptedRequest = try intercept(request)
38+
completion(.success(interceptedRequest))
39+
} catch {
40+
completion(.failure(error))
41+
}
42+
}
2843
}

AmplifyPlugins.podspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
$AMPLIFY_VERSION = '1.29.3'
1111
$AMPLIFY_RELEASE_TAG = "#{$AMPLIFY_VERSION}"
1212

13-
$AWS_SDK_VERSION = '2.30.1'
13+
$AWS_SDK_VERSION = '2.31.0'
1414
$OPTIMISTIC_AWS_SDK_VERSION = "~> #{$AWS_SDK_VERSION}"
1515

1616
Pod::Spec.new do |s|
@@ -36,7 +36,7 @@ Pod::Spec.new do |s|
3636

3737
s.subspec 'AWSAPIPlugin' do |ss|
3838
ss.source_files = 'AmplifyPlugins/API/AWSAPICategoryPlugin/**/*.swift'
39-
ss.dependency 'AppSyncRealTimeClient', "~> 3.0"
39+
ss.dependency 'AppSyncRealTimeClient', "~> 3.1"
4040
end
4141

4242
s.subspec 'AWSCognitoAuthPlugin' do |ss|

AmplifyPlugins/API/APICategoryPlugin.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
B478F6E12374E0CF00C4F92B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B478F6D52374E0CF00C4F92B /* Assets.xcassets */; };
148148
B478F6E22374E0CF00C4F92B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B478F6D62374E0CF00C4F92B /* LaunchScreen.storyboard */; };
149149
B478F6E32374E0CF00C4F92B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B478F6D82374E0CF00C4F92B /* Main.storyboard */; };
150+
B48D04AF29EE203F000A73BD /* IAMHeaderSigningHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B48D04AE29EE203F000A73BD /* IAMHeaderSigningHelper.swift */; };
150151
B4DFA5E0237A611D0013E17B /* MockSessionFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DFA5C0237A611D0013E17B /* MockSessionFactory.swift */; };
151152
B4DFA5E1237A611D0013E17B /* MockURLSessionTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DFA5C1237A611D0013E17B /* MockURLSessionTask.swift */; };
152153
B4DFA5E2237A611D0013E17B /* MockURLSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DFA5C2237A611D0013E17B /* MockURLSession.swift */; };
@@ -524,6 +525,7 @@
524525
B478F6D72374E0CF00C4F92B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
525526
B478F6D92374E0CF00C4F92B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
526527
B478F6DA2374E0CF00C4F92B /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
528+
B48D04AE29EE203F000A73BD /* IAMHeaderSigningHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IAMHeaderSigningHelper.swift; sourceTree = "<group>"; };
527529
B4DFA5C0237A611D0013E17B /* MockSessionFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockSessionFactory.swift; sourceTree = "<group>"; };
528530
B4DFA5C1237A611D0013E17B /* MockURLSessionTask.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockURLSessionTask.swift; sourceTree = "<group>"; };
529531
B4DFA5C2237A611D0013E17B /* MockURLSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockURLSession.swift; sourceTree = "<group>"; };
@@ -900,6 +902,7 @@
900902
21D5286624169E74005186BA /* IAMAuthInterceptor.swift */,
901903
763C857026B0651A005164B2 /* AuthenticationTokenAuthInterceptor.swift */,
902904
6BD4620525380EA200906831 /* OIDCAuthProviderWrapper.swift */,
905+
B48D04AE29EE203F000A73BD /* IAMHeaderSigningHelper.swift */,
903906
);
904907
path = SubscriptionInterceptor;
905908
sourceTree = "<group>";
@@ -2461,6 +2464,7 @@
24612464
buildActionMask = 2147483647;
24622465
files = (
24632466
21D7A102237B54D90057D00D /* URLSessionBehaviorDelegate.swift in Sources */,
2467+
B48D04AF29EE203F000A73BD /* IAMHeaderSigningHelper.swift in Sources */,
24642468
21D7A0FD237B54D90057D00D /* URLSession+URLSessionBehavior.swift in Sources */,
24652469
212B29212592454400593ED5 /* AppSyncListPayload.swift in Sources */,
24662470
21A4F35A25A4F2E800E1047D /* AppSyncListResponse.swift in Sources */,

AmplifyPlugins/API/AWSAPICategoryPlugin/Interceptor/RequestInterceptor/AuthTokenProviderWrapper.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,19 @@ class AuthTokenProviderWrapper: AuthTokenProvider {
2929
}
3030
}
3131

32+
func getToken(completion: @escaping (Result<String, AuthError>) -> Void) {
33+
wrappedAuthTokenProvider.getLatestAuthToken { result in
34+
switch result {
35+
case .success(let token):
36+
completion(.success(token))
37+
return
38+
case .failure(let error):
39+
completion(.failure(AuthError.service("Unable to get latest auth token",
40+
"",
41+
error)))
42+
return
43+
}
44+
}
45+
}
46+
3247
}

AmplifyPlugins/API/AWSAPICategoryPlugin/Interceptor/RequestInterceptor/AuthTokenURLRequestInterceptor.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,29 @@ struct AuthTokenURLRequestInterceptor: URLRequestInterceptor {
4141
mutableRequest.setValue(token, forHTTPHeaderField: "authorization")
4242
return mutableRequest as URLRequest
4343
}
44+
45+
func intercept(_ request: URLRequest, completion: @escaping (Result<URLRequest, Error>) -> Void) {
46+
guard let mutableRequest = (request as NSURLRequest).mutableCopy() as? NSMutableURLRequest else {
47+
completion(.failure(APIError.unknown("Could not get mutable request", "")))
48+
return
49+
}
50+
51+
authTokenProvider.getToken { result in
52+
do {
53+
let token = try result.get()
54+
mutableRequest.setValue(NSDate().aws_stringValue(AWSDateISO8601DateFormat2),
55+
forHTTPHeaderField: URLRequestConstants.Header.xAmzDate)
56+
mutableRequest.setValue(URLRequestConstants.ContentType.applicationJson,
57+
forHTTPHeaderField: URLRequestConstants.Header.contentType)
58+
mutableRequest.setValue(AmplifyAWSServiceConfiguration.baseUserAgent(),
59+
forHTTPHeaderField: URLRequestConstants.Header.userAgent)
60+
mutableRequest.setValue(token, forHTTPHeaderField: "authorization")
61+
completion(.success(mutableRequest as URLRequest))
62+
return
63+
} catch {
64+
let apiError = APIError.operationError("Failed to retrieve authorization token.", "", error)
65+
completion(.failure(apiError))
66+
}
67+
}
68+
}
4469
}

AmplifyPlugins/API/AWSAPICategoryPlugin/Interceptor/RequestInterceptor/IAMURLRequestInterceptor.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,49 @@ struct IAMURLRequestInterceptor: URLRequestInterceptor {
6262

6363
return mutableRequest as URLRequest
6464
}
65+
66+
func intercept(_ request: URLRequest, completion: @escaping (Result<URLRequest, Error>) -> Void) {
67+
68+
guard let mutableRequest = (request as NSURLRequest).mutableCopy() as? NSMutableURLRequest else {
69+
let apiError = APIError.unknown("Could not get mutable request", "")
70+
completion(.failure(apiError))
71+
return
72+
}
73+
74+
let serviceConfiguration = AmplifyAWSServiceConfiguration(
75+
region: region,
76+
credentialsProvider: iamCredentialsProvider.getCredentialsProvider())
77+
mutableRequest.setValue(NSDate().aws_stringValue(AWSDateISO8601DateFormat2),
78+
forHTTPHeaderField: URLRequestConstants.Header.xAmzDate)
79+
mutableRequest.setValue(URLRequestConstants.ContentType.applicationJson,
80+
forHTTPHeaderField: URLRequestConstants.Header.contentType)
81+
mutableRequest.setValue(serviceConfiguration.userAgent,
82+
forHTTPHeaderField: URLRequestConstants.Header.userAgent)
83+
84+
let endpoint: AWSEndpoint
85+
switch endpointType {
86+
case .graphQL:
87+
endpoint = AWSEndpoint(region: region,
88+
serviceName: URLRequestConstants.appSyncServiceName,
89+
url: mutableRequest.url)
90+
case .rest:
91+
endpoint = AWSEndpoint(region: region,
92+
service: AWSServiceType.APIGateway,
93+
url: mutableRequest.url)
94+
}
95+
96+
let signer: AWSSignatureV4Signer = AWSSignatureV4Signer(
97+
credentialsProvider: iamCredentialsProvider.getCredentialsProvider(),
98+
endpoint: endpoint)
99+
100+
signer.interceptRequest(mutableRequest).continueWith { task in
101+
if let error = task.error {
102+
let apiError = APIError.operationError("Got error trying to sign", "", error)
103+
completion(.failure(apiError))
104+
return nil
105+
}
106+
completion(.success(mutableRequest as URLRequest))
107+
return nil
108+
}
109+
}
65110
}

AmplifyPlugins/API/AWSAPICategoryPlugin/Interceptor/SubscriptionInterceptor/AuthenticationTokenAuthInterceptor.swift

Lines changed: 85 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,35 +19,50 @@ class AuthenticationTokenAuthInterceptor: AuthInterceptor {
1919
self.authTokenProvider = authTokenProvider
2020
}
2121

22-
func interceptMessage(_ message: AppSyncMessage, for endpoint: URL) -> AppSyncMessage {
23-
let host = endpoint.host!
24-
guard let authToken = getAuthToken() else {
25-
log.warn("Missing authentication token for subscription")
26-
return message
22+
func interceptMessage(
23+
_ message: AppSyncMessage,
24+
for endpoint: URL,
25+
completion: @escaping (AppSyncMessage) -> Void) {
26+
let host = endpoint.host!
27+
28+
guard case .subscribe = message.messageType else {
29+
completion(message)
30+
return
31+
}
32+
33+
authTokenProvider.getLatestAuthToken { result in
34+
let signedMessage = self.signedMessage(
35+
message,
36+
host: host,
37+
tokenResult: result)
38+
completion(signedMessage)
39+
return
40+
}
2741
}
2842

29-
guard case .subscribe = message.messageType else {
30-
return message
43+
func interceptConnection(
44+
_ request: AppSyncConnectionRequest,
45+
for endpoint: URL,
46+
completion: @escaping (AppSyncConnectionRequest) -> Void) {
47+
let host = endpoint.host!
48+
authTokenProvider.getLatestAuthToken { result in
49+
let signedRequest = self.signedRequest(
50+
request,
51+
for: endpoint,
52+
host: host,
53+
tokenResult: result)
54+
completion(signedRequest)
55+
return
56+
}
3157
}
3258

33-
let authHeader = TokenAuthHeader(token: authToken, host: host)
34-
var payload = message.payload ?? AppSyncMessage.Payload()
35-
payload.authHeader = authHeader
36-
37-
let signedMessage = AppSyncMessage(
38-
id: message.id,
39-
payload: payload,
40-
type: message.messageType
41-
)
42-
return signedMessage
43-
}
44-
45-
func interceptConnection(
59+
private func signedRequest(
4660
_ request: AppSyncConnectionRequest,
47-
for endpoint: URL
61+
for endpoint: URL,
62+
host: String,
63+
tokenResult: Result<String, Error>
4864
) -> AppSyncConnectionRequest {
49-
let host = endpoint.host!
50-
guard let authToken = getAuthToken() else {
65+
guard let authToken = try? tokenResult.get() else {
5166
log.warn("Missing authentication token for subscription request")
5267
return request
5368
}
@@ -71,9 +86,54 @@ class AuthenticationTokenAuthInterceptor: AuthInterceptor {
7186
return signedRequest
7287
}
7388

74-
private func getAuthToken() -> AmplifyAuthTokenProvider.AuthToken? {
75-
try? authTokenProvider.getLatestAuthToken().get()
89+
private func signedMessage(
90+
_ message: AppSyncMessage,
91+
host: String,
92+
tokenResult: Result<String, Error>) -> AppSyncMessage {
93+
94+
guard let authToken = try? tokenResult.get() else {
95+
log.warn("Missing authentication token for subscription")
96+
return message
97+
}
98+
99+
let authHeader = TokenAuthHeader(token: authToken, host: host)
100+
var payload = message.payload ?? AppSyncMessage.Payload()
101+
payload.authHeader = authHeader
102+
103+
let signedMessage = AppSyncMessage(
104+
id: message.id,
105+
payload: payload,
106+
type: message.messageType
107+
)
108+
return signedMessage
109+
}
110+
111+
func interceptMessage(_ message: AppSyncMessage, for endpoint: URL) -> AppSyncMessage {
112+
let host = endpoint.host!
113+
114+
guard case .subscribe = message.messageType else {
115+
return message
116+
}
117+
let signedMessage = self.signedMessage(
118+
message,
119+
host: host,
120+
tokenResult: authTokenProvider.getLatestAuthToken())
121+
return signedMessage
122+
}
123+
124+
func interceptConnection(
125+
_ request: AppSyncConnectionRequest,
126+
for endpoint: URL
127+
) -> AppSyncConnectionRequest {
128+
let host = endpoint.host!
129+
let signedRequest = signedRequest(
130+
request,
131+
for: endpoint,
132+
host: host,
133+
tokenResult: authTokenProvider.getLatestAuthToken())
134+
return signedRequest
76135
}
136+
77137
}
78138

79139
// MARK: AuthorizationTokenAuthInterceptor + DefaultLogger

0 commit comments

Comments
 (0)