From b39f4c90e002f14d1d5d0164ac0db8fc8ff0c0fe Mon Sep 17 00:00:00 2001 From: Kevin McKee Date: Tue, 8 Jul 2025 12:01:37 -0700 Subject: [PATCH 1/8] Dry run --- .github/workflows/docc.yml | 44 ++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/.github/workflows/docc.yml b/.github/workflows/docc.yml index 0b7c4d2..4316093 100644 --- a/.github/workflows/docc.yml +++ b/.github/workflows/docc.yml @@ -4,7 +4,7 @@ name: DocC on: push: - branches: [ "main" ] + branches: [ "*" ] # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: @@ -36,19 +36,35 @@ jobs: - uses: actions/checkout@v4 - name: Select Xcode run: sudo xcode-select -s "/Applications/$XCODE_VERSION.app" - - name: Generate DocC - run: xcodebuild docbuild -scheme OAuthKit -derivedDataPath /tmp/docbuild -destination 'generic/platform=macOS'; - - name: Transform DocC + - name: Add Plugin Dependency + run: swift package add-dependency "https://github.com/apple/swift-docc-plugin" --branch main + - name: Generate Documentation run: | - $(xcrun --find docc) process-archive \ - transform-for-static-hosting /tmp/docbuild/Build/Products/Debug/OAuthKit.doccarchive \ + swift package \ + --allow-writing-to-package-directory \ + --allow-writing-to-directory ${{github.workspace}}/docs \ + generate-documentation \ + --target OAuthKit \ + --transform-for-static-hosting \ --hosting-base-path OAuthKit \ - --output-path docs; + --output-path ${{github.workspace}}/docs \ + --source-service github \ + --source-service-base-url https://github.com/codefiesta/OAuthKit/blob/main \ + --checkout-path ${{github.workspace}}; + +# - name: Generate DocC +# run: xcodebuild docbuild -scheme OAuthKit -derivedDataPath /tmp/docbuild -destination 'generic/platform=macOS'; +# - name: Transform DocC +# run: | +# $(xcrun --find docc) process-archive \ +# transform-for-static-hosting /tmp/docbuild/Build/Products/Debug/OAuthKit.doccarchive \ +# --hosting-base-path OAuthKit \ +# --output-path docs; - name: Update Index - run: echo "" > docs/index.html; - - name: Upload Pages Artifact - uses: actions/upload-pages-artifact@v3 - with: - path: 'docs' - - name: Deploy to GitHub Pages - uses: actions/deploy-pages@v4 + run: echo "" > ${{github.workspace}}/docs/index.html; +# - name: Upload Pages Artifact +# uses: actions/upload-pages-artifact@v3 +# with: +# path: 'docs' +# - name: Deploy to GitHub Pages +# uses: actions/deploy-pages@v4 From e0b71ca750325133b2e102917a063cb566949292 Mon Sep 17 00:00:00 2001 From: Kevin McKee Date: Tue, 8 Jul 2025 12:03:59 -0700 Subject: [PATCH 2/8] WIP --- .github/workflows/docc.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docc.yml b/.github/workflows/docc.yml index 4316093..3ad4386 100644 --- a/.github/workflows/docc.yml +++ b/.github/workflows/docc.yml @@ -62,9 +62,9 @@ jobs: # --output-path docs; - name: Update Index run: echo "" > ${{github.workspace}}/docs/index.html; -# - name: Upload Pages Artifact -# uses: actions/upload-pages-artifact@v3 -# with: -# path: 'docs' -# - name: Deploy to GitHub Pages -# uses: actions/deploy-pages@v4 + - name: Upload Pages Artifact + uses: actions/upload-pages-artifact@v3 + with: + path: 'docs' + - name: Deploy to GitHub Pages + uses: actions/deploy-pages@v4 From 9c6551b6851c9b47afc2638f543138d4d2155d00 Mon Sep 17 00:00:00 2001 From: Kevin McKee Date: Tue, 8 Jul 2025 12:07:37 -0700 Subject: [PATCH 3/8] Flipping back to main only branch. --- .github/workflows/docc.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/docc.yml b/.github/workflows/docc.yml index 3ad4386..0bc1cc6 100644 --- a/.github/workflows/docc.yml +++ b/.github/workflows/docc.yml @@ -4,7 +4,7 @@ name: DocC on: push: - branches: [ "*" ] + branches: [ "main" ] # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: @@ -51,7 +51,6 @@ jobs: --source-service github \ --source-service-base-url https://github.com/codefiesta/OAuthKit/blob/main \ --checkout-path ${{github.workspace}}; - # - name: Generate DocC # run: xcodebuild docbuild -scheme OAuthKit -derivedDataPath /tmp/docbuild -destination 'generic/platform=macOS'; # - name: Transform DocC From 2f8bea40241e27051266c898b036edd127f578ed Mon Sep 17 00:00:00 2001 From: Kevin McKee Date: Tue, 8 Jul 2025 12:24:09 -0700 Subject: [PATCH 4/8] Removing old docbuild command --- .github/workflows/docc.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/docc.yml b/.github/workflows/docc.yml index 0bc1cc6..e045153 100644 --- a/.github/workflows/docc.yml +++ b/.github/workflows/docc.yml @@ -51,14 +51,6 @@ jobs: --source-service github \ --source-service-base-url https://github.com/codefiesta/OAuthKit/blob/main \ --checkout-path ${{github.workspace}}; -# - name: Generate DocC -# run: xcodebuild docbuild -scheme OAuthKit -derivedDataPath /tmp/docbuild -destination 'generic/platform=macOS'; -# - name: Transform DocC -# run: | -# $(xcrun --find docc) process-archive \ -# transform-for-static-hosting /tmp/docbuild/Build/Products/Debug/OAuthKit.doccarchive \ -# --hosting-base-path OAuthKit \ -# --output-path docs; - name: Update Index run: echo "" > ${{github.workspace}}/docs/index.html; - name: Upload Pages Artifact From 0bd622caa126eea1d0c4dbe489c1048cb3391955 Mon Sep 17 00:00:00 2001 From: Kevin McKee Date: Tue, 8 Jul 2025 12:37:54 -0700 Subject: [PATCH 5/8] Moving README links over to documentation site. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e0d1c28..259e430 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,9 @@ OAuthKit is a small, lightweight package that provides out of the box [Swift Con Key features include: - [Simple Configuration](#oauthkit-configuration) -- [Keychain protection with biometrics or companion device](#oauth-initialized-with-keychain-protection-and-private-browsing) -- [Private Browsing with non-persistent WebKit Datastores](#oauth-initialized-with-keychain-protection-and-private-browsing) -- [Custom URLSession](#oauth-initialized-with-keychain-protection-and-private-browsing) configuration for complete control custom protocol specific data +- [Keychain protection with biometrics or companion device](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/configuration#Keychain-Protection) +- [Private Browsing with non-persistent WebKit Datastores](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/configuration#Private-Browsing) +- [Custom URLSession](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/configuration#URL-Session) configuration for complete control custom protocol specific data - [Observable State](https://github.com/codefiesta/OAuthKit/blob/main/Sources/OAuthKit/OAuth.swift#L36) driven events to allow full control over when and if users are prompted to authenticate with an OAuth provider - Supports all Apple Platforms (iOS, macOS, tvOS, visionOS, watchOS) - [Support for every OAuth 2.0 Flow](#oauthkit-configuration) From 7961824b990558eb2391516886af2e7c5f2d2977 Mon Sep 17 00:00:00 2001 From: Kevin McKee Date: Tue, 8 Jul 2025 12:45:36 -0700 Subject: [PATCH 6/8] Documentation Link update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 259e430..cfce10b 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Key features include: - [Keychain protection with biometrics or companion device](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/configuration#Keychain-Protection) - [Private Browsing with non-persistent WebKit Datastores](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/configuration#Private-Browsing) - [Custom URLSession](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/configuration#URL-Session) configuration for complete control custom protocol specific data -- [Observable State](https://github.com/codefiesta/OAuthKit/blob/main/Sources/OAuthKit/OAuth.swift#L36) driven events to allow full control over when and if users are prompted to authenticate with an OAuth provider +- [Observable State](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/gettingstarted#Observing-OAuth-State) driven events to allow full control over when and if users are prompted to authenticate with an OAuth provider - Supports all Apple Platforms (iOS, macOS, tvOS, visionOS, watchOS) - [Support for every OAuth 2.0 Flow](#oauthkit-configuration) - [Authorization Code](#oauth-20-authorization-code-flow) From 7c5bcafffdf22ea2ccd2c35f364e4b621768b25f Mon Sep 17 00:00:00 2001 From: Kevin McKee Date: Tue, 8 Jul 2025 12:51:44 -0700 Subject: [PATCH 7/8] Moving the README links over to the documentation site. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cfce10b..47adde4 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ OAuthKit is a contemporary, event-driven Swift Package that utilizes the [Observ ## OAuthKit Features -OAuthKit is a small, lightweight package that provides out of the box [Swift Concurrency](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/concurrency/) safety support and [Observable](https://github.com/codefiesta/OAuthKit/blob/main/Sources/OAuthKit/OAuth.swift#L36) OAuth 2.0 state events that allow fine grained control over when and how to start authorization flows. +OAuthKit is a small, lightweight package that provides out of the box [Swift Concurrency](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/concurrency/) safety support and [Observable](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/oauth/state-swift.enum) OAuth 2.0 state events that allow fine grained control over when and how to start authorization flows. Key features include: @@ -160,7 +160,7 @@ struct ContentView: View { ``` ## OAuthKit Configuration -By default, the easiest way to configure OAuthKit is to simply drop an `oauth.json` file into your main bundle and it will get automatically loaded into your swift application and available as an [Environment](https://developer.apple.com/documentation/swiftui/environment) property wrapper. You can find an example `oauth.json` file [here](https://github.com/codefiesta/OAuthKit/blob/main/Tests/OAuthKitTests/Resources/oauth.json). OAuthKit provides flexible constructor options that allows developers to customize how their oauth client is initialized and what features they want to implement. See the [oauth.init(\_:bundle:options)](https://github.com/codefiesta/OAuthKit/blob/main/Sources/OAuthKit/OAuth.swift#L98) method for details. +By default, the easiest way to configure OAuthKit is to simply drop an `oauth.json` file into your main bundle and it will get automatically loaded into your swift application and available as an [Environment](https://developer.apple.com/documentation/swiftui/environment) property wrapper. You can find an example `oauth.json` file [here](https://github.com/codefiesta/OAuthKit/blob/main/Tests/OAuthKitTests/Resources/oauth.json). OAuthKit provides flexible constructor options that allows developers to customize how their oauth client is initialized and what features they want to implement. See the [oauth.init(\_:bundle:options)](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/oauth) method for details. ### OAuth initialized from main bundle (default) ```swift @@ -222,7 +222,7 @@ let oauth: OAuth = .init(.main, options: options) ``` ## OAuthKit Authorization Flows -OAuth 2.0 authorization flows are started by calling the [oauth.authorize(provider:grantType:)](https://github.com/codefiesta/OAuthKit/blob/main/Sources/OAuthKit/OAuth.swift#L117) method. +OAuth 2.0 authorization flows are started by calling the [oauth.authorize(provider:grantType:)](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/oauth#Starting-an-authorization-flow) method. A good resource to help understand the detailed steps involved in OAuth 2.0 authorization flows can be found on the [OAuth 2.0 Playground](https://www.oauth.com/playground/index.html). From 110d6eef80eba5a7b7b42ba17f86be9c8fa82b96 Mon Sep 17 00:00:00 2001 From: Kevin McKee Date: Tue, 8 Jul 2025 13:04:27 -0700 Subject: [PATCH 8/8] Cleanup - moved the sample code into it's companion markdown. --- Sources/OAuthKit/OAuth+State.swift | 37 -------------- .../OAuthKit.docc/Extensions/State.md | 48 +++++++++++++++++++ Sources/OAuthKit/OAuthKit.docc/OAuthKit.md | 1 + 3 files changed, 49 insertions(+), 37 deletions(-) create mode 100644 Sources/OAuthKit/OAuthKit.docc/Extensions/State.md diff --git a/Sources/OAuthKit/OAuth+State.swift b/Sources/OAuthKit/OAuth+State.swift index 87031c0..cb3df55 100644 --- a/Sources/OAuthKit/OAuth+State.swift +++ b/Sources/OAuthKit/OAuth+State.swift @@ -10,43 +10,6 @@ import Foundation extension OAuth { /// Holds the OAuth state that is published to subscribers via the ``state`` property. - /// - /// A n example of observing the ``state`` property in SwiftUI: - /// ```swift - ///struct ContentView: View { - /// - /// @Environment(\.oauth) - /// var oauth: OAuth - /// - /// var body: some View { - /// VStack { - /// switch oauth.state { - /// case .empty: - /// providerList - /// case .authorizing(let provider, let grantType): - /// Text("Authorizing [\(provider.id)] with [\(grantType.rawValue)]") - /// case .requestingAccessToken(let provider): - /// Text("Requesting Access Token [\(provider.id)]") - /// case .requestingDeviceCode(let provider): - /// Text("Requesting Device Code [\(provider.id)]") - /// case .authorized(let provider, _): - /// Button("Authorized [\(provider.id)]") { - /// oauth.clear() - /// } - /// 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) - /// } - /// } - /// .onChange(of: oauth.state) { oldState, newState in - /// handle(state: newState) - /// } - /// } - /// } - /// ``` public enum State: Equatable, Sendable { /// The state is empty and no authorizations or tokens have been issued. diff --git a/Sources/OAuthKit/OAuthKit.docc/Extensions/State.md b/Sources/OAuthKit/OAuthKit.docc/Extensions/State.md new file mode 100644 index 0000000..097bd55 --- /dev/null +++ b/Sources/OAuthKit/OAuthKit.docc/Extensions/State.md @@ -0,0 +1,48 @@ +# ``OAuthKit/OAuth/State`` + +@Metadata { + @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 +An example of observing the ``state`` property in SwiftUI: + +```swift +struct ContentView: View { + + @Environment(\.oauth) + var oauth: OAuth + + var body: some View { + VStack { + switch oauth.state { + case .empty: + providerList + case .authorizing(let provider, let grantType): + Text("Authorizing [\(provider.id)] with [\(grantType.rawValue)]") + case .requestingAccessToken(let provider): + Text("Requesting Access Token [\(provider.id)]") + case .requestingDeviceCode(let provider): + Text("Requesting Device Code [\(provider.id)]") + case .authorized(let provider, _): + Button("Authorized [\(provider.id)]") { + oauth.clear() + } + 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) + } + } + .onChange(of: oauth.state) { oldState, newState in + handle(state: newState) + } + } +} +``` diff --git a/Sources/OAuthKit/OAuthKit.docc/OAuthKit.md b/Sources/OAuthKit/OAuthKit.docc/OAuthKit.md index 36a5547..6338fe2 100644 --- a/Sources/OAuthKit/OAuthKit.docc/OAuthKit.md +++ b/Sources/OAuthKit/OAuthKit.docc/OAuthKit.md @@ -41,4 +41,5 @@ This has the advantage of avoiding direct coupling with an authorization flow, e - ``OAuth/GrantType`` ### State Observability +- ``OAuth/State`` - ``OAuth/state``