Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
MasterJ93 committed Aug 24, 2024
2 parents 576a139 + 8a21a7b commit c8504d2
Show file tree
Hide file tree
Showing 16 changed files with 718 additions and 508 deletions.
75 changes: 75 additions & 0 deletions Sources/ATProtoKit/APIReference/AppBskyAPI/GetQuotes.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//
// GetQuotes.swift
//
//
// Created by Christopher Jr Riley on 2024-08-23.
//

import Foundation

extension ATProtoKit {

/// Gets an array of quuote posts that has embeded a given post.
///
/// - Note: According to the AT Protocol specifications: "Get a list of quotes for a
/// given post."
///
/// - SeeAlso: This is based on the [`app.bsky.feed.getQuotes`][github] lexicon.
///
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/app/bsky/feed/getQuotes.json
///
///
public func getQuotes(
from postURI: String,
postCID: String?,
limit: Int? = 50
) async throws -> AppBskyLexicon.Feed.GetQuotesOutput {
guard session != nil,
let accessToken = session?.accessToken else {
throw ATRequestPrepareError.missingActiveSession
}

guard let sessionURL = session?.pdsURL,
let requestURL = URL(string: "\(sessionURL)/xrpc/app.bsky.feed.getQuotes") else {
throw ATRequestPrepareError.invalidRequestURL
}

var queryItems = [(String, String)]()

queryItems.append(("uri", postURI))

if let postCID {
queryItems.append(("cid", postCID))
}

if let limit {
let finalLimit = max(1, min(limit, 100))
queryItems.append(("limit", "\(finalLimit)"))
}

let queryURL: URL

do {
queryURL = try APIClientService.setQueryItems(
for: requestURL,
with: queryItems
)

let request = APIClientService.createRequest(
forRequest: queryURL,
andMethod: .get,
acceptValue: "application/json",
contentTypeValue: nil,
authorizationValue: "Bearer \(accessToken)"
)
let response = try await APIClientService.shared.sendRequest(
request,
decodeTo: AppBskyLexicon.Feed.GetQuotesOutput.self
)

return response
} catch {
throw error
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//
// CreateAccount.swift
//
//
// Created by Christopher Jr Riley on 2024-08-18.
//

import Foundation

extension ATProtocolConfiguration {

/// Creates an a new account for the user.
///
/// - Note: `plcOp` may be updated when full account migration is implemented.
///
/// - Bug: `plcOp` is currently broken: there's nothing that can be used for this at the
/// moment while Bluesky continues to work on account migration. Until everything settles
/// and they have a concrete example of what to do, don't use it. In the meantime, leave it
/// at `nil`.
///
/// - Note: According to the AT Protocol specifications: "Create an account. Implemented
/// by PDS."
///
/// - SeeAlso: This is based on the [`com.atproto.server.createAccount`][github] lexicon.
///
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/com/atproto/server/createAccount.json
///
/// - Parameters:
/// - email: The email of the user. Optional
/// - handle: The handle the user wishes to use.
/// - existingDID: A decentralized identifier (DID) that has existed before and will be
/// used to be imported to the new account. Optional.
/// - inviteCode: The invite code for the user. Optional.
/// - verificationCode: A verification code.
/// - verificationPhone: A code that has come from a text message in the user's
/// phone. Optional.
/// - password: The password the user will use for the account. Optional.
/// - recoveryKey: DID PLC rotation key (aka, recovery key) to be included in PLC
/// creation operation. Optional.
/// - plcOp: A signed DID PLC operation to be submitted as part of importing an existing
/// account to this instance. Optional.
/// - Returns: An instance of an authenticated user session within the AT Protocol. It may also
/// have logging information, as well as the URL of the Personal Data Server (PDS).
///
/// - Throws: An ``ATProtoError``-conforming error type, depending on the issue. Go to
/// ``ATAPIError`` and ``ATRequestPrepareError`` for more details.
public func createAccount(
email: String? = nil,
handle: String,
existingDID: String? = nil,
inviteCode: String? = nil,
verificationCode: String? = nil,
verificationPhone: String? = nil,
password: String? = nil,
recoveryKey: String? = nil,
plcOp: UnknownType? = nil
) async throws -> UserSession {
guard let requestURL = URL(string: "\(self.pdsURL)/xrpc/com.atproto.server.createAccount") else {
throw ATRequestPrepareError.invalidRequestURL
}

let requestBody = ComAtprotoLexicon.Server.CreateAccountRequestBody(
email: email,
handle: handle,
existingDID: existingDID,
inviteCode: inviteCode,
verificationCode: verificationCode,
verificationPhone: verificationPhone,
password: password,
recoveryKey: recoveryKey,
plcOp: plcOp
)

do {
let request = APIClientService.createRequest(
forRequest: requestURL,
andMethod: .post,
acceptValue: nil,
contentTypeValue: nil,
authorizationValue: nil
)
var response = try await APIClientService.shared.sendRequest(
request,
withEncodingBody: requestBody,
decodeTo: UserSession.self
)
response.pdsURL = self.pdsURL

if self.logger != nil {
response.logger = self.logger
}

return response
} catch {
throw error
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// CreateSession.swift
//
//
// Created by Christopher Jr Riley on 2024-08-18.
//

import Foundation

extension ATProtocolConfiguration {

/// Attempts to authenticate the user into the server.
///
/// If the user has Two-Factor Authentication enabled, then `authenticationFactorToken`
/// is required to be used. If the user is inputting their App Password, then the parameter
/// shouldn't be used.
///
/// - Note: According to the AT Protocol specifications: "Handle or other identifier supported
/// by the server for the authenticating user."
///
/// - SeeAlso: This is based on the [`com.atproto.server.createSession`][github] lexicon.
///
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/com/atproto/server/createSession.json
///
/// - Parameter authenticationFactorToken: A token used for
/// Two-Factor Authentication. Optional.
/// - Returns: An instance of an authenticated user session within the AT Protocol. It may also
/// have logging information, as well as the URL of the Personal Data Server (PDS).
///
/// - Throws: An ``ATProtoError``-conforming error type, depending on the issue. Go to
/// ``ATAPIError`` and ``ATRequestPrepareError`` for more details.
public func authenticate(authenticationFactorToken: String? = nil) async throws -> UserSession {
guard let requestURL = URL(string: "\(self.pdsURL)/xrpc/com.atproto.server.createSession") else {
throw ATRequestPrepareError.invalidRequestURL
}

let credentials = ComAtprotoLexicon.Server.CreateSessionRequestBody(
identifier: handle,
password: appPassword,
authenticationFactorToken: authenticationFactorToken
)

do {
let request = APIClientService.createRequest(
forRequest: requestURL,
andMethod: .post
)
var response = try await APIClientService.shared.sendRequest(
request,
withEncodingBody: credentials,
decodeTo: UserSession.self
)
response.pdsURL = self.pdsURL

if self.logger != nil {
response.logger = self.logger
}

return response
} catch {
throw error
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// DeleteSession.swift
//
//
// Created by Christopher Jr Riley on 2024-08-18.
//

import Foundation

extension ATProtocolConfiguration {

/// Refreshes the user's session using a refresh token.
///
/// - Note: According to the AT Protocol specifications: "Delete the current session.
/// Requires auth."
///
/// - SeeAlso: This is based on the [`com.atproto.server.deleteSession`][github] lexicon.
///
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/com/atproto/server/deleteSession.json
///
/// - Parameters:
/// - accessToken: The access token for the session.
/// - pdsURL: The URL of the Personal Data Server (PDS). Defaults to `nil`.
///
/// - Throws: An ``ATProtoError``-conforming error type, depending on the issue. Go to
/// ``ATAPIError`` and ``ATRequestPrepareError`` for more details.
public func deleteSession(
using accessToken: String,
pdsURL: String? = nil
) async throws {
guard let sessionURL = pdsURL != nil ? pdsURL : self.pdsURL,
let requestURL = URL(string: "\(sessionURL)/xrpc/com.atproto.server.deleteSession") else {
throw ATRequestPrepareError.invalidRequestURL
}

do {
let request = APIClientService.createRequest(
forRequest: requestURL,
andMethod: .post,
authorizationValue: "Bearer \(accessToken)"
)

_ = try await APIClientService.shared.sendRequest(
request,
withEncodingBody: nil
)
} catch {
throw error
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// GetSession.swift
//
//
// Created by Christopher Jr Riley on 2024-08-18.
//

import Foundation

extension ATProtocolConfiguration {

/// Fetches an existing session using an access token.
///
/// - Note: According to the AT Protocol specifications: "Get information about the current
/// auth session. Requires auth."
///
/// - SeeAlso: This is based on the [`com.atproto.server.getSession`][github] lexicon.
///
/// [github]: https://github.com/bluesky-social/atproto/blob/main/lexicons/com/atproto/server/getSession.json
///
/// - Parameters:
/// - accessToken: The access token for the session.
/// - pdsURL: The URL of the Personal Data Server (PDS). Defaults to `nil`.
/// - Returns: An instance of the session-related information what contains a session response
/// within the AT Protocol.
///
/// - Throws: An ``ATProtoError``-conforming error type, depending on the issue. Go to
/// ``ATAPIError`` and ``ATRequestPrepareError`` for more details.
public func getSession(
by accessToken: String,
pdsURL: String? = nil
) async throws -> SessionResponse {
guard let sessionURL = pdsURL != nil ? pdsURL : self.pdsURL,
let requestURL = URL(string: "\(sessionURL)/xrpc/com.atproto.server.getSession") else {
throw ATRequestPrepareError.invalidRequestURL
}

do {
let request = APIClientService.createRequest(
forRequest: requestURL,
andMethod: .get,
authorizationValue: "Bearer \(accessToken)"
)
let response = try await APIClientService.shared.sendRequest(
request,
decodeTo: SessionResponse.self
)

return response
} catch {
throw error
}
}
}
Loading

0 comments on commit c8504d2

Please sign in to comment.