diff --git a/.spi.yml b/.spi.yml index 85d47a3..d80a0e1 100644 --- a/.spi.yml +++ b/.spi.yml @@ -1,3 +1,4 @@ version: 1 -external_links: - documentation: "https://codefiesta.github.io/OAuthKit/documentation/oauthkit" +builder: + configs: + - documentation_targets: [OAuthKit] diff --git a/Sources/OAuthKit/OAuthKit.docc/Extensions/OAuth.md b/Sources/OAuthKit/OAuthKit.docc/Extensions/OAuth.md index 44206c7..8ee463d 100644 --- a/Sources/OAuthKit/OAuthKit.docc/Extensions/OAuth.md +++ b/Sources/OAuthKit/OAuthKit.docc/Extensions/OAuth.md @@ -11,7 +11,7 @@ - ``authorize(provider:grantType:)`` -### Observing an OAuth object +### OAuth State Tracking - ``state`` - ``providers`` diff --git a/Sources/OAuthKit/OAuthKit.docc/GettingStarted.md b/Sources/OAuthKit/OAuthKit.docc/GettingStarted.md index f20f516..84d01ba 100644 --- a/Sources/OAuthKit/OAuthKit.docc/GettingStarted.md +++ b/Sources/OAuthKit/OAuthKit.docc/GettingStarted.md @@ -4,6 +4,11 @@ Create an ``OAuth`` instance and start an authorization flow. @Metadata { @PageKind(article) + @Available(iOS, introduced: "18.0") + @Available(macOS, introduced: "15.0") + @Available(tvOS, introduced: "18.0") + @Available(visionOS, introduced: "2.0") + @Available(watchOS, introduced: "11.0") } ## Overview @@ -120,3 +125,62 @@ struct ContentView: View { } ``` +## Presenting Authorization Windows +When a ``OAuth/state`` has reached an ``OAuth/State/authorizing(_:_:)`` state, your application should present +a browser window that allows the user to authenticate with an ``OAuth/Provider``. +OAuthKit provides an out of the box SwiftUI view ``OAWebView`` that will automatically handle the rest of the steps in the OAuth authorization flow for you. + +```swift +/// Handle `.authorizing` or `.authorized` oauth state changes by opening or closing authorization windows. +/// - Parameter state: the published state change +func handle(state: OAuth.State) { + switch state { + case .empty, .requestingAccessToken, .requestingDeviceCode, .receivedDeviceCode: + break + case .authorizing: + openWindow(id: "oauth") + case .authorized: + dismissWindow(id: "oauth") + } +} +``` +Once the user has successfully authorized with the ``OAuth/Provider``, the ``OAuth/state`` will move to an ``OAuth/State/authorized(_:_:)`` state. You can then automaticaly close the ``OAWebView`` window in your SwiftUI application. + +> Tip: Once authorized, a ``OAuth/Authorization/token`` will be inserted into the user's Keychain that can be used in subsequent API requests by inserting the `Authorization` header into an ``Foundation/URLRequest`` via ``OAuthKit/Foundation/URLRequest/addAuthorization(auth:)`` . + +## Presenting Device Codes (tvOS and watchOS) +OAuthKit also supports the [OAuth 2.0 Device Code Flow Grant](https://alexbilbie.github.io/2016/04/oauth-2-device-flow-grant/), which is used by apps that don't have access to a web browser (like tvOS or watchOS). To leverage OAuthKit in tvOS or watchOS apps, simply add the `deviceCodeURL` to your ``OAuth/Provider`` and start an ``OAuth/authorize(provider:grantType:)`` flow with the ``OAuth/GrantType/deviceCode`` grantType. + +```swift +let grantType: OAuth.GrantType = .deviceCode +oauth.authorize(provider: provider, grantType: grantType) + +struct ContentView: View { + ... + var body: some View { + VStack { + switch oauth.state { + case .empty, .authorizing, .requestingAccessToken, .requestingDeviceCode: + EmptyView() + case .authorized: + Text("Authorized [\(provider.id)]") + case .receivedDeviceCode(_, let deviceCode): + Text("To login, visit") + Text(.init("[\(deviceCode.verificationUri)](\(deviceCode.verificationUri))")) + .foregroundStyle(.blue) + Text("and enter the following code:") + Text(deviceCode.userCode) + .padding() + .border(Color.primary) + .font(.title) + } + } + } +} +``` + +The observable ``OAuth`` instance will proceed to poll the ``OAuth/Provider`` access token endpoint until the device code has expired or has successfully received an ``OAuth/Token`` and moved to an ``OAuth/State/authorized(_:_:)`` state. + +> Tip: Click [here](https://oauth.net/2/grant-types/device-code/) to see details of how the OAuth 2.0 Device Code Grant Type works. + + diff --git a/Sources/OAuthKit/OAuthKit.docc/OAuthKit.md b/Sources/OAuthKit/OAuthKit.docc/OAuthKit.md index 89ebac4..fd294b2 100644 --- a/Sources/OAuthKit/OAuthKit.docc/OAuthKit.md +++ b/Sources/OAuthKit/OAuthKit.docc/OAuthKit.md @@ -4,6 +4,11 @@ A modern and observable framework for implementing OAuth 2.0 authorization flows @Metadata { @PageColor(purple) + @Available(iOS, introduced: "18.0") + @Available(macOS, introduced: "15.0") + @Available(tvOS, introduced: "18.0") + @Available(visionOS, introduced: "2.0") + @Available(watchOS, introduced: "11.0") } ## Overview diff --git a/Sources/OAuthKit/OAuthKit.docc/SampleCode.md b/Sources/OAuthKit/OAuthKit.docc/SampleCode.md index 030ecbd..4d22238 100644 --- a/Sources/OAuthKit/OAuthKit.docc/SampleCode.md +++ b/Sources/OAuthKit/OAuthKit.docc/SampleCode.md @@ -8,8 +8,13 @@ Integrate OAuthKit into a multiplatform app with support for iOS, macOS, tvOS, v url: "https://github.com/codefiesta/OAuthSample" ) @PageKind(sampleCode) + @Available(iOS, introduced: "18.0") + @Available(macOS, introduced: "15.0") + @Available(tvOS, introduced: "18.0") + @Available(visionOS, introduced: "2.0") + @Available(watchOS, introduced: "11.0") } ## Overview -This sample creates _OAuthSample_, an app for demonstrating how to get up and running quickly with OAuthKit. +The OAuthSample app demonstrates how to get up and running quickly with OAuthKit.