Request to /api/mobile/register/hebe
This commit is contained in:
parent
5b2bda83f8
commit
4a7319aab8
8 changed files with 132 additions and 7 deletions
50
sdk/Sources/Sdk/Extensions/getSignatures.swift
Normal file
50
sdk/Sources/Sdk/Extensions/getSignatures.swift
Normal file
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// getSignatures.swift
|
||||
//
|
||||
//
|
||||
// Created by Tomasz on 02/03/2021.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import KeychainAccess
|
||||
|
||||
@available (iOS 14, macOS 11, watchOS 7, tvOS 14, *)
|
||||
func getSignatures(request: URLRequest, certificate: X509) -> String {
|
||||
guard let urlString = request.url?.absoluteString else {
|
||||
return "\(Sdk.APIError.urlError)"
|
||||
}
|
||||
|
||||
// Get private key
|
||||
guard let privateKeyRawData = certificate.getPrivateKeyData(format: .DER),
|
||||
let privateKeyString = String(data: privateKeyRawData, encoding: .utf8)?
|
||||
.split(separator: "\n")
|
||||
.dropFirst()
|
||||
.dropLast()
|
||||
.joined()
|
||||
.data(using: .utf8) else {
|
||||
return "\(Sdk.APIError.noPrivateKey)"
|
||||
}
|
||||
|
||||
// Create SecKey
|
||||
let attributes = [
|
||||
kSecAttrKeyType: kSecAttrKeyTypeRSA,
|
||||
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
|
||||
]
|
||||
guard let privateKeyData = Data(base64Encoded: privateKeyString),
|
||||
let secKey = SecKeyCreateWithData(privateKeyData as NSData, attributes as NSDictionary, nil) else {
|
||||
return "\(Sdk.APIError.noPrivateKey)"
|
||||
}
|
||||
|
||||
// Get fingerprint
|
||||
guard let signatureValues = Sdk.Signer.getSignatureValues(body: request.httpBody, url: urlString, privateKey: secKey, fingerprint: certificate.getCertificateFingerprint().lowercased()) else {
|
||||
return "\(Sdk.APIError.noPrivateKey)"
|
||||
}
|
||||
|
||||
// Headers
|
||||
let keychain = Keychain()
|
||||
let fingerprint: String! = keychain["keyFingerprint"]
|
||||
|
||||
let signature = "\(signatureValues.signature.replacingOccurrences(of: "nil", with: fingerprint))"
|
||||
|
||||
return signature
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
import Foundation
|
||||
import Combine
|
||||
import os
|
||||
import KeychainAccess
|
||||
|
||||
@available (iOS 14, macOS 11, watchOS 7, tvOS 14, *)
|
||||
public class Sdk {
|
||||
|
@ -17,6 +18,9 @@ public class Sdk {
|
|||
private let loggerSubsystem: String = "com.wulkanowy-ios.Sdk"
|
||||
private var cancellables: Set<AnyCancellable> = []
|
||||
|
||||
var firebaseToken: String!
|
||||
var endpointURL: String!
|
||||
|
||||
public let certificate: X509
|
||||
|
||||
// MARK: - Init
|
||||
|
@ -136,6 +140,7 @@ public class Sdk {
|
|||
let parsedError = self.parseResponse(response) {
|
||||
completionHandler(parsedError)
|
||||
} else {
|
||||
self.getStudents(symbol: symbol, deviceModel: deviceModel)
|
||||
completionHandler(nil)
|
||||
}
|
||||
})
|
||||
|
@ -155,6 +160,8 @@ public class Sdk {
|
|||
/// - Throws: Error
|
||||
/// - Returns: URLSession.DataTaskPublisher
|
||||
private func registerDevice(endpointURL: String, firebaseToken: String, token: String, symbol: String, pin: String, deviceModel: String) throws -> URLSession.DataTaskPublisher {
|
||||
self.endpointURL = endpointURL
|
||||
self.firebaseToken = firebaseToken
|
||||
guard let keyFingerprint = certificate.getPrivateKeyFingerprint(format: .PEM)?.replacingOccurrences(of: ":", with: "").lowercased(),
|
||||
let keyData = certificate.getPublicKeyData(),
|
||||
let keyBase64 = String(data: keyData, encoding: .utf8)?
|
||||
|
@ -179,7 +186,10 @@ public class Sdk {
|
|||
|
||||
return dateFormatter.string(from: now)
|
||||
}
|
||||
|
||||
|
||||
let keychain = Keychain()
|
||||
keychain[string: "keyFingerprint"] = keyFingerprint
|
||||
|
||||
// Body
|
||||
let body: [String: Encodable?] = [
|
||||
"AppName": "DzienniczekPlus 2.0",
|
||||
|
@ -201,7 +211,7 @@ public class Sdk {
|
|||
"Timestamp": now.millisecondsSince1970,
|
||||
"TimestampFormatted": "\(timestampFormatted) GMT"
|
||||
]
|
||||
|
||||
|
||||
request.httpBody = try? JSONSerialization.data(withJSONObject: body)
|
||||
|
||||
request.allHTTPHeaderFields = [
|
||||
|
@ -211,9 +221,54 @@ public class Sdk {
|
|||
]
|
||||
|
||||
let signedRequest = try request.signed(with: certificate)
|
||||
|
||||
return URLSession.shared.dataTaskPublisher(for: signedRequest)
|
||||
}
|
||||
|
||||
private func getStudents(symbol: String, deviceModel: String) {
|
||||
let url = "\(self.endpointURL!)/\(symbol)/api/mobile/register/hebe"
|
||||
var request = URLRequest(url: URL(string: url)!)
|
||||
request.httpMethod = "GET"
|
||||
|
||||
let now = Date()
|
||||
var vDate: String {
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss"
|
||||
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
|
||||
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
|
||||
|
||||
return "\(dateFormatter.string(from: now)) GMT"
|
||||
}
|
||||
|
||||
let signatures = getSignatures(request: request, certificate: certificate)
|
||||
request.setValue("\(signatures)", forHTTPHeaderField: "Signature")
|
||||
|
||||
request.allHTTPHeaderFields = [
|
||||
"User-Agent": "wulkanowy/1 CFNetwork/1220.1 Darwin/20.1.0",
|
||||
"vOS": "iOS",
|
||||
"vDeviceModel": deviceModel,
|
||||
"vAPI": "1",
|
||||
"vDate": vDate,
|
||||
"vCanonicalUrl": "api%2fmobile%2fregister%2fhebe"
|
||||
]
|
||||
|
||||
let session = URLSession.shared
|
||||
let task = session.dataTask(with: request) { (data, response, error) in
|
||||
if let error = error {
|
||||
// Handle HTTP request error
|
||||
print(error)
|
||||
} else if let data = data {
|
||||
// Handle HTTP request response
|
||||
print(String(data: data, encoding: String.Encoding.utf8) as Any)
|
||||
} else {
|
||||
// Handle unexpected error
|
||||
}
|
||||
}
|
||||
|
||||
task.resume()
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Helper functions
|
||||
|
||||
/// Parses the response
|
||||
|
|
12
sdk/Sources/Sdk/data/luckyNumber.swift
Normal file
12
sdk/Sources/Sdk/data/luckyNumber.swift
Normal file
|
@ -0,0 +1,12 @@
|
|||
//
|
||||
// luckyNumber.swift
|
||||
//
|
||||
//
|
||||
// Created by Tomasz on 27/02/2021.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public func getLuckyNumber() -> Int {
|
||||
return 7
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import Foundation
|
||||
import CryptoKit
|
||||
import KeychainAccess
|
||||
|
||||
@available (iOS 14, macOS 11, watchOS 7, tvOS 14, *)
|
||||
public extension Sdk {
|
||||
|
|
|
@ -6,8 +6,19 @@
|
|||
//
|
||||
|
||||
import SwiftUI
|
||||
import KeychainAccess
|
||||
import Sdk
|
||||
|
||||
struct DashboardView: View {
|
||||
init() {
|
||||
let keychain = Keychain()
|
||||
let key = keychain["privateKey"]
|
||||
|
||||
let luckyNumber = getLuckyNumber()
|
||||
print(luckyNumber)
|
||||
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
VStack {
|
||||
|
|
|
@ -55,7 +55,6 @@ struct LoginView: View {
|
|||
}
|
||||
} else {
|
||||
print("success")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,9 +52,6 @@ final class VulcanStore: ObservableObject {
|
|||
if let base64Encoded = utf8str?.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0)) {
|
||||
let keychain = Keychain()
|
||||
keychain[string: "privateKey"] = base64Encoded
|
||||
|
||||
let key = keychain["privateKey"]
|
||||
print("Encoded: \(String(describing: key))")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,4 +59,3 @@ final class VulcanStore: ObservableObject {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import XCTest
|
||||
@testable import wulkanowy
|
||||
|
||||
@available (iOS 14, macOS 11, watchOS 7, tvOS 14, *)
|
||||
class wulkanowyTests: XCTestCase {
|
||||
|
||||
override func setUpWithError() throws {
|
||||
|
|
Loading…
Reference in a new issue