-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathUID2Client.swift
More file actions
89 lines (72 loc) · 3 KB
/
UID2Client.swift
File metadata and controls
89 lines (72 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//
// UID2Client.swift
//
//
// Created by Brad Leege on 1/31/23.
//
import Foundation
internal final class UID2Client {
private let uid2APIURL: String
private let clientVersion: String
private let session: NetworkSession
init(uid2APIURL: String, sdkVersion: String, _ session: NetworkSession = URLSession.shared) {
self.uid2APIURL = uid2APIURL
#if os(tvOS)
self.clientVersion = "tvos-\(sdkVersion)"
#else
self.clientVersion = "ios-\(sdkVersion)"
#endif
self.session = session
}
func refreshIdentity(refreshToken: String, refreshResponseKey: String) async throws -> RefreshAPIPackage {
let request = Request.refresh(token: refreshToken)
let (data, statusCode) = try await execute(request)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
// Only Decrypt If HTTP Status is 200 (Success or Opt Out)
if statusCode != 200 {
do {
let tokenResponse = try decoder.decode(RefreshTokenResponse.self, from: data)
throw UID2Error.refreshTokenServer(status: tokenResponse.status, message: tokenResponse.message)
} catch {
throw UID2Error.refreshTokenServerDecoding(httpStatus: statusCode, message: error.localizedDescription)
}
}
// Decrypt Data Envelop
// https://github.com/UnifiedID2/uid2docs/blob/main/api/v2/encryption-decryption.md
guard let payloadData = DataEnvelope.decrypt(refreshResponseKey, data, true) else {
throw UID2Error.decryptPayloadData
}
let tokenResponse = try decoder.decode(RefreshTokenResponse.self, from: payloadData)
guard let refreshAPIPackage = tokenResponse.toRefreshAPIPackage() else {
throw UID2Error.refreshResponseToRefreshAPIPackage
}
return refreshAPIPackage
}
// MARK: - Request Execution
internal func urlRequest(
_ request: Request,
baseURL: URL
) -> URLRequest {
var urlComponents = URLComponents(url: baseURL, resolvingAgainstBaseURL: true)!
urlComponents.path = request.path
urlComponents.queryItems = request.queryItems.isEmpty ? nil : request.queryItems
var urlRequest = URLRequest(url: urlComponents.url!)
urlRequest.httpMethod = request.method.rawValue
if request.method == .post {
urlRequest.httpBody = request.body
}
request.headers.forEach { field, value in
urlRequest.addValue(value, forHTTPHeaderField: field)
}
urlRequest.addValue(clientVersion, forHTTPHeaderField: "X-UID2-Client-Version")
return urlRequest
}
private func execute(_ request: Request) async throws -> (Data, Int) {
let urlRequest = urlRequest(
request,
baseURL: URL(string: uid2APIURL)!
)
return try await session.loadData(for: urlRequest)
}
}