Skip to content

Commit 3174b58

Browse files
Merge pull request #68 from dimitribouniol/dimitri/jwkkit5-cleanup
Minimal Update to JWTKit 5
2 parents 2ccb38f + f5a027b commit 3174b58

File tree

4 files changed

+20
-20
lines changed

4 files changed

+20
-20
lines changed

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import PackageDescription
77
let package = Package(
88
name: "AppStoreServerLibrary",
99
platforms: [
10-
.macOS(.v11), // And other server environments
10+
.macOS(.v13), // And other server environments
1111
],
1212
products: [
1313
.library(
@@ -18,7 +18,7 @@ let package = Package(
1818
.package(url: "https://github.com/apple/swift-certificates.git", from: "1.0.0"),
1919
.package(url: "https://github.com/apple/swift-asn1.git", from: "1.1.0"),
2020
.package(url: "https://github.com/apple/swift-crypto.git", "1.0.0" ..< "4.0.0"),
21-
.package(url: "https://github.com/vapor/jwt-kit.git", from: "4.0.0"),
21+
.package(url: "https://github.com/vapor/jwt-kit.git", from: "5.0.0"),
2222
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
2323
.package(url: "https://github.com/apple/swift-nio", from: "2.0.0"),
2424
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.9.0"),

Sources/AppStoreServerLibrary/AppStoreServerAPIClient.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public class AppStoreServerAPIClient {
7676
}
7777

7878
var urlRequest = HTTPClientRequest(url: url.absoluteString)
79-
let token = try generateToken()
79+
let token = try await generateToken()
8080
urlRequest.headers.add(name: "User-Agent", value: AppStoreServerAPIClient.userAgent)
8181
urlRequest.headers.add(name: "Authorization", value: "Bearer \(token)")
8282
urlRequest.headers.add(name: "Accept", value: "application/json")
@@ -141,18 +141,17 @@ public class AppStoreServerAPIClient {
141141
}
142142
}
143143

144-
private func generateToken() throws -> String {
145-
let signers = JWTSigners()
144+
private func generateToken() async throws -> String {
145+
let keys = JWTKeyCollection()
146146
let payload = AppStoreServerAPIJWT(
147147
exp: .init(value: Date().addingTimeInterval(5 * 60)), // 5 minutes
148148
iss: .init(value: self.issuerId),
149149
bid: self.bundleId,
150150
aud: .init(value: AppStoreServerAPIClient.appStoreConnectAudience),
151151
iat: .init(value: Date())
152152
)
153-
let key: ECDSAKey = try ECDSAKey.private(pem: self.signingKey.pemRepresentation)
154-
signers.use(.es256(key: key))
155-
return try signers.sign(payload, typ: "JWT", kid: JWKIdentifier(stringLiteral: self.keyId))
153+
try await keys.add(ecdsa: ECDSA.PrivateKey<P256>(backing: signingKey))
154+
return try await keys.sign(payload, header: ["typ": "JWT", "kid": .string(self.keyId)])
156155
}
157156

158157
///Uses a subscription’s product identifier to extend the renewal date for all of its eligible active subscribers.
@@ -333,7 +332,8 @@ public class AppStoreServerAPIClient {
333332
var bid: String
334333
var aud: AudienceClaim
335334
var iat: IssuedAtClaim
336-
func verify(using signer: JWTSigner) throws {
335+
336+
func verify(using algorithm: some JWTAlgorithm) async throws {
337337
fatalError("Do not attempt to locally verify a JWT")
338338
}
339339
}

Sources/AppStoreServerLibrary/ChainVerifier.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ struct ChainVerifier {
7272
return VerificationResult.invalid(VerificationError.VERIFICATION_FAILURE)
7373
}
7474
// Verify using Vapor
75-
let signers = JWTSigners()
76-
try signers.use(.es256(key: .public(pem: publicKey.pemRepresentation)))
77-
let verifiedBody: VerificationResult<VaporBody> = try VerificationResult<VaporBody>.valid(signers.verify(signedData))
75+
let keys = JWTKeyCollection()
76+
await keys.add(ecdsa: try ECDSA.PublicKey<P256>(backing: publicKey))
77+
let verifiedBody: VerificationResult<VaporBody> = try await VerificationResult<VaporBody>.valid(keys.verify(signedData))
7878
switch verifiedBody {
7979
case .invalid(_):
8080
return VerificationResult.invalid(VerificationError.VERIFICATION_FAILURE)
@@ -102,8 +102,8 @@ struct ChainVerifier {
102102
}
103103
}
104104

105-
class VaporBody : JWTPayload {
106-
func verify(using signer: JWTKit.JWTSigner) throws {
105+
struct VaporBody : JWTPayload {
106+
func verify(using algorithm: some JWTAlgorithm) async throws {
107107
// No-op
108108
}
109109
}

Tests/AppStoreServerLibraryTests/TestingUtility.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,19 @@ public class TestingUtility {
4040
public static func createSignedDataFromJson(_ path: String) -> String {
4141
let payload = readFile(path)
4242
let signingKey = Crypto.P256.Signing.PrivateKey()
43-
let signer: JWTSigner = try! .es256(key: .private(pem: signingKey.pemRepresentation))
4443

4544
let header = JWTHeader(alg: "ES256")
4645

4746
let encoder = JSONEncoder()
4847
let headerData = try! encoder.encode(header)
49-
let encodedHeader = headerData.base64EncodedString()
48+
let encodedHeader = base64ToBase64URL(headerData.base64EncodedString())
5049

51-
let encodedPayload = payload.data(using: .utf8)!.base64EncodedString()
52-
53-
let signature = try! signer.algorithm.sign("\(encodedHeader).\(encodedPayload)".data(using: .utf8)!)
50+
let encodedPayload = base64ToBase64URL(payload.data(using: .utf8)!.base64EncodedString())
51+
52+
var signingInput = "\(encodedHeader).\(encodedPayload)"
53+
let signature = try! signingInput.withUTF8 { try signingKey.signature(for: $0) }
5454

55-
return "\(base64ToBase64URL(encodedHeader)).\(base64ToBase64URL(encodedPayload)).\(base64ToBase64URL(Data(signature).base64EncodedString()))";
55+
return "\(signingInput).\(base64ToBase64URL(signature.rawRepresentation.base64EncodedString()))";
5656
}
5757

5858
private static func base64ToBase64URL(_ encodedString: String) -> String {

0 commit comments

Comments
 (0)