Skip to content

disregard #113

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,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"]
Expand Down
2 changes: 1 addition & 1 deletion Sources/JWA/HMAC/HMACCommonCrypto.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import CommonCrypto
extension HMACAlgorithm: SignAlgorithm, VerifyAlgorithm {
public func sign(_ message: Data) -> Data {
let context = UnsafeMutablePointer<CCHmacContext>.allocate(capacity: 1)
defer { context.deallocate(capacity: 1) }
defer { context.deallocate() }

key.withUnsafeBytes() { (buffer: UnsafePointer<UInt8>) in
CCHmacInit(context, hash.commonCryptoAlgorithm, buffer, size_t(key.count))
Expand Down
9 changes: 7 additions & 2 deletions Sources/JWT/ClaimSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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")
}

Expand Down
12 changes: 0 additions & 12 deletions Sources/JWT/Decode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
11 changes: 0 additions & 11 deletions Sources/JWT/Encode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
4 changes: 2 additions & 2 deletions Tests/JWTTests/ClaimSetTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.")
}
Expand Down
41 changes: 17 additions & 24 deletions Tests/JWTTests/JWTDecodeTests.swift
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
import Foundation
import XCTest
import JWT
@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")
}

Expand All @@ -25,15 +18,15 @@ class DecodeTests: XCTestCase {

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

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")
}

Expand Down Expand Up @@ -63,15 +56,15 @@ class DecodeTests: XCTestCase {
// 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)
}

func testUnexpiredClaimString() throws {
// 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)
}

Expand All @@ -80,14 +73,14 @@ 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)
}

Expand All @@ -107,14 +100,14 @@ 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)
}

Expand Down Expand Up @@ -185,24 +178,24 @@ class DecodeTests: XCTestCase {

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)!))) { 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.")
Expand All @@ -213,7 +206,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):
Expand Down
42 changes: 32 additions & 10 deletions Tests/JWTTests/JWTEncodeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +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"
}

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"])

XCTAssertEqual(jwt, "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IngifQ.e30.ddEotxYYMMdat5HPgYFQnkHRdPXsxPG71ooyhIUoqGA")

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))
}
}
Loading