134 lines
2.8 KiB
Swift
134 lines
2.8 KiB
Swift
import Foundation
|
|
|
|
struct UserProfile: Codable, Equatable {
|
|
let id: String
|
|
let username: String
|
|
let displayName: String
|
|
}
|
|
|
|
struct AuthResponse: Codable {
|
|
let token: String
|
|
let user: UserProfile
|
|
}
|
|
|
|
struct AccessKeySummary: Codable, Equatable, Identifiable {
|
|
let id: String
|
|
let credentialId: String
|
|
let label: String
|
|
let transports: [String]
|
|
let deviceType: String
|
|
let backedUp: Bool
|
|
let aaguid: String
|
|
let createdAt: String
|
|
}
|
|
|
|
struct AccessKeyListResponse: Codable {
|
|
let credentials: [AccessKeySummary]
|
|
}
|
|
|
|
struct SessionResponse: Codable {
|
|
let user: UserProfile
|
|
}
|
|
|
|
struct RegistrationOptionsResponse: Codable {
|
|
struct RelyingParty: Codable {
|
|
let name: String
|
|
let id: String
|
|
}
|
|
|
|
struct UserEntity: Codable {
|
|
let id: String
|
|
let name: String
|
|
let displayName: String
|
|
}
|
|
|
|
let expectedOrigin: String?
|
|
let rp: RelyingParty
|
|
let user: UserEntity
|
|
let challenge: String
|
|
}
|
|
|
|
struct AuthenticationOptionsResponse: Codable {
|
|
let attemptId: String
|
|
let expectedOrigin: String?
|
|
let challenge: String
|
|
let rpId: String?
|
|
}
|
|
|
|
struct APIErrorResponse: Codable, Error {
|
|
let message: String
|
|
}
|
|
|
|
struct PasskeyRegistrationPayload: Encodable {
|
|
struct Response: Encodable {
|
|
let clientDataJSON: String
|
|
let attestationObject: String
|
|
let transports: [String]?
|
|
}
|
|
|
|
let id: String
|
|
let rawId: String
|
|
let response: Response
|
|
let clientExtensionResults: [String: String]
|
|
let type: String
|
|
}
|
|
|
|
struct PasskeyAuthenticationPayload: Encodable {
|
|
struct Response: Encodable {
|
|
let clientDataJSON: String
|
|
let authenticatorData: String
|
|
let signature: String
|
|
let userHandle: String?
|
|
}
|
|
|
|
let id: String
|
|
let rawId: String
|
|
let response: Response
|
|
let clientExtensionResults: [String: String]
|
|
let type: String
|
|
}
|
|
|
|
extension Data {
|
|
init?(base64URLEncoded value: String) {
|
|
var normalized = value.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
|
|
let padding = (4 - normalized.count % 4) % 4
|
|
normalized.append(String(repeating: "=", count: padding))
|
|
self.init(base64Encoded: normalized)
|
|
}
|
|
|
|
func base64URLEncodedString() -> String {
|
|
base64EncodedString()
|
|
.replacingOccurrences(of: "+", with: "-")
|
|
.replacingOccurrences(of: "/", with: "_")
|
|
.replacingOccurrences(of: "=", with: "")
|
|
}
|
|
}
|
|
|
|
extension Encodable {
|
|
func jsonString() -> String {
|
|
let encoder = JSONEncoder()
|
|
encoder.outputFormatting = [.withoutEscapingSlashes]
|
|
|
|
guard let data = try? encoder.encode(AnyEncodable(self)),
|
|
let string = String(data: data, encoding: .utf8)
|
|
else {
|
|
return "null"
|
|
}
|
|
|
|
return string
|
|
}
|
|
}
|
|
|
|
private struct AnyEncodable: Encodable {
|
|
private let encodeValue: (Encoder) throws -> Void
|
|
|
|
init(_ value: some Encodable) {
|
|
encodeValue = value.encode
|
|
}
|
|
|
|
func encode(to encoder: Encoder) throws {
|
|
try encodeValue(encoder)
|
|
}
|
|
}
|
|
|