@capgo/capacitor-updater 8.40.4 → 8.40.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Package.swift +1 -1
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +1 -1
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoUpdater.java +4 -1
- package/ios/Sources/CapacitorUpdaterPlugin/AES.swift +26 -8
- package/ios/Sources/CapacitorUpdaterPlugin/BigInt.swift +9 -9
- package/ios/Sources/CapacitorUpdaterPlugin/BundleInfo.swift +51 -14
- package/ios/Sources/CapacitorUpdaterPlugin/BundleStatus.swift +11 -11
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/CryptoCipher.swift +4 -2
- package/ios/Sources/CapacitorUpdaterPlugin/DelayUpdateUtils.swift +23 -7
- package/ios/Sources/CapacitorUpdaterPlugin/InternalUtils.swift +10 -1
- package/ios/Sources/CapacitorUpdaterPlugin/Logger.swift +9 -9
- package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +6 -5
- package/package.json +1 -1
package/Package.swift
CHANGED
|
@@ -10,7 +10,7 @@ let package = Package(
|
|
|
10
10
|
targets: ["CapacitorUpdaterPlugin"])
|
|
11
11
|
],
|
|
12
12
|
dependencies: [
|
|
13
|
-
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0
|
|
13
|
+
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0"),
|
|
14
14
|
.package(url: "https://github.com/Alamofire/Alamofire.git", .upToNextMajor(from: "5.10.2")),
|
|
15
15
|
.package(url: "https://github.com/weichsel/ZIPFoundation.git", from: "0.9.0"),
|
|
16
16
|
.package(url: "https://github.com/mrackwitz/Version.git", exact: "0.8.0"),
|
|
@@ -85,7 +85,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
|
|
|
85
85
|
private static final String[] BREAKING_EVENT_NAMES = { "breakingAvailable", "majorAvailable" };
|
|
86
86
|
private static final String LAST_FAILED_BUNDLE_PREF_KEY = "CapacitorUpdater.lastFailedBundle";
|
|
87
87
|
|
|
88
|
-
private final String pluginVersion = "8.40.
|
|
88
|
+
private final String pluginVersion = "8.40.6";
|
|
89
89
|
private static final String DELAY_CONDITION_PREFERENCES = "";
|
|
90
90
|
|
|
91
91
|
private SharedPreferences.Editor editor;
|
|
@@ -105,7 +105,10 @@ public class CapgoUpdater {
|
|
|
105
105
|
|
|
106
106
|
private boolean isProd() {
|
|
107
107
|
try {
|
|
108
|
-
|
|
108
|
+
if (activity == null) {
|
|
109
|
+
return true; // Default to production if no activity context
|
|
110
|
+
}
|
|
111
|
+
return (activity.getApplicationInfo().flags & android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE) == 0;
|
|
109
112
|
} catch (Exception e) {
|
|
110
113
|
return true; // Default to production if we can't determine
|
|
111
114
|
}
|
|
@@ -19,15 +19,18 @@ private enum AESConstants {
|
|
|
19
19
|
///
|
|
20
20
|
public struct AES128Key {
|
|
21
21
|
/// Initialization vector
|
|
22
|
-
private let
|
|
22
|
+
private let initVector: Data
|
|
23
23
|
private let logger: Logger
|
|
24
24
|
private let aes128Key: Data
|
|
25
25
|
#if DEBUG
|
|
26
|
-
|
|
26
|
+
// swiftlint:disable:next identifier_name
|
|
27
|
+
public var __debug_iv: Data { initVector }
|
|
28
|
+
// swiftlint:disable:next identifier_name
|
|
27
29
|
public var __debug_aes128Key: Data { aes128Key }
|
|
28
30
|
#endif
|
|
31
|
+
// swiftlint:disable:next identifier_name
|
|
29
32
|
init(iv: Data, aes128Key: Data, logger: Logger) {
|
|
30
|
-
self.
|
|
33
|
+
self.initVector = iv
|
|
31
34
|
self.aes128Key = aes128Key
|
|
32
35
|
self.logger = logger
|
|
33
36
|
}
|
|
@@ -39,20 +42,35 @@ public struct AES128Key {
|
|
|
39
42
|
/// Returns the decrypted data.
|
|
40
43
|
///
|
|
41
44
|
public func decrypt(data: Data) -> Data? {
|
|
42
|
-
let encryptedData: UnsafePointer<UInt8> = (data as NSData).bytes.bindMemory(
|
|
45
|
+
let encryptedData: UnsafePointer<UInt8> = (data as NSData).bytes.bindMemory(
|
|
46
|
+
to: UInt8.self, capacity: data.count)
|
|
43
47
|
let encryptedDataLength: Int = data.count
|
|
44
48
|
|
|
45
49
|
if let result: NSMutableData = NSMutableData(length: encryptedDataLength) {
|
|
46
|
-
let keyData: UnsafePointer<UInt8> = (self.aes128Key as NSData).bytes.bindMemory(
|
|
50
|
+
let keyData: UnsafePointer<UInt8> = (self.aes128Key as NSData).bytes.bindMemory(
|
|
51
|
+
to: UInt8.self, capacity: self.aes128Key.count)
|
|
47
52
|
let keyLength: size_t = size_t(self.aes128Key.count)
|
|
48
|
-
let ivData: UnsafePointer<UInt8> = (
|
|
53
|
+
let ivData: UnsafePointer<UInt8> = (initVector as NSData).bytes.bindMemory(
|
|
54
|
+
to: UInt8.self, capacity: self.initVector.count)
|
|
49
55
|
|
|
50
|
-
let decryptedData: UnsafeMutablePointer<UInt8> = UnsafeMutablePointer<UInt8>(
|
|
56
|
+
let decryptedData: UnsafeMutablePointer<UInt8> = UnsafeMutablePointer<UInt8>(
|
|
57
|
+
result.mutableBytes.assumingMemoryBound(to: UInt8.self))
|
|
51
58
|
let decryptedDataLength: size_t = size_t(result.length)
|
|
52
59
|
|
|
53
60
|
var decryptedLength: size_t = 0
|
|
54
61
|
|
|
55
|
-
let status: CCCryptorStatus = CCCrypt(
|
|
62
|
+
let status: CCCryptorStatus = CCCrypt(
|
|
63
|
+
CCOperation(kCCDecrypt),
|
|
64
|
+
AESConstants.aesAlgorithm,
|
|
65
|
+
AESConstants.aesOptions,
|
|
66
|
+
keyData,
|
|
67
|
+
keyLength,
|
|
68
|
+
ivData,
|
|
69
|
+
encryptedData,
|
|
70
|
+
encryptedDataLength,
|
|
71
|
+
decryptedData,
|
|
72
|
+
decryptedDataLength,
|
|
73
|
+
&decryptedLength)
|
|
56
74
|
|
|
57
75
|
if Int32(status) == Int32(kCCSuccess) {
|
|
58
76
|
result.length = Int(decryptedLength)
|
|
@@ -7,8 +7,8 @@ extension BigInt {
|
|
|
7
7
|
var bytes = [UInt8](repeating: 0, count: byteCount)
|
|
8
8
|
|
|
9
9
|
var value = self
|
|
10
|
-
for
|
|
11
|
-
bytes[byteCount -
|
|
10
|
+
for index in 0..<byteCount {
|
|
11
|
+
bytes[byteCount - index - 1] = UInt8(truncatingIfNeeded: value & 0xFF)
|
|
12
12
|
value >>= 8
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -39,15 +39,15 @@ extension BigInt {
|
|
|
39
39
|
|
|
40
40
|
// Square and multiply algorithm for modular exponentiation
|
|
41
41
|
var result = BigUInt(1)
|
|
42
|
-
var
|
|
43
|
-
var
|
|
42
|
+
var currentBase = base % mod
|
|
43
|
+
var currentExp = exp
|
|
44
44
|
|
|
45
|
-
while
|
|
46
|
-
if
|
|
47
|
-
result = (result *
|
|
45
|
+
while currentExp > 0 {
|
|
46
|
+
if currentExp & 1 == 1 {
|
|
47
|
+
result = (result * currentBase) % mod
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
currentBase = (currentBase * currentBase) % mod
|
|
50
|
+
currentExp >>= 1
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
return BigInt(result)
|
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
import Foundation
|
|
8
8
|
|
|
9
9
|
@objc public class BundleInfo: NSObject, Decodable, Encodable {
|
|
10
|
+
// swiftlint:disable identifier_name
|
|
10
11
|
public static let ID_BUILTIN: String = "builtin"
|
|
11
12
|
public static let VERSION_UNKNOWN: String = "unknown"
|
|
12
13
|
public static let DOWNLOADED_BUILTIN: String = "1970-01-01T00:00:00.000Z"
|
|
14
|
+
// swiftlint:enable identifier_name
|
|
13
15
|
|
|
14
16
|
private let downloaded: String
|
|
15
17
|
private let id: String
|
|
@@ -19,11 +21,21 @@ import Foundation
|
|
|
19
21
|
private let link: String?
|
|
20
22
|
private let comment: String?
|
|
21
23
|
|
|
22
|
-
convenience init(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
convenience init(
|
|
25
|
+
id: String, version: String, status: BundleStatus, downloaded: Date,
|
|
26
|
+
checksum: String, link: String? = nil, comment: String? = nil
|
|
27
|
+
) {
|
|
28
|
+
self.init(
|
|
29
|
+
id: id, version: version, status: status,
|
|
30
|
+
downloaded: downloaded.iso8601withFractionalSeconds,
|
|
31
|
+
checksum: checksum, link: link, comment: comment)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
init(
|
|
35
|
+
id: String, version: String, status: BundleStatus,
|
|
36
|
+
downloaded: String = BundleInfo.DOWNLOADED_BUILTIN, checksum: String,
|
|
37
|
+
link: String? = nil, comment: String? = nil
|
|
38
|
+
) {
|
|
27
39
|
self.downloaded = downloaded.trim()
|
|
28
40
|
self.id = id
|
|
29
41
|
self.version = version
|
|
@@ -54,7 +66,8 @@ import Foundation
|
|
|
54
66
|
}
|
|
55
67
|
|
|
56
68
|
public func isDownloaded() -> Bool {
|
|
57
|
-
return !self.isBuiltin() && self.downloaded != "" &&
|
|
69
|
+
return !self.isBuiltin() && self.downloaded != "" &&
|
|
70
|
+
self.downloaded != BundleInfo.DOWNLOADED_BUILTIN && !self.isDeleted()
|
|
58
71
|
}
|
|
59
72
|
|
|
60
73
|
public func getDownloaded() -> String {
|
|
@@ -66,11 +79,17 @@ import Foundation
|
|
|
66
79
|
}
|
|
67
80
|
|
|
68
81
|
public func setChecksum(checksum: String) -> BundleInfo {
|
|
69
|
-
return BundleInfo(
|
|
82
|
+
return BundleInfo(
|
|
83
|
+
id: self.id, version: self.version, status: self.status,
|
|
84
|
+
downloaded: self.downloaded, checksum: checksum,
|
|
85
|
+
link: self.link, comment: self.comment)
|
|
70
86
|
}
|
|
71
87
|
|
|
72
88
|
public func setDownloaded(downloaded: Date) -> BundleInfo {
|
|
73
|
-
return BundleInfo(
|
|
89
|
+
return BundleInfo(
|
|
90
|
+
id: self.id, version: self.version, status: self.status,
|
|
91
|
+
downloaded: downloaded, checksum: self.checksum,
|
|
92
|
+
link: self.link, comment: self.comment)
|
|
74
93
|
}
|
|
75
94
|
|
|
76
95
|
public func getId() -> String {
|
|
@@ -78,7 +97,10 @@ import Foundation
|
|
|
78
97
|
}
|
|
79
98
|
|
|
80
99
|
public func setId(id: String) -> BundleInfo {
|
|
81
|
-
return BundleInfo(
|
|
100
|
+
return BundleInfo(
|
|
101
|
+
id: id, version: self.version, status: self.status,
|
|
102
|
+
downloaded: self.downloaded, checksum: self.checksum,
|
|
103
|
+
link: self.link, comment: self.comment)
|
|
82
104
|
}
|
|
83
105
|
|
|
84
106
|
public func getVersionName() -> String {
|
|
@@ -86,15 +108,23 @@ import Foundation
|
|
|
86
108
|
}
|
|
87
109
|
|
|
88
110
|
public func setVersionName(version: String) -> BundleInfo {
|
|
89
|
-
return BundleInfo(
|
|
111
|
+
return BundleInfo(
|
|
112
|
+
id: self.id, version: version, status: self.status,
|
|
113
|
+
downloaded: self.downloaded, checksum: self.checksum,
|
|
114
|
+
link: self.link, comment: self.comment)
|
|
90
115
|
}
|
|
91
116
|
|
|
92
117
|
public func getStatus() -> String {
|
|
93
|
-
return self.isBuiltin() ?
|
|
118
|
+
return self.isBuiltin() ?
|
|
119
|
+
BundleStatus.SUCCESS.localizedString : self.status.localizedString
|
|
94
120
|
}
|
|
95
121
|
|
|
96
122
|
public func setStatus(status: String) -> BundleInfo {
|
|
97
|
-
return BundleInfo(
|
|
123
|
+
return BundleInfo(
|
|
124
|
+
id: self.id, version: self.version,
|
|
125
|
+
status: BundleStatus(localizedString: status)!,
|
|
126
|
+
downloaded: self.downloaded, checksum: self.checksum,
|
|
127
|
+
link: self.link, comment: self.comment)
|
|
98
128
|
}
|
|
99
129
|
|
|
100
130
|
public func getLink() -> String? {
|
|
@@ -102,7 +132,10 @@ import Foundation
|
|
|
102
132
|
}
|
|
103
133
|
|
|
104
134
|
public func setLink(link: String?) -> BundleInfo {
|
|
105
|
-
return BundleInfo(
|
|
135
|
+
return BundleInfo(
|
|
136
|
+
id: self.id, version: self.version, status: self.status,
|
|
137
|
+
downloaded: self.downloaded, checksum: self.checksum,
|
|
138
|
+
link: link, comment: self.comment)
|
|
106
139
|
}
|
|
107
140
|
|
|
108
141
|
public func getComment() -> String? {
|
|
@@ -110,7 +143,10 @@ import Foundation
|
|
|
110
143
|
}
|
|
111
144
|
|
|
112
145
|
public func setComment(comment: String?) -> BundleInfo {
|
|
113
|
-
return BundleInfo(
|
|
146
|
+
return BundleInfo(
|
|
147
|
+
id: self.id, version: self.version, status: self.status,
|
|
148
|
+
downloaded: self.downloaded, checksum: self.checksum,
|
|
149
|
+
link: self.link, comment: comment)
|
|
114
150
|
}
|
|
115
151
|
|
|
116
152
|
public func toJSON() -> [String: String] {
|
|
@@ -135,6 +171,7 @@ import Foundation
|
|
|
135
171
|
}
|
|
136
172
|
|
|
137
173
|
public func toString() -> String {
|
|
174
|
+
// swiftlint:disable:next line_length
|
|
138
175
|
return "{ \"id\": \"\(self.getId())\", \"version\": \"\(self.getVersionName())\", \"downloaded\": \"\(self.getDownloaded())\", \"checksum\": \"\(self.getChecksum())\", \"status\": \"\(self.getStatus())\"}"
|
|
139
176
|
}
|
|
140
177
|
}
|
|
@@ -8,27 +8,27 @@ import Foundation
|
|
|
8
8
|
|
|
9
9
|
struct LocalizedString: ExpressibleByStringLiteral, Equatable {
|
|
10
10
|
|
|
11
|
-
let
|
|
11
|
+
let value: String
|
|
12
12
|
|
|
13
13
|
init(key: String) {
|
|
14
|
-
self.
|
|
14
|
+
self.value = NSLocalizedString(key, comment: "")
|
|
15
15
|
}
|
|
16
16
|
init(localized: String) {
|
|
17
|
-
self.
|
|
17
|
+
self.value = localized
|
|
18
18
|
}
|
|
19
|
-
init(stringLiteral
|
|
20
|
-
self.init(key:
|
|
19
|
+
init(stringLiteral val: String) {
|
|
20
|
+
self.init(key: val)
|
|
21
21
|
}
|
|
22
|
-
init(extendedGraphemeClusterLiteral
|
|
23
|
-
self.init(key:
|
|
22
|
+
init(extendedGraphemeClusterLiteral val: String) {
|
|
23
|
+
self.init(key: val)
|
|
24
24
|
}
|
|
25
|
-
init(unicodeScalarLiteral
|
|
26
|
-
self.init(key:
|
|
25
|
+
init(unicodeScalarLiteral val: String) {
|
|
26
|
+
self.init(key: val)
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
func == (lhs: LocalizedString, rhs: LocalizedString) -> Bool {
|
|
31
|
-
return lhs.
|
|
31
|
+
return lhs.value == rhs.value
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
enum BundleStatus: LocalizedString, Decodable, Encodable {
|
|
@@ -39,7 +39,7 @@ enum BundleStatus: LocalizedString, Decodable, Encodable {
|
|
|
39
39
|
case DOWNLOADING = "downloading"
|
|
40
40
|
|
|
41
41
|
var localizedString: String {
|
|
42
|
-
return self.rawValue.
|
|
42
|
+
return self.rawValue.value
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
init?(localizedString: String) {
|
|
@@ -60,7 +60,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
60
60
|
CAPPluginMethod(name: "completeFlexibleUpdate", returnType: CAPPluginReturnPromise)
|
|
61
61
|
]
|
|
62
62
|
public var implementation = CapgoUpdater()
|
|
63
|
-
private let pluginVersion: String = "8.40.
|
|
63
|
+
private let pluginVersion: String = "8.40.6"
|
|
64
64
|
static let updateUrlDefault = "https://plugin.capgo.app/updates"
|
|
65
65
|
static let statsUrlDefault = "https://plugin.capgo.app/stats"
|
|
66
66
|
static let channelUrlDefault = "https://plugin.capgo.app/channel_self"
|
|
@@ -18,8 +18,8 @@ public struct CryptoCipher {
|
|
|
18
18
|
private static func hexStringToData(_ hex: String) -> Data? {
|
|
19
19
|
var data = Data()
|
|
20
20
|
var hexIterator = hex.makeIterator()
|
|
21
|
-
while let
|
|
22
|
-
guard let byte = UInt8(String([
|
|
21
|
+
while let char1 = hexIterator.next(), let char2 = hexIterator.next() {
|
|
22
|
+
guard let byte = UInt8(String([char1, char2]), radix: 16) else {
|
|
23
23
|
return nil
|
|
24
24
|
}
|
|
25
25
|
data.append(byte)
|
|
@@ -62,6 +62,7 @@ public struct CryptoCipher {
|
|
|
62
62
|
checksumBytes = base64Data
|
|
63
63
|
detectedFormat = "base64"
|
|
64
64
|
}
|
|
65
|
+
// swiftlint:disable:next line_length
|
|
65
66
|
logger.debug("Received encrypted checksum format: \(detectedFormat) (length: \(checksum.count) chars, \(checksumBytes.count) bytes)")
|
|
66
67
|
|
|
67
68
|
if checksumBytes.isEmpty {
|
|
@@ -94,6 +95,7 @@ public struct CryptoCipher {
|
|
|
94
95
|
logger.error("Unknown checksum algorithm detected")
|
|
95
96
|
logger.debug("Byte count: \(decryptedChecksum.count), Expected: 32 (SHA-256)")
|
|
96
97
|
}
|
|
98
|
+
// swiftlint:disable:next line_length
|
|
97
99
|
logger.debug("Decrypted checksum: \(detectedAlgorithm) hex format (length: \(result.count) chars, \(decryptedChecksum.count) bytes)")
|
|
98
100
|
return result
|
|
99
101
|
} catch {
|
|
@@ -17,8 +17,10 @@ import Version
|
|
|
17
17
|
|
|
18
18
|
public class DelayUpdateUtils {
|
|
19
19
|
|
|
20
|
+
// swiftlint:disable identifier_name
|
|
20
21
|
static let DELAY_CONDITION_PREFERENCES = "DELAY_CONDITION_PREFERENCES_CAPGO"
|
|
21
22
|
static let BACKGROUND_TIMESTAMP_KEY = "BACKGROUND_TIMESTAMP_KEY_CAPGO"
|
|
23
|
+
// swiftlint:enable identifier_name
|
|
22
24
|
private let logger: Logger
|
|
23
25
|
|
|
24
26
|
private let currentVersionNative: Version
|
|
@@ -43,9 +45,10 @@ public class DelayUpdateUtils {
|
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
public func checkCancelDelay(source: CancelDelaySource) {
|
|
46
|
-
let delayUpdatePreferences = UserDefaults.standard.string(
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
let delayUpdatePreferences = UserDefaults.standard.string(
|
|
49
|
+
forKey: DelayUpdateUtils.DELAY_CONDITION_PREFERENCES) ?? "[]"
|
|
50
|
+
let delayConditionList: [DelayCondition] = fromJsonArr(json: delayUpdatePreferences).compactMap { obj in
|
|
51
|
+
guard let kind = obj.value(forKey: "kind") as? String else { return nil }
|
|
49
52
|
let value: String? = obj.value(forKey: "value") as? String
|
|
50
53
|
return DelayCondition(kind: kind, value: value)
|
|
51
54
|
}
|
|
@@ -70,21 +73,25 @@ public class DelayUpdateUtils {
|
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
if delta > longValue {
|
|
76
|
+
// swiftlint:disable:next line_length
|
|
73
77
|
logger.info("Background condition (value: \(value ?? "")) deleted at index \(index). Delta: \(delta), longValue: \(longValue)")
|
|
74
78
|
} else {
|
|
75
79
|
delayConditionListToKeep.append(condition)
|
|
80
|
+
// swiftlint:disable:next line_length
|
|
76
81
|
logger.info("Background delay (value: \(value ?? "")) condition kept at index \(index) (source: \(source.description))")
|
|
77
82
|
}
|
|
78
83
|
} else {
|
|
79
84
|
delayConditionListToKeep.append(condition)
|
|
85
|
+
// swiftlint:disable:next line_length
|
|
80
86
|
logger.info("Background delay (value: \(value ?? "")) condition kept at index \(index) (source: \(source.description))")
|
|
81
87
|
}
|
|
82
88
|
|
|
83
89
|
case "kill":
|
|
84
90
|
if source == .killed {
|
|
85
|
-
logger.info("Kill delay (value: \(value ?? ""))
|
|
91
|
+
logger.info("Kill delay (value: \(value ?? "")) removed at index \(index) after app kill")
|
|
86
92
|
} else {
|
|
87
93
|
delayConditionListToKeep.append(condition)
|
|
94
|
+
// swiftlint:disable:next line_length
|
|
88
95
|
logger.info("Kill delay (value: \(value ?? "")) condition kept at index \(index) (source: \(source.description))")
|
|
89
96
|
}
|
|
90
97
|
|
|
@@ -96,18 +103,22 @@ public class DelayUpdateUtils {
|
|
|
96
103
|
|
|
97
104
|
if let date = dateFormatter.date(from: value) {
|
|
98
105
|
if Date() > date {
|
|
106
|
+
// swiftlint:disable:next line_length
|
|
99
107
|
logger.info("Date delay (value: \(value)) condition removed due to expired date at index \(index)")
|
|
100
108
|
} else {
|
|
101
109
|
delayConditionListToKeep.append(condition)
|
|
102
|
-
logger.info("Date delay (value: \(value))
|
|
110
|
+
logger.info("Date delay (value: \(value)) kept at index \(index)")
|
|
103
111
|
}
|
|
104
112
|
} else {
|
|
113
|
+
// swiftlint:disable:next line_length
|
|
105
114
|
logger.error("Date delay (value: \(value)) condition removed due to parsing issue at index \(index)")
|
|
106
115
|
}
|
|
107
116
|
} catch {
|
|
117
|
+
// swiftlint:disable:next line_length
|
|
108
118
|
logger.error("Date delay (value: \(value)) condition removed due to parsing issue at index \(index): \(error)")
|
|
109
119
|
}
|
|
110
120
|
} else {
|
|
121
|
+
// swiftlint:disable:next line_length
|
|
111
122
|
logger.error("Date delay (value: \(value ?? "")) condition removed due to empty value at index \(index)")
|
|
112
123
|
}
|
|
113
124
|
|
|
@@ -116,15 +127,18 @@ public class DelayUpdateUtils {
|
|
|
116
127
|
do {
|
|
117
128
|
let versionLimit = try Version(value)
|
|
118
129
|
if currentVersionNative >= versionLimit {
|
|
130
|
+
// swiftlint:disable:next line_length
|
|
119
131
|
logger.info("Native version delay (value: \(value)) condition removed due to above limit at index \(index)")
|
|
120
132
|
} else {
|
|
121
133
|
delayConditionListToKeep.append(condition)
|
|
122
|
-
logger.info("Native version delay (value: \(value))
|
|
134
|
+
logger.info("Native version delay (value: \(value)) kept at index \(index)")
|
|
123
135
|
}
|
|
124
136
|
} catch {
|
|
137
|
+
// swiftlint:disable:next line_length
|
|
125
138
|
logger.error("Native version delay (value: \(value)) condition removed due to parsing issue at index \(index): \(error)")
|
|
126
139
|
}
|
|
127
140
|
} else {
|
|
141
|
+
// swiftlint:disable:next line_length
|
|
128
142
|
logger.error("Native version delay (value: \(value ?? "")) condition removed due to empty value at index \(index)")
|
|
129
143
|
}
|
|
130
144
|
|
|
@@ -172,13 +186,15 @@ public class DelayUpdateUtils {
|
|
|
172
186
|
UserDefaults.standard.synchronize()
|
|
173
187
|
logger.info("Background timestamp removed")
|
|
174
188
|
} catch {
|
|
189
|
+
// swiftlint:disable:next line_length
|
|
175
190
|
logger.error("Failed to remove background timestamp, [Error calling 'unsetBackgroundTimestamp()']: \(error)")
|
|
176
191
|
}
|
|
177
192
|
}
|
|
178
193
|
|
|
179
194
|
private func getBackgroundTimestamp() -> Int64 {
|
|
180
195
|
do {
|
|
181
|
-
let
|
|
196
|
+
let key = DelayUpdateUtils.BACKGROUND_TIMESTAMP_KEY
|
|
197
|
+
let timestamp = UserDefaults.standard.object(forKey: key) as? Int64 ?? 0
|
|
182
198
|
return timestamp
|
|
183
199
|
} catch {
|
|
184
200
|
logger.error("Failed to get background timestamp, [Error calling 'getBackgroundTimestamp()']: \(error)")
|
|
@@ -67,12 +67,14 @@ extension GetChannel {
|
|
|
67
67
|
return dict
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
+
// swiftlint:disable identifier_name
|
|
70
71
|
struct ChannelInfo: Codable {
|
|
71
72
|
let id: String?
|
|
72
73
|
let name: String?
|
|
73
74
|
let `public`: Bool?
|
|
74
75
|
let allow_self_set: Bool?
|
|
75
76
|
}
|
|
77
|
+
// swiftlint:enable identifier_name
|
|
76
78
|
struct ListChannelsDec: Decodable {
|
|
77
79
|
let channels: [ChannelInfo]?
|
|
78
80
|
let error: String?
|
|
@@ -112,6 +114,7 @@ extension ListChannels {
|
|
|
112
114
|
return dict
|
|
113
115
|
}
|
|
114
116
|
}
|
|
117
|
+
// swiftlint:disable identifier_name
|
|
115
118
|
struct InfoObject: Codable {
|
|
116
119
|
let platform: String?
|
|
117
120
|
let device_id: String?
|
|
@@ -130,12 +133,15 @@ struct InfoObject: Codable {
|
|
|
130
133
|
var defaultChannel: String?
|
|
131
134
|
var key_id: String?
|
|
132
135
|
}
|
|
136
|
+
// swiftlint:enable identifier_name
|
|
133
137
|
|
|
138
|
+
// swiftlint:disable identifier_name
|
|
134
139
|
public struct ManifestEntry: Codable {
|
|
135
140
|
let file_name: String?
|
|
136
141
|
let file_hash: String?
|
|
137
142
|
let download_url: String?
|
|
138
143
|
}
|
|
144
|
+
// swiftlint:enable identifier_name
|
|
139
145
|
|
|
140
146
|
extension ManifestEntry {
|
|
141
147
|
func toDict() -> [String: Any] {
|
|
@@ -150,6 +156,7 @@ extension ManifestEntry {
|
|
|
150
156
|
}
|
|
151
157
|
}
|
|
152
158
|
|
|
159
|
+
// swiftlint:disable identifier_name
|
|
153
160
|
struct AppVersionDec: Decodable {
|
|
154
161
|
let version: String?
|
|
155
162
|
let checksum: String?
|
|
@@ -165,6 +172,7 @@ struct AppVersionDec: Decodable {
|
|
|
165
172
|
let comment: String?
|
|
166
173
|
// The HTTP status code is captured separately in CapgoUpdater; this struct only mirrors JSON.
|
|
167
174
|
}
|
|
175
|
+
// swiftlint:enable identifier_name
|
|
168
176
|
|
|
169
177
|
public class AppVersion: NSObject {
|
|
170
178
|
var version: String = ""
|
|
@@ -220,7 +228,8 @@ extension ISO8601DateFormatter {
|
|
|
220
228
|
}
|
|
221
229
|
}
|
|
222
230
|
extension Formatter {
|
|
223
|
-
static let iso8601withFractionalSeconds: ISO8601DateFormatter = ISO8601DateFormatter(
|
|
231
|
+
static let iso8601withFractionalSeconds: ISO8601DateFormatter = ISO8601DateFormatter(
|
|
232
|
+
[.withInternetDateTime, .withFractionalSeconds])
|
|
224
233
|
}
|
|
225
234
|
extension Date {
|
|
226
235
|
var iso8601withFractionalSeconds: String { return Formatter.iso8601withFractionalSeconds.string(from: self) }
|
|
@@ -217,15 +217,15 @@ public class Logger {
|
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
// Fallback manual escaping (unlikely to be used)
|
|
220
|
-
var
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
return "\"\(
|
|
220
|
+
var escaped = value
|
|
221
|
+
escaped = escaped.replacingOccurrences(of: "\\", with: "\\\\")
|
|
222
|
+
escaped = escaped.replacingOccurrences(of: "\"", with: "\\\"")
|
|
223
|
+
escaped = escaped.replacingOccurrences(of: "'", with: "\\'")
|
|
224
|
+
escaped = escaped.replacingOccurrences(of: "\n", with: "\\n")
|
|
225
|
+
escaped = escaped.replacingOccurrences(of: "\r", with: "\\r")
|
|
226
|
+
escaped = escaped.replacingOccurrences(of: "\u{2028}", with: "\\u2028")
|
|
227
|
+
escaped = escaped.replacingOccurrences(of: "\u{2029}", with: "\\u2029")
|
|
228
|
+
return "\"\(escaped)\""
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
public func log(atLevel level: LogLevel, label: String?, tag: String, message: String) {
|
|
@@ -8,6 +8,7 @@ import UIKit
|
|
|
8
8
|
import Capacitor
|
|
9
9
|
|
|
10
10
|
extension UIApplication {
|
|
11
|
+
// swiftlint:disable:next line_length
|
|
11
12
|
public class func topViewController(_ base: UIViewController? = UIApplication.shared.windows.first?.rootViewController) -> UIViewController? {
|
|
12
13
|
if let nav = base as? UINavigationController {
|
|
13
14
|
return topViewController(nav.visibleViewController)
|
|
@@ -61,9 +62,9 @@ extension UIWindow {
|
|
|
61
62
|
updater.reset()
|
|
62
63
|
bridge.setServerBasePath("")
|
|
63
64
|
DispatchQueue.main.async {
|
|
64
|
-
if let
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
if let viewController = (self.rootViewController as? CAPBridgeViewController) {
|
|
66
|
+
viewController.loadView()
|
|
67
|
+
viewController.viewDidLoad()
|
|
67
68
|
}
|
|
68
69
|
_ = updater.delete(id: updater.getCurrentBundleId())
|
|
69
70
|
plugin.logger.info("Reset to builtin version")
|
|
@@ -71,8 +72,8 @@ extension UIWindow {
|
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
let bundleId = updater.getCurrentBundleId()
|
|
74
|
-
if let
|
|
75
|
-
plugin.logger.info("getServerBasePath: \(
|
|
75
|
+
if let viewController = (self.rootViewController as? CAPBridgeViewController) {
|
|
76
|
+
plugin.logger.info("getServerBasePath: \(viewController.getServerBasePath())")
|
|
76
77
|
}
|
|
77
78
|
plugin.logger.info("bundleId: \(bundleId)")
|
|
78
79
|
|