Skip to content

Commit 20097b0

Browse files
committed
Merge branch 'main' into av/bsky-video-size-update
2 parents 8ae2fd4 + 263f093 commit 20097b0

32 files changed

Lines changed: 444 additions & 461 deletions
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
name: OAuth Issue
2+
description: Report an OAuth problem, ask for integration help, or suggest an OAuth improvement.
3+
title: "[OAuth]: "
4+
body:
5+
- type: markdown
6+
attributes:
7+
value: |
8+
Thanks for taking the time to explain what you are running into. You do not need to know the OAuth terminology; describe what you saw in your own words and use **I'm not sure** where needed.
9+
10+
> Note: **Keep credentials private.** Do not include access or refresh tokens, authorization codes, client secrets, private keys, DPoP proofs, cookies, or complete `Authorization` headers. Replace them with `<redacted>` in code, URLs, screenshots, and logs.
11+
12+
- type: dropdown
13+
id: issue-type
14+
attributes:
15+
label: What do you need help with?
16+
description: Choose the option that comes closest. It does not need to be exact.
17+
options:
18+
- Something is not working
19+
- I need help integrating OAuth
20+
- The documentation is unclear or incomplete
21+
- I would like an OAuth improvement
22+
- I'm not sure
23+
validations:
24+
required: true
25+
26+
- type: input
27+
id: summary
28+
attributes:
29+
label: Summary
30+
description: In one or two sentences, what are you trying to do and what is getting in the way?
31+
placeholder: "After signing in, my app returns from the browser but ATProtoKit does not have an active session."
32+
validations:
33+
required: true
34+
35+
- type: textarea
36+
id: flow
37+
attributes:
38+
label: What happened?
39+
description: Walk through what you did and what you saw. A short numbered list is ideal.
40+
placeholder: |
41+
1. I started sign-in for `alice.example`.
42+
2. The browser opened and I approved access.
43+
3. My app received the callback URL.
44+
4. When I created the ATProtoKit session, I received the error below.
45+
validations:
46+
required: true
47+
48+
- type: textarea
49+
id: expected-result
50+
attributes:
51+
label: What did you expect to happen?
52+
description: Describe the result that would have let you continue.
53+
placeholder: "I expected the callback to create a session and an authenticated request to succeed."
54+
validations:
55+
required: true
56+
57+
- type: dropdown
58+
id: failure-stage
59+
attributes:
60+
label: Where did the OAuth flow stop?
61+
description: Choose the closest point, even if you are not certain.
62+
options:
63+
- Before the sign-in page opened
64+
- On the sign-in or consent page
65+
- When returning to the app or callback URL
66+
- While exchanging the authorization code
67+
- While creating or restoring the ATProtoKit session
68+
- During an authenticated request
69+
- While refreshing or resuming a session
70+
- While signing out or deleting a session
71+
- It did not stop, but behaved unexpectedly
72+
- I'm not certain
73+
validations:
74+
required: true
75+
76+
- type: input
77+
id: atprotokit-version
78+
attributes:
79+
label: ATProtoKit Version
80+
description: State the version or commit you are using.
81+
placeholder: "0.18.0 or commit abc1234"
82+
validations:
83+
required: true
84+
85+
- type: input
86+
id: oauth-implementation
87+
attributes:
88+
label: OAuth Package or Implementation
89+
description: Name the OAuth package and version you use. If you built it yourself or do not know, say so.
90+
placeholder: "PackageName 1.2.0, custom implementation, or I'm not sure"
91+
validations:
92+
required: true
93+
94+
- type: dropdown
95+
id: operating-system
96+
attributes:
97+
label: Where does this happen?
98+
multiple: true
99+
options:
100+
- macOS
101+
- iOS/iPadOS
102+
- tvOS
103+
- visionOS
104+
- watchOS
105+
- Linux
106+
- Windows
107+
- Other
108+
validations:
109+
required: true
110+
111+
- type: input
112+
id: environment-version
113+
attributes:
114+
label: Environment Version
115+
description: Include the operating system version and, when relevant, the Xcode or Swift version.
116+
placeholder: "iOS 19.0, Xcode 17.0"
117+
validations:
118+
required: true
119+
120+
- type: textarea
121+
id: minimal-code
122+
attributes:
123+
label: Relevant Code
124+
description: If possible, share the smallest code sample that shows how OAuth connects to ATProtoKit. Please remove credentials and private information.
125+
render: swift
126+
127+
- type: textarea
128+
id: diagnostics
129+
attributes:
130+
label: Error and Sanitized Diagnostics
131+
description: Paste the complete error and any useful sanitized logs, HTTP status codes, or endpoint hostnames. Attach screenshots or files below if that is easier.
132+
placeholder: |
133+
Error: ATOAuthSessionConfigurationError...
134+
HTTP status: 401
135+
Endpoint hostname: example.com
136+
137+
Replace credentials and private values with <redacted>.
138+
139+
- type: textarea
140+
id: additional-context
141+
attributes:
142+
label: Additional Context
143+
description: Share anything else that may help, such as whether this is consistent or intermittent, a link to a small reproduction, or a workaround you tried.
144+
145+
- type: checkboxes
146+
id: sensitive-information
147+
attributes:
148+
label: Sensitive Information
149+
options:
150+
- label: I have removed tokens, authorization codes, secrets, private keys, DPoP proofs, cookies, and complete authorization headers from this report.
151+
required: true

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ You can use the Swift Package Manager to download and import the library into yo
8181

8282
```swift
8383
dependencies: [
84-
.package(url: "https://github.com/MasterJ93/ATProtoKit.git", from: "0.33.0")
84+
.package(url: "https://github.com/MasterJ93/ATProtoKit.git", from: "0.34.0")
8585
]
8686
```
8787

Sources/ATProtoKit/APIReference/ATProtoBlueskyAPI/PostRecord/CreatePostRecord.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,11 @@ extension ATProtoBluesky {
682682
/// The language of the captions.
683683
public let language: Locale
684684

685+
public init(file: Data, language: Locale) {
686+
self.file = file
687+
self.language = language
688+
}
689+
685690
enum CodingKeys: String, CodingKey {
686691
case file
687692
case language = "lang"

Sources/ATProtoKit/APIReference/ComAtprotoAPI/ComAtprotoRepoDescribeRepoMethod.swift

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,15 @@ extension ATProtoKit {
2121
///
2222
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/com/atproto/repo/describeRepo.json
2323
///
24-
/// - Parameters:
25-
/// - repositoryDID: The decentralized identifier (DID) or handle of the repository.
26-
/// - pdsURL: The URL of the Personal Data Server (PDS). Optional. Defaults to `nil`.
24+
/// - Parameter repositoryDID: The decentralized identifier (DID) or handle of the repository.
2725
/// - Returns: Some general information about the repository that matches `repositoryDID`.
2826
///
2927
/// - Throws: An ``ATProtoError``-conforming error type, depending on the issue. Go to
3028
/// ``ATAPIError`` and ``ATRequestPrepareError`` for more details.
3129
public func describeRepository(
32-
_ repositoryDID: String,
33-
pdsURL: String? = nil
30+
_ repositoryDID: String
3431
) async throws -> ComAtprotoLexicon.Repository.DescribeRepositoryOutput {
35-
let host: String
36-
if let pdsURL, !pdsURL.isEmpty {
37-
host = pdsURL
38-
} else {
39-
host = await resolvePDSHost(for: repositoryDID)
40-
}
32+
let host = try await self.atidentityResolver.resolvePDSEndpoint(from: repositoryDID)
4133

4234
guard let requestURL = URL(string: "\(host)/xrpc/com.atproto.repo.describeRepo") else {
4335
throw ATRequestPrepareError.invalidRequestURL
@@ -72,27 +64,4 @@ extension ATProtoKit {
7264
throw error
7365
}
7466
}
75-
76-
/// Determines the base hostname for a repository-scoped request.
77-
///
78-
/// Some `com.atproto.repo.*` methods are implemented by the Personal Data Server (PDS) that
79-
/// hosts the target repository, which may differ from the instance's own PDS. This resolves
80-
/// the PDS service endpoint from the target DID via ``ATBuiltInIdentityResolver``, falling back
81-
/// to the instance's own ``pdsURL`` (the prior behaviour, served via entryway proxying) when
82-
/// resolution isn't possible.
83-
///
84-
/// Resolution is only attempted when `repository` is a DID; handles fall through to the
85-
/// instance's own host to preserve existing behaviour. Callers that already know the PDS URL
86-
/// should use it directly instead of calling this method.
87-
///
88-
/// - Parameter repository: The decentralized identifier (DID) or handle of the target repository.
89-
/// - Returns: The base hostname to use for the request.
90-
func resolvePDSHost(for repository: String) async -> String {
91-
if repository.hasPrefix("did:"),
92-
let endpoint = try? await ATBuiltInIdentityResolver().resolvePDSEndpoint(from: repository) {
93-
return endpoint
94-
}
95-
96-
return pdsURL
97-
}
9867
}

Sources/ATProtoKit/APIReference/ComAtprotoAPI/ComAtprotoRepoGetRecordMethod.swift

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,7 @@ extension ATProtoKit {
3838
recordCID: String? = nil,
3939
pdsURL: String? = nil
4040
) async throws -> ComAtprotoLexicon.Repository.GetRecordOutput {
41-
let host: String
42-
if let pdsURL, !pdsURL.isEmpty {
43-
host = pdsURL
44-
} else {
45-
host = await resolvePDSHost(for: repository)
46-
}
41+
let host = try await self.atidentityResolver.resolvePDSEndpoint(from: repository)
4742

4843
guard let requestURL = URL(string: "\(host)/xrpc/com.atproto.repo.getRecord") else {
4944
throw ATRequestPrepareError.invalidRequestURL

Sources/ATProtoKit/APIReference/ComAtprotoAPI/ComAtprotoRepoListRecordsMethod.swift

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,7 @@ extension ATProtoKit {
4141
isArrayReverse: Bool? = nil,
4242
pdsURL: String? = nil
4343
) async throws -> ComAtprotoLexicon.Repository.ListRecordsOutput {
44-
let host: String
45-
if let pdsURL, !pdsURL.isEmpty {
46-
host = pdsURL
47-
} else {
48-
host = await resolvePDSHost(for: repository)
49-
}
44+
let host = try await self.atidentityResolver.resolvePDSEndpoint(from: repository)
5045

5146
guard let requestURL = URL(string: "\(host)/xrpc/com.atproto.repo.listRecords") else {
5247
throw ATRequestPrepareError.invalidRequestURL

Sources/ATProtoKit/APIReference/ComAtprotoAPI/ComAtprotoSyncGetBlobMethod.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ extension ATProtoKit {
3333
from accountDID: String,
3434
cid: String
3535
) async throws -> Data {
36-
guard let requestURL = URL(string: "https://bsky.network/xrpc/com.atproto.sync.getBlob") else {
36+
let host = try await self.atidentityResolver.resolvePDSEndpoint(from: accountDID)
37+
38+
guard let requestURL = URL(string: "https://\(host)/xrpc/com.atproto.sync.getBlob") else {
3739
throw ATRequestPrepareError.invalidRequestURL
3840
}
3941

@@ -53,7 +55,7 @@ extension ATProtoKit {
5355
let request = apiClientService.createRequest(
5456
forRequest: queryURL,
5557
andMethod: .get,
56-
acceptValue: "'*/*'",
58+
acceptValue: "*/*",
5759
contentTypeValue: nil,
5860
authorizationValue: nil
5961
)

Sources/ATProtoKit/APIReference/ComAtprotoAPI/ComAtprotoSyncGetBlocksMethod.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ extension ATProtoKit {
3737
from repositoryDID: String,
3838
by repositoryCIDs: [String]
3939
) async throws -> Data {
40-
guard let requestURL = URL(string: "https://bsky.network/xrpc/com.atproto.sync.getBlocks") else {
40+
let host = try await self.atidentityResolver.resolvePDSEndpoint(from: repositoryDID)
41+
42+
guard let requestURL = URL(string: "https://\(host)/xrpc/com.atproto.sync.getBlocks") else {
4143
throw ATRequestPrepareError.invalidRequestURL
4244
}
4345

Sources/ATProtoKit/APIReference/ComAtprotoAPI/ComAtprotoSyncGetLatestCommitMethod.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ extension ATProtoKit {
4848
let request = apiClientService.createRequest(
4949
forRequest: queryURL,
5050
andMethod: .get,
51-
acceptValue: "application/vnd.ipld.car",
51+
acceptValue: "application/json",
5252
contentTypeValue: nil,
5353
authorizationValue: nil
5454
)

Sources/ATProtoKit/APIReference/ComAtprotoAPI/ComAtprotoSyncGetRecordMethod.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ extension ATProtoKit {
3636
recordKey: String,
3737
recordCID: String? = nil
3838
) async throws -> Data {
39-
guard let requestURL = URL(string: "https://bsky.network/xrpc/com.atproto.sync.getRecord") else {
39+
let host = try await self.atidentityResolver.resolvePDSEndpoint(from: repositoryDID)
40+
41+
guard let requestURL = URL(string: "https://\(host)/xrpc/com.atproto.sync.getRecord") else {
4042
throw ATRequestPrepareError.invalidRequestURL
4143
}
4244

0 commit comments

Comments
 (0)