Skip to content

Commit

Permalink
add ci, fix test
Browse files Browse the repository at this point in the history
  • Loading branch information
zunda-pixel committed Jul 14, 2024
1 parent 2329736 commit af62c50
Show file tree
Hide file tree
Showing 23 changed files with 294 additions and 176 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: CI

on: pull_request

jobs:
test:
runs-on: ubuntu-latest
container: swiftlang/swift:nightly-6.0-jammy
steps:
- uses: actions/checkout@v4
- run: swift build --build-tests --disable-xctest --enable-code-coverage
- run: swift test --skip-build --disable-xctest --parallel --enable-code-coverage --skip emailRequired
env:
FIREBASE_API_TOKEN: ${{ secrets.FIREBASE_API_TOKEN }}
GOOGLE_USER_ID: ${{ secrets.GOOGLE_USER_ID }}
lint:
runs-on: ubuntu-latest
container: swiftlang/swift:nightly-6.0-jammy
steps:
- uses: actions/checkout@v4
- run: swift format lint -r -p -s .
26 changes: 22 additions & 4 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
{
"originHash" : "19ecdf48e8ce159bc6db3b46aca5683f5a83f8f3d637b9cf87f244f56e076d7f",
"originHash" : "674b8690cdb48dcfdfaa3f5068df2393c8e4e86328172c8dac42f9f1f667155d",
"pins" : [
{
"identity" : "swift-http-types",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-http-types",
"location" : "https://github.com/zunda-pixel/swift-http-types",
"state" : {
"revision" : "1ddbea1ee34354a6a2532c60f98501c35ae8edfa",
"version" : "1.2.0"
"branch" : "fix-swift-6",
"revision" : "c8e8a8c733723f0b9f4d56873649b718b0c005bc"
}
},
{
"identity" : "swift-syntax",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-syntax.git",
"state" : {
"revision" : "4c6cc0a3b9e8f14b3ae2307c5ccae4de6167ac2c",
"version" : "600.0.0-prerelease-2024-06-12"
}
},
{
"identity" : "swift-testing",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-testing",
"state" : {
"revision" : "69d59cfc76e5daf498ca61f5af409f594768eef9",
"version" : "0.10.0"
}
}
],
Expand Down
10 changes: 6 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ import PackageDescription
let package = Package(
name: "firebase-swift",
platforms: [
.macOS(.v15),
.iOS(.v18),
.macOS(.v14),
.iOS(.v17),
],
products: [
.library(
name: "Auth",
targets: ["Auth"]
),
)
],
dependencies: [
.package(url: "https://github.com/apple/swift-http-types", from: "1.2.0"),
.package(url: "https://github.com/zunda-pixel/swift-http-types", branch: "fix-swift-6"),
.package(url: "https://github.com/apple/swift-testing", from: "0.10.0"),
],
targets: [
.target(
Expand All @@ -30,6 +31,7 @@ let package = Package(
name: "AuthTests",
dependencies: [
.target(name: "Auth"),
.product(name: "Testing", package: "swift-testing"),
]
),
.target(
Expand Down
2 changes: 1 addition & 1 deletion Sources/Auth/Auth.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation
import HTTPClient
import HTTPTypes
import HTTPTypesFoundation
import HTTPClient

public struct Auth<HTTPClient: HTTPClientProtocol>: Sendable, Hashable {
public var apiKey: String
Expand Down
21 changes: 12 additions & 9 deletions Sources/Auth/ConfirmEmailVerification.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,42 @@ extension Auth {
private struct Body: Sendable, Hashable, Codable {
var oobCode: String
}

/// Confirm email verification
/// You can confirm an email verification code by issuing an HTTP POST request to the Auth setAccountInfo endpoint.
/// https://firebase.google.com/docs/reference/rest/auth#section-confirm-email-verification
/// - Parameter oobCode: The action code sent to user's email for email verification.
/// - Returns: ``ConfirmEmailVerificationResponse``
public func confirmEmailVerification(oobCode: String) async throws -> ConfirmEmailVerificationResponse {
public func confirmEmailVerification(
oobCode: String
) async throws -> ConfirmEmailVerificationResponse {
let path = "accounts:update"
let endpoint = baseURL
let endpoint =
baseURL
.appending(path: path)
.appending(queryItems: [.init(name: "key", value: apiKey)])

let body = Body(oobCode: oobCode)
let bodyData = try! JSONEncoder().encode(body)

let request = HTTPRequest(
method: .post,
url: endpoint,
headerFields: [.contentType: "application/json"]
)

let (data, _) = try await self.httpClient.execute(for: request, from: bodyData)

let response = try self.decode(ConfirmEmailVerificationResponse.self, from: data)

return response
}
}

public struct ConfirmEmailVerificationResponse: Sendable, Hashable, Codable {
public var email: String
public var displayName: String?
public var photoUrl: String?
public var photoUrl: URL?
public var passwordHash: String
public var providerUserInfo: [ProviderUserInfo]
public var emailVerified: Bool
Expand Down
4 changes: 2 additions & 2 deletions Sources/Auth/DecodeHandler.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import Foundation

extension Auth {
func decode<T>(_ type: T.Type, from data: Data) throws -> T where T : Decodable {
func decode<T>(_ type: T.Type, from data: Data) throws -> T where T: Decodable {
let decoder = JSONDecoder()

do {
return try decoder.decode(T.self, from: data)
} catch {
Expand Down
13 changes: 7 additions & 6 deletions Sources/Auth/DeleteAccount.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extension Auth {
private struct Body: Sendable, Hashable, Codable {
var idToken: String
}

/// Delete account
/// You can delete a current user by issuing an HTTP POST request to the Auth deleteAccount endpoint.
/// https://firebase.google.com/docs/reference/rest/auth#section-delete-account
Expand All @@ -15,10 +15,11 @@ extension Auth {
/// - Returns: ``DeleteAccountResponse``
public func deleteAccount(idToken: String) async throws -> DeleteAccountResponse {
let path = "accounts:delete"
let endpoint = baseURL
let endpoint =
baseURL
.appending(path: path)
.appending(queryItems: [.init(name: "key", value: apiKey)])

let body = Body(idToken: idToken)
let bodyData = try! JSONEncoder().encode(body)

Expand All @@ -27,11 +28,11 @@ extension Auth {
url: endpoint,
headerFields: [.contentType: "application/json"]
)

let (data, _) = try await self.httpClient.execute(for: request, from: bodyData)

let response = try self.decode(DeleteAccountResponse.self, from: data)

return response
}
}
Expand Down
17 changes: 9 additions & 8 deletions Sources/Auth/GetUser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,32 @@ extension Auth {
private struct Body: Sendable, Hashable, Codable {
var idToken: String
}

/// Get user data
/// You can get a user's data by issuing an HTTP POST request to the Auth getAccountInfo endpoint.
/// https://firebase.google.com/docs/reference/rest/auth#section-get-account-info
/// - Parameter idToken: The Firebase ID token of the account.
/// - Returns: ``UserResponse``
public func user(idToken: String) async throws -> UserResponse {
let path = "accounts:lookup"
let endpoint = baseURL
let endpoint =
baseURL
.appending(path: path)
.appending(queryItems: [.init(name: "key", value: apiKey)])

let body = Body(idToken: idToken)
let bodyData = try! JSONEncoder().encode(body)

let request = HTTPRequest(
method: .post,
url: endpoint,
headerFields: [.contentType: "application/json"]
)

let (data, _) = try await self.httpClient.execute(for: request, from: bodyData)

let response = try self.decode(UsersResponse.self, from: data)

return response.users.first!
}
}
Expand All @@ -54,7 +55,7 @@ public struct UserResponse: Sendable, Hashable, Codable {
public var createdAt: Date
public var customAuth: Bool?
public var lastRefreshAt: Date

public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: UserResponse.CodingKeys.self)
self.localId = try container.decode(String.self, forKey: .localId)
Expand Down
23 changes: 14 additions & 9 deletions Sources/Auth/LinkEmail.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ extension Auth {
var password: String
var returnSecureToken = true
}

/// Link with email/password
/// You can link an email/password to a current user by issuing an HTTP POST request to the Auth setAccountInfo endpoint.
/// https://firebase.google.com/docs/reference/rest/auth#section-link-with-email-password
Expand All @@ -18,25 +18,30 @@ extension Auth {
/// - email: The email to link to the account.
/// - password: The new password of the account.
/// - Returns: ``LinkEmailResponse``
public func linkEmail(idToken: String, email: String, password: String) async throws -> LinkEmailResponse {
public func linkEmail(
idToken: String,
email: String,
password: String
) async throws -> LinkEmailResponse {
let path = "accounts:update"
let endpoint = baseURL
let endpoint =
baseURL
.appending(path: path)
.appending(queryItems: [.init(name: "key", value: apiKey)])

let body = Body(idToken: idToken, email: email, password: password)
let bodyData = try! JSONEncoder().encode(body)

let request = HTTPRequest(
method: .post,
url: endpoint,
headerFields: [.contentType: "application/json"]
)

let (data, _) = try await self.httpClient.execute(for: request, from: bodyData)

let response = try self.decode(LinkEmailResponse.self, from: data)

return response
}
}
Expand All @@ -52,7 +57,7 @@ public struct LinkEmailResponse: Sendable, Hashable, Codable {
public var idToken: String
public var refreshToken: String
public var expiresIn: Int

public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: LinkEmailResponse.CodingKeys.self)
self.localId = try container.decode(String.self, forKey: .localId)
Expand Down
21 changes: 11 additions & 10 deletions Sources/Auth/RefreshToken.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,38 @@ extension Auth {
private struct Body: Sendable, Hashable, Codable {
var grantType: String = "refresh_token"
var refreshToken: String

private enum CodingKeys: String, CodingKey {
case grantType = "grant_type"
case refreshToken = "refresh_token"
}
}

/// Exchange a refresh token for an ID token
/// You can refresh a Firebase ID token by issuing an HTTP POST request to the securetoken.googleapis.com endpoint.
/// https://firebase.google.com/docs/reference/rest/auth#section-refresh-token
/// - Parameter refreshToken: A Firebase Auth refresh token.
/// - Returns: ``RefreshTokenResponse``
public func refreshToken(refreshToken: String) async throws -> RefreshTokenResponse {
let path = "token"
let endpoint = baseURL
let endpoint =
baseURL
.appending(path: path)
.appending(queryItems: [.init(name: "key", value: apiKey)])

let body = Body(refreshToken: refreshToken)
let bodyData = try! JSONEncoder().encode(body)

let request = HTTPRequest(
method: .post,
url: endpoint,
headerFields: [.contentType: "application/json"]
)

let (data, _) = try await self.httpClient.execute(for: request, from: bodyData)

let response = try self.decode(RefreshTokenResponse.self, from: data)

return response
}
}
Expand All @@ -48,7 +49,7 @@ public struct RefreshTokenResponse: Sendable, Hashable, Codable {
public var idToken: String
public var userId: String
public var projectId: String

private enum CodingKeys: String, CodingKey {
case expiresIn = "expires_in"
case tokenType = "token_type"
Expand All @@ -57,7 +58,7 @@ public struct RefreshTokenResponse: Sendable, Hashable, Codable {
case userId = "user_id"
case projectId = "project_id"
}

public init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: RefreshTokenResponse.CodingKeys.self)
let expiresInString = try container.decode(String.self, forKey: .expiresIn)
Expand Down
Loading

0 comments on commit af62c50

Please sign in to comment.