Skip to content

Commit

Permalink
ensure date claims use unix epoch
Browse files Browse the repository at this point in the history
  • Loading branch information
tanner0101 committed Aug 14, 2018
1 parent af11cb5 commit 2e225c7
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 19 deletions.
52 changes: 34 additions & 18 deletions Sources/JWT/JWTClaims.swift
Expand Up @@ -50,20 +50,6 @@ public struct AudienceClaim: JWTClaim, ExpressibleByStringLiteral {
}
}

/// The "iat" (issued at) claim identifies the time at which the JWT was
/// issued. This claim can be used to determine the age of the JWT. Its
/// value MUST be a number containing a NumericDate value. Use of this
/// claim is OPTIONAL.
public struct IssuedAtClaim: JWTClaim {
/// See `JWTClaim`.
public var value: Date

/// See `JWTClaim`.
public init(value: Date) {
self.value = value
}
}

/// The "jti" (JWT ID) claim provides a unique identifier for the JWT.
/// The identifier value MUST be assigned in a manner that ensures that
/// there is a negligible probability that the same value will be
Expand All @@ -72,7 +58,21 @@ public struct IssuedAtClaim: JWTClaim {
/// produced by different issuers as well. The "jti" claim can be used
/// to prevent the JWT from being replayed. The "jti" value is a case-
/// sensitive string. Use of this claim is OPTIONAL.
public struct IDClaim: JWTClaim {
public struct IDClaim: JWTClaim, ExpressibleByStringLiteral {
/// See `JWTClaim`.
public var value: String

/// See `JWTClaim`.
public init(value: String) {
self.value = value
}
}

/// The "iat" (issued at) claim identifies the time at which the JWT was
/// issued. This claim can be used to determine the age of the JWT. Its
/// value MUST be a number containing a NumericDate value. Use of this
/// claim is OPTIONAL.
public struct IssuedAtClaim: JWTUnixEpochClaim {
/// See `JWTClaim`.
public var value: Date

Expand All @@ -89,7 +89,7 @@ public struct IDClaim: JWTClaim {
/// Implementers MAY provide for some small leeway, usually no more than
/// a few minutes, to account for clock skew. Its value MUST be a number
/// containing a NumericDate value. Use of this claim is OPTIONAL.
public struct ExpirationClaim: JWTClaim {
public struct ExpirationClaim: JWTUnixEpochClaim {
/// See `JWTClaim`.
public var value: Date

Expand All @@ -114,15 +114,15 @@ public struct ExpirationClaim: JWTClaim {
/// provide for some small leeway, usually no more than a few minutes, to
/// account for clock skew. Its value MUST be a number containing a
/// NumericDate value. Use of this claim is OPTIONAL.
public struct NotBeforeClaim: JWTClaim {
public struct NotBeforeClaim: JWTUnixEpochClaim {
/// See `JWTClaim`.
public var value: Date

/// See `JWTClaim`.
public init(value: Date) {
self.value = value
}

/// Throws an error if the claim's date is earlier than current date.
public func verifyNotBefore(currentDate: Date = .init()) throws {
switch value.compare(currentDate) {
Expand All @@ -131,3 +131,19 @@ public struct NotBeforeClaim: JWTClaim {
}
}
}

public protocol JWTUnixEpochClaim: JWTClaim where Value == Date { }

extension JWTUnixEpochClaim {
/// See `Decodable`.
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
try self.init(value: .init(timeIntervalSince1970: container.decode(Double.self)))
}

/// See `Encodable`.
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(value.timeIntervalSince1970)
}
}
2 changes: 1 addition & 1 deletion Tests/JWTTests/JWTTests.swift
Expand Up @@ -66,7 +66,7 @@ class JWTTests: XCTestCase {
admin: false,
exp: .init(value: .init(timeIntervalSince1970: 2_000_000_000))
)
var jwt = JWT(payload: payload)
let jwt = JWT(payload: payload)
do {
_ = try jwt.sign(using: publicSigner)
XCTFail("cannot sign with public signer")
Expand Down

0 comments on commit 2e225c7

Please sign in to comment.