@capgo/capacitor-updater 8.51.7 → 8.51.9
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/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +1 -1
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoUpdater.java +62 -21
- package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipher.java +115 -20
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +142 -114
- package/ios/Sources/CapacitorUpdaterPlugin/AES.swift +119 -0
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/CapgoUpdater.swift +249 -160
- package/ios/Sources/CapacitorUpdaterPlugin/CryptoCipher.swift +41 -29
- package/ios/Sources/CapacitorUpdaterPlugin/ShakeMenu.swift +30 -18
- package/package.json +5 -5
|
@@ -141,8 +141,43 @@ public struct CryptoCipher {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
private static let twoGiB: UInt64 = 2 * 1024 * 1024 * 1024
|
|
145
|
+
private static let threeGiB: UInt64 = 3 * 1024 * 1024 * 1024
|
|
146
|
+
private static let fourGiB: UInt64 = 4 * 1024 * 1024 * 1024
|
|
147
|
+
private static let eightGiB: UInt64 = 8 * 1024 * 1024 * 1024
|
|
148
|
+
private static let flagshipIoBufferBytes = 5 * 1024 * 1024
|
|
149
|
+
|
|
150
|
+
/// Checksum and copy share one ladder. 64-wide peak RAM = 64 * buffer.
|
|
151
|
+
/// <2GB: 64KB. <3GB: 256KB. <4GB: 512KB. <8GB: 1MB. Else 5MB (flagship / unknown).
|
|
152
|
+
static func ioBufferBytes(_ physicalRamBytes: UInt64 = ProcessInfo.processInfo.physicalMemory) -> Int {
|
|
153
|
+
if physicalRamBytes == 0 {
|
|
154
|
+
return flagshipIoBufferBytes
|
|
155
|
+
}
|
|
156
|
+
if physicalRamBytes < twoGiB {
|
|
157
|
+
return 64 * 1024
|
|
158
|
+
}
|
|
159
|
+
if physicalRamBytes < threeGiB {
|
|
160
|
+
return 256 * 1024
|
|
161
|
+
}
|
|
162
|
+
if physicalRamBytes < fourGiB {
|
|
163
|
+
return 512 * 1024
|
|
164
|
+
}
|
|
165
|
+
if physicalRamBytes < eightGiB {
|
|
166
|
+
return 1024 * 1024
|
|
167
|
+
}
|
|
168
|
+
return flagshipIoBufferBytes
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
static func checksumBufferBytes(_ physicalRamBytes: UInt64 = ProcessInfo.processInfo.physicalMemory) -> Int {
|
|
172
|
+
return ioBufferBytes(physicalRamBytes)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
static func copyBufferBytes(_ physicalRamBytes: UInt64 = ProcessInfo.processInfo.physicalMemory) -> Int {
|
|
176
|
+
return ioBufferBytes(physicalRamBytes)
|
|
177
|
+
}
|
|
178
|
+
|
|
144
179
|
public static func calcChecksum(filePath: URL) -> String {
|
|
145
|
-
let bufferSize =
|
|
180
|
+
let bufferSize = checksumBufferBytes()
|
|
146
181
|
var sha256 = SHA256()
|
|
147
182
|
|
|
148
183
|
do {
|
|
@@ -243,42 +278,19 @@ public struct CryptoCipher {
|
|
|
243
278
|
|
|
244
279
|
let aesPrivateKey = AES128Key(iv: ivData, aes128Key: sessionKeyDataDecrypted, logger: logger)
|
|
245
280
|
|
|
246
|
-
let
|
|
247
|
-
|
|
248
|
-
encryptedData = try Data(contentsOf: filePath)
|
|
249
|
-
} catch {
|
|
250
|
-
logger.error("Failed to read encrypted data")
|
|
251
|
-
logger.debug("Error: \(error)")
|
|
252
|
-
throw NSError(domain: "Failed to read encrypted data", code: 3, userInfo: nil)
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if encryptedData.isEmpty {
|
|
281
|
+
let encryptedSize = (try FileManager.default.attributesOfItem(atPath: filePath.path)[.size] as? NSNumber)?.uint64Value ?? 0
|
|
282
|
+
if encryptedSize == 0 {
|
|
256
283
|
logger.error("Encrypted file data is empty")
|
|
257
284
|
throw NSError(domain: "Empty encrypted data", code: 6, userInfo: nil)
|
|
258
285
|
}
|
|
259
286
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if decryptedData.isEmpty {
|
|
287
|
+
try aesPrivateKey.decrypt(from: filePath, to: filePath)
|
|
288
|
+
let decryptedSize = (try FileManager.default.attributesOfItem(atPath: filePath.path)[.size] as? NSNumber)?.uint64Value ?? 0
|
|
289
|
+
if decryptedSize == 0 {
|
|
266
290
|
logger.error("Decrypted data is empty")
|
|
267
291
|
throw NSError(domain: "Empty decrypted data", code: 7, userInfo: nil)
|
|
268
292
|
}
|
|
269
293
|
|
|
270
|
-
do {
|
|
271
|
-
try decryptedData.write(to: filePath, options: .atomic)
|
|
272
|
-
if !FileManager.default.fileExists(atPath: filePath.path) {
|
|
273
|
-
logger.error("File was not created after write")
|
|
274
|
-
throw NSError(domain: "File write failed", code: 8, userInfo: nil)
|
|
275
|
-
}
|
|
276
|
-
} catch {
|
|
277
|
-
logger.error("Error writing decrypted file")
|
|
278
|
-
logger.debug("Error: \(error)")
|
|
279
|
-
throw error
|
|
280
|
-
}
|
|
281
|
-
|
|
282
294
|
} catch {
|
|
283
295
|
logger.error("File decryption failed")
|
|
284
296
|
throw CustomError.cannotDecode
|
|
@@ -92,18 +92,26 @@ final class ThreeFingerPinchGestureRecognizer: UIGestureRecognizer {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
extension UIApplication {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if let nav =
|
|
95
|
+
public class func topViewController(_ base: UIViewController? = nil) -> UIViewController? {
|
|
96
|
+
let resolvedBase = base ?? keyWindowRootViewController
|
|
97
|
+
if let nav = resolvedBase as? UINavigationController {
|
|
98
98
|
return topViewController(nav.visibleViewController)
|
|
99
99
|
}
|
|
100
|
-
if let tab =
|
|
100
|
+
if let tab = resolvedBase as? UITabBarController, let selected = tab.selectedViewController {
|
|
101
101
|
return topViewController(selected)
|
|
102
102
|
}
|
|
103
|
-
if let presented =
|
|
103
|
+
if let presented = resolvedBase?.presentedViewController {
|
|
104
104
|
return topViewController(presented)
|
|
105
105
|
}
|
|
106
|
-
return
|
|
106
|
+
return resolvedBase
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private static var keyWindowRootViewController: UIViewController? {
|
|
110
|
+
let scenes = shared.connectedScenes.compactMap { $0 as? UIWindowScene }
|
|
111
|
+
let foregroundScenes = scenes.filter { $0.activationState == .foregroundActive }
|
|
112
|
+
let candidates = foregroundScenes.isEmpty ? scenes : foregroundScenes
|
|
113
|
+
let window = candidates.flatMap(\.windows).first(where: \.isKeyWindow) ?? candidates.first?.windows.first
|
|
114
|
+
return window?.rootViewController
|
|
107
115
|
}
|
|
108
116
|
}
|
|
109
117
|
|
|
@@ -184,6 +192,10 @@ extension CapacitorUpdaterPlugin: UIGestureRecognizerDelegate {
|
|
|
184
192
|
}
|
|
185
193
|
|
|
186
194
|
extension UIWindow {
|
|
195
|
+
private var menuHostViewController: UIViewController? {
|
|
196
|
+
UIApplication.topViewController(rootViewController)
|
|
197
|
+
}
|
|
198
|
+
|
|
187
199
|
override open func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
|
|
188
200
|
if motion == .motionShake {
|
|
189
201
|
guard let bridgeViewController = rootViewController as? CAPBridgeViewController,
|
|
@@ -230,7 +242,7 @@ extension UIWindow {
|
|
|
230
242
|
@discardableResult
|
|
231
243
|
private func showDefaultMenu(plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) -> Bool {
|
|
232
244
|
// Prevent multiple alerts from showing
|
|
233
|
-
guard let topVC =
|
|
245
|
+
guard let topVC = self.menuHostViewController else {
|
|
234
246
|
return false
|
|
235
247
|
}
|
|
236
248
|
if topVC.isKind(of: UIAlertController.self) {
|
|
@@ -365,7 +377,7 @@ extension UIWindow {
|
|
|
365
377
|
})
|
|
366
378
|
|
|
367
379
|
DispatchQueue.main.async {
|
|
368
|
-
if let topVC =
|
|
380
|
+
if let topVC = self.menuHostViewController {
|
|
369
381
|
topVC.present(alertShake, animated: true)
|
|
370
382
|
}
|
|
371
383
|
}
|
|
@@ -388,7 +400,7 @@ extension UIWindow {
|
|
|
388
400
|
}
|
|
389
401
|
|
|
390
402
|
private func showPreviewSelector(plugin: CapacitorUpdaterPlugin) {
|
|
391
|
-
guard let topVC =
|
|
403
|
+
guard let topVC = self.menuHostViewController else {
|
|
392
404
|
return
|
|
393
405
|
}
|
|
394
406
|
if topVC.isKind(of: UIAlertController.self) {
|
|
@@ -456,7 +468,7 @@ extension UIWindow {
|
|
|
456
468
|
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
|
|
457
469
|
|
|
458
470
|
DispatchQueue.main.async {
|
|
459
|
-
if let topVC =
|
|
471
|
+
if let topVC = self.menuHostViewController {
|
|
460
472
|
topVC.present(alert, animated: true)
|
|
461
473
|
}
|
|
462
474
|
}
|
|
@@ -479,7 +491,7 @@ extension UIWindow {
|
|
|
479
491
|
}
|
|
480
492
|
|
|
481
493
|
DispatchQueue.main.async {
|
|
482
|
-
if let topVC =
|
|
494
|
+
if let topVC = self.menuHostViewController {
|
|
483
495
|
topVC.present(alert, animated: true)
|
|
484
496
|
}
|
|
485
497
|
}
|
|
@@ -498,7 +510,7 @@ extension UIWindow {
|
|
|
498
510
|
@discardableResult
|
|
499
511
|
private func showChannelSelector(plugin: CapacitorUpdaterPlugin, bridge: CAPBridgeProtocol) -> Bool {
|
|
500
512
|
// Prevent multiple alerts from showing
|
|
501
|
-
guard let topVC =
|
|
513
|
+
guard let topVC = self.menuHostViewController else {
|
|
502
514
|
return false
|
|
503
515
|
}
|
|
504
516
|
if topVC.isKind(of: UIAlertController.self) {
|
|
@@ -582,7 +594,7 @@ extension UIWindow {
|
|
|
582
594
|
}
|
|
583
595
|
|
|
584
596
|
DispatchQueue.main.async {
|
|
585
|
-
if let topVC =
|
|
597
|
+
if let topVC = self.menuHostViewController {
|
|
586
598
|
topVC.present(alert, animated: true)
|
|
587
599
|
}
|
|
588
600
|
}
|
|
@@ -627,7 +639,7 @@ extension UIWindow {
|
|
|
627
639
|
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
|
|
628
640
|
|
|
629
641
|
DispatchQueue.main.async {
|
|
630
|
-
if let topVC =
|
|
642
|
+
if let topVC = self.menuHostViewController {
|
|
631
643
|
topVC.present(alert, animated: true)
|
|
632
644
|
}
|
|
633
645
|
}
|
|
@@ -649,7 +661,7 @@ extension UIWindow {
|
|
|
649
661
|
])
|
|
650
662
|
|
|
651
663
|
DispatchQueue.main.async {
|
|
652
|
-
if let topVC =
|
|
664
|
+
if let topVC = self.menuHostViewController {
|
|
653
665
|
topVC.present(progressAlert, animated: true) {
|
|
654
666
|
DispatchQueue.global(qos: .userInitiated).async {
|
|
655
667
|
// Set the channel - respect plugin's allowSetDefaultChannel config
|
|
@@ -806,7 +818,7 @@ extension UIWindow {
|
|
|
806
818
|
alert.addAction(UIAlertAction(title: "OK", style: .default))
|
|
807
819
|
|
|
808
820
|
DispatchQueue.main.async {
|
|
809
|
-
if let topVC =
|
|
821
|
+
if let topVC = self.menuHostViewController {
|
|
810
822
|
topVC.present(alert, animated: true)
|
|
811
823
|
}
|
|
812
824
|
}
|
|
@@ -818,7 +830,7 @@ extension UIWindow {
|
|
|
818
830
|
alert.addAction(UIAlertAction(title: "OK", style: .default))
|
|
819
831
|
|
|
820
832
|
DispatchQueue.main.async {
|
|
821
|
-
if let topVC =
|
|
833
|
+
if let topVC = self.menuHostViewController {
|
|
822
834
|
topVC.present(alert, animated: true)
|
|
823
835
|
}
|
|
824
836
|
}
|
|
@@ -844,7 +856,7 @@ extension UIWindow {
|
|
|
844
856
|
})
|
|
845
857
|
|
|
846
858
|
DispatchQueue.main.async {
|
|
847
|
-
if let topVC =
|
|
859
|
+
if let topVC = self.menuHostViewController {
|
|
848
860
|
topVC.present(alert, animated: true)
|
|
849
861
|
}
|
|
850
862
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capgo/capacitor-updater",
|
|
3
|
-
"version": "8.51.
|
|
3
|
+
"version": "8.51.9",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "Live update for capacitor apps",
|
|
6
6
|
"main": "dist/plugin.cjs.js",
|
|
@@ -81,11 +81,11 @@
|
|
|
81
81
|
"generate:rsa-contract": "bun scripts/generate-rsa-contract-fixtures.mjs"
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
|
-
"@capacitor/android": "^8.
|
|
85
|
-
"@capacitor/cli": "^8.
|
|
86
|
-
"@capacitor/core": "^8.
|
|
84
|
+
"@capacitor/android": "^8.5.0",
|
|
85
|
+
"@capacitor/cli": "^8.5.0",
|
|
86
|
+
"@capacitor/core": "^8.5.0",
|
|
87
87
|
"@capacitor/docgen": "^0.3.0",
|
|
88
|
-
"@capacitor/ios": "^8.
|
|
88
|
+
"@capacitor/ios": "^8.5.0",
|
|
89
89
|
"@ionic/eslint-config": "^0.4.0",
|
|
90
90
|
"@ionic/prettier-config": "^4.0.0",
|
|
91
91
|
"@ionic/swiftlint-config": "^2.0.0",
|