@@ -54,6 +54,7 @@ public protocol AuthorizationServerClientType {
5454 retry: Bool
5555 ) async throws -> Result < (
5656 IssuanceAccessToken ,
57+ IssuanceRefreshToken ,
5758 CNonce ? ,
5859 AuthorizationDetailsIdentifiers ? ,
5960 TokenType ? ,
@@ -71,10 +72,25 @@ public protocol AuthorizationServerClientType {
7172 retry: Bool
7273 ) async throws -> Result < (
7374 IssuanceAccessToken ,
75+ IssuanceRefreshToken ,
7476 CNonce ? ,
7577 AuthorizationDetailsIdentifiers ? ,
7678 Int ? ,
7779 Nonce ? ) , Error >
80+
81+ func refreshAccessToken(
82+ clientId: String ,
83+ refreshToken: IssuanceRefreshToken ,
84+ dpopNonce: Nonce ? ,
85+ retry: Bool
86+ ) async throws -> Result < (
87+ IssuanceAccessToken ,
88+ CNonce ? ,
89+ AuthorizationDetailsIdentifiers ? ,
90+ TokenType ? ,
91+ Int ? ,
92+ Nonce ?
93+ ) , Error >
7894}
7995
8096public actor AuthorizationServerClient : AuthorizationServerClientType {
@@ -313,6 +329,7 @@ public actor AuthorizationServerClient: AuthorizationServerClientType {
313329 retry: Bool
314330 ) async throws -> Result < (
315331 IssuanceAccessToken ,
332+ IssuanceRefreshToken ,
316333 CNonce ? ,
317334 AuthorizationDetailsIdentifiers ? ,
318335 TokenType ? ,
@@ -339,7 +356,7 @@ public actor AuthorizationServerClient: AuthorizationServerClientType {
339356 )
340357
341358 switch response. body {
342- case . success( let tokenType, let accessToken, _ , let expiresIn, _, let nonce, _, let identifiers) :
359+ case . success( let tokenType, let accessToken, let refreshToken , let expiresIn, _, let nonce, _, let identifiers) :
343360 return . success(
344361 (
345362 try . init(
@@ -348,6 +365,9 @@ public actor AuthorizationServerClient: AuthorizationServerClientType {
348365 value: tokenType
349366 )
350367 ) ,
368+ try . init(
369+ refreshToken: refreshToken
370+ ) ,
351371 . init(
352372 value: nonce
353373 ) ,
@@ -389,27 +409,25 @@ public actor AuthorizationServerClient: AuthorizationServerClientType {
389409 }
390410 }
391411
392- public func requestAccessTokenPreAuthFlow(
393- preAuthorizedCode: String ,
394- txCode: TxCode ? ,
412+ public func refreshAccessToken(
395413 clientId: String ,
396- transactionCode: String ? ,
397- identifiers: [ CredentialConfigurationIdentifier ] ,
414+ refreshToken: IssuanceRefreshToken ,
398415 dpopNonce: Nonce ? ,
399416 retry: Bool
400417 ) async throws -> Result < (
401418 IssuanceAccessToken ,
402419 CNonce ? ,
403420 AuthorizationDetailsIdentifiers ? ,
421+ TokenType ? ,
404422 Int ? ,
405- Nonce ? ) , Error > {
406- let parameters : JSON = try await preAuthCodeFlow (
407- preAuthorizedCode : preAuthorizedCode ,
408- txCode : txCode ,
409- clientId : clientId,
410- transactionCode : transactionCode ,
411- identifiers : identifiers
412- )
423+ Nonce ?
424+ ) , Error > {
425+
426+ let parameters : JSON = JSON ( [
427+ Constants . CLIENT_ID_PARAM : clientId,
428+ Constants . GRANT_TYPE_PARAM : Constants . REFRESH_TOKEN ,
429+ Constants . REFRESH_TOKEN_PARAM : refreshToken . refreshToken
430+ ] . compactMapValues { $0 } )
413431
414432 do {
415433 let response : ResponseWithHeaders < AccessTokenRequestResponse > = try await service. formPost (
@@ -422,21 +440,34 @@ public actor AuthorizationServerClient: AuthorizationServerClientType {
422440 )
423441
424442 switch response. body {
425- case . success( let tokenType, let accessToken, _, let expiresIn, _, let nonce, _, let identifiers) :
443+ case . success(
444+ let tokenType,
445+ let accessToken,
446+ _,
447+ let expiresIn,
448+ _,
449+ let nonce,
450+ _,
451+ let identifiers
452+ ) :
426453 return . success(
427454 (
428455 try . init(
429456 accessToken: accessToken,
430457 tokenType: . init(
431458 value: tokenType
432- )
459+ ) ,
460+ expiresIn: TimeInterval ( expiresIn)
433461 ) ,
434462 . init(
435463 value: nonce
436464 ) ,
437465 identifiers,
466+ TokenType (
467+ value: tokenType
468+ ) ,
438469 expiresIn,
439- dpopNonce
470+ response . dpopNonce ( )
440471 )
441472 )
442473 case . failure( let error, let errorDescription) :
@@ -450,14 +481,12 @@ public actor AuthorizationServerClient: AuthorizationServerClientType {
450481 switch postError {
451482 case . useDpopNonce( let nonce) :
452483 if retry {
453- return try await requestAccessTokenPreAuthFlow (
454- preAuthorizedCode: preAuthorizedCode,
455- txCode: txCode,
484+ return try await refreshAccessToken (
456485 clientId: clientId,
457- transactionCode: transactionCode,
458- identifiers: identifiers,
486+ refreshToken: refreshToken,
459487 dpopNonce: nonce,
460- retry: false )
488+ retry: false
489+ )
461490 } else {
462491 return . failure( ValidationError . retryFailedAfterDpopNonce)
463492 }
@@ -470,6 +499,91 @@ public actor AuthorizationServerClient: AuthorizationServerClientType {
470499 }
471500 }
472501
502+ public func requestAccessTokenPreAuthFlow(
503+ preAuthorizedCode: String ,
504+ txCode: TxCode ? ,
505+ clientId: String ,
506+ transactionCode: String ? ,
507+ identifiers: [ CredentialConfigurationIdentifier ] ,
508+ dpopNonce: Nonce ? ,
509+ retry: Bool
510+ ) async throws -> Result < (
511+ IssuanceAccessToken ,
512+ IssuanceRefreshToken ,
513+ CNonce ? ,
514+ AuthorizationDetailsIdentifiers ? ,
515+ Int ? ,
516+ Nonce ? ) , Error > {
517+ let parameters : JSON = try await preAuthCodeFlow (
518+ preAuthorizedCode: preAuthorizedCode,
519+ txCode: txCode,
520+ clientId: clientId,
521+ transactionCode: transactionCode,
522+ identifiers: identifiers
523+ )
524+
525+ do {
526+ let response : ResponseWithHeaders < AccessTokenRequestResponse > = try await service. formPost (
527+ poster: tokenPoster,
528+ url: tokenEndpoint,
529+ headers: try tokenEndPointHeaders (
530+ dpopNonce: dpopNonce
531+ ) ,
532+ parameters: parameters. toDictionary ( ) . convertToDictionaryOfStrings ( )
533+ )
534+
535+ switch response. body {
536+ case . success( let tokenType, let accessToken, let refreshToken, let expiresIn, _, let nonce, _, let identifiers) :
537+ return . success(
538+ (
539+ try . init(
540+ accessToken: accessToken,
541+ tokenType: . init(
542+ value: tokenType
543+ )
544+ ) ,
545+ try . init(
546+ refreshToken: refreshToken
547+ ) ,
548+ . init(
549+ value: nonce
550+ ) ,
551+ identifiers,
552+ expiresIn,
553+ dpopNonce
554+ )
555+ )
556+ case . failure( let error, let errorDescription) :
557+ throw CredentialIssuanceError . pushedAuthorizationRequestFailed (
558+ error: error,
559+ errorDescription: errorDescription
560+ )
561+ }
562+ } catch {
563+ if let postError = error as? PostError {
564+ switch postError {
565+ case . useDpopNonce( let nonce) :
566+ if retry {
567+ return try await requestAccessTokenPreAuthFlow (
568+ preAuthorizedCode: preAuthorizedCode,
569+ txCode: txCode,
570+ clientId: clientId,
571+ transactionCode: transactionCode,
572+ identifiers: identifiers,
573+ dpopNonce: nonce,
574+ retry: false )
575+ } else {
576+ return . failure( ValidationError . retryFailedAfterDpopNonce)
577+ }
578+ default :
579+ return . failure( error)
580+ }
581+ } else {
582+ return . failure( error)
583+ }
584+ }
585+ }
586+
473587 func toAuthorizationDetail(
474588 credentialConfigurationIds: [ CredentialConfigurationIdentifier ]
475589 ) -> [ AuthorizationDetail ] {
0 commit comments