498f407585
Introduce optional Apple account-backed credits with scoped gateway access while preserving local and BYOK paths. Refresh assistant behavior, tests, privacy disclosures, docs, and the website for the 2.0 experience.
79 lines
2.6 KiB
Swift
79 lines
2.6 KiB
Swift
// AccountSecurityPrimitiveTests.swift
|
|
// OSGKeyboardTests
|
|
//
|
|
// Fixed vectors for nonce hashing, canonical payloads, and Keychain isolation.
|
|
|
|
@testable import OSGKeyboardHostSupport
|
|
import XCTest
|
|
|
|
final class AccountSecurityPrimitiveTests: XCTestCase {
|
|
func testNonceUsesRawBase64URLAndLowercaseSHA256Hex() throws {
|
|
let bytes = Data(0..<32)
|
|
let generator = AppleSignInNonceGenerator(
|
|
random: FixedRandomBytesGenerator(value: bytes)
|
|
)
|
|
|
|
let nonce = try generator.makeNonce()
|
|
|
|
XCTAssertEqual(
|
|
nonce.rawValue,
|
|
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8"
|
|
)
|
|
XCTAssertEqual(
|
|
nonce.sha256Hex,
|
|
"ea866a757e4c38babfa8127cbe9a409d3e1f93a00ff1488ff735fcf917afffd0"
|
|
)
|
|
XCTAssertNotNil(
|
|
nonce.sha256Hex.range(
|
|
of: #"^[0-9a-f]{64}$"#,
|
|
options: .regularExpression
|
|
)
|
|
)
|
|
}
|
|
|
|
func testAppleSignInCanonicalPayloadMatchesServerByteForByte() throws {
|
|
let payload = try AppAttestCanonicalPayload.appleSignIn(
|
|
challenge: "AQID",
|
|
credential: AppleSignInCredential(
|
|
identityToken: "identity-token",
|
|
authorizationCode: "authorization-code"
|
|
),
|
|
rawNonce: "raw-nonce"
|
|
)
|
|
|
|
XCTAssertEqual(
|
|
String(data: payload, encoding: .utf8),
|
|
"""
|
|
osg-app-attest-v1
|
|
purpose=apple-sign-in
|
|
challenge=AQID
|
|
identity_token_sha256=OcwzHhEgHO3_IBV8hI8o_WTuAx0hgRrERJAbfcPbjvA
|
|
authorization_code_sha256=WVYUJ4163Fe7kuKPogOooY15egdoT9_3XLvyqW6_hXc
|
|
nonce_sha256=LF0QeTgFOiJ18CLBU8mnH2XuB3VLi8pUPul6DDzGaZA
|
|
|
|
"""
|
|
)
|
|
XCTAssertEqual(payload.last, 0x0A, "The server contract includes the final line feed")
|
|
}
|
|
|
|
func testHostPrivateKeychainDescriptorRejectsSharedAccessGroup() throws {
|
|
XCTAssertThrowsError(
|
|
try HostPrivateAccountKeychainDescriptor(
|
|
accessGroup: "TEAMID.com.osgkeyboard.shared"
|
|
)
|
|
)
|
|
|
|
let descriptor = try HostPrivateAccountKeychainDescriptor.hostApplication(
|
|
appIdentifierPrefix: "TEAMID"
|
|
)
|
|
XCTAssertEqual(descriptor.service, "com.osgkeyboard.ios.account")
|
|
XCTAssertEqual(descriptor.accessGroup, "TEAMID.com.osgkeyboard.ios")
|
|
}
|
|
|
|
func testBase64URLRejectsNonCanonicalAlphabet() {
|
|
XCTAssertNil(Data(base64URLEncoded: "AQID="))
|
|
XCTAssertNil(Data(base64URLEncoded: "AQ+ID"))
|
|
XCTAssertEqual(Data(base64URLEncoded: "AQID"), Data([1, 2, 3]))
|
|
}
|
|
}
|