Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add apiKey (sitekey) syntax validation #159

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# 2.8.1

- Feature: sitekey ("apiKey") syntax validation

# 2.8.0

- Feature: passive site key ([#152](https://github.com/hCaptcha/HCaptcha-ios-sdk/issues/152))
- Feature: passive sitekey ([#152](https://github.com/hCaptcha/HCaptcha-ios-sdk/issues/152))
- Feature: upgrade Xcode to 15. NOTE: this also increases the minimum supported iOS version to 12. ([#134](https://github.com/hCaptcha/HCaptcha-ios-sdk/issues/134))


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class HCaptchaWebViewManager__Tests: XCTestCase {
super.setUp()

presenterView = UIApplication.shared.keyWindow?.rootViewController?.view
apiKey = String(arc4random())
apiKey = UUID().uuidString
}

override func tearDown() {
Expand Down
31 changes: 16 additions & 15 deletions Example/HCaptcha_Tests/Core/HCaptcha__Config__Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@
import XCTest

class HCaptcha__Config__Tests: XCTestCase {
private static let sApiKey = UUID().uuidString
private let expected = "https://hcaptcha.com/1/api.js?onload=onloadCallback&render=explicit&recaptchacompat=off"
+ "&host=some-api-key.ios-sdk.hcaptcha.com&sentry=false&endpoint=https%3A%2F%2Fapi.hcaptcha.com"
+ "&host=\(sApiKey).ios-sdk.hcaptcha.com&sentry=false&endpoint=https%3A%2F%2Fapi.hcaptcha.com"
+ "&assethost=https%3A%2F%2Fnewassets.hcaptcha.com&imghost=https%3A%2F%2Fimgs.hcaptcha.com"
+ "&reportapi=https%3A%2F%2Faccounts.hcaptcha.com"
private let apiKey = sApiKey

func test__Base_URL() {
// Ensures baseURL failure when nil
do {
_ = try HCaptchaConfig(apiKey: "", infoPlistKey: nil, baseURL: nil, infoPlistURL: nil)
_ = try HCaptchaConfig(apiKey: apiKey, infoPlistKey: nil, baseURL: nil, infoPlistURL: nil)
XCTFail("Should have failed")
} catch let e as HCaptchaError {
print(e)
Expand All @@ -29,24 +31,24 @@ class HCaptcha__Config__Tests: XCTestCase {

// Ensures plist url if nil key
let plistURL = URL(string: "https://bar")!
let config1 = try? HCaptchaConfig(apiKey: "", infoPlistKey: nil, baseURL: nil, infoPlistURL: plistURL)
let config1 = try? HCaptchaConfig(apiKey: apiKey, infoPlistKey: nil, baseURL: nil, infoPlistURL: plistURL)
XCTAssertEqual(config1?.baseURL, plistURL)

// Ensures preference of given url over plist entry
let url = URL(string: "ftp://foo")!
let config2 = try? HCaptchaConfig(apiKey: "", infoPlistKey: nil, baseURL: url, infoPlistURL: plistURL)
let config2 = try? HCaptchaConfig(apiKey: apiKey, infoPlistKey: nil, baseURL: url, infoPlistURL: plistURL)
XCTAssertEqual(config2?.baseURL, url)
}

func test__Base_URL_Without_Scheme() {
// Ignores URL with scheme
let goodURL = URL(string: "https://foo.bar")!
let config0 = try? HCaptchaConfig(apiKey: "", infoPlistKey: nil, baseURL: goodURL, infoPlistURL: nil)
let config0 = try? HCaptchaConfig(apiKey: apiKey, infoPlistKey: nil, baseURL: goodURL, infoPlistURL: nil)
XCTAssertEqual(config0?.baseURL, goodURL)

// Fixes URL without scheme
let badURL = URL(string: "foo")!
let config = try? HCaptchaConfig(apiKey: "", infoPlistKey: nil, baseURL: badURL, infoPlistURL: nil)
let config = try? HCaptchaConfig(apiKey: apiKey, infoPlistKey: nil, baseURL: badURL, infoPlistURL: nil)
XCTAssertEqual(config?.baseURL.absoluteString, "http://" + badURL.absoluteString)
}

Expand All @@ -63,7 +65,7 @@ class HCaptcha__Config__Tests: XCTestCase {
}

// Ensures plist key if nil key
let plistKey = "bar"
let plistKey = UUID().uuidString
let config1 = try? HCaptchaConfig(
apiKey: nil,
infoPlistKey: plistKey,
Expand All @@ -73,35 +75,34 @@ class HCaptcha__Config__Tests: XCTestCase {
XCTAssertEqual(config1?.apiKey, plistKey)

// Ensures preference of given key over plist entry
let key = "foo"
let config2 = try? HCaptchaConfig(
apiKey: key,
apiKey: apiKey,
infoPlistKey: plistKey,
baseURL: URL(string: "foo"),
infoPlistURL: nil
)
XCTAssertEqual(config2?.apiKey, key)
XCTAssertEqual(config2?.apiKey, apiKey)
}

func test__Locale__Nil() {
let config = try? HCaptchaConfig()
let config = try? HCaptchaConfig(apiKey: apiKey)
let actual = config?.actualEndpoint.absoluteString
XCTAssertEqual(actual, expected)
}

func test__Locale__Valid() {
let locale = Locale(identifier: "pt-BR")
let config = try? HCaptchaConfig(locale: locale)
let config = try? HCaptchaConfig(apiKey: apiKey, locale: locale)
let actual = config?.actualEndpoint.absoluteString
XCTAssertEqual(actual, "\(expected)&hl=\(locale.identifier)")
}

func test__Custom__Host() {
let host = "custom-host"
let config = try? HCaptchaConfig(host: host)
let config = try? HCaptchaConfig(apiKey: apiKey, host: host)
let actual = config?.actualEndpoint.absoluteString
XCTAssertEqual(actual, expected.replacingOccurrences(
of: "some-api-key.ios-sdk.hcaptcha.com",
of: "\(apiKey).ios-sdk.hcaptcha.com",
with: host))
}

Expand All @@ -117,7 +118,7 @@ class HCaptcha__Config__Tests: XCTestCase {
}
}
"""
let config = try? HCaptchaConfig(customTheme: customTheme)
let config = try? HCaptchaConfig(apiKey: apiKey, customTheme: customTheme)
let actual = config?.actualEndpoint.absoluteString
XCTAssertEqual(actual, expected + "&custom=true")
}
Expand Down
4 changes: 2 additions & 2 deletions Example/HCaptcha_Tests/Helpers/HCaptchaConfig+Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Foundation

extension HCaptchaConfig {
init(html: String = HCaptchaHtml.template,
apiKey: String? = String(arc4random()),
apiKey: String? = UUID().uuidString,
passiveApiKey: Bool = false,
infoPlistKey: String? = "api-key",
baseURL: URL? = URL(string: "http://localhost")!,
Expand Down Expand Up @@ -46,7 +46,7 @@ extension HCaptchaConfig {
locale: locale)
}

init(apiKey: String = "some-api-key",
init(apiKey: String = UUID().uuidString,
host: String? = nil,
customTheme: String? = nil,
locale: Locale? = nil) throws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ extension HCaptchaWebViewManager {

self.init(
html: html,
apiKey: apiKey ?? "api-key",
apiKey: apiKey ?? UUID().uuidString,
passiveApiKey: passiveApiKey,
endpoint: endpoint ?? URL(string: "https://api.hcaptcha.com")!,
size: size,
Expand Down
2 changes: 1 addition & 1 deletion Example/HCaptcha_Tests/RxSwift/HCaptcha+Rx__Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class HCaptcha_Rx__Tests: XCTestCase {
super.setUp()

presenterView = UIApplication.shared.keyWindow!
apiKey = String(arc4random())
apiKey = UUID().uuidString
}

override func tearDown() {
Expand Down
6 changes: 3 additions & 3 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PODS:
- AppSwizzle (1.3.1)
- HCaptcha/Core (2.8.0)
- HCaptcha/RxSwift (2.8.0):
- HCaptcha/Core (2.8.1)
- HCaptcha/RxSwift (2.8.1):
- HCaptcha/Core
- RxSwift (~> 6.2.0)
- RxBlocking (6.2.0):
Expand Down Expand Up @@ -37,7 +37,7 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
AppSwizzle: db36e436f56110d93e5ae0147683435df593cabc
HCaptcha: 062308169f5cbd964f2ae25954fb773d19e469ed
HCaptcha: 210d88f8b553a0b33e71f0d3cc2fb2a52b520575
RxBlocking: 0b29f7d2079109a8de49c411381bed7c33ef1eeb
RxCocoa: 4baf94bb35f2c0ab31bc0cb9f1900155f646ba42
RxRelay: e72dbfd157807478401ef1982e1c61c945c94b2f
Expand Down
2 changes: 1 addition & 1 deletion HCaptcha.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'HCaptcha'
s.version = '2.8.0'
s.version = '2.8.1'
s.summary = 'HCaptcha for iOS'
s.swift_version = '5.0'

Expand Down
4 changes: 4 additions & 0 deletions HCaptcha/Classes/HCaptchaConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ struct HCaptchaConfig: CustomDebugStringConvertible {
throw HCaptchaError.baseURLNotFound
}

guard UUID(uuidString: apiKey) != nil else {
throw HCaptchaError.apiKeyInvalid
}

if let customTheme = customTheme {
let validationJS: String = "(function() { return \(customTheme) })()"
let context = JSContext()!
Expand Down
6 changes: 6 additions & 0 deletions HCaptcha/Classes/HCaptchaError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ public enum HCaptchaError: Error, CustomStringConvertible {
/// Invalid custom theme passed
case invalidCustomTheme

/// HCaptchaKey is invalid
case apiKeyInvalid

public static func == (lhs: HCaptchaError, rhs: HCaptchaError) -> Bool {
return lhs.description == rhs.description
}
Expand All @@ -63,6 +66,9 @@ public enum HCaptchaError: Error, CustomStringConvertible {
case .apiKeyNotFound:
return "HCaptchaKey not provided"

case .apiKeyInvalid:
return "HCaptchaKey invalid"

case .baseURLNotFound:
return "HCaptchaDomain not provided"

Expand Down
Loading