Skip to content

Commit

Permalink
Paywalls Tester 0.1 (#3868)
Browse files Browse the repository at this point in the history
This code has been reviewed in other branches.
  • Loading branch information
jamesrb1 committed May 3, 2024
1 parent 2cff931 commit e4b69c3
Show file tree
Hide file tree
Showing 50 changed files with 2,695 additions and 305 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
"colors" : [
{
"color" : {
"platform" : "universal",
"reference" : "systemOrangeColor"
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "91",
"green" : "84",
"red" : "242"
}
},
"idiom" : "universal"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "logo46 1.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "logo46.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "logo69.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// Configuration.swift
// SimpleApp
// PaywallsPreview
//
// Created by Nacho Soto on 7/13/23.
//
Expand Down Expand Up @@ -33,7 +33,7 @@ final class Configuration: ObservableObject {
#warning("Configure API key if you want to test paywalls from your dashboard")
// Note: you can leave this empty to use the production server, or point to your own instance.
private static let proxyURL = ""
private static let apiKey = ""
private static let apiKey = "appl_TFIZqBlauHeMhnqfNlWWFBjZwkf"

// This is modified by CI:
private static let apiKeyFromCIForTesting = ""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// ApplicationData.swift
//
//
// Created by Nacho Soto on 12/11/23.
//

import Foundation

import OSLog

@Observable
final class ApplicationData {

private(set) var authenticationStatus: AuthenticationStatus = .unknown {
didSet {
Self.logger.info("Changed authentication: \(String(describing: self.authenticationStatus))")
}
}

@MainActor
func loadApplicationData() async throws {
do {
self.authenticationStatus = .signedIn(try await self.manager.loadApplicationData())
} catch ApplicationManager.Error.unauthenticated {
Self.logger.warning("Received unauthentication error when loading application data")
self.authenticationStatus = .signedOut
}
}

func signOut() {
self.manager.signOut()
self.authenticationStatus = .signedOut
}

var isSignedIn: Bool {
if case .signedIn = self.authenticationStatus {
return true
}
return false
}

@ObservationIgnored
private var manager: ApplicationManagerType = ApplicationManager()
private static let logger = Logging.shared.logger(category: "ApplicationData")

}

extension ApplicationData {

enum AuthenticationStatus: Equatable {

case signedIn(DeveloperResponse)
case signedOut
case unknown

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// ApplicationManager.swift
//
//
// Created by Nacho Soto on 12/11/23.
//

import Foundation


public protocol ApplicationManagerType {

func loadApplicationData() async throws -> DeveloperResponse
func signOut()

}

public final class ApplicationManager: ApplicationManagerType {

private var client = HTTPClient.shared

public init() {}

/// - Throws: ``ApplicationManager/Error``
public func loadApplicationData() async throws -> DeveloperResponse {
do {
return try await self.client.perform(
.init(method: .get, endpoint: .me)
)
} catch HTTPClient.Error.errorResponse(.unauthorized, _, _, _),
HTTPClient.Error.errorResponse(.forbidden, _, _, _){
throw Error.unauthenticated
} catch let error as HTTPClient.Error {
throw Error.requestError(error)
} catch URLError.cancelled, is CancellationError {
throw Error.operationCancelled
} catch {
throw Error.unknown(error)
}
}

public func signOut() {
self.client.removeCookies()
}

}

// MARK: - Errors

public extension ApplicationManager {

enum Error: Swift.Error {
case unauthenticated
case requestError(HTTPClient.Error)
case operationCancelled
case unknown(Swift.Error)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//
// AuthenticationActor.swift
//
//
// Created by Nacho Soto on 12/11/23.
//

import Foundation

public protocol AuthenticationActorType {

func logIn(user: String, password: String, code: String?) async throws

}

public actor AuthenticationActor: AuthenticationActorType {

private var client: HTTPClient = HTTPClient.shared

public init() {}

/// - Returns: authentication code
/// - Throws: ``AuthenticationActor/Error``
public func logIn(user: String, password: String, code: String?) async throws {
do {
let _: LoginResponse = try await self.client.perform(
.init(
method: .post,
endpoint: .login(
user: user,
password: password,
code: code?.notEmptyOrWhitespaces
)
)
)
} catch HTTPClient.Error.errorResponse(_, .optCodeRequired, _, _) {
throw Error.codeRequired
} catch HTTPClient.Error.errorResponse(.unauthorized, _, _, _),
HTTPClient.Error.errorResponse(.forbidden, _, _, _) {
throw Error.invalidCredentials
} catch let error as HTTPClient.Error {
throw Error.requestError(error)
} catch {
throw Error.unknown(error)
}
}

}

// MARK: - Errors

public extension AuthenticationActor {

enum Error: Swift.Error {
case codeRequired
case invalidCredentials
case requestError(HTTPClient.Error)
case unknown(Swift.Error)
}

}

extension AuthenticationActor.Error: LocalizedError {

public var errorDescription: String? {
switch self {
case .codeRequired:
return "Code required"
case .invalidCredentials:
return "Error"
case .requestError, .unknown:
return nil
}
}

public var failureReason: String? {
switch self {
case .codeRequired:
return "This account required 2FA"

case .invalidCredentials:
return "Invalid credentials"

case let .requestError(error):
return error.failureReason

case let .unknown(error):
return "Unknown error: \(error.localizedDescription)"
}
}

}
Loading

0 comments on commit e4b69c3

Please sign in to comment.