diff --git a/Sources/Imperial/Services/DeviantArt/DeviantArt.swift b/Sources/Imperial/Services/DeviantArt/DeviantArt.swift index 239a3de8..70b5847e 100644 --- a/Sources/Imperial/Services/DeviantArt/DeviantArt.swift +++ b/Sources/Imperial/Services/DeviantArt/DeviantArt.swift @@ -8,10 +8,10 @@ public class DeviantArt: FederatedService { public required init( router: Router, authenticate: String, - authenticateCallback: ((Request)throws -> (Future))?, + authenticateCallback: ((Request)async throws -> Void)?, callback: String, scope: [String] = [], - completion: @escaping (Request, String)throws -> (Future) + completion: @escaping (Request, String) async throws -> Response) ) throws { self.router = try DeviantArtRouter(callback: callback, completion: completion) self.tokens = self.router.tokens diff --git a/Sources/Imperial/Services/DeviantArt/DeviantArtRouter.swift b/Sources/Imperial/Services/DeviantArt/DeviantArtRouter.swift index 66e8dd93..e38b3ee7 100644 --- a/Sources/Imperial/Services/DeviantArt/DeviantArtRouter.swift +++ b/Sources/Imperial/Services/DeviantArt/DeviantArtRouter.swift @@ -3,12 +3,12 @@ import Foundation public class DeviantArtRouter: FederatedServiceRouter { public let tokens: FederatedServiceTokens - public let callbackCompletion: (Request, String)throws -> (Future) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public var callbackURL: String public let accessTokenURL: String = "https://www.deviantart.com/oauth2/token" - public required init(callback: String, completion: @escaping (Request, String)throws -> (Future)) throws { + public required init(callback: String, completion: @escaping (Request, String)async throws -> Response) throws { self.tokens = try DeviantArtAuth() self.callbackURL = callback self.callbackCompletion = completion @@ -27,7 +27,7 @@ public class DeviantArtRouter: FederatedServiceRouter { "response_type=code" } - public func fetchToken(from request: Request)throws -> Future { + public func fetchToken(from request: Request) async throws -> String { let code: String if let queryCode: String = try request.query.get(at: "code") { code = queryCode @@ -38,35 +38,33 @@ public class DeviantArtRouter: FederatedServiceRouter { } let body = DeviantArtCallbackBody(code: code, clientId: self.tokens.clientID, clientSecret: self.tokens.clientSecret, redirectURI: self.callbackURL) - return try body.encode(using: request).flatMap(to: Response.self) { request in - guard let url = URL(string: self.accessTokenURL) else { - throw Abort(.internalServerError, reason: "Unable to convert String '\(self.accessTokenURL)' to URL") - } - request.http.method = .POST - request.http.url = url - return try request.make(Client.self).send(request) - }.flatMap(to: String.self) { response in - let session = try request.session() + let requestBody = try await body.encode(using: request) + guard let url = URL(string: self.accessTokenURL) else { + throw Abort(.internalServerError, reason: "Unable to convert String '\(self.accessTokenURL)' to URL") + } + requestBody.http.method = .POST + requestBody.http.url = url + let response = try await requestBody.make(Client.self).send(request) + let session = try request.session() - return response.content.get(String.self, at: ["refresh_token"]) - .flatMap { refresh in - session.setRefreshToken(refresh) + return response.content.get(String.self, at: ["refresh_token"]) + .flatMap { refresh in + session.setRefreshToken(refresh) - return response.content.get(String.self, at: ["access_token"]) - } + return response.content.get(String.self, at: ["access_token"]) } + } - public func callback(_ request: Request)throws -> Future { - return try self.fetchToken(from: request).flatMap(to: ResponseEncodable.self) { accessToken in - let session = try request.session() + public func callback(_ request: Request) async throws -> Response { + let accessToken = try await self.fetchToken(from: request) + let session = try request.session() - session.setAccessToken(accessToken) - try session.set("access_token_service", to: OAuthService.deviantart) + session.setAccessToken(accessToken) + try session.set("access_token_service", to: OAuthService.deviantart) - return try self.callbackCompletion(request, accessToken) - }.flatMap(to: Response.self) { response in - return try response.encode(for: request) - } + let response = try await self.callbackCompletion(request, accessToken) + return try response.encode(for: request) + } } diff --git a/Sources/Imperial/Services/Imgur/Imgur.swift b/Sources/Imperial/Services/Imgur/Imgur.swift index 17e360ee..296bf1f8 100644 --- a/Sources/Imperial/Services/Imgur/Imgur.swift +++ b/Sources/Imperial/Services/Imgur/Imgur.swift @@ -8,10 +8,10 @@ public class Imgur: FederatedService { public required init( router: Router, authenticate: String, - authenticateCallback: ((Request)throws -> (Future))?, + authenticateCallback: ((Request) async throws -> Void?, callback: String, scope: [String] = [], - completion: @escaping (Request, String)throws -> (Future) + completion: @escaping (Request, String) async throws -> Response ) throws { self.router = try ImgurRouter(callback: callback, completion: completion) self.tokens = self.router.tokens diff --git a/Sources/Imperial/Services/Imgur/ImgurRouter.swift b/Sources/Imperial/Services/Imgur/ImgurRouter.swift index 52e3756f..7f2b7515 100644 --- a/Sources/Imperial/Services/Imgur/ImgurRouter.swift +++ b/Sources/Imperial/Services/Imgur/ImgurRouter.swift @@ -3,12 +3,12 @@ import Foundation public class ImgurRouter: FederatedServiceRouter { public let tokens: FederatedServiceTokens - public let callbackCompletion: (Request, String)throws -> (Future) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public var callbackURL: String public let accessTokenURL: String = "https://api.imgur.com/oauth2/token" - public required init(callback: String, completion: @escaping (Request, String)throws -> (Future)) throws { + public required init(callback: String, completion: @escaping (Request, String) async throws -> Response) throws { self.tokens = try ImgurAuth() self.callbackURL = callback self.callbackCompletion = completion @@ -20,7 +20,7 @@ public class ImgurRouter: FederatedServiceRouter { "response_type=code" } - public func fetchToken(from request: Request)throws -> Future { + public func fetchToken(from request: Request) async throws -> String { let code: String if let queryCode: String = try request.query.get(at: "code") { code = queryCode @@ -50,8 +50,8 @@ public class ImgurRouter: FederatedServiceRouter { } } - public func callback(_ request: Request)throws -> Future { - return try self.fetchToken(from: request).flatMap(to: ResponseEncodable.self) { accessToken in + public func callback(_ request: Request) async throws -> Response { + return try self.fetchToken(from: request).flatMap(to: Response.self) { accessToken in let session = try request.session() session.setAccessToken(accessToken) diff --git a/Sources/Imperial/Services/Microsoft/Microsoft.swift b/Sources/Imperial/Services/Microsoft/Microsoft.swift index 2279eaa2..0f11498e 100644 --- a/Sources/Imperial/Services/Microsoft/Microsoft.swift +++ b/Sources/Imperial/Services/Microsoft/Microsoft.swift @@ -8,10 +8,10 @@ public class Microsoft: FederatedService { public required init( router: Router, authenticate: String, - authenticateCallback: ((Request)throws -> (Future))?, + authenticateCallback: ((Request) async throws -> Void)?, callback: String, scope: [String] = [], - completion: @escaping (Request, String)throws -> (Future) + completion: @escaping (Request, String) async throws -> Response ) throws { self.router = try MicrosoftRouter(callback: callback, completion: completion) self.tokens = self.router.tokens diff --git a/Sources/Imperial/Services/Microsoft/MicrosoftRouter.swift b/Sources/Imperial/Services/Microsoft/MicrosoftRouter.swift index 2e6ec451..1878a44a 100644 --- a/Sources/Imperial/Services/Microsoft/MicrosoftRouter.swift +++ b/Sources/Imperial/Services/Microsoft/MicrosoftRouter.swift @@ -5,7 +5,7 @@ public class MicrosoftRouter: FederatedServiceRouter { public static var tenantIDEnvKey: String = "MICROSOFT_TENANT_ID" public let tokens: FederatedServiceTokens - public let callbackCompletion: (Request, String)throws -> (Future) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public let callbackURL: String public var tenantID: String { Environment.get(MicrosoftRouter.tenantIDEnvKey) ?? "common" } @@ -13,7 +13,7 @@ public class MicrosoftRouter: FederatedServiceRouter { public required init( callback: String, - completion: @escaping (Request, String) throws -> (Future) + completion: @escaping (Request, String) assync throws -> Response ) throws { self.tokens = try MicrosoftAuth() self.callbackURL = callback @@ -30,7 +30,7 @@ public class MicrosoftRouter: FederatedServiceRouter { + "prompt=consent" } - public func fetchToken(from request: Request)throws -> Future { + public func fetchToken(from request: Request) async throws -> String { let code: String if let queryCode: String = try request.query.get(at: "code") { @@ -66,8 +66,8 @@ public class MicrosoftRouter: FederatedServiceRouter { } } - public func callback(_ request: Request)throws -> Future { - return try self.fetchToken(from: request).flatMap(to: ResponseEncodable.self) { accessToken in + public func callback(_ request: Request) async throws -> Response { + return try self.fetchToken(from: request).flatMap(to: Response.self) { accessToken in let session = try request.session() session.setAccessToken(accessToken) diff --git a/Sources/Imperial/Services/Mixcloud/Mixcloud.swift b/Sources/Imperial/Services/Mixcloud/Mixcloud.swift index 5396a325..7c03c2f7 100644 --- a/Sources/Imperial/Services/Mixcloud/Mixcloud.swift +++ b/Sources/Imperial/Services/Mixcloud/Mixcloud.swift @@ -13,7 +13,7 @@ public class Mixcloud: FederatedService { authenticateCallback: ((Request)throws -> (Future))?, callback: String, scope: [String] = [], - completion: @escaping (Request, String)throws -> (Future) + completion: @escaping (Request, String) async throws -> Response ) throws { self.router = try MixcloudRouter(callback: callback, completion: completion) self.tokens = self.router.tokens diff --git a/Sources/Imperial/Services/Mixcloud/MixcloudRouter.swift b/Sources/Imperial/Services/Mixcloud/MixcloudRouter.swift index 5f832a75..3d51dfc0 100644 --- a/Sources/Imperial/Services/Mixcloud/MixcloudRouter.swift +++ b/Sources/Imperial/Services/Mixcloud/MixcloudRouter.swift @@ -3,12 +3,12 @@ import Foundation public class MixcloudRouter: FederatedServiceRouter { public let tokens: FederatedServiceTokens - public let callbackCompletion: (Request, String)throws -> (Future) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public var callbackURL: String public let accessTokenURL: String = "https://www.mixcloud.com/oauth/access_token" - public required init(callback: String, completion: @escaping (Request, String)throws -> (Future)) throws { + public required init(callback: String, completion: @escaping (Request, String) async throws -> Response) throws { self.tokens = try MixcloudAuth() self.callbackURL = callback self.callbackCompletion = completion @@ -20,7 +20,7 @@ public class MixcloudRouter: FederatedServiceRouter { "redirect_uri=\(self.callbackURL)" } - public func fetchToken(from request: Request)throws -> Future { + public func fetchToken(from request: Request) async throws -> String { let code: String if let queryCode: String = try request.query.get(at: "code") { code = queryCode @@ -40,7 +40,7 @@ public class MixcloudRouter: FederatedServiceRouter { } } - public func callback(_ request: Request)throws -> Future { + public func callback(_ request: Request) async throws -> Response { return try self.fetchToken(from: request).flatMap(to: ResponseEncodable.self) { accessToken in let session = try request.session() diff --git a/Sources/ImperialAuth0/Auth0.swift b/Sources/ImperialAuth0/Auth0.swift index b9c07945..8c484c80 100644 --- a/Sources/ImperialAuth0/Auth0.swift +++ b/Sources/ImperialAuth0/Auth0.swift @@ -9,16 +9,16 @@ public class Auth0: FederatedService { public required init( routes: RoutesBuilder, authenticate: String, - authenticateCallback: ((Request) throws -> (EventLoopFuture))?, + authenticateCallback: ((Request) async throws -> Void)?, callback: String, scope: [String] = [], - completion: @escaping (Request, String) throws -> (EventLoopFuture) - ) throws { - self.router = try Auth0Router(callback: callback, completion: completion) + completion: @escaping (Request, String) async throws -> Response + ) async throws { + self.router = try await Auth0Router(callback: callback, completion: completion) self.tokens = self.router.tokens self.router.scope = scope - try self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) + try await self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) OAuthService.register(.auth0) } diff --git a/Sources/ImperialAuth0/Auth0Router.swift b/Sources/ImperialAuth0/Auth0Router.swift index d8064081..9dcf9b89 100644 --- a/Sources/ImperialAuth0/Auth0Router.swift +++ b/Sources/ImperialAuth0/Auth0Router.swift @@ -5,7 +5,7 @@ public class Auth0Router: FederatedServiceRouter { public let baseURL: String public let tokens: FederatedServiceTokens - public let callbackCompletion: (Request, String) throws -> (EventLoopFuture) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [ ] public var requiredScopes = [ "openid" ] public let callbackURL: String @@ -17,7 +17,7 @@ public class Auth0Router: FederatedServiceRouter { return self.baseURL.finished(with: "/") + path } - public required init(callback: String, completion: @escaping (Request, String) throws -> (EventLoopFuture)) throws { + public required init(callback: String, completion: @escaping (Request, String) async throws -> Response) async throws { let auth = try Auth0Auth() self.tokens = auth self.baseURL = "https://\(auth.domain)" @@ -45,7 +45,7 @@ public class Auth0Router: FederatedServiceRouter { return rtn } - public func callbackBody(with code: String) -> ResponseEncodable { + public func callbackBody(with code: String) -> any Content { Auth0CallbackBody(clientId: self.tokens.clientID, clientSecret: self.tokens.clientSecret, code: code, diff --git a/Sources/ImperialCore/Routing/FederatedServiceRouter.swift b/Sources/ImperialCore/Routing/FederatedServiceRouter.swift index 623a460a..3d951b53 100644 --- a/Sources/ImperialCore/Routing/FederatedServiceRouter.swift +++ b/Sources/ImperialCore/Routing/FederatedServiceRouter.swift @@ -10,7 +10,7 @@ public protocol FederatedServiceRouter { /// The callback that is fired after the access token is fetched from the OAuth provider. /// The response that is returned from this callback is also returned from the callback route. - var callbackCompletion: (Request, String) throws -> (EventLoopFuture) { get } + var callbackCompletion: (Request, String) async throws -> Response { get } /// The scopes to get permission for when getting the access token. /// Usage of this property varies by provider. @@ -43,7 +43,7 @@ public protocol FederatedServiceRouter { /// - callback: The callback URL that the OAuth provider will redirect to after authenticating the user. /// - completion: The completion handler that will be fired at the end of the `callback` route. The access token is passed into it. /// - Throws: Any errors that could occur in the implementation. - init(callback: String, completion: @escaping (Request, String) throws -> (EventLoopFuture)) throws + init(callback: String, completion: @escaping (Request, String) async throws -> Response) async throws /// Configures the `authenticate` and `callback` routes with the droplet. /// @@ -51,24 +51,24 @@ public protocol FederatedServiceRouter { /// - authURL: The URL for the route that will redirect the user to the OAuth provider. /// - authenticateCallback: Execute custom code within the authenticate closure before redirection. /// - Throws: N/A - func configureRoutes(withAuthURL authURL: String, authenticateCallback: ((Request) throws -> (EventLoopFuture))?, on router: RoutesBuilder) throws + func configureRoutes(withAuthURL authURL: String, authenticateCallback: ((Request) async throws -> Void)?, on router: RoutesBuilder) async throws /// Gets an access token from an OAuth provider. /// This method is the main body of the `callback` handler. /// /// - Parameters: request: The request for the route /// this method is called in. - func fetchToken(from request: Request) throws -> EventLoopFuture + func fetchToken(from request: Request) async throws -> String /// Creates CallbackBody with authorization code - func callbackBody(with code: String) -> ResponseEncodable + func callbackBody(with code: String) -> any Content /// The route that the OAuth provider calls when the user has been authenticated. /// /// - Parameter request: The request from the OAuth provider. /// - Returns: A response that should redirect the user back to the app. /// - Throws: An errors that occur in the implementation code. - func callback(_ request: Request) throws -> EventLoopFuture + func callback(_ request: Request) async throws -> Response } extension FederatedServiceRouter { @@ -77,20 +77,19 @@ extension FederatedServiceRouter { public var errorKey: String { "error" } public var callbackHeaders: HTTPHeaders { [:] } - public func configureRoutes(withAuthURL authURL: String, authenticateCallback: ((Request) throws -> (EventLoopFuture))?, on router: RoutesBuilder) throws { - router.get(callbackURL.pathComponents, use: callback) - router.get(authURL.pathComponents) { req -> EventLoopFuture in + public func configureRoutes(withAuthURL authURL: String, authenticateCallback: ((Request) async throws -> Void)?, on router: RoutesBuilder) async throws { + router.get(callbackURL.pathComponents, use: self.callback) + router.get(authURL.pathComponents) { req async throws -> Response in let redirect: Response = req.redirect(to: try self.authURL(req)) guard let authenticateCallback = authenticateCallback else { - return req.eventLoop.makeSucceededFuture(redirect) - } - return try authenticateCallback(req).map { return redirect } + try await authenticateCallback(req) + return redirect } } - public func fetchToken(from request: Request) throws -> EventLoopFuture { + public func fetchToken(from request: Request) async throws -> String { let code: String if let queryCode: String = try request.query.get(at: codeKey) { code = queryCode @@ -100,31 +99,21 @@ extension FederatedServiceRouter { throw Abort(.badRequest, reason: "Missing 'code' key in URL query") } - let body = callbackBody(with: code) let url = URI(string: accessTokenURL) + let body = try JSONEncoder().encode(callbackBody(with: code)) - return body.encodeResponse(for: request) - .map { $0.body.buffer } - .flatMap { buffer in - return request.client.post(url, headers: self.callbackHeaders) { $0.body = buffer } - }.flatMapThrowing { response in - return try response.content.get(String.self, at: ["access_token"]) - } + let response = try await request.client.post(url, headers: self.callbackHeaders, beforeSend: { r in + r.body = ByteBuffer(data: body) + }) + return try response.content.get(String.self, at: ["access_token"]) } - public func callback(_ request: Request) throws -> EventLoopFuture { - return try self.fetchToken(from: request).flatMap { accessToken in - let session = request.session - do { - try session.setAccessToken(accessToken) - try session.set("access_token_service", to: self.service) - return try self.callbackCompletion(request, accessToken).flatMap { response in - return response.encodeResponse(for: request) - } - } catch { - return request.eventLoop.makeFailedFuture(error) - } - } + public func callback(_ request: Request) async throws -> Response { + let accessToken = try await self.fetchToken(from: request) + let session = request.session + try session.setAccessToken(accessToken) + try session.set("access_token_service", to: self.service) + return try await self.callbackCompletion(request, accessToken) } } diff --git a/Sources/ImperialCore/ServiceRegister.swift b/Sources/ImperialCore/ServiceRegister.swift index 3de41f1d..83c645ed 100644 --- a/Sources/ImperialCore/ServiceRegister.swift +++ b/Sources/ImperialCore/ServiceRegister.swift @@ -17,12 +17,12 @@ extension RoutesBuilder { public func oAuth( from provider: OAuthProvider.Type, authenticate authUrl: String, - authenticateCallback: ((Request) throws -> (EventLoopFuture))? = nil, + authenticateCallback: ((Request) async throws -> Void)? = nil, callback: String, scope: [String] = [], - completion: @escaping (Request, String) throws -> EventLoopFuture - ) throws where OAuthProvider: FederatedService { - _ = try OAuthProvider( + completion: @escaping (Request, String) async throws -> Response + ) async throws where OAuthProvider: FederatedService { + _ = try await OAuthProvider( routes: self, authenticate: authUrl, authenticateCallback: authenticateCallback, @@ -46,14 +46,14 @@ extension RoutesBuilder { public func oAuth( from provider: OAuthProvider.Type, authenticate authUrl: String, - authenticateCallback: ((Request) throws -> (EventLoopFuture))? = nil, + authenticateCallback: ((Request) async throws -> Void)? = nil, callback: String, scope: [String] = [], redirect redirectURL: String - ) throws where OAuthProvider: FederatedService { - try self.oAuth(from: OAuthProvider.self, authenticate: authUrl, authenticateCallback: authenticateCallback, callback: callback, scope: scope) { (request, _) in + ) async throws where OAuthProvider: FederatedService { + try await self.oAuth(from: OAuthProvider.self, authenticate: authUrl, authenticateCallback: authenticateCallback, callback: callback, scope: scope) { (request, _) in let redirect: Response = request.redirect(to: redirectURL) - return request.eventLoop.makeSucceededFuture(redirect) + return redirect } } } diff --git a/Sources/ImperialCore/Services/FederatedService.swift b/Sources/ImperialCore/Services/FederatedService.swift index 12e4d7ef..8a066527 100644 --- a/Sources/ImperialCore/Services/FederatedService.swift +++ b/Sources/ImperialCore/Services/FederatedService.swift @@ -42,5 +42,5 @@ public protocol FederatedService { /// - scope: The scopes to send to the provider to request access to. /// - completion: The completion handler that will fire at the end of the callback route. The access token is passed into the callback and the response that is returned will be returned from the callback route. This will usually be a redirect back to the app. /// - Throws: Any errors that occur in the implementation. - init(routes: RoutesBuilder, authenticate: String, authenticateCallback: ((Request) throws -> (EventLoopFuture))?, callback: String, scope: [String], completion: @escaping (Request, String) throws -> (EventLoopFuture)) throws + init(routes: RoutesBuilder, authenticate: String, authenticateCallback: ((Request) async throws -> Void)?, callback: String, scope: [String], completion: @escaping (Request, String) async throws -> Response) async throws } diff --git a/Sources/ImperialDiscord/Discord.swift b/Sources/ImperialDiscord/Discord.swift index fa2db848..2e6f7440 100644 --- a/Sources/ImperialDiscord/Discord.swift +++ b/Sources/ImperialDiscord/Discord.swift @@ -9,16 +9,16 @@ public class Discord: FederatedService { public required init( routes: RoutesBuilder, authenticate: String, - authenticateCallback: ((Request) throws -> (EventLoopFuture))?, + authenticateCallback: ((Request) async throws -> Void)?, callback: String, scope: [String] = [], - completion: @escaping (Request, String) throws -> (EventLoopFuture) - ) throws { + completion: @escaping (Request, String) async throws -> Response + ) async throws { self.router = try DiscordRouter(callback: callback, completion: completion) self.tokens = self.router.tokens self.router.scope = scope - try self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) + try await self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) OAuthService.register(.discord) } diff --git a/Sources/ImperialDiscord/DiscordRouter.swift b/Sources/ImperialDiscord/DiscordRouter.swift index 6932a865..2958d963 100644 --- a/Sources/ImperialDiscord/DiscordRouter.swift +++ b/Sources/ImperialDiscord/DiscordRouter.swift @@ -2,18 +2,19 @@ import Vapor import Foundation public class DiscordRouter: FederatedServiceRouter { + public static var baseURL: String = "https://discord.com/" public static var callbackURL: String = "callback" public let tokens: FederatedServiceTokens - public let callbackCompletion: (Request, String) throws -> (EventLoopFuture) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public let callbackURL: String public let accessTokenURL: String = "\(DiscordRouter.baseURL.finished(with: "/"))api/oauth2/token" public let service: OAuthService = .discord public let callbackHeaders = HTTPHeaders([("Content-Type", "application/x-www-form-urlencoded")]) - public required init(callback: String, completion: @escaping (Request, String) throws -> (EventLoopFuture)) throws { + public required init(callback: String, completion: @escaping (Request, String) async throws -> Response) throws { self.tokens = try DiscordAuth() self.callbackURL = callback self.callbackCompletion = completion @@ -39,7 +40,7 @@ public class DiscordRouter: FederatedServiceRouter { return url.absoluteString } - public func callbackBody(with code: String) -> ResponseEncodable { + public func callbackBody(with code: String) -> any Content { return DiscordCallbackBody( clientId: tokens.clientID, clientSecret: tokens.clientSecret, diff --git a/Sources/ImperialDropbox/Dropbox.swift b/Sources/ImperialDropbox/Dropbox.swift index 667f7d94..31be38fa 100644 --- a/Sources/ImperialDropbox/Dropbox.swift +++ b/Sources/ImperialDropbox/Dropbox.swift @@ -2,6 +2,8 @@ import Vapor public class Dropbox: FederatedService { + + public var tokens: FederatedServiceTokens public var router: FederatedServiceRouter @@ -9,16 +11,16 @@ public class Dropbox: FederatedService { public required init( routes: RoutesBuilder, authenticate: String, - authenticateCallback: ((Request) throws -> (EventLoopFuture))?, + authenticateCallback: ((Request) async throws -> Void)?, callback: String, scope: [String] = [], - completion: @escaping (Request, String) throws -> (EventLoopFuture) - ) throws { + completion: @escaping (Request, String) async throws -> Response + ) async throws { self.router = try DropboxRouter(callback: callback, completion: completion) self.tokens = self.router.tokens self.router.scope = scope - try self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) + try await self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) OAuthService.register(.dropbox) } diff --git a/Sources/ImperialDropbox/DropboxRouter.swift b/Sources/ImperialDropbox/DropboxRouter.swift index 78d6ab88..eeb7a813 100644 --- a/Sources/ImperialDropbox/DropboxRouter.swift +++ b/Sources/ImperialDropbox/DropboxRouter.swift @@ -2,8 +2,9 @@ import Vapor import Foundation public class DropboxRouter: FederatedServiceRouter { + public let tokens: FederatedServiceTokens - public let callbackCompletion: (Request, String) throws -> (EventLoopFuture) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public let callbackURL: String public let accessTokenURL: String = "https://api.dropboxapi.com/oauth2/token" @@ -17,7 +18,7 @@ public class DropboxRouter: FederatedServiceRouter { public let service: OAuthService = .dropbox - public required init(callback: String, completion: @escaping (Request, String) throws -> (EventLoopFuture)) throws { + public required init(callback: String, completion: @escaping (Request, String) async throws -> Response) throws { self.tokens = try DropboxAuth() self.callbackURL = callback self.callbackCompletion = completion @@ -42,7 +43,7 @@ public class DropboxRouter: FederatedServiceRouter { return url.absoluteString } - public func callbackBody(with code: String) -> ResponseEncodable { + public func callbackBody(with code: String) -> any Content { DropboxCallbackBody(code: code, redirectURI: callbackURL) } diff --git a/Sources/ImperialFacebook/Facebook.swift b/Sources/ImperialFacebook/Facebook.swift index 41fdde79..912237aa 100644 --- a/Sources/ImperialFacebook/Facebook.swift +++ b/Sources/ImperialFacebook/Facebook.swift @@ -9,16 +9,16 @@ public class Facebook: FederatedService { public required init( routes: RoutesBuilder, authenticate: String, - authenticateCallback: ((Request) throws -> (EventLoopFuture))?, + authenticateCallback: ((Request) async throws -> Void)?, callback: String, scope: [String] = [], - completion: @escaping (Request, String) throws -> (EventLoopFuture) - ) throws { + completion: @escaping (Request, String) async throws -> Response + ) async throws { self.router = try FacebookRouter(callback: callback, completion: completion) self.tokens = self.router.tokens self.router.scope = scope - try self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) + try await self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) OAuthService.register(.facebook) } diff --git a/Sources/ImperialFacebook/FacebookRouter.swift b/Sources/ImperialFacebook/FacebookRouter.swift index 7f404ab5..5f1c54e3 100644 --- a/Sources/ImperialFacebook/FacebookRouter.swift +++ b/Sources/ImperialFacebook/FacebookRouter.swift @@ -4,7 +4,7 @@ import Foundation public class FacebookRouter: FederatedServiceRouter { public let tokens: FederatedServiceTokens - public let callbackCompletion: (Request, String) throws -> (EventLoopFuture) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public let callbackURL: String public var accessTokenURL: String = "https://graph.facebook.com/v3.2/oauth/access_token" @@ -29,13 +29,13 @@ public class FacebookRouter: FederatedServiceRouter { return url.absoluteString } - public required init(callback: String, completion: @escaping (Request, String) throws -> (EventLoopFuture)) throws { + public required init(callback: String, completion: @escaping (Request, String) async throws -> Response) throws { self.tokens = try FacebookAuth() self.callbackURL = callback self.callbackCompletion = completion } - public func callbackBody(with code: String) -> ResponseEncodable { + public func callbackBody(with code: String) -> any Content { FacebookCallbackBody(code: code, clientId: tokens.clientID, clientSecret: tokens.clientSecret, diff --git a/Sources/ImperialGitHub/GitHub.swift b/Sources/ImperialGitHub/GitHub.swift index ee511d48..cabe3d24 100644 --- a/Sources/ImperialGitHub/GitHub.swift +++ b/Sources/ImperialGitHub/GitHub.swift @@ -9,16 +9,16 @@ public class GitHub: FederatedService { public required init( routes: RoutesBuilder, authenticate: String, - authenticateCallback: ((Request) throws -> (EventLoopFuture))?, + authenticateCallback: ((Request) async throws -> Void)?, callback: String, scope: [String] = [], - completion: @escaping (Request, String) throws -> (EventLoopFuture) - ) throws { - self.router = try GitHubRouter(callback: callback, completion: completion) + completion: @escaping (Request, String) async throws -> Response + ) async throws { + self.router = try await GitHubRouter(callback: callback, completion: completion) self.tokens = self.router.tokens self.router.scope = scope - try self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) + try await self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) OAuthService.register(.github) } diff --git a/Sources/ImperialGitHub/GitHubCallbackBody.swift b/Sources/ImperialGitHub/GitHubCallbackBody.swift index e697eae4..aa1d515d 100644 --- a/Sources/ImperialGitHub/GitHubCallbackBody.swift +++ b/Sources/ImperialGitHub/GitHubCallbackBody.swift @@ -1,6 +1,6 @@ import Vapor -struct GitHubCallbackBody: Content { +public struct GitHubCallbackBody: Content { let clientId: String let clientSecret: String let code: String diff --git a/Sources/ImperialGitHub/GitHubRouter.swift b/Sources/ImperialGitHub/GitHubRouter.swift index a1a53d02..7ec73189 100644 --- a/Sources/ImperialGitHub/GitHubRouter.swift +++ b/Sources/ImperialGitHub/GitHubRouter.swift @@ -2,10 +2,9 @@ import Vapor import Foundation public class GitHubRouter: FederatedServiceRouter { - public static var baseURL: String = "https://github.com/" public let tokens: FederatedServiceTokens - public let callbackCompletion: (Request, String) throws -> (EventLoopFuture) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public let callbackURL: String public let accessTokenURL: String = "\(GitHubRouter.baseURL.finished(with: "/"))login/oauth/access_token" @@ -16,7 +15,7 @@ public class GitHubRouter: FederatedServiceRouter { return headers }() - public required init(callback: String, completion: @escaping (Request, String) throws -> (EventLoopFuture)) throws { + public required init(callback: String, completion: @escaping (Vapor.Request, String) async throws -> Vapor.Response) async throws { self.tokens = try GitHubAuth() self.callbackURL = callback self.callbackCompletion = completion @@ -40,7 +39,7 @@ public class GitHubRouter: FederatedServiceRouter { return url.absoluteString } - public func callbackBody(with code: String) -> ResponseEncodable { + public func callbackBody(with code: String) -> any Content { GitHubCallbackBody(clientId: tokens.clientID, clientSecret: tokens.clientSecret, code: code) diff --git a/Sources/ImperialGitlab/Gitlab.swift b/Sources/ImperialGitlab/Gitlab.swift index 62b88efb..81d9f823 100644 --- a/Sources/ImperialGitlab/Gitlab.swift +++ b/Sources/ImperialGitlab/Gitlab.swift @@ -9,16 +9,16 @@ public class Gitlab: FederatedService { public required init( routes: RoutesBuilder, authenticate: String, - authenticateCallback: ((Request) throws -> (EventLoopFuture))?, + authenticateCallback: ((Request) async throws -> Void)?, callback: String, scope: [String] = [], - completion: @escaping (Request, String) throws -> (EventLoopFuture) - ) throws { - self.router = try GitlabRouter(callback: callback, completion: completion) + completion: @escaping (Request, String) async throws -> Response + ) async throws { + self.router = try await GitlabRouter(callback: callback, completion: completion) self.tokens = self.router.tokens self.router.scope = scope - try self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) + try await self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) OAuthService.register(.gitlab) } diff --git a/Sources/ImperialGitlab/GitlabRouter.swift b/Sources/ImperialGitlab/GitlabRouter.swift index de35b259..52156575 100644 --- a/Sources/ImperialGitlab/GitlabRouter.swift +++ b/Sources/ImperialGitlab/GitlabRouter.swift @@ -6,13 +6,13 @@ public class GitlabRouter: FederatedServiceRouter { public static var baseURL: String = "https://gitlab.com/" public static var callbackURL: String = "callback" public let tokens: FederatedServiceTokens - public let callbackCompletion: (Request, String) throws -> (EventLoopFuture) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public let callbackURL: String public let accessTokenURL: String = "\(GitlabRouter.baseURL.finished(with: "/"))oauth/token" public let service: OAuthService = .gitlab - public required init(callback: String, completion: @escaping (Request, String) throws -> (EventLoopFuture)) throws { + public required init(callback: String, completion: @escaping (Request, String) async throws -> Response) async throws { self.tokens = try GitlabAuth() self.callbackURL = callback self.callbackCompletion = completion @@ -37,7 +37,7 @@ public class GitlabRouter: FederatedServiceRouter { return url.absoluteString } - public func callbackBody(with code: String) -> ResponseEncodable { + public func callbackBody(with code: String) -> any Content { GitlabCallbackBody(clientId: tokens.clientID, clientSecret: tokens.clientSecret, code: code, diff --git a/Sources/ImperialGoogle/JWT/GoogleJWT.swift b/Sources/ImperialGoogle/JWT/GoogleJWT.swift index f610d293..2704b7dd 100644 --- a/Sources/ImperialGoogle/JWT/GoogleJWT.swift +++ b/Sources/ImperialGoogle/JWT/GoogleJWT.swift @@ -8,16 +8,16 @@ public class GoogleJWT: FederatedService { public required init( routes: RoutesBuilder, authenticate: String, - authenticateCallback: ((Request) throws -> (EventLoopFuture))?, + authenticateCallback: ((Request) async throws -> Void)?, callback: String, scope: [String] = [], - completion: @escaping (Request, String) throws -> (EventLoopFuture) - ) throws { - self.router = try GoogleJWTRouter(callback: callback, completion: completion) + completion: @escaping (Request, String) async throws -> Response + ) async throws { + self.router = try await GoogleJWTRouter(callback: callback, completion: completion) self.tokens = self.router.tokens self.router.scope = scope - try self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) + try await self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) OAuthService.register(.google) } diff --git a/Sources/ImperialGoogle/JWT/GoogleJWTRouter.swift b/Sources/ImperialGoogle/JWT/GoogleJWTRouter.swift index 3664067a..5637cc4b 100644 --- a/Sources/ImperialGoogle/JWT/GoogleJWTRouter.swift +++ b/Sources/ImperialGoogle/JWT/GoogleJWTRouter.swift @@ -6,7 +6,7 @@ import JWTKit public final class GoogleJWTRouter: FederatedServiceRouter { public var tokens: FederatedServiceTokens - public var callbackCompletion: (Request, String) throws -> (EventLoopFuture) + public var callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public var callbackURL: String public var accessTokenURL: String = "https://www.googleapis.com/oauth2/v4/token" @@ -18,7 +18,7 @@ public final class GoogleJWTRouter: FederatedServiceRouter { return headers }() - public init(callback: String, completion: @escaping (Request, String) throws -> (EventLoopFuture)) throws { + public init(callback: String, completion: @escaping (Request, String) async throws -> Response) async throws { self.tokens = try GoogleJWTAuth() self.callbackURL = callback self.authURL = callback @@ -29,27 +29,23 @@ public final class GoogleJWTRouter: FederatedServiceRouter { return authURL } - public func callbackBody(with code: String) -> ResponseEncodable { + public func callbackBody(with code: String) -> any Content { return "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=\(code)" } - public func fetchToken(from request: Request) throws -> EventLoopFuture { + public func fetchToken(from request: Request) async throws -> String { let token = try self.jwt() let body = callbackBody(with: token) let url = URI(string: self.accessTokenURL) - return body.encodeResponse(for: request) - .map { $0.body.buffer } - .flatMap { buffer in - return request.client.post(url, headers: self.callbackHeaders) { $0.body = buffer } - }.flatMapThrowing { response in - return try response.content.get(GoogleJWTResponse.self) - }.map { $0.accessToken } + let buffer = try ByteBuffer(data:JSONEncoder().encode(body)) + let response = try await request.client.post(url, headers: self.callbackHeaders) { $0.body = buffer } + return try response.content.get(GoogleJWTResponse.self).accessToken } - public func authenticate(_ request: Request) throws -> EventLoopFuture { + public func authenticate(_ request: Request) async throws -> Response { let redirect: Response = request.redirect(to: self.callbackURL) - return request.eventLoop.makeSucceededFuture(redirect) + return redirect } public func jwt() throws -> String { diff --git a/Sources/ImperialGoogle/Standard/Google.swift b/Sources/ImperialGoogle/Standard/Google.swift index 1589f3a5..250530c0 100644 --- a/Sources/ImperialGoogle/Standard/Google.swift +++ b/Sources/ImperialGoogle/Standard/Google.swift @@ -9,16 +9,16 @@ public class Google: FederatedService { public required init( routes: RoutesBuilder, authenticate: String, - authenticateCallback: ((Request) throws -> (EventLoopFuture))?, + authenticateCallback: ((Request) async throws -> Void)?, callback: String, scope: [String] = [], - completion: @escaping (Request, String) throws -> (EventLoopFuture) - ) throws { + completion: @escaping (Request, String) async throws -> Response + ) async throws { self.router = try GoogleRouter(callback: callback, completion: completion) self.tokens = self.router.tokens self.router.scope = scope - try self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) + try await self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) OAuthService.register(.google) } diff --git a/Sources/ImperialGoogle/Standard/GoogleRouter.swift b/Sources/ImperialGoogle/Standard/GoogleRouter.swift index 56b70519..6600214b 100644 --- a/Sources/ImperialGoogle/Standard/GoogleRouter.swift +++ b/Sources/ImperialGoogle/Standard/GoogleRouter.swift @@ -3,7 +3,7 @@ import Foundation public class GoogleRouter: FederatedServiceRouter { public let tokens: FederatedServiceTokens - public let callbackCompletion: (Request, String) throws -> (EventLoopFuture) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public let callbackURL: String public let accessTokenURL: String = "https://www.googleapis.com/oauth2/v4/token" @@ -14,7 +14,7 @@ public class GoogleRouter: FederatedServiceRouter { return headers }() - public required init(callback: String, completion: @escaping (Request, String) throws -> (EventLoopFuture)) throws { + public required init(callback: String, completion: @escaping (Request, String) async throws -> Response) throws { self.tokens = try GoogleAuth() self.callbackURL = callback self.callbackCompletion = completion @@ -39,7 +39,7 @@ public class GoogleRouter: FederatedServiceRouter { return url.absoluteString } - public func callbackBody(with code: String) -> ResponseEncodable { + public func callbackBody(with code: String) -> any Content { GoogleCallbackBody(code: code, clientId: tokens.clientID, clientSecret: tokens.clientSecret, diff --git a/Sources/ImperialKeycloak/Keycloak.swift b/Sources/ImperialKeycloak/Keycloak.swift index a5432fae..f6c09424 100644 --- a/Sources/ImperialKeycloak/Keycloak.swift +++ b/Sources/ImperialKeycloak/Keycloak.swift @@ -9,16 +9,16 @@ public class Keycloak: FederatedService { public required init( routes: RoutesBuilder, authenticate: String, - authenticateCallback: ((Request) throws -> (EventLoopFuture))?, + authenticateCallback: ((Request) async throws -> Void)?, callback: String, scope: [String] = [], - completion: @escaping (Request, String) throws -> (EventLoopFuture) - ) throws { - self.router = try KeycloakRouter(callback: callback, completion: completion) + completion: @escaping (Request, String) async throws -> Response + ) async throws { + self.router = try await KeycloakRouter(callback: callback, completion: completion) self.tokens = self.router.tokens self.router.scope = scope - try self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) + try await self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) OAuthService.register(.keycloak) } diff --git a/Sources/ImperialKeycloak/KeycloakRouter.swift b/Sources/ImperialKeycloak/KeycloakRouter.swift index e1fc8c5e..9aee5364 100644 --- a/Sources/ImperialKeycloak/KeycloakRouter.swift +++ b/Sources/ImperialKeycloak/KeycloakRouter.swift @@ -4,13 +4,13 @@ import Foundation public class KeycloakRouter: FederatedServiceRouter { public let tokens: FederatedServiceTokens public let keycloakTokens: KeycloakAuth - public let callbackCompletion: (Request, String) throws -> (EventLoopFuture) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public let callbackURL: String public let accessTokenURL: String public let service: OAuthService = .keycloak - public required init(callback: String, completion: @escaping (Request, String) throws -> (EventLoopFuture)) throws { + public required init(callback: String, completion: @escaping (Request, String) async throws -> Response) async throws { self.tokens = try KeycloakAuth() self.keycloakTokens = self.tokens as! KeycloakAuth self.accessTokenURL = keycloakTokens.accessTokenURL @@ -26,7 +26,7 @@ public class KeycloakRouter: FederatedServiceRouter { "response_type=code" } - public func callbackBody(with code: String) -> ResponseEncodable { + public func callbackBody(with code: String) -> any Content { KeycloakCallbackBody(code: code, clientId: tokens.clientID, clientSecret: tokens.clientSecret, diff --git a/Sources/ImperialMicrosoft/Microsoft.swift b/Sources/ImperialMicrosoft/Microsoft.swift index 5621922e..d439e248 100644 --- a/Sources/ImperialMicrosoft/Microsoft.swift +++ b/Sources/ImperialMicrosoft/Microsoft.swift @@ -9,16 +9,16 @@ public class Microsoft: FederatedService { public required init( routes: RoutesBuilder, authenticate: String, - authenticateCallback: ((Request) throws -> (EventLoopFuture))?, + authenticateCallback: ((Request) async throws -> Void)?, callback: String, scope: [String] = [], - completion: @escaping (Request, String)throws -> (EventLoopFuture) - ) throws { - self.router = try MicrosoftRouter(callback: callback, completion: completion) + completion: @escaping (Request, String) async throws -> Response + ) async throws { + self.router = try await MicrosoftRouter(callback: callback, completion: completion) self.tokens = self.router.tokens self.router.scope = scope - try self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) + try await self.router.configureRoutes(withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes) OAuthService.register(.microsoft) } diff --git a/Sources/ImperialMicrosoft/MicrosoftRouter.swift b/Sources/ImperialMicrosoft/MicrosoftRouter.swift index 1d05d6a9..77fdfeba 100644 --- a/Sources/ImperialMicrosoft/MicrosoftRouter.swift +++ b/Sources/ImperialMicrosoft/MicrosoftRouter.swift @@ -6,7 +6,7 @@ public class MicrosoftRouter: FederatedServiceRouter { public static var tenantIDEnvKey: String = "MICROSOFT_TENANT_ID" public let tokens: FederatedServiceTokens - public let callbackCompletion: (Request, String)throws -> (EventLoopFuture) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public let callbackURL: String public var tenantID: String { Environment.get(MicrosoftRouter.tenantIDEnvKey) ?? "common" } @@ -16,8 +16,8 @@ public class MicrosoftRouter: FederatedServiceRouter { public required init( callback: String, - completion: @escaping (Request, String) throws -> (EventLoopFuture) - ) throws { + completion: @escaping (Request, String) async throws -> Response + ) async throws { self.tokens = try MicrosoftAuth() self.callbackURL = callback self.callbackCompletion = completion @@ -44,7 +44,7 @@ public class MicrosoftRouter: FederatedServiceRouter { return url.absoluteString } - public func callbackBody(with code: String) -> ResponseEncodable { + public func callbackBody(with code: String) -> any Content { MicrosoftCallbackBody(code: code, clientId: tokens.clientID, clientSecret: tokens.clientSecret, diff --git a/Sources/ImperialShopify/Shopify.swift b/Sources/ImperialShopify/Shopify.swift index e3774709..1ab5c106 100644 --- a/Sources/ImperialShopify/Shopify.swift +++ b/Sources/ImperialShopify/Shopify.swift @@ -11,15 +11,15 @@ public final class Shopify: FederatedService { public init( routes: RoutesBuilder, authenticate: String, - authenticateCallback: ((Request) throws -> (EventLoopFuture))?, + authenticateCallback: ((Request) async throws -> Void)?, callback: String, scope: [String], - completion: @escaping (Request, String) throws -> (EventLoopFuture) - ) throws { - self.shopifyRouter = try ShopifyRouter(callback: callback, completion: completion) + completion: @escaping (Request, String) async throws -> Response + ) async throws { + self.shopifyRouter = try await ShopifyRouter(callback: callback, completion: completion) self.shopifyRouter.scope = scope - try self.router.configureRoutes( + try await self.router.configureRoutes( withAuthURL: authenticate, authenticateCallback: authenticateCallback, on: routes diff --git a/Sources/ImperialShopify/ShopifyRouter.swift b/Sources/ImperialShopify/ShopifyRouter.swift index 5e7f4a3e..657e931b 100644 --- a/Sources/ImperialShopify/ShopifyRouter.swift +++ b/Sources/ImperialShopify/ShopifyRouter.swift @@ -3,13 +3,13 @@ import Vapor public class ShopifyRouter: FederatedServiceRouter { public let tokens: FederatedServiceTokens - public let callbackCompletion: (Request, String) throws -> (EventLoopFuture) + public let callbackCompletion: (Request, String) async throws -> Response public var scope: [String] = [] public let callbackURL: String public var accessTokenURL: String = "" public let service: OAuthService = .shopify - required public init(callback: String, completion: @escaping (Request, String) throws -> (EventLoopFuture)) throws { + required public init(callback: String, completion: @escaping (Request, String) async throws -> Response) async throws { self.tokens = try ShopifyAuth() self.callbackURL = callback self.callbackCompletion = completion @@ -25,7 +25,7 @@ public class ShopifyRouter: FederatedServiceRouter { return try authURLFrom(shop, nonce: nonce).absoluteString } - public func callbackBody(with code: String) -> ResponseEncodable { + public func callbackBody(with code: String) -> any Content { ShopifyCallbackBody(code: code, clientId: tokens.clientID, clientSecret: tokens.clientSecret) @@ -66,22 +66,17 @@ public class ShopifyRouter: FederatedServiceRouter { /// - Parameter request: The request from the OAuth provider. /// - Returns: A response that should redirect the user back to the app. /// - Throws: Any errors that occur in the implementation code. - public func callback(_ request: Request) throws -> EventLoopFuture { - return try self.fetchToken(from: request).flatMap { accessToken in - let session = request.session - do { - guard let domain = request.query[String.self, at: "shop"] else { throw Abort(.badRequest) } + public func callback(_ request: Request) async throws -> Response { + let accessToken = try await self.fetchToken(from: request) + let session = request.session + + guard let domain = request.query[String.self, at: "shop"] else { throw Abort(.badRequest) } - try session.setAccessToken(accessToken) - try session.setShopDomain(domain) - try session.setNonce(nil) - return try self.callbackCompletion(request, accessToken).flatMap { response in - return response.encodeResponse(for: request) - } - } catch { - return request.eventLoop.makeFailedFuture(error) - } - } + try session.setAccessToken(accessToken) + try session.setShopDomain(domain) + try session.setNonce(nil) + return try await self.callbackCompletion(request, accessToken) + } private func authURLFrom(_ shop: String, nonce: String) throws -> URL {