From 7f422516b1be5fae8dc5888185f4ddb7bea12dfb Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 17:21:23 -0500 Subject: [PATCH 01/23] Remove CommonCrypto directory as Swift 4.2 no longer requires this --- CommonCrypto/module.modulemap | 4 ---- CommonCrypto/shim.h | 1 - Package.swift | 4 +--- 3 files changed, 1 insertion(+), 8 deletions(-) delete mode 100644 CommonCrypto/module.modulemap delete mode 100644 CommonCrypto/shim.h diff --git a/CommonCrypto/module.modulemap b/CommonCrypto/module.modulemap deleted file mode 100644 index b70f7d6..0000000 --- a/CommonCrypto/module.modulemap +++ /dev/null @@ -1,4 +0,0 @@ -module CommonCrypto [system] { - header "shim.h" - export * -} diff --git a/CommonCrypto/shim.h b/CommonCrypto/shim.h deleted file mode 100644 index c332624..0000000 --- a/CommonCrypto/shim.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/Package.swift b/Package.swift index 5ba29b4..7b5d1f1 100644 --- a/Package.swift +++ b/Package.swift @@ -4,9 +4,7 @@ import PackageDescription #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) -let dependencies = [ - Package.Dependency.package(url: "https://github.com/kylef-archive/CommonCrypto.git", from: "1.0.0"), -] +let dependencies: [Package.Dependency] = [] let excludes = ["HMAC/HMACCryptoSwift.swift"] let targetDependencies: [Target.Dependency] = [] #else From 800490657dc81ea1c22a46bcd94226d3337214c3 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 17:59:06 -0500 Subject: [PATCH 02/23] Correct encoding unit tests to account for unordered Swift dictionaries --- Tests/JWTTests/JWTEncodeTests.swift | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/Tests/JWTTests/JWTEncodeTests.swift b/Tests/JWTTests/JWTEncodeTests.swift index 0dbb7b3..08882a2 100644 --- a/Tests/JWTTests/JWTEncodeTests.swift +++ b/Tests/JWTTests/JWTEncodeTests.swift @@ -23,14 +23,36 @@ class JWTEncodeTests: XCTestCase { let jwt = JWT.encode(algorithm) { builder in builder.issuer = "fuller.li" } - - XCTAssertEqual(jwt, "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmdWxsZXIubGkifQ.d7B7PAQcz1E6oNhrlxmHxHXHgg39_k7X7wWeahl8kSQ") + + let expected = [ + // { "alg": "HS256", "typ": "JWT" } + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmdWxsZXIubGkifQ.d7B7PAQcz1E6oNhrlxmHxHXHgg39_k7X7wWeahl8kSQ", + // { "typ": "JWT", "alg": "HS256" } + "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmdWxsZXIubGkifQ.x5Fdll-kZBImOPtpT1fZH_8hDW01Ax3pbZx_EiljoLk" + ] + + XCTAssertTrue(expected.contains(jwt)) } func testEncodingClaimsWithHeaders() { let algorithm = Algorithm.hs256("secret".data(using: .utf8)!) let jwt = JWT.encode(claims: ClaimSet(), algorithm: algorithm, headers: ["kid": "x"]) + + let expected = [ + // { "alg": "HS256", "typ": "JWT", "kid": "x" } + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IngifQ.e30.ddEotxYYMMdat5HPgYFQnkHRdPXsxPG71ooyhIUoqGA", + // { "alg": "HS256", "kid": "x", "typ": "JWT" } + "eyJhbGciOiJIUzI1NiIsImtpZCI6IngiLCJ0eXAiOiJKV1QifQ.e30.xiT6fWe5dWGeuq8zFb0je_14Maa_9mHbVPSyJhUIJ54", + // { "typ": "JWT", "alg": "HS256", "kid": "x" } + "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IngifQ.e30.5t6a61tpSXFo5QBHYCnKAz2mTHrW9kaQ9n_b7e-jWw0", + // { "typ": "JWT", "kid": "x", "alg": "HS256" } + "eyJ0eXAiOiJKV1QiLCJraWQiOiJ4IiwiYWxnIjoiSFMyNTYifQ.e30.DG5nmV2CVH6mV_iEm0xXZvL0DUJ22ek2xy6fNi_pGLc", + // { "kid": "x", "typ": "JWT", "alg": "HS256" } + "eyJraWQiOiJ4IiwidHlwIjoiSldUIiwiYWxnIjoiSFMyNTYifQ.e30.h5ZvlqECBIvu9uocR5_5uF3wnhga8vTruvXpzaHpRdA", + // { "kid": "x", "alg": "HS256", "typ": "JWT" } + "eyJraWQiOiJ4IiwiYWxnIjoiSFMyNTYiLCJ0eXAiOiJKV1QifQ.e30.5KqN7N5a7Cfbe2eKN41FJIfgMjcdSZ7Nt16xqlyOeMo" + ] - XCTAssertEqual(jwt, "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IngifQ.e30.ddEotxYYMMdat5HPgYFQnkHRdPXsxPG71ooyhIUoqGA") + XCTAssertTrue(expected.contains(jwt)) } } From 398c8254d3f0e75a067a3ac57526135545da4f45 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 18:27:09 -0500 Subject: [PATCH 03/23] Reindent to match existing style --- Tests/JWTTests/JWTEncodeTests.swift | 62 ++++++++++++++--------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/Tests/JWTTests/JWTEncodeTests.swift b/Tests/JWTTests/JWTEncodeTests.swift index 08882a2..9ff7f14 100644 --- a/Tests/JWTTests/JWTEncodeTests.swift +++ b/Tests/JWTTests/JWTEncodeTests.swift @@ -6,53 +6,53 @@ class JWTEncodeTests: XCTestCase { func testEncodingJWT() { let payload = ["name": "Kyle"] as Payload let jwt = JWT.encode(claims: payload, algorithm: .hs256("secret".data(using: .utf8)!)) - + let expected = [ // { "alg": "HS256", "typ": "JWT" } "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiS3lsZSJ9.zxm7xcp1eZtZhp4t-nlw09ATQnnFKIiSN83uG8u6cAg", - + // { "typ": "JWT", "alg": "HS256" } - "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiS3lsZSJ9.4tCpoxfyfjbUyLjm9_zu-r52Vxn6bFq9kp6Rt9xMs4A", + "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiS3lsZSJ9.4tCpoxfyfjbUyLjm9_zu-r52Vxn6bFq9kp6Rt9xMs4A" ] - + XCTAssertTrue(expected.contains(jwt)) } - + func testEncodingWithBuilder() { let algorithm = Algorithm.hs256("secret".data(using: .utf8)!) let jwt = JWT.encode(algorithm) { builder in builder.issuer = "fuller.li" } - - let expected = [ - // { "alg": "HS256", "typ": "JWT" } - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmdWxsZXIubGkifQ.d7B7PAQcz1E6oNhrlxmHxHXHgg39_k7X7wWeahl8kSQ", - // { "typ": "JWT", "alg": "HS256" } - "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmdWxsZXIubGkifQ.x5Fdll-kZBImOPtpT1fZH_8hDW01Ax3pbZx_EiljoLk" - ] - - XCTAssertTrue(expected.contains(jwt)) + + let expected = [ + // { "alg": "HS256", "typ": "JWT" } + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmdWxsZXIubGkifQ.d7B7PAQcz1E6oNhrlxmHxHXHgg39_k7X7wWeahl8kSQ", + // { "typ": "JWT", "alg": "HS256" } + "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJmdWxsZXIubGkifQ.x5Fdll-kZBImOPtpT1fZH_8hDW01Ax3pbZx_EiljoLk" + ] + + XCTAssertTrue(expected.contains(jwt)) } - + func testEncodingClaimsWithHeaders() { let algorithm = Algorithm.hs256("secret".data(using: .utf8)!) let jwt = JWT.encode(claims: ClaimSet(), algorithm: algorithm, headers: ["kid": "x"]) - - let expected = [ - // { "alg": "HS256", "typ": "JWT", "kid": "x" } - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IngifQ.e30.ddEotxYYMMdat5HPgYFQnkHRdPXsxPG71ooyhIUoqGA", - // { "alg": "HS256", "kid": "x", "typ": "JWT" } - "eyJhbGciOiJIUzI1NiIsImtpZCI6IngiLCJ0eXAiOiJKV1QifQ.e30.xiT6fWe5dWGeuq8zFb0je_14Maa_9mHbVPSyJhUIJ54", - // { "typ": "JWT", "alg": "HS256", "kid": "x" } - "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IngifQ.e30.5t6a61tpSXFo5QBHYCnKAz2mTHrW9kaQ9n_b7e-jWw0", - // { "typ": "JWT", "kid": "x", "alg": "HS256" } - "eyJ0eXAiOiJKV1QiLCJraWQiOiJ4IiwiYWxnIjoiSFMyNTYifQ.e30.DG5nmV2CVH6mV_iEm0xXZvL0DUJ22ek2xy6fNi_pGLc", - // { "kid": "x", "typ": "JWT", "alg": "HS256" } - "eyJraWQiOiJ4IiwidHlwIjoiSldUIiwiYWxnIjoiSFMyNTYifQ.e30.h5ZvlqECBIvu9uocR5_5uF3wnhga8vTruvXpzaHpRdA", - // { "kid": "x", "alg": "HS256", "typ": "JWT" } - "eyJraWQiOiJ4IiwiYWxnIjoiSFMyNTYiLCJ0eXAiOiJKV1QifQ.e30.5KqN7N5a7Cfbe2eKN41FJIfgMjcdSZ7Nt16xqlyOeMo" - ] - + + let expected = [ + // { "alg": "HS256", "typ": "JWT", "kid": "x" } + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IngifQ.e30.ddEotxYYMMdat5HPgYFQnkHRdPXsxPG71ooyhIUoqGA", + // { "alg": "HS256", "kid": "x", "typ": "JWT" } + "eyJhbGciOiJIUzI1NiIsImtpZCI6IngiLCJ0eXAiOiJKV1QifQ.e30.xiT6fWe5dWGeuq8zFb0je_14Maa_9mHbVPSyJhUIJ54", + // { "typ": "JWT", "alg": "HS256", "kid": "x" } + "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImtpZCI6IngifQ.e30.5t6a61tpSXFo5QBHYCnKAz2mTHrW9kaQ9n_b7e-jWw0", + // { "typ": "JWT", "kid": "x", "alg": "HS256" } + "eyJ0eXAiOiJKV1QiLCJraWQiOiJ4IiwiYWxnIjoiSFMyNTYifQ.e30.DG5nmV2CVH6mV_iEm0xXZvL0DUJ22ek2xy6fNi_pGLc", + // { "kid": "x", "typ": "JWT", "alg": "HS256" } + "eyJraWQiOiJ4IiwidHlwIjoiSldUIiwiYWxnIjoiSFMyNTYifQ.e30.h5ZvlqECBIvu9uocR5_5uF3wnhga8vTruvXpzaHpRdA", + // { "kid": "x", "alg": "HS256", "typ": "JWT" } + "eyJraWQiOiJ4IiwiYWxnIjoiSFMyNTYiLCJ0eXAiOiJKV1QifQ.e30.5KqN7N5a7Cfbe2eKN41FJIfgMjcdSZ7Nt16xqlyOeMo" + ] + XCTAssertTrue(expected.contains(jwt)) } } From ec735aa8e5516f698540c013b57b4628a9ab9ffc Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 18:30:37 -0500 Subject: [PATCH 04/23] Fix warning about deallocate(capacity:) deprecation --- Sources/JWA/HMAC/HMACCommonCrypto.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/JWA/HMAC/HMACCommonCrypto.swift b/Sources/JWA/HMAC/HMACCommonCrypto.swift index 299fd8a..6dffce0 100644 --- a/Sources/JWA/HMAC/HMACCommonCrypto.swift +++ b/Sources/JWA/HMAC/HMACCommonCrypto.swift @@ -5,7 +5,7 @@ import CommonCrypto extension HMACAlgorithm: SignAlgorithm, VerifyAlgorithm { public func sign(_ message: Data) -> Data { let context = UnsafeMutablePointer.allocate(capacity: 1) - defer { context.deallocate(capacity: 1) } + defer { context.deallocate() } key.withUnsafeBytes() { (buffer: UnsafePointer) in CCHmacInit(context, hash.commonCryptoAlgorithm, buffer, size_t(key.count)) From 264a622ddd48523a0827dc7932203a57902f41b2 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 18:44:21 -0500 Subject: [PATCH 05/23] Update many unit tests to stop using deprecated decode method --- Tests/JWTTests/JWTDecodeTests.swift | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Tests/JWTTests/JWTDecodeTests.swift b/Tests/JWTTests/JWTDecodeTests.swift index 24a17b3..3876301 100644 --- a/Tests/JWTTests/JWTDecodeTests.swift +++ b/Tests/JWTTests/JWTDecodeTests.swift @@ -18,7 +18,7 @@ class DecodeTests: XCTestCase { } func testFailsToDecodeInvalidStringWithoutThreeSegments() { - XCTAssertThrowsError(try decode("a.b", algorithm: .none), "Not enough segments") + XCTAssertThrowsError(try decode("a.b", algorithm: .none) as ClaimSet, "Not enough segments") } // MARK: Disable verify @@ -39,24 +39,24 @@ class DecodeTests: XCTestCase { func testIncorrectIssuerValidation() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmdWxsZXIubGkifQ.wOhJ9_6lx-3JGJPmJmtFCDI3kt7uMAMmhHIslti7ryI" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), issuer: "querykit.org")) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), issuer: "querykit.org") as ClaimSet) } func testMissingIssuerValidation() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.2_8pWJfyPup0YwOXK7g9Dn0cF1E3pdn299t4hSeJy5w" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), issuer: "fuller.li")) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), issuer: "fuller.li") as ClaimSet) } // MARK: Expiration claim func testExpiredClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0MjgxODg0OTF9.cy6b2szsNkKnHFnz2GjTatGjoHBTs8vBKnPGZgpp91I" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!))) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) as ClaimSet) } func testInvalidExpiaryClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOlsiMTQyODE4ODQ5MSJdfQ.OwF-wd3THjxrEGUhh6IdnNhxQZ7ydwJ3Z6J_dfl9MBs" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!))) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) as ClaimSet) } func testUnexpiredClaim() throws { @@ -99,7 +99,7 @@ class DecodeTests: XCTestCase { func testUnmetNotBeforeClaim() { // If this just started failing, hello 2024! let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE3MjgxODg0OTF9.Tzhu1tu-7BXcF5YEIFFE1Vmg4tEybUnaz58FR4PcblQ" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!))) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) as ClaimSet) } // MARK: Issued at claim @@ -121,7 +121,7 @@ class DecodeTests: XCTestCase { func testIssuedAtClaimInTheFuture() { // If this just started failing, hello 2024! let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MjgxODg0OTF9.owHiJyJmTcW1lBW5y_Rz3iBfSbcNiXlbZ2fY9qR7-aU" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!))) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) as ClaimSet) } func testInvalidIssuedAtClaim() { @@ -149,12 +149,12 @@ class DecodeTests: XCTestCase { func testMismatchAudienceClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJreWxlIn0.VEB_n06pTSLlTXPFkc46ARADJ9HXNUBUPo3VhL9RDe4" // kyle - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "maxine")) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "maxine") as ClaimSet) } func testMissingAudienceClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.2_8pWJfyPup0YwOXK7g9Dn0cF1E3pdn299t4hSeJy5w" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "kyle")) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "kyle") as ClaimSet) } // MARK: Signature verification @@ -168,7 +168,7 @@ class DecodeTests: XCTestCase { func testNoneFailsWithSecretAlgorithm() { let jwt = "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ0ZXN0IjoiaW5nIn0." - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!))) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) as ClaimSet) } func testMatchesAnyAlgorithm() { From 61e4cd73a19c957c52a407c6d99cd5ac378566de Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 19:01:34 -0500 Subject: [PATCH 06/23] Fix remaining unit tests --- Tests/JWTTests/JWTDecodeTests.swift | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Tests/JWTTests/JWTDecodeTests.swift b/Tests/JWTTests/JWTDecodeTests.swift index 3876301..cc4bf6d 100644 --- a/Tests/JWTTests/JWTDecodeTests.swift +++ b/Tests/JWTTests/JWTDecodeTests.swift @@ -1,6 +1,6 @@ import Foundation import XCTest -import JWT +@testable import JWT class DecodeTests: XCTestCase { func testDecodingValidJWTAsClaimSet() throws { @@ -93,7 +93,7 @@ class DecodeTests: XCTestCase { func testInvalidNotBeforeClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOlsxNDI4MTg5NzIwXX0.PUL1FQubzzJa4MNXe2D3d5t5cMaqFr3kYlzRUzly-C8" - assertDecodeError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)), error: "Not before claim (nbf) must be an integer") + assertDecodeError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) as ClaimSet, error: "Not before claim (nbf) must be an integer") } func testUnmetNotBeforeClaim() { @@ -134,7 +134,7 @@ class DecodeTests: XCTestCase { func testAudiencesClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibWF4aW5lIiwia2F0aWUiXX0.-PKvdNLCClrWG7CvesHP6PB0-vxu-_IZcsYhJxBy5JM" - assertSuccess(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "maxine")) { payload in + assertSuccess(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "maxine") as ClaimSet) { payload in XCTAssertEqual(payload.count, 1) XCTAssertEqual(payload["aud"] as! [String], ["maxine", "katie"]) } @@ -142,7 +142,7 @@ class DecodeTests: XCTestCase { func testAudienceClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJreWxlIn0.dpgH4JOwueReaBoanLSxsGTc7AjKUvo7_M1sAfy_xVE" - assertSuccess(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "kyle")) { payload in + assertSuccess(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "kyle") as ClaimSet) { payload in XCTAssertEqual(payload as! [String: String], ["aud": "kyle"]) } } @@ -161,7 +161,7 @@ class DecodeTests: XCTestCase { func testNoneAlgorithm() { let jwt = "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ0ZXN0IjoiaW5nIn0." - assertSuccess(try decode(jwt, algorithm: .none)) { payload in + assertSuccess(try decode(jwt, algorithm: .none) as ClaimSet) { payload in XCTAssertEqual(payload as! [String: String], ["test": "ing"]) } } @@ -173,36 +173,36 @@ class DecodeTests: XCTestCase { func testMatchesAnyAlgorithm() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.2_8pWJfyPup0YwOXK7g9Dn0cF1E3pdn299t4hSeJy5w." - assertFailure(try decode(jwt, algorithms: [.hs256("anothersecret".data(using: .utf8)!), .hs256("secret".data(using: .utf8)!)])) + assertFailure(try decode(jwt, algorithms: [.hs256("anothersecret".data(using: .utf8)!), .hs256("secret".data(using: .utf8)!)]) as ClaimSet) } func testHS384Algorithm() { let jwt = "eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.lddiriKLoo42qXduMhCTKZ5Lo3njXxOC92uXyvbLyYKzbq4CVVQOb3MpDwnI19u4" - assertSuccess(try decode(jwt, algorithm: .hs384("secret".data(using: .utf8)!))) { payload in + assertSuccess(try decode(jwt, algorithm: .hs384("secret".data(using: .utf8)!)) as ClaimSet) { payload in XCTAssertEqual(payload as! [String: String], ["some": "payload"]) } } func testHS512Algorithm() { let jwt = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.WTzLzFO079PduJiFIyzrOah54YaM8qoxH9fLMQoQhKtw3_fMGjImIOokijDkXVbyfBqhMo2GCNu4w9v7UXvnpA" - assertSuccess(try decode(jwt, algorithm: .hs512("secret".data(using: .utf8)!))) { payload in - XCTAssertEqual(payload as! [String: String], ["some": "payload"]) + assertSuccess(try decode(jwt, algorithm: .hs512("secret".data(using: .utf8)!)) as ClaimSet) { claims in + XCTAssertEqual(claims as! [String: String], ["some": "payload"]) } } } // MARK: Helpers -func assertSuccess(_ decoder: @autoclosure () throws -> Payload, closure: ((Payload) -> Void)? = nil) { +func assertSuccess(_ decoder: @autoclosure () throws -> ClaimSet, closure: (([String: Any]) -> Void)? = nil) { do { - let payload = try decoder() - closure?(payload) + let claims = try decoder() + closure?(claims.claims as [String: Any]) } catch { XCTFail("Failed to decode while expecting success. \(error)") } } -func assertFailure(_ decoder: @autoclosure () throws -> Payload, closure: ((InvalidToken) -> Void)? = nil) { +func assertFailure(_ decoder: @autoclosure () throws -> ClaimSet, closure: ((InvalidToken) -> Void)? = nil) { do { _ = try decoder() XCTFail("Decoding succeeded, expected a failure.") @@ -213,7 +213,7 @@ func assertFailure(_ decoder: @autoclosure () throws -> Payload, closure: ((Inva } } -func assertDecodeError(_ decoder: @autoclosure () throws -> Payload, error: String) { +func assertDecodeError(_ decoder: @autoclosure () throws -> ClaimSet, error: String) { assertFailure(try decoder()) { failure in switch failure { case .decodeError(let decodeError): From 14ddad4a6ca570757dbcf22fbd32451dfbe3f1d0 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 19:14:45 -0500 Subject: [PATCH 07/23] Bump CryptoSwift to 0.10.0 --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 7b5d1f1..7461b1a 100644 --- a/Package.swift +++ b/Package.swift @@ -9,7 +9,7 @@ let excludes = ["HMAC/HMACCryptoSwift.swift"] let targetDependencies: [Target.Dependency] = [] #else let dependencies = [ - Package.Dependency.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", from: "0.8.0"), + Package.Dependency.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", from: "0.10.0"), ] let excludes = ["HMAC/HMACCommonCrypto.swift"] let targetDependencies: [Target.Dependency] = ["CryptoSwift"] From 2ab9490a71f94ed8b1700cd42af478af186bc848 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 19:27:44 -0500 Subject: [PATCH 08/23] Correct misspelled method name for validateExpiry(leeway:), retain old method name as a deprecated method --- Sources/JWT/ClaimSet.swift | 9 +++++++-- Tests/JWTTests/ClaimSetTests.swift | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Sources/JWT/ClaimSet.swift b/Sources/JWT/ClaimSet.swift index 114c04e..08eeb9f 100644 --- a/Sources/JWT/ClaimSet.swift +++ b/Sources/JWT/ClaimSet.swift @@ -104,7 +104,7 @@ extension ClaimSet { try validateAudience(audience) } - try validateExpiary(leeway: leeway) + try validateExpiry(leeway: leeway) try validateNotBefore(leeway: leeway) try validateIssuedAt(leeway: leeway) } @@ -132,8 +132,13 @@ extension ClaimSet { throw InvalidToken.invalidIssuer } } - + + @available(*, deprecated, message: "This method's name is misspelled. Please instead use validateExpiry(leeway:).") public func validateExpiary(leeway: TimeInterval = 0) throws { + try validateExpiry(leeway: leeway) + } + + public func validateExpiry(leeway: TimeInterval = 0) throws { try validateDate(claims, key: "exp", comparison: .orderedAscending, leeway: (-1 * leeway), failure: .expiredSignature, decodeError: "Expiration time claim (exp) must be an integer") } diff --git a/Tests/JWTTests/ClaimSetTests.swift b/Tests/JWTTests/ClaimSetTests.swift index 594e648..aa8e8dd 100644 --- a/Tests/JWTTests/ClaimSetTests.swift +++ b/Tests/JWTTests/ClaimSetTests.swift @@ -7,7 +7,7 @@ class ValidationTests: XCTestCase { claims.expiration = Date().addingTimeInterval(-1) do { - try claims.validateExpiary() + try claims.validateExpiry() XCTFail("InvalidToken.expiredSignature error should have been thrown.") } catch InvalidToken.expiredSignature { // Correct error thrown @@ -21,7 +21,7 @@ class ValidationTests: XCTestCase { claims.expiration = Date().addingTimeInterval(-1) do { - try claims.validateExpiary(leeway: 2) + try claims.validateExpiry(leeway: 2) } catch { XCTFail("Unexpected error while validating exp claim that should be valid with leeway.") } From 312dce7d8007673275841b3f249f26210a3514b5 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 19:42:38 -0500 Subject: [PATCH 09/23] Remove deprecated encode/decode methods --- Sources/JWT/Decode.swift | 12 ------ Sources/JWT/Encode.swift | 11 ------ Tests/JWTTests/JWTDecodeTests.swift | 59 +++++++++++++---------------- 3 files changed, 26 insertions(+), 56 deletions(-) diff --git a/Sources/JWT/Decode.swift b/Sources/JWT/Decode.swift index 0e2b6d0..b6aa428 100644 --- a/Sources/JWT/Decode.swift +++ b/Sources/JWT/Decode.swift @@ -63,18 +63,6 @@ public func decode(_ jwt: String, algorithm: Algorithm, verify: Bool = true, aud return try decode(jwt, algorithms: [algorithm], verify: verify, audience: audience, issuer: issuer, leeway: leeway) } -/// Decode a JWT -@available(*, deprecated, message: "use decode that returns a ClaimSet instead") -public func decode(_ jwt: String, algorithms: [Algorithm], verify: Bool = true, audience: String? = nil, issuer: String? = nil) throws -> Payload { - return try decode(jwt, algorithms: algorithms, verify: verify, audience: audience, issuer: issuer).claims -} - -/// Decode a JWT -@available(*, deprecated, message: "use decode that returns a ClaimSet instead") -public func decode(_ jwt: String, algorithm: Algorithm, verify: Bool = true, audience: String? = nil, issuer: String? = nil) throws -> Payload { - return try decode(jwt, algorithms: [algorithm], verify: verify, audience: audience, issuer: issuer).claims -} - // MARK: Parsing a JWT func load(_ jwt: String) throws -> (header: JOSEHeader, payload: ClaimSet, signature: Data, signatureInput: String) { diff --git a/Sources/JWT/Encode.swift b/Sources/JWT/Encode.swift index 643c827..22d1960 100644 --- a/Sources/JWT/Encode.swift +++ b/Sources/JWT/Encode.swift @@ -38,14 +38,3 @@ public func encode(_ algorithm: Algorithm, closure: ((ClaimSetBuilder) -> Void)) closure(builder) return encode(claims: builder.claims, algorithm: algorithm) } - - -/*** Encode a payload - - parameter payload: The payload to sign - - parameter algorithm: The algorithm to sign the payload with - - returns: The JSON web token as a String - */ -@available(*, deprecated, message: "use encode(claims: algorithm:) instead") -public func encode(_ payload: Payload, algorithm: Algorithm) -> String { - return encode(claims: ClaimSet(claims: payload), algorithm: algorithm) -} diff --git a/Tests/JWTTests/JWTDecodeTests.swift b/Tests/JWTTests/JWTDecodeTests.swift index cc4bf6d..313b000 100644 --- a/Tests/JWTTests/JWTDecodeTests.swift +++ b/Tests/JWTTests/JWTDecodeTests.swift @@ -3,29 +3,22 @@ import XCTest @testable import JWT class DecodeTests: XCTestCase { - func testDecodingValidJWTAsClaimSet() throws { - let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiS3lsZSJ9.zxm7xcp1eZtZhp4t-nlw09ATQnnFKIiSN83uG8u6cAg" - - let claims: ClaimSet = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) - XCTAssertEqual(claims["name"] as? String, "Kyle") - } - func testDecodingValidJWT() throws { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiS3lsZSJ9.zxm7xcp1eZtZhp4t-nlw09ATQnnFKIiSN83uG8u6cAg" - let claims: ClaimSet = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) + let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) XCTAssertEqual(claims["name"] as? String, "Kyle") } func testFailsToDecodeInvalidStringWithoutThreeSegments() { - XCTAssertThrowsError(try decode("a.b", algorithm: .none) as ClaimSet, "Not enough segments") + XCTAssertThrowsError(try decode("a.b", algorithm: .none), "Not enough segments") } // MARK: Disable verify func testDisablingVerify() throws { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.2_8pWJfyPup0YwOXK7g9Dn0cF1E3pdn299t4hSeJy5w" - _ = try decode(jwt, algorithm: .none, verify: false, issuer: "fuller.li") as ClaimSet + _ = try decode(jwt, algorithm: .none, verify: false, issuer: "fuller.li") } // MARK: Issuer claim @@ -33,37 +26,37 @@ class DecodeTests: XCTestCase { func testSuccessfulIssuerValidation() throws { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmdWxsZXIubGkifQ.d7B7PAQcz1E6oNhrlxmHxHXHgg39_k7X7wWeahl8kSQ" - let claims: ClaimSet = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) + let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) XCTAssertEqual(claims.issuer, "fuller.li") } func testIncorrectIssuerValidation() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmdWxsZXIubGkifQ.wOhJ9_6lx-3JGJPmJmtFCDI3kt7uMAMmhHIslti7ryI" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), issuer: "querykit.org") as ClaimSet) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), issuer: "querykit.org")) } func testMissingIssuerValidation() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.2_8pWJfyPup0YwOXK7g9Dn0cF1E3pdn299t4hSeJy5w" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), issuer: "fuller.li") as ClaimSet) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), issuer: "fuller.li")) } // MARK: Expiration claim func testExpiredClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0MjgxODg0OTF9.cy6b2szsNkKnHFnz2GjTatGjoHBTs8vBKnPGZgpp91I" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) as ClaimSet) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!))) } func testInvalidExpiaryClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOlsiMTQyODE4ODQ5MSJdfQ.OwF-wd3THjxrEGUhh6IdnNhxQZ7ydwJ3Z6J_dfl9MBs" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) as ClaimSet) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!))) } func testUnexpiredClaim() throws { // If this just started failing, hello 2024! let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MjgxODg0OTF9.EW7k-8Mvnv0GpvOKJalFRLoCB3a3xGG3i7hAZZXNAz0" - let claims: ClaimSet = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) + let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) XCTAssertEqual(claims.expiration?.timeIntervalSince1970, 1728188491) } @@ -71,7 +64,7 @@ class DecodeTests: XCTestCase { // If this just started failing, hello 2024! let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNzI4MTg4NDkxIn0.y4w7lNLrfRRPzuNUfM-ZvPkoOtrTU_d8ZVYasLdZGpk" - let claims: ClaimSet = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) + let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) XCTAssertEqual(claims.expiration?.timeIntervalSince1970, 1728188491) } @@ -80,26 +73,26 @@ class DecodeTests: XCTestCase { func testNotBeforeClaim() throws { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0MjgxODk3MjB9.jFT0nXAJvEwyG6R7CMJlzNJb7FtZGv30QRZpYam5cvs" - let claims: ClaimSet = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) + let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) XCTAssertEqual(claims.notBefore?.timeIntervalSince1970, 1428189720) } func testNotBeforeClaimString() throws { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOiIxNDI4MTg5NzIwIn0.qZsj36irdmIAeXv6YazWDSFbpuxHtEh4Deof5YTpnVI" - let claims: ClaimSet = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) + let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) XCTAssertEqual(claims.notBefore?.timeIntervalSince1970, 1428189720) } func testInvalidNotBeforeClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOlsxNDI4MTg5NzIwXX0.PUL1FQubzzJa4MNXe2D3d5t5cMaqFr3kYlzRUzly-C8" - assertDecodeError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) as ClaimSet, error: "Not before claim (nbf) must be an integer") + assertDecodeError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)), error: "Not before claim (nbf) must be an integer") } func testUnmetNotBeforeClaim() { // If this just started failing, hello 2024! let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE3MjgxODg0OTF9.Tzhu1tu-7BXcF5YEIFFE1Vmg4tEybUnaz58FR4PcblQ" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) as ClaimSet) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!))) } // MARK: Issued at claim @@ -107,21 +100,21 @@ class DecodeTests: XCTestCase { func testIssuedAtClaimInThePast() throws { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MjgxODk3MjB9.I_5qjRcCUZVQdABLwG82CSuu2relSdIyJOyvXWUAJh4" - let claims: ClaimSet = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) + let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) XCTAssertEqual(claims.issuedAt?.timeIntervalSince1970, 1428189720) } func testIssuedAtClaimInThePastString() throws { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOiIxNDI4MTg5NzIwIn0.M8veWtsY52oBwi7LRKzvNnzhjK0QBS8Su1r0atlns2k" - let claims: ClaimSet = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) + let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) XCTAssertEqual(claims.issuedAt?.timeIntervalSince1970, 1428189720) } func testIssuedAtClaimInTheFuture() { // If this just started failing, hello 2024! let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MjgxODg0OTF9.owHiJyJmTcW1lBW5y_Rz3iBfSbcNiXlbZ2fY9qR7-aU" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) as ClaimSet) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!))) } func testInvalidIssuedAtClaim() { @@ -134,7 +127,7 @@ class DecodeTests: XCTestCase { func testAudiencesClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsibWF4aW5lIiwia2F0aWUiXX0.-PKvdNLCClrWG7CvesHP6PB0-vxu-_IZcsYhJxBy5JM" - assertSuccess(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "maxine") as ClaimSet) { payload in + assertSuccess(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "maxine")) { payload in XCTAssertEqual(payload.count, 1) XCTAssertEqual(payload["aud"] as! [String], ["maxine", "katie"]) } @@ -142,50 +135,50 @@ class DecodeTests: XCTestCase { func testAudienceClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJreWxlIn0.dpgH4JOwueReaBoanLSxsGTc7AjKUvo7_M1sAfy_xVE" - assertSuccess(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "kyle") as ClaimSet) { payload in + assertSuccess(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "kyle")) { payload in XCTAssertEqual(payload as! [String: String], ["aud": "kyle"]) } } func testMismatchAudienceClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJreWxlIn0.VEB_n06pTSLlTXPFkc46ARADJ9HXNUBUPo3VhL9RDe4" // kyle - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "maxine") as ClaimSet) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "maxine")) } func testMissingAudienceClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.2_8pWJfyPup0YwOXK7g9Dn0cF1E3pdn299t4hSeJy5w" - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "kyle") as ClaimSet) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!), audience: "kyle")) } // MARK: Signature verification func testNoneAlgorithm() { let jwt = "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ0ZXN0IjoiaW5nIn0." - assertSuccess(try decode(jwt, algorithm: .none) as ClaimSet) { payload in + assertSuccess(try decode(jwt, algorithm: .none)) { payload in XCTAssertEqual(payload as! [String: String], ["test": "ing"]) } } func testNoneFailsWithSecretAlgorithm() { let jwt = "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ0ZXN0IjoiaW5nIn0." - XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) as ClaimSet) + XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!))) } func testMatchesAnyAlgorithm() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.2_8pWJfyPup0YwOXK7g9Dn0cF1E3pdn299t4hSeJy5w." - assertFailure(try decode(jwt, algorithms: [.hs256("anothersecret".data(using: .utf8)!), .hs256("secret".data(using: .utf8)!)]) as ClaimSet) + assertFailure(try decode(jwt, algorithms: [.hs256("anothersecret".data(using: .utf8)!), .hs256("secret".data(using: .utf8)!)])) } func testHS384Algorithm() { let jwt = "eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.lddiriKLoo42qXduMhCTKZ5Lo3njXxOC92uXyvbLyYKzbq4CVVQOb3MpDwnI19u4" - assertSuccess(try decode(jwt, algorithm: .hs384("secret".data(using: .utf8)!)) as ClaimSet) { payload in + assertSuccess(try decode(jwt, algorithm: .hs384("secret".data(using: .utf8)!))) { payload in XCTAssertEqual(payload as! [String: String], ["some": "payload"]) } } func testHS512Algorithm() { let jwt = "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.WTzLzFO079PduJiFIyzrOah54YaM8qoxH9fLMQoQhKtw3_fMGjImIOokijDkXVbyfBqhMo2GCNu4w9v7UXvnpA" - assertSuccess(try decode(jwt, algorithm: .hs512("secret".data(using: .utf8)!)) as ClaimSet) { claims in + assertSuccess(try decode(jwt, algorithm: .hs512("secret".data(using: .utf8)!))) { claims in XCTAssertEqual(claims as! [String: String], ["some": "payload"]) } } From 30677dfbb1c473b87ea55bc3775fed1fb6b3f5a7 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 20:14:48 -0500 Subject: [PATCH 10/23] Undo removal of CommonCrypto; will try to find compatible solution between Swift 4.0 and 4.2 --- CommonCrypto/module.modulemap | 4 ++++ CommonCrypto/shim.h | 1 + Package.swift | 4 +++- 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 CommonCrypto/module.modulemap create mode 100644 CommonCrypto/shim.h diff --git a/CommonCrypto/module.modulemap b/CommonCrypto/module.modulemap new file mode 100644 index 0000000..b70f7d6 --- /dev/null +++ b/CommonCrypto/module.modulemap @@ -0,0 +1,4 @@ +module CommonCrypto [system] { + header "shim.h" + export * +} diff --git a/CommonCrypto/shim.h b/CommonCrypto/shim.h new file mode 100644 index 0000000..c332624 --- /dev/null +++ b/CommonCrypto/shim.h @@ -0,0 +1 @@ +#include diff --git a/Package.swift b/Package.swift index 7461b1a..36bc2f2 100644 --- a/Package.swift +++ b/Package.swift @@ -4,7 +4,9 @@ import PackageDescription #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) -let dependencies: [Package.Dependency] = [] +let dependencies = [ + Package.Dependency.package(url: "https://github.com/kylef-archive/CommonCrypto.git", from: "1.0.0"), +] let excludes = ["HMAC/HMACCryptoSwift.swift"] let targetDependencies: [Target.Dependency] = [] #else From 662871d1b9a4c4ba2642ac6f08237ecfed4b5dd0 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 21:33:46 -0500 Subject: [PATCH 11/23] see if stripping down the Travis config gets builds working on macOS at least --- .travis.yml | 86 ++++++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/.travis.yml b/.travis.yml index 225f25f..701dcfa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,44 +1,48 @@ -os: - - osx - - linux -osx_image: xcode9 -language: generic -sudo: required -dist: trusty -env: - global: - - SWIFT_VERSION=4.0 - matrix: - - SWIFTPM_BUILD=true - - SWIFTPM_TEST=true - - XCODE_TEST_SDK=macosx - - XCODE_BUILD_SDK=iphonesimulator - - XCODE_BUILD_SDK=appletvsimulator - - XCODE_BUILD_SDK=watchsimulator +os: osx +osx_image: xcode9.4 +script: swift build -matrix: - exclude: - # No need to build and test on macOS - - os: osx - env: SWIFTPM_BUILD=true - # LinuxMain.swift is out of sync - - os: linux - env: SWIFTPM_TEST=true - - os: linux - env: XCODE_TEST_SDK=macosx - - os: linux - env: XCODE_BUILD_SDK=iphonesimulator - - os: linux - env: XCODE_BUILD_SDK=appletvsimulator - - os: linux - env: XCODE_BUILD_SDK=watchsimulator +# os: +# - osx +# - linux +# osx_image: xcode9 +# language: generic +# sudo: required +# dist: trusty +# env: +# global: +# - SWIFT_VERSION=4.0 +# matrix: +# - SWIFTPM_BUILD=true +# - SWIFTPM_TEST=true +# - XCODE_TEST_SDK=macosx +# - XCODE_BUILD_SDK=iphonesimulator +# - XCODE_BUILD_SDK=appletvsimulator +# - XCODE_BUILD_SDK=watchsimulator -install: - - eval "$(curl -sL https://swiftenv.fuller.li/install.sh)" +# matrix: +# exclude: +# # No need to build and test on macOS +# - os: osx +# env: SWIFTPM_BUILD=true +# # LinuxMain.swift is out of sync +# - os: linux +# env: SWIFTPM_TEST=true +# - os: linux +# env: XCODE_TEST_SDK=macosx +# - os: linux +# env: XCODE_BUILD_SDK=iphonesimulator +# - os: linux +# env: XCODE_BUILD_SDK=appletvsimulator +# - os: linux +# env: XCODE_BUILD_SDK=watchsimulator -script: -- if [ -n "$SWIFTPM_BUILD" ]; then swift build; fi -- if [ -n "$SWIFTPM_TEST" ]; then swift test; fi -- if [ -n "$XCODE_BUILD_SDK" ] || [ -n "$XCODE_TEST_SDK" ]; then swift package generate-xcodeproj; fi -- if [ -n "$XCODE_BUILD_SDK" ]; then xcodebuild -project JWT.xcodeproj -scheme JWT-Package build -sdk $XCODE_BUILD_SDK; fi -- if [ -n "$XCODE_TEST_SDK" ]; then xcodebuild -project JWT.xcodeproj -scheme JWT-Package test -sdk $XCODE_TEST_SDK; fi +# install: +# - eval "$(curl -sL https://swiftenv.fuller.li/install.sh)" + +# script: +# - if [ -n "$SWIFTPM_BUILD" ]; then swift build; fi +# - if [ -n "$SWIFTPM_TEST" ]; then swift test; fi +# - if [ -n "$XCODE_BUILD_SDK" ] || [ -n "$XCODE_TEST_SDK" ]; then swift package generate-xcodeproj; fi +# - if [ -n "$XCODE_BUILD_SDK" ]; then xcodebuild -project JWT.xcodeproj -scheme JWT-Package build -sdk $XCODE_BUILD_SDK; fi +# - if [ -n "$XCODE_TEST_SDK" ]; then xcodebuild -project JWT.xcodeproj -scheme JWT-Package test -sdk $XCODE_TEST_SDK; fi From 47a8b7f6f8c0523202f9d468eab1b0dd69b26fdf Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 21:44:27 -0500 Subject: [PATCH 12/23] try adding Ubuntu back into Travis builds --- .travis.yml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 701dcfa..a50c6e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,20 @@ -os: osx +os: + - osx + - linux osx_image: xcode9.4 script: swift build +language: generic +sudo: required +dist: xenial + +env: + global: + - SWIFT_VERSION=4.1.2 + +install: + - eval "$(curl -sL https://swiftenv.fuller.li/install.sh)" +script: + - swift build # os: # - osx @@ -10,8 +24,6 @@ script: swift build # sudo: required # dist: trusty # env: -# global: -# - SWIFT_VERSION=4.0 # matrix: # - SWIFTPM_BUILD=true # - SWIFTPM_TEST=true From 11351084b4cd4eb7a9558b5c109ab5be361fccb5 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 22:20:33 -0500 Subject: [PATCH 13/23] =?UTF-8?q?Travis=20doesn=E2=80=99t=20support=20Xeni?= =?UTF-8?q?al,=20back=20to=20Trusty?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a50c6e2..8d4abdd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ osx_image: xcode9.4 script: swift build language: generic sudo: required -dist: xenial +dist: trusty env: global: From a50823d3c9c85a6f70fd162e7043610ca098a037 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 22:43:44 -0500 Subject: [PATCH 14/23] getting closer to original config --- .travis.yml | 69 +++++++++++++++++++++-------------------------------- 1 file changed, 27 insertions(+), 42 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8d4abdd..6a5dca8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,7 @@ os: - - osx - - linux + - osx + - linux osx_image: xcode9.4 -script: swift build language: generic sudo: required dist: trusty @@ -10,51 +9,37 @@ dist: trusty env: global: - SWIFT_VERSION=4.1.2 + matrix: + - SWIFTPM_BUILD=true + - SWIFTPM_TEST=true + - XCODE_TEST_SDK=macosx + - XCODE_BUILD_SDK=iphonesimulator + - XCODE_BUILD_SDK=appletvsimulator + - XCODE_BUILD_SDK=watchsimulator -install: - - eval "$(curl -sL https://swiftenv.fuller.li/install.sh)" -script: - - swift build - -# os: -# - osx -# - linux -# osx_image: xcode9 -# language: generic -# sudo: required -# dist: trusty -# env: -# matrix: -# - SWIFTPM_BUILD=true -# - SWIFTPM_TEST=true -# - XCODE_TEST_SDK=macosx -# - XCODE_BUILD_SDK=iphonesimulator -# - XCODE_BUILD_SDK=appletvsimulator -# - XCODE_BUILD_SDK=watchsimulator - -# matrix: -# exclude: +matrix: + exclude: # # No need to build and test on macOS # - os: osx # env: SWIFTPM_BUILD=true # # LinuxMain.swift is out of sync # - os: linux # env: SWIFTPM_TEST=true -# - os: linux -# env: XCODE_TEST_SDK=macosx -# - os: linux -# env: XCODE_BUILD_SDK=iphonesimulator -# - os: linux -# env: XCODE_BUILD_SDK=appletvsimulator -# - os: linux -# env: XCODE_BUILD_SDK=watchsimulator + - os: linux + env: XCODE_TEST_SDK=macosx + - os: linux + env: XCODE_BUILD_SDK=iphonesimulator + - os: linux + env: XCODE_BUILD_SDK=appletvsimulator + - os: linux + env: XCODE_BUILD_SDK=watchsimulator -# install: -# - eval "$(curl -sL https://swiftenv.fuller.li/install.sh)" +install: + - eval "$(curl -sL https://swiftenv.fuller.li/install.sh)" -# script: -# - if [ -n "$SWIFTPM_BUILD" ]; then swift build; fi -# - if [ -n "$SWIFTPM_TEST" ]; then swift test; fi -# - if [ -n "$XCODE_BUILD_SDK" ] || [ -n "$XCODE_TEST_SDK" ]; then swift package generate-xcodeproj; fi -# - if [ -n "$XCODE_BUILD_SDK" ]; then xcodebuild -project JWT.xcodeproj -scheme JWT-Package build -sdk $XCODE_BUILD_SDK; fi -# - if [ -n "$XCODE_TEST_SDK" ]; then xcodebuild -project JWT.xcodeproj -scheme JWT-Package test -sdk $XCODE_TEST_SDK; fi +script: +- if [ -n "$SWIFTPM_BUILD" ]; then swift build; fi +- if [ -n "$SWIFTPM_TEST" ]; then swift test; fi +- if [ -n "$XCODE_BUILD_SDK" ] || [ -n "$XCODE_TEST_SDK" ]; then swift package generate-xcodeproj; fi +- if [ -n "$XCODE_BUILD_SDK" ]; then xcodebuild -project JWT.xcodeproj -scheme JWT-Package build -sdk $XCODE_BUILD_SDK; fi +- if [ -n "$XCODE_TEST_SDK" ]; then xcodebuild -project JWT.xcodeproj -scheme JWT-Package test -sdk $XCODE_TEST_SDK; fi From 44d6d594da50911cddf3792e004b48d11c5f4908 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 23:03:52 -0500 Subject: [PATCH 15/23] Sync up LinuxMain.swift (hopefully) --- Tests/LinuxMain.swift | 89 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 9 deletions(-) diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index 8488183..b12a121 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -1,18 +1,51 @@ import XCTest +@testable import JWATests @testable import JWTTests +extension HMACAlgorithmTests { + static var allTests: [(String, (HMACAlgorithmTests) -> () throws -> Void)] { + return [ + ("testSHA256Name", testSHA256Name), + ("testSHA384Name", testSHA384Name), + ("testSHA512Name", testSHA512Name), + ("testSHA256Sign", testSHA256Sign), + ("testSHA384Sign", testSHA384Sign), + ("testSHA512Sign", testSHA512Sign), + ("testSHA256Verify", testSHA256Verify), + ("testSHA384Verify", testSHA384Verify), + ("testSHA512Verify", testSHA512Verify) + ] + } +} -extension EncodeTests { - static var allTests: [(String, (EncodeTests) -> (Void) throws -> Void)] { +extension NoneAlgorithmTests { + static var allTests: [(String, (NoneAlgorithmTests) -> () throws -> Void)] { return [ - ("testEncodingJWT", testEncodingJWT), - ("testEncodingWithBuilder", testEncodingWithBuilder), + ("testName", testName), + ("testSign", testSign), + ("testVerify", testVerify) ] } } +extension CompactJSONDecoderTests { + static var allTests: [(String, (CompactJSONDecoderTests) -> () throws -> Void)] { + return [ + ("testDecoder", testDecoder) + ] + } +} + +extension CompactJSONEncoderTests { + static var allTests: [(String, (CompactJSONEncoderTests) -> () throws -> Void)] { + return [ + ("testEncode", testEncode) + ] + } +} + extension DecodeTests { - static var allTests: [(String, (DecodeTests) -> (Void) throws -> Void)] { + static var allTests: [(String, (DecodeTests) -> () throws -> Void)] { return [ ("testDecodingValidJWT", testDecodingValidJWT), ("testFailsToDecodeInvalidStringWithoutThreeSegments", testFailsToDecodeInvalidStringWithoutThreeSegments), @@ -40,26 +73,64 @@ extension DecodeTests { ("testNoneFailsWithSecretAlgorithm", testNoneFailsWithSecretAlgorithm), ("testMatchesAnyAlgorithm", testMatchesAnyAlgorithm), ("testHS384Algorithm", testHS384Algorithm), - ("testHS512Algorithm", testHS512Algorithm), + ("testHS512Algorithm", testHS512Algorithm) ] } } +extension IntegrationTests { + static var allTests: [(String, (IntegrationTests) -> () throws -> Void)] { + return [ + ("testVerificationFailureWithoutLeeway", testVerificationFailureWithoutLeeway), + ("testVerificationSuccessWithLeeway", testVerificationSuccessWithLeeway) + ] + } +} + +extension JWTEncodeTests { + static var allTests: [(String, (JWTEncodeTests) -> () throws -> Void)] { + return [ + ("testEncodingJWT", testEncodingJWT), + ("testEncodingWithBuilder", testEncodingWithBuilder), + ("testEncodingClaimsWithHeaders", testEncodingClaimsWithHeaders) + ] + } +} + extension PayloadTests { - static var allTests: [(String, (PayloadTests) -> (Void) throws -> Void)] { + static var allTests: [(String, (PayloadTests) -> () throws -> Void)] { return [ ("testIssuer", testIssuer), ("testAudience", testAudience), ("testExpiration", testExpiration), ("testNotBefore", testNotBefore), ("testIssuedAt", testIssuedAt), - ("testCustomAttributes", testCustomAttributes), + ("testCustomAttributes", testCustomAttributes) ] } } +extension ValidationTests { + static var allTests: [(String, (ValidationTests) -> () throws -> Void)] { + return [ + ("testClaimJustExpiredWithoutLeeway", testClaimJustExpiredWithoutLeeway), + ("testClaimJustNotExpiredWithoutLeeway", testClaimJustNotExpiredWithoutLeeway), + ("testNotBeforeIsImmatureSignatureWithoutLeeway", testNotBeforeIsImmatureSignatureWithoutLeeway), + ("testNotBeforeIsValidWithLeeway", testNotBeforeIsValidWithLeeway), + ("testIssuedAtIsInFutureWithoutLeeway", testIssuedAtIsInFutureWithoutLeeway), + ("testIssuedAtIsValidWithLeeway", testIssuedAtIsValidWithLeeway) + ] + } +} + XCTMain([ - testCase(EncodeTests.allTests), + testCase(HMACAlgorithmTests.allTests), + testCase(NoneAlgorithmTests.allTests), + testCase(CompactJSONDecoder.allTests), + testCase(CompactJSONEncoder.allTests), testCase(DecodeTests.allTests), + testCase(IntegrationTests.allTests), + testCase(JWTEncodeTests.allTests), testCase(PayloadTests.allTests), + testCase(ValidationTests.allTests) ]) From 32b7b6e5db2edd889bd9e3a6c2c2d15f1d42390b Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 23 Jul 2018 23:15:30 -0500 Subject: [PATCH 16/23] Fix LinuxMain.swift typo --- Tests/LinuxMain.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index b12a121..3f3b768 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -126,8 +126,8 @@ extension ValidationTests { XCTMain([ testCase(HMACAlgorithmTests.allTests), testCase(NoneAlgorithmTests.allTests), - testCase(CompactJSONDecoder.allTests), - testCase(CompactJSONEncoder.allTests), + testCase(CompactJSONDecoderTests.allTests), + testCase(CompactJSONEncoderTests.allTests), testCase(DecodeTests.allTests), testCase(IntegrationTests.allTests), testCase(JWTEncodeTests.allTests), From 65dfb1a9f61a76f55bb9c23ff272ed1443a954dc Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Tue, 24 Jul 2018 12:49:03 -0500 Subject: [PATCH 17/23] See if converting TimeInterval/Double to Int might help Travis builds pass --- Tests/JWTTests/JWTDecodeTests.swift | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/Tests/JWTTests/JWTDecodeTests.swift b/Tests/JWTTests/JWTDecodeTests.swift index 313b000..adca9ab 100644 --- a/Tests/JWTTests/JWTDecodeTests.swift +++ b/Tests/JWTTests/JWTDecodeTests.swift @@ -57,7 +57,12 @@ class DecodeTests: XCTestCase { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MjgxODg0OTF9.EW7k-8Mvnv0GpvOKJalFRLoCB3a3xGG3i7hAZZXNAz0" let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) - XCTAssertEqual(claims.expiration?.timeIntervalSince1970, 1728188491) + + if let expirationClaim = claims.expiration?.timeIntervalSince1970 { + XCTAssertEqual(Int(expirationClaim), 1728188491) + } else { + XCTFail() + } } func testUnexpiredClaimString() throws { @@ -74,7 +79,11 @@ class DecodeTests: XCTestCase { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0MjgxODk3MjB9.jFT0nXAJvEwyG6R7CMJlzNJb7FtZGv30QRZpYam5cvs" let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) - XCTAssertEqual(claims.notBefore?.timeIntervalSince1970, 1428189720) + if let notBeforeClaim = claims.notBefore?.timeIntervalSince1970 { + XCTAssertEqual(Int(notBeforeClaim), 1428189720) + } else { + XCTFail() + } } func testNotBeforeClaimString() throws { @@ -101,7 +110,11 @@ class DecodeTests: XCTestCase { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MjgxODk3MjB9.I_5qjRcCUZVQdABLwG82CSuu2relSdIyJOyvXWUAJh4" let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) - XCTAssertEqual(claims.issuedAt?.timeIntervalSince1970, 1428189720) + if let issuedAtClaim = claims.issuedAt?.timeIntervalSince1970 { + XCTAssertEqual(Int(issuedAtClaim), 1428189720) + } else { + XCTFail() + } } func testIssuedAtClaimInThePastString() throws { From f2bbd1d8dbf2e53234f9d632c5a8808aaaf9b0db Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Tue, 24 Jul 2018 12:59:51 -0500 Subject: [PATCH 18/23] See if explicitly handling Ints in parsing JWT times fixes Ubuntu builds --- Sources/JWT/ClaimSet.swift | 5 +++++ Tests/JWTTests/JWTDecodeTests.swift | 19 +++---------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/Sources/JWT/ClaimSet.swift b/Sources/JWT/ClaimSet.swift index 08eeb9f..4b253be 100644 --- a/Sources/JWT/ClaimSet.swift +++ b/Sources/JWT/ClaimSet.swift @@ -6,6 +6,11 @@ func parseTimeInterval(_ value: Any?) -> Date? { if let string = value as? String, let interval = TimeInterval(string) { return Date(timeIntervalSince1970: interval) } + + if let interval = value as? Int { + let double = Double(interval) + return Date(timeIntervalSince1970: double) + } if let interval = value as? TimeInterval { return Date(timeIntervalSince1970: interval) diff --git a/Tests/JWTTests/JWTDecodeTests.swift b/Tests/JWTTests/JWTDecodeTests.swift index adca9ab..7cfe348 100644 --- a/Tests/JWTTests/JWTDecodeTests.swift +++ b/Tests/JWTTests/JWTDecodeTests.swift @@ -57,12 +57,7 @@ class DecodeTests: XCTestCase { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MjgxODg0OTF9.EW7k-8Mvnv0GpvOKJalFRLoCB3a3xGG3i7hAZZXNAz0" let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) - - if let expirationClaim = claims.expiration?.timeIntervalSince1970 { - XCTAssertEqual(Int(expirationClaim), 1728188491) - } else { - XCTFail() - } + XCTAssertEqual(claims.expiration?.timeIntervalSince1970, 1728188491) } func testUnexpiredClaimString() throws { @@ -79,11 +74,7 @@ class DecodeTests: XCTestCase { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0MjgxODk3MjB9.jFT0nXAJvEwyG6R7CMJlzNJb7FtZGv30QRZpYam5cvs" let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) - if let notBeforeClaim = claims.notBefore?.timeIntervalSince1970 { - XCTAssertEqual(Int(notBeforeClaim), 1428189720) - } else { - XCTFail() - } + XCTAssertEqual(claims.notBefore?.timeIntervalSince1970, 1428189720) } func testNotBeforeClaimString() throws { @@ -110,11 +101,7 @@ class DecodeTests: XCTestCase { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MjgxODk3MjB9.I_5qjRcCUZVQdABLwG82CSuu2relSdIyJOyvXWUAJh4" let claims = try JWT.decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!)) - if let issuedAtClaim = claims.issuedAt?.timeIntervalSince1970 { - XCTAssertEqual(Int(issuedAtClaim), 1428189720) - } else { - XCTFail() - } + XCTAssertEqual(claims.issuedAt?.timeIntervalSince1970, 1428189720) } func testIssuedAtClaimInThePastString() throws { From 4b83583095569f47751f97832f990933c113d7f8 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Tue, 24 Jul 2018 16:16:47 -0500 Subject: [PATCH 19/23] simplify Travis config to use swift test only swift test builds JWT and JWA, so compilation errors for those will otherwise just result in two jobs that fail for the same reason; one can still check the Travis output to see where exactly the failure is occurring --- .travis.yml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6a5dca8..2c00dc4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,9 @@ dist: trusty env: global: + - SWIFT_VERSION=4.0 - SWIFT_VERSION=4.1.2 matrix: - - SWIFTPM_BUILD=true - SWIFTPM_TEST=true - XCODE_TEST_SDK=macosx - XCODE_BUILD_SDK=iphonesimulator @@ -19,12 +19,6 @@ env: matrix: exclude: -# # No need to build and test on macOS -# - os: osx -# env: SWIFTPM_BUILD=true -# # LinuxMain.swift is out of sync -# - os: linux -# env: SWIFTPM_TEST=true - os: linux env: XCODE_TEST_SDK=macosx - os: linux @@ -38,7 +32,6 @@ install: - eval "$(curl -sL https://swiftenv.fuller.li/install.sh)" script: -- if [ -n "$SWIFTPM_BUILD" ]; then swift build; fi - if [ -n "$SWIFTPM_TEST" ]; then swift test; fi - if [ -n "$XCODE_BUILD_SDK" ] || [ -n "$XCODE_TEST_SDK" ]; then swift package generate-xcodeproj; fi - if [ -n "$XCODE_BUILD_SDK" ]; then xcodebuild -project JWT.xcodeproj -scheme JWT-Package build -sdk $XCODE_BUILD_SDK; fi From 708c7a75e38d689c27e6fec1b6bc18a251455559 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Tue, 24 Jul 2018 16:48:23 -0500 Subject: [PATCH 20/23] Correct misspelled unit test method name --- Tests/JWTTests/JWTDecodeTests.swift | 2 +- Tests/LinuxMain.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/JWTTests/JWTDecodeTests.swift b/Tests/JWTTests/JWTDecodeTests.swift index 7cfe348..cde1a10 100644 --- a/Tests/JWTTests/JWTDecodeTests.swift +++ b/Tests/JWTTests/JWTDecodeTests.swift @@ -47,7 +47,7 @@ class DecodeTests: XCTestCase { XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!))) } - func testInvalidExpiaryClaim() { + func testInvalidExpiryClaim() { let jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOlsiMTQyODE4ODQ5MSJdfQ.OwF-wd3THjxrEGUhh6IdnNhxQZ7ydwJ3Z6J_dfl9MBs" XCTAssertThrowsError(try decode(jwt, algorithm: .hs256("secret".data(using: .utf8)!))) } diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index 3f3b768..492555b 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -54,7 +54,7 @@ extension DecodeTests { ("testIncorrectIssuerValidation", testIncorrectIssuerValidation), ("testMissingIssuerValidation", testMissingIssuerValidation), ("testExpiredClaim", testExpiredClaim), - ("testInvalidExpiaryClaim", testInvalidExpiaryClaim), + ("testInvalidExpiryClaim", testInvalidExpiryClaim), ("testUnexpiredClaim", testUnexpiredClaim), ("testUnexpiredClaimString", testUnexpiredClaimString), ("testNotBeforeClaim", testNotBeforeClaim), From 44f4b7a4ed7c1d2a165e106f2eb236ad199a54be Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Tue, 24 Jul 2018 17:41:02 -0500 Subject: [PATCH 21/23] Fix for CommonCrypto inclusion in Swift 4.2 --- Package.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Package.swift b/Package.swift index 36bc2f2..01b5e95 100644 --- a/Package.swift +++ b/Package.swift @@ -4,9 +4,13 @@ import PackageDescription #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) +#if canImport(CommonCrypto) +let dependencies: [Package.Dependency] = [] +#else let dependencies = [ Package.Dependency.package(url: "https://github.com/kylef-archive/CommonCrypto.git", from: "1.0.0"), ] +#endif let excludes = ["HMAC/HMACCryptoSwift.swift"] let targetDependencies: [Target.Dependency] = [] #else From 898f0c8ef842134c585cd5d0bc5dc0eb5dd878ed Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 6 Aug 2018 19:11:16 -0500 Subject: [PATCH 22/23] Add podspec --- JSONWebToken.podspec | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 JSONWebToken.podspec diff --git a/JSONWebToken.podspec b/JSONWebToken.podspec new file mode 100644 index 0000000..3e885ae --- /dev/null +++ b/JSONWebToken.podspec @@ -0,0 +1,32 @@ +Pod::Spec.new do |spec| + spec.name = 'JSONWebToken' + spec.version = '3.0.0' + spec.summary = 'Swift library for JSON Web Tokens (JWT).' + spec.homepage = 'https://github.com/kylef/JSONWebToken.swift' + spec.license = { :type => 'BSD', :file => 'LICENSE' } + spec.author = { 'Kyle Fuller' => 'kyle@fuller.li' } + spec.source = { :git => 'https://github.com/kylef/JSONWebToken.swift.git' } + spec.source_files = 'Sources/JWT/*.swift', 'Build-Phases/common-crypto.sh' + spec.ios.deployment_target = '8.0' + spec.osx.deployment_target = '10.9' + spec.tvos.deployment_target = '9.0' + spec.watchos.deployment_target = '2.0' + spec.requires_arc = true + spec.module_name = 'JWT' + spec.exclude_files = ['Sources/JWT/HMACCryptoSwift.swift'] + + spec.swift_version = '4.0' + + if ARGV.include?('lint') + spec.pod_target_xcconfig = { + 'SWIFT_INCLUDE_PATHS' => Dir.pwd, + } + else + spec.pod_target_xcconfig = { + 'SWIFT_INCLUDE_PATHS' => '$(PODS_ROOT)/JSONWebToken/', + } + end + + spec.preserve_paths = 'Build-Phases/*.sh' + spec.script_phase = { :name => 'CommonCrypto', :script => 'sh $SRCROOT/JSONWebToken/Build-Phases/common-crypto.sh', :execution_position => :before_compile } +end From 50b7757bec445b2bd2d2cccdfc18d2ade912d940 Mon Sep 17 00:00:00 2001 From: Jonathan Thornton Date: Mon, 6 Aug 2018 21:26:28 -0500 Subject: [PATCH 23/23] Delete JSONWebToken.podspec --- JSONWebToken.podspec | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 JSONWebToken.podspec diff --git a/JSONWebToken.podspec b/JSONWebToken.podspec deleted file mode 100644 index 3e885ae..0000000 --- a/JSONWebToken.podspec +++ /dev/null @@ -1,32 +0,0 @@ -Pod::Spec.new do |spec| - spec.name = 'JSONWebToken' - spec.version = '3.0.0' - spec.summary = 'Swift library for JSON Web Tokens (JWT).' - spec.homepage = 'https://github.com/kylef/JSONWebToken.swift' - spec.license = { :type => 'BSD', :file => 'LICENSE' } - spec.author = { 'Kyle Fuller' => 'kyle@fuller.li' } - spec.source = { :git => 'https://github.com/kylef/JSONWebToken.swift.git' } - spec.source_files = 'Sources/JWT/*.swift', 'Build-Phases/common-crypto.sh' - spec.ios.deployment_target = '8.0' - spec.osx.deployment_target = '10.9' - spec.tvos.deployment_target = '9.0' - spec.watchos.deployment_target = '2.0' - spec.requires_arc = true - spec.module_name = 'JWT' - spec.exclude_files = ['Sources/JWT/HMACCryptoSwift.swift'] - - spec.swift_version = '4.0' - - if ARGV.include?('lint') - spec.pod_target_xcconfig = { - 'SWIFT_INCLUDE_PATHS' => Dir.pwd, - } - else - spec.pod_target_xcconfig = { - 'SWIFT_INCLUDE_PATHS' => '$(PODS_ROOT)/JSONWebToken/', - } - end - - spec.preserve_paths = 'Build-Phases/*.sh' - spec.script_phase = { :name => 'CommonCrypto', :script => 'sh $SRCROOT/JSONWebToken/Build-Phases/common-crypto.sh', :execution_position => :before_compile } -end