From aa211072d1f3c657aaa8c2bcb6f0276df47c50a8 Mon Sep 17 00:00:00 2001 From: dtsiflit Date: Fri, 12 Jul 2024 14:46:49 +0300 Subject: [PATCH 1/3] [fix] access token updates --- Gemfile.lock | 113 +++++++++--------- .../CredentialIssuer/CredentialIssuerId.swift | 4 +- .../Entities/Issuance/AuthorizedRequest.swift | 84 ++++++++++--- Sources/Entities/IssuanceAccessToken.swift | 8 +- .../GetAuthorizationCodeURL.swift | 4 + Sources/Entities/IssuanceRefreshToken.swift | 4 +- Sources/Issuers/Issuer.swift | 39 +++--- .../AuthorizationServerClient.swift | 19 +-- Tests/Helpers/Wallet.swift | 3 +- .../Issuance/IssuanceAuthorizationTest.swift | 6 +- Tests/Issuance/IssuanceBatchRequestTest.swift | 2 +- .../IssuanceDeferredRequestTest.swift | 2 +- Tests/Issuance/IssuanceNotificationTest.swift | 4 +- .../Issuance/IssuanceSingleRequestTest.swift | 6 +- 14 files changed, 188 insertions(+), 110 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5ce0856..e5591ac 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,29 +1,32 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.6) + CFPropertyList (3.0.7) + base64 + nkf rexml - addressable (2.8.5) - public_suffix (>= 2.0.2, < 6.0) - artifactory (3.0.15) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + artifactory (3.0.17) atomos (0.1.3) - aws-eventstream (1.2.0) - aws-partitions (1.835.0) - aws-sdk-core (3.185.1) - aws-eventstream (~> 1, >= 1.0.2) + aws-eventstream (1.3.0) + aws-partitions (1.953.0) + aws-sdk-core (3.201.1) + aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) - aws-sigv4 (~> 1.5) + aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.72.0) - aws-sdk-core (~> 3, >= 3.184.0) - aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.136.0) - aws-sdk-core (~> 3, >= 3.181.0) + aws-sdk-kms (1.88.0) + aws-sdk-core (~> 3, >= 3.201.0) + aws-sigv4 (~> 1.5) + aws-sdk-s3 (1.156.0) + aws-sdk-core (~> 3, >= 3.201.0) aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.6) - aws-sigv4 (1.6.0) + aws-sigv4 (~> 1.5) + aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) + base64 (0.2.0) claide (1.1.0) colored (1.2) colored2 (3.1.2) @@ -32,11 +35,10 @@ GEM declarative (0.0.20) digest-crc (0.6.5) rake (>= 12.0.0, < 14.0.0) - domain_name (0.5.20190701) - unf (>= 0.0.5, < 1.0.0) + domain_name (0.6.20240107) dotenv (2.8.1) emoji_regex (3.2.3) - excon (0.104.0) + excon (0.111.0) faraday (1.10.3) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) @@ -65,15 +67,15 @@ GEM faraday-retry (1.0.3) faraday_middleware (1.2.0) faraday (~> 1.0) - fastimage (2.2.7) - fastlane (2.216.0) + fastimage (2.3.1) + fastlane (2.221.1) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) aws-sdk-s3 (~> 1.0) babosa (>= 1.0.3, < 2.0.0) bundler (>= 1.12.0, < 3.0.0) - colored + colored (~> 1.2) commander (~> 4.6) dotenv (>= 2.1.1, < 3.0.0) emoji_regex (>= 0.1, < 4.0) @@ -85,6 +87,7 @@ GEM gh_inspector (>= 1.1.2, < 2.0.0) google-apis-androidpublisher_v3 (~> 0.3) google-apis-playcustomapp_v1 (~> 0.1) + google-cloud-env (>= 1.6.0, < 2.0.0) google-cloud-storage (~> 1.31) highline (~> 2.0) http-cookie (~> 1.0.5) @@ -93,10 +96,10 @@ GEM mini_magick (>= 4.9.4, < 5.0.0) multipart-post (>= 2.0.0, < 3.0.0) naturally (~> 2.2) - optparse (~> 0.1.1) + optparse (>= 0.1.1, < 1.0.0) plist (>= 3.1.0, < 4.0.0) rubyzip (>= 2.0.0, < 3.0.0) - security (= 0.1.3) + security (= 0.1.5) simctl (~> 1.6.3) terminal-notifier (>= 2.0.0, < 3.0.0) terminal-table (~> 3) @@ -105,11 +108,11 @@ GEM word_wrap (~> 1.0.0) xcodeproj (>= 1.13.0, < 2.0.0) xcpretty (~> 0.3.0) - xcpretty-travis-formatter (>= 0.0.3) + xcpretty-travis-formatter (>= 0.0.3, < 2.0.0) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.51.0) + google-apis-androidpublisher_v3 (0.54.0) google-apis-core (>= 0.11.0, < 2.a) - google-apis-core (0.11.1) + google-apis-core (0.11.3) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) @@ -117,24 +120,23 @@ GEM representable (~> 3.0) retriable (>= 2.0, < 4.a) rexml - webrick google-apis-iamcredentials_v1 (0.17.0) google-apis-core (>= 0.11.0, < 2.a) google-apis-playcustomapp_v1 (0.13.0) google-apis-core (>= 0.11.0, < 2.a) - google-apis-storage_v1 (0.19.0) - google-apis-core (>= 0.9.0, < 2.a) - google-cloud-core (1.6.0) - google-cloud-env (~> 1.0) + google-apis-storage_v1 (0.31.0) + google-apis-core (>= 0.11.0, < 2.a) + google-cloud-core (1.7.0) + google-cloud-env (>= 1.0, < 3.a) google-cloud-errors (~> 1.0) google-cloud-env (1.6.0) faraday (>= 0.17.3, < 3.0) - google-cloud-errors (1.3.1) - google-cloud-storage (1.44.0) + google-cloud-errors (1.4.0) + google-cloud-storage (1.47.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.19.0) + google-apis-storage_v1 (~> 0.31.0) google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) @@ -145,34 +147,37 @@ GEM os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) highline (2.0.3) - http-cookie (1.0.5) + http-cookie (1.0.6) domain_name (~> 0.5) httpclient (2.8.3) jmespath (1.6.2) - json (2.6.3) - jwt (2.7.1) - mini_magick (4.12.0) + json (2.7.2) + jwt (2.8.2) + base64 + mini_magick (4.13.2) mini_mime (1.1.5) multi_json (1.15.0) - multipart-post (2.3.0) + multipart-post (2.4.1) nanaimo (0.3.0) naturally (2.2.1) - optparse (0.1.1) + nkf (0.2.0) + optparse (0.5.0) os (1.1.4) - plist (3.7.0) - public_suffix (5.0.3) - rake (13.0.6) + plist (3.7.1) + public_suffix (6.0.0) + rake (13.2.1) representable (3.2.0) declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) retriable (3.1.2) - rexml (3.2.6) + rexml (3.2.9) + strscan rouge (2.0.7) ruby2_keywords (0.0.5) rubyzip (2.3.2) - security (0.1.3) - signet (0.18.0) + security (0.1.5) + signet (0.19.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 3.0) @@ -180,22 +185,19 @@ GEM simctl (1.6.10) CFPropertyList naturally + strscan (3.1.0) terminal-notifier (2.0.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) trailblazer-option (0.1.2) tty-cursor (0.7.1) - tty-screen (0.8.1) + tty-screen (0.8.2) tty-spinner (0.9.3) tty-cursor (~> 0.7) uber (0.1.0) - unf (0.1.4) - unf_ext - unf_ext (0.0.8.2) unicode-display_width (2.5.0) - webrick (1.8.1) word_wrap (1.0.0) - xcodeproj (1.23.0) + xcodeproj (1.24.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) @@ -208,10 +210,11 @@ GEM xcpretty (~> 0.2, >= 0.0.7) PLATFORMS - arm64-darwin-22 + arm64-darwin-23 + ruby DEPENDENCIES fastlane BUNDLED WITH - 2.4.19 + 2.5.14 diff --git a/Sources/Entities/CredentialIssuer/CredentialIssuerId.swift b/Sources/Entities/CredentialIssuer/CredentialIssuerId.swift index 3846b37..b48f263 100644 --- a/Sources/Entities/CredentialIssuer/CredentialIssuerId.swift +++ b/Sources/Entities/CredentialIssuer/CredentialIssuerId.swift @@ -25,7 +25,9 @@ public struct CredentialIssuerId: Codable, Equatable { } guard - let validURL = URL(string: string) + let validURL = URL(string: string), + validURL.scheme == "https", + validURL.fragment == nil else { throw CredentialError.genericError } diff --git a/Sources/Entities/Issuance/AuthorizedRequest.swift b/Sources/Entities/Issuance/AuthorizedRequest.swift index 26d8264..1a3dcf0 100644 --- a/Sources/Entities/Issuance/AuthorizedRequest.swift +++ b/Sources/Entities/Issuance/AuthorizedRequest.swift @@ -15,22 +15,71 @@ */ import Foundation +public protocol CanExpire { + var expiresIn: TimeInterval? { get } + func isExpired(issued: TimeInterval, at: TimeInterval) -> Bool +} + +public extension CanExpire { + func isExpired(issued: TimeInterval, at: TimeInterval) -> Bool { + if issued >= at { + return true + } + + guard let expiresIn = expiresIn else { + return false + } + + let expiration = issued + expiresIn + return expiration <= at + } +} + public enum AuthorizedRequest { - case noProofRequired( - accessToken: IssuanceAccessToken, - refreshToken: IssuanceRefreshToken?, - credentialIdentifiers: AuthorizationDetailsIdentifiers? + case noProofRequired( + accessToken: IssuanceAccessToken, + refreshToken: IssuanceRefreshToken?, + credentialIdentifiers: AuthorizationDetailsIdentifiers?, + timeStamp: TimeInterval ) - case proofRequired( - accessToken: IssuanceAccessToken, - refreshToken: IssuanceRefreshToken?, - cNonce: CNonce, - credentialIdentifiers: AuthorizationDetailsIdentifiers? - ) - + case proofRequired( + accessToken: IssuanceAccessToken, + refreshToken: IssuanceRefreshToken?, + cNonce: CNonce, + credentialIdentifiers: AuthorizationDetailsIdentifiers?, + timeStamp: TimeInterval + ) + + + public func isAccessTokenExpired(clock: TimeInterval) -> Bool { + guard let timeStamp = self.timeStamp else { + return true + } + return accessToken?.isExpired(issued: timeStamp, at: clock) ?? false + } + + public func isRefreshTokenExpired(clock: TimeInterval) -> Bool { + guard let timeStamp = self.timeStamp else { + return true + } + return accessToken?.isExpired( + issued: timeStamp, + at: clock + ) ?? false + } + + public var timeStamp: TimeInterval? { + switch self { + case .noProofRequired(_, _, _, let timeStamp): + return timeStamp + case .proofRequired(_, _, _, _, let timeStamp): + return timeStamp + } + } + public var noProofToken: IssuanceAccessToken? { switch self { - case .noProofRequired(let accessToken, _, _): + case .noProofRequired(let accessToken, _, _, _): return accessToken case .proofRequired: return nil @@ -41,7 +90,7 @@ public enum AuthorizedRequest { switch self { case .noProofRequired: return nil - case .proofRequired(let accessToken, _, _, _): + case .proofRequired(let accessToken, _, _, _, _): return accessToken } } @@ -50,9 +99,9 @@ public enum AuthorizedRequest { public extension AuthorizedRequest { var accessToken: IssuanceAccessToken? { switch self { - case .noProofRequired(let accessToken, _, _): + case .noProofRequired(let accessToken, _, _, _): return accessToken - case .proofRequired(let accessToken, _, _, _): + case .proofRequired(let accessToken, _, _, _, _): return accessToken } } @@ -60,12 +109,13 @@ public extension AuthorizedRequest { func handleInvalidProof(cNonce: CNonce) throws -> AuthorizedRequest { switch self { - case .noProofRequired(let accessToken, let refreshToken, let credentialIdentifiers): + case .noProofRequired(let accessToken, let refreshToken, let credentialIdentifiers, let timeStamp): return .proofRequired( accessToken: accessToken, refreshToken: refreshToken, cNonce: cNonce, - credentialIdentifiers: credentialIdentifiers + credentialIdentifiers: credentialIdentifiers, + timeStamp: timeStamp ) default: throw ValidationError.error(reason: "Expected .noProofRequired authorisation request") } diff --git a/Sources/Entities/IssuanceAccessToken.swift b/Sources/Entities/IssuanceAccessToken.swift index 50eba11..c08badd 100644 --- a/Sources/Entities/IssuanceAccessToken.swift +++ b/Sources/Entities/IssuanceAccessToken.swift @@ -35,19 +35,23 @@ public enum TokenType: String, Codable { } } -public struct IssuanceAccessToken: Codable { +public struct IssuanceAccessToken: Codable, CanExpire { + public var expiresIn: TimeInterval? + public let accessToken: String public let tokenType: TokenType? public init( accessToken: String, - tokenType: TokenType? + tokenType: TokenType?, + expiresIn: TimeInterval = .zero ) throws { guard !accessToken.isEmpty else { throw ValidationError.error(reason: "Access token cannot be empty") } self.accessToken = accessToken self.tokenType = tokenType + self.expiresIn = expiresIn } } diff --git a/Sources/Entities/IssuanceFlows/GetAuthorizationCodeURL.swift b/Sources/Entities/IssuanceFlows/GetAuthorizationCodeURL.swift index 24be4ab..3089f4d 100644 --- a/Sources/Entities/IssuanceFlows/GetAuthorizationCodeURL.swift +++ b/Sources/Entities/IssuanceFlows/GetAuthorizationCodeURL.swift @@ -27,6 +27,10 @@ public struct GetAuthorizationCodeURL { throw ValidationError.invalidUrl(urlString) } + guard url.scheme == "https" else { + throw ValidationError.nonHttpsUrl(urlString) + } + let parameters = url.queryParameters guard parameters["\(Self.PARAM_CLIENT_ID)"] != nil diff --git a/Sources/Entities/IssuanceRefreshToken.swift b/Sources/Entities/IssuanceRefreshToken.swift index 9b0e252..f80577a 100644 --- a/Sources/Entities/IssuanceRefreshToken.swift +++ b/Sources/Entities/IssuanceRefreshToken.swift @@ -15,7 +15,9 @@ */ import Foundation -public struct IssuanceRefreshToken: Codable { +public struct IssuanceRefreshToken: Codable, CanExpire { + public var expiresIn: TimeInterval? + public let refreshToken: String? public init(refreshToken: String?) throws { diff --git a/Sources/Issuers/Issuer.swift b/Sources/Issuers/Issuer.swift index b445f27..f0386f1 100644 --- a/Sources/Issuers/Issuer.swift +++ b/Sources/Issuers/Issuer.swift @@ -228,17 +228,19 @@ public actor Issuer: IssuerType { ) switch response { - case .success((let accessToken, let nonce, let identifiers)): + case .success((let accessToken, let nonce, let identifiers, let expiresIn)): if let cNonce = nonce { return .success( .proofRequired( accessToken: try IssuanceAccessToken( accessToken: accessToken.accessToken, - tokenType: accessToken.tokenType + tokenType: accessToken.tokenType, + expiresIn: TimeInterval(expiresIn ?? .zero) ), refreshToken: nil, cNonce: cNonce, - credentialIdentifiers: identifiers + credentialIdentifiers: identifiers, + timeStamp: Date().timeIntervalSinceReferenceDate ) ) } else { @@ -246,10 +248,12 @@ public actor Issuer: IssuerType { .noProofRequired( accessToken: try IssuanceAccessToken( accessToken: accessToken.accessToken, - tokenType: accessToken.tokenType + tokenType: accessToken.tokenType, + expiresIn: TimeInterval(expiresIn ?? .zero) ), refreshToken: nil, - credentialIdentifiers: identifiers + credentialIdentifiers: identifiers, + timeStamp: Date().timeIntervalSinceReferenceDate ) ) } @@ -279,7 +283,8 @@ public actor Issuer: IssuerType { accessToken: IssuanceAccessToken, nonce: CNonce?, identifiers: AuthorizationDetailsIdentifiers?, - tokenType: TokenType? + tokenType: TokenType?, + expiresIn: Int? ) = try await authorizer.requestAccessTokenAuthFlow( authorizationCode: authorizationCode, codeVerifier: request.pkceVerifier.codeVerifier @@ -290,11 +295,13 @@ public actor Issuer: IssuerType { .proofRequired( accessToken: try IssuanceAccessToken( accessToken: response.accessToken.accessToken, - tokenType: response.tokenType + tokenType: response.tokenType, + expiresIn: TimeInterval(response.expiresIn ?? .zero) ), refreshToken: nil, cNonce: cNonce, - credentialIdentifiers: response.identifiers + credentialIdentifiers: response.identifiers, + timeStamp: Date().timeIntervalSinceReferenceDate ) ) } else { @@ -302,10 +309,12 @@ public actor Issuer: IssuerType { .noProofRequired( accessToken: try IssuanceAccessToken( accessToken: response.accessToken.accessToken, - tokenType: response.tokenType + tokenType: response.tokenType, + expiresIn: TimeInterval(response.expiresIn ?? .zero) ), refreshToken: nil, - credentialIdentifiers: response.identifiers + credentialIdentifiers: response.identifiers, + timeStamp: Date().timeIntervalSinceReferenceDate ) ) } @@ -371,9 +380,9 @@ public actor Issuer: IssuerType { private func accessToken(from request: AuthorizedRequest) -> IssuanceAccessToken { switch request { - case .noProofRequired(let token, _, _): + case .noProofRequired(let token, _, _, _): return token - case .proofRequired(let token, _, _, _): + case .proofRequired(let token, _, _, _, _): return token } } @@ -382,7 +391,7 @@ public actor Issuer: IssuerType { switch request { case .noProofRequired: return nil - case .proofRequired(_, _, let cnonce, _): + case .proofRequired(_, _, let cnonce, _, _): return cnonce } } @@ -466,7 +475,7 @@ public actor Issuer: IssuerType { responseEncryptionSpecProvider: (_ issuerResponseEncryptionMetadata: CredentialResponseEncryption) -> IssuanceResponseEncryptionSpec? ) async throws -> Result { switch noProofRequest { - case .noProofRequired(let token, _, _): + case .noProofRequired(let token, _, _, _): return try await requestIssuance(token: token) { let credentialRequests: [CredentialIssuanceRequest] = try requestPayload.map { identifier in guard let supportedCredential = issuerMetadata @@ -504,7 +513,7 @@ public actor Issuer: IssuerType { responseEncryptionSpecProvider: (_ issuerResponseEncryptionMetadata: CredentialResponseEncryption) -> IssuanceResponseEncryptionSpec? ) async throws -> Result { switch proofRequest { - case .proofRequired(let token, _, let cNonce, _): + case .proofRequired(let token, _, let cNonce, _, _): return try await requestIssuance(token: token) { let credentialRequests: [CredentialIssuanceRequest] = try requestPayload.map { identifier in guard let supportedCredential = issuerMetadata diff --git a/Sources/Main/Authorisers/AuthorizationServerClient.swift b/Sources/Main/Authorisers/AuthorizationServerClient.swift index 3665710..4cac653 100644 --- a/Sources/Main/Authorisers/AuthorizationServerClient.swift +++ b/Sources/Main/Authorisers/AuthorizationServerClient.swift @@ -37,14 +37,14 @@ public protocol AuthorizationServerClientType { func requestAccessTokenAuthFlow( authorizationCode: String, codeVerifier: String - ) async throws -> Result<(IssuanceAccessToken, CNonce?, AuthorizationDetailsIdentifiers?, TokenType?), ValidationError> + ) async throws -> Result<(IssuanceAccessToken, CNonce?, AuthorizationDetailsIdentifiers?, TokenType?, Int?), ValidationError> func requestAccessTokenPreAuthFlow( preAuthorizedCode: String, txCode: TxCode?, clientId: String, transactionCode: String? - ) async throws -> Result<(IssuanceAccessToken, CNonce?, AuthorizationDetailsIdentifiers?), ValidationError> + ) async throws -> Result<(IssuanceAccessToken, CNonce?, AuthorizationDetailsIdentifiers?, Int?), ValidationError> } public actor AuthorizationServerClient: AuthorizationServerClientType { @@ -249,7 +249,8 @@ public actor AuthorizationServerClient: AuthorizationServerClientType { IssuanceAccessToken, CNonce?, AuthorizationDetailsIdentifiers?, - TokenType? + TokenType?, + Int? ), ValidationError> { let parameters: [String: String] = authCodeFlow( @@ -267,13 +268,14 @@ public actor AuthorizationServerClient: AuthorizationServerClientType { ) switch response { - case .success(let tokenType, let accessToken, _, _, _, let nonce, _, let identifiers): + case .success(let tokenType, let accessToken, _, let expiresIn, _, let nonce, _, let identifiers): return .success( ( try .init(accessToken: accessToken, tokenType: .init(value: tokenType)), .init(value: nonce), identifiers, - TokenType(value: tokenType) + TokenType(value: tokenType), + expiresIn ) ) case .failure(let error, let errorDescription): @@ -289,7 +291,7 @@ public actor AuthorizationServerClient: AuthorizationServerClientType { txCode: TxCode?, clientId: String, transactionCode: String? - ) async throws -> Result<(IssuanceAccessToken, CNonce?, AuthorizationDetailsIdentifiers?), ValidationError> { + ) async throws -> Result<(IssuanceAccessToken, CNonce?, AuthorizationDetailsIdentifiers?, Int?), ValidationError> { let parameters: JSON = try await preAuthCodeFlow( preAuthorizedCode: preAuthorizedCode, txCode: txCode, @@ -305,12 +307,13 @@ public actor AuthorizationServerClient: AuthorizationServerClientType { ) switch response { - case .success(let tokenType, let accessToken, _, _, _, let nonce, _, let identifiers): + case .success(let tokenType, let accessToken, _, let expiresIn, _, let nonce, _, let identifiers): return .success( ( try .init(accessToken: accessToken, tokenType: .init(value: tokenType)), .init(value: nonce), - identifiers + identifiers, + expiresIn ) ) case .failure(let error, let errorDescription): diff --git a/Tests/Helpers/Wallet.swift b/Tests/Helpers/Wallet.swift index a390c17..af4d16b 100644 --- a/Tests/Helpers/Wallet.swift +++ b/Tests/Helpers/Wallet.swift @@ -446,9 +446,10 @@ extension Wallet { case .success(let request): let authorizedRequest = await issuer.requestAccessToken(authorizationCode: request) if case let .success(authorized) = authorizedRequest, - case let .noProofRequired(token, _, _) = authorized { + case let .noProofRequired(token, _, _, _) = authorized { print("--> [AUTHORIZATION] Authorization code exchanged with access token : \(token.accessToken)") + let hasExpired = authorized.accessToken?.isExpired(issued: authorized.timeStamp!, at: Date().timeIntervalSinceReferenceDate) return authorized } diff --git a/Tests/Issuance/IssuanceAuthorizationTest.swift b/Tests/Issuance/IssuanceAuthorizationTest.swift index 9c27fb2..6b64752 100644 --- a/Tests/Issuance/IssuanceAuthorizationTest.swift +++ b/Tests/Issuance/IssuanceAuthorizationTest.swift @@ -145,7 +145,7 @@ class IssuanceAuthorizationTest: XCTestCase { let authorizedRequest = await issuer.requestAccessToken(authorizationCode: authorizationCode) if case let .success(authorized) = authorizedRequest, - case let .noProofRequired(token, _, _) = authorized { + case let .noProofRequired(token, _, _, _) = authorized { XCTAssert(true, "Got access token: \(token)") return } @@ -197,7 +197,7 @@ class IssuanceAuthorizationTest: XCTestCase { case .success(let authorizationCode): let authorizedRequest = await issuer.requestAccessToken(authorizationCode: authorizationCode) if case let .success(authorized) = authorizedRequest, - case let .proofRequired(token, _, _, _) = authorized { + case let .proofRequired(token, _, _, _, _) = authorized { XCTAssert(true, "Got access token: \(token)") return } @@ -311,7 +311,7 @@ class IssuanceAuthorizationTest: XCTestCase { switch result { case .success(let request): - if case let .noProofRequired(token, _, _) = request { + if case let .noProofRequired(token, _, _, _) = request { XCTAssert(true, "Got access token: \(token)") } case .failure(let error): diff --git a/Tests/Issuance/IssuanceBatchRequestTest.swift b/Tests/Issuance/IssuanceBatchRequestTest.swift index f55b553..b212fc0 100644 --- a/Tests/Issuance/IssuanceBatchRequestTest.swift +++ b/Tests/Issuance/IssuanceBatchRequestTest.swift @@ -103,7 +103,7 @@ class IssuanceBatchRequestTest: XCTestCase { let authorizedRequest = await issuer.requestAccessToken(authorizationCode: authorizationCode) if case let .success(authorized) = authorizedRequest, - case let .noProofRequired(token, _, _) = authorized { + case let .noProofRequired(token, _, _, _) = authorized { XCTAssert(true, "Got access token: \(token)") XCTAssert(true, "Is no proof required") diff --git a/Tests/Issuance/IssuanceDeferredRequestTest.swift b/Tests/Issuance/IssuanceDeferredRequestTest.swift index e70c0d3..9f06f8a 100644 --- a/Tests/Issuance/IssuanceDeferredRequestTest.swift +++ b/Tests/Issuance/IssuanceDeferredRequestTest.swift @@ -101,7 +101,7 @@ class IssuanceDeferredRequestTest: XCTestCase { let authorizedRequest = await issuer.requestAccessToken(authorizationCode: authorizationCode) if case let .success(authorized) = authorizedRequest, - case let .noProofRequired(token, _, _) = authorized { + case let .noProofRequired(token, _, _, _) = authorized { XCTAssert(true, "Got access token: \(token)") XCTAssert(true, "Is no proof required") diff --git a/Tests/Issuance/IssuanceNotificationTest.swift b/Tests/Issuance/IssuanceNotificationTest.swift index 1f6dec8..2a1e422 100644 --- a/Tests/Issuance/IssuanceNotificationTest.swift +++ b/Tests/Issuance/IssuanceNotificationTest.swift @@ -108,7 +108,7 @@ class IssuanceNotificationTest: XCTestCase { let authorizedRequest = await issuer.requestAccessToken(authorizationCode: authorizationCode) if case let .success(authorized) = authorizedRequest, - case let .noProofRequired(token, _, _) = authorized { + case let .noProofRequired(token, _, _, _) = authorized { XCTAssert(true, "Got access token: \(token)") XCTAssert(true, "Is no proof required") @@ -251,7 +251,7 @@ class IssuanceNotificationTest: XCTestCase { let authorizedRequest = await issuer.requestAccessToken(authorizationCode: authorizationCode) if case let .success(authorized) = authorizedRequest, - case let .noProofRequired(token, _, _) = authorized { + case let .noProofRequired(token, _, _, _) = authorized { XCTAssert(true, "Got access token: \(token)") XCTAssert(true, "Is no proof required") diff --git a/Tests/Issuance/IssuanceSingleRequestTest.swift b/Tests/Issuance/IssuanceSingleRequestTest.swift index c134945..4b32d22 100644 --- a/Tests/Issuance/IssuanceSingleRequestTest.swift +++ b/Tests/Issuance/IssuanceSingleRequestTest.swift @@ -102,7 +102,7 @@ class IssuanceSingleRequestTest: XCTestCase { let authorizedRequest = await issuer.requestAccessToken(authorizationCode: authorizationCode) if case let .success(authorized) = authorizedRequest, - case let .noProofRequired(token, _, _) = authorized { + case let .noProofRequired(token, _, _, _) = authorized { XCTAssert(true, "Got access token: \(token)") XCTAssert(true, "Is no proof required") @@ -235,7 +235,7 @@ class IssuanceSingleRequestTest: XCTestCase { ) if case let .success(authorized) = unAuthorized, - case let .noProofRequired(token, _, _) = authorized { + case let .noProofRequired(token, _, _, _) = authorized { XCTAssert(true, "Got access token: \(token)") XCTAssert(true, "Is no proof required") @@ -363,7 +363,7 @@ class IssuanceSingleRequestTest: XCTestCase { let authorizedRequest = await issuer.requestAccessToken(authorizationCode: authorizationCode) if case let .success(authorized) = authorizedRequest, - case let .noProofRequired(token, _, identifiers) = authorized { + case let .noProofRequired(token, _, identifiers, _) = authorized { XCTAssert(true, "Got access token: \(token)") XCTAssert(true, "Is no proof required") From e2dd7b75a415432e95ab5c3f09e41c56c9c74ee8 Mon Sep 17 00:00:00 2001 From: dtsiflit Date: Fri, 12 Jul 2024 14:46:58 +0300 Subject: [PATCH 2/3] [fix] access token updates --- Gemfile | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Gemfile diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..adc90d9 --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source "https://rubygems.org" + +gem "fastlane" \ No newline at end of file From 8a1a92d71f1bc462c9dd6f0ba75c41256e77235a Mon Sep 17 00:00:00 2001 From: dtsiflit Date: Mon, 15 Jul 2024 11:16:33 +0300 Subject: [PATCH 3/3] [fix] formatting --- .../Entities/Issuance/AuthorizedRequest.swift | 69 +++++++++---------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/Sources/Entities/Issuance/AuthorizedRequest.swift b/Sources/Entities/Issuance/AuthorizedRequest.swift index 1a3dcf0..b4be2a2 100644 --- a/Sources/Entities/Issuance/AuthorizedRequest.swift +++ b/Sources/Entities/Issuance/AuthorizedRequest.swift @@ -36,44 +36,43 @@ public extension CanExpire { } public enum AuthorizedRequest { - case noProofRequired( - accessToken: IssuanceAccessToken, - refreshToken: IssuanceRefreshToken?, - credentialIdentifiers: AuthorizationDetailsIdentifiers?, - timeStamp: TimeInterval - ) - case proofRequired( - accessToken: IssuanceAccessToken, - refreshToken: IssuanceRefreshToken?, - cNonce: CNonce, - credentialIdentifiers: AuthorizationDetailsIdentifiers?, - timeStamp: TimeInterval - ) + case noProofRequired( + accessToken: IssuanceAccessToken, + refreshToken: IssuanceRefreshToken?, + credentialIdentifiers: AuthorizationDetailsIdentifiers?, + timeStamp: TimeInterval + ) + case proofRequired( + accessToken: IssuanceAccessToken, + refreshToken: IssuanceRefreshToken?, + cNonce: CNonce, + credentialIdentifiers: AuthorizationDetailsIdentifiers?, + timeStamp: TimeInterval + ) - - public func isAccessTokenExpired(clock: TimeInterval) -> Bool { - guard let timeStamp = self.timeStamp else { - return true - } - return accessToken?.isExpired(issued: timeStamp, at: clock) ?? false + public func isAccessTokenExpired(clock: TimeInterval) -> Bool { + guard let timeStamp = self.timeStamp else { + return true } + return accessToken?.isExpired(issued: timeStamp, at: clock) ?? false + } - public func isRefreshTokenExpired(clock: TimeInterval) -> Bool { - guard let timeStamp = self.timeStamp else { - return true - } - return accessToken?.isExpired( - issued: timeStamp, - at: clock - ) ?? false + public func isRefreshTokenExpired(clock: TimeInterval) -> Bool { + guard let timeStamp = self.timeStamp else { + return true } - - public var timeStamp: TimeInterval? { - switch self { - case .noProofRequired(_, _, _, let timeStamp): - return timeStamp - case .proofRequired(_, _, _, _, let timeStamp): - return timeStamp + return accessToken?.isExpired( + issued: timeStamp, + at: clock + ) ?? false + } + + public var timeStamp: TimeInterval? { + switch self { + case .noProofRequired(_, _, _, let timeStamp): + return timeStamp + case .proofRequired(_, _, _, _, let timeStamp): + return timeStamp } } @@ -85,7 +84,7 @@ public enum AuthorizedRequest { return nil } } - + public var proofToken: IssuanceAccessToken? { switch self { case .noProofRequired: