@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.
@@ -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 = 1024 * 1024 * 5 // 5 MB
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 encryptedData: Data
247
- do {
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
- guard let decryptedData = aesPrivateKey.decrypt(data: encryptedData) else {
261
- logger.error("Failed to decrypt data")
262
- throw NSError(domain: "Failed to decrypt data", code: 4, userInfo: nil)
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
- // swiftlint:disable:next line_length
96
- public class func topViewController(_ base: UIViewController? = UIApplication.shared.windows.first?.rootViewController) -> UIViewController? {
97
- if let nav = base as? UINavigationController {
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 = base as? UITabBarController, let selected = tab.selectedViewController {
100
+ if let tab = resolvedBase as? UITabBarController, let selected = tab.selectedViewController {
101
101
  return topViewController(selected)
102
102
  }
103
- if let presented = base?.presentedViewController {
103
+ if let presented = resolvedBase?.presentedViewController {
104
104
  return topViewController(presented)
105
105
  }
106
- return base
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 = UIApplication.topViewController() else {
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 = UIApplication.topViewController() {
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 = UIApplication.topViewController() else {
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 = UIApplication.topViewController() {
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 = UIApplication.topViewController() {
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 = UIApplication.topViewController() else {
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 = UIApplication.topViewController() {
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 = UIApplication.topViewController() {
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 = UIApplication.topViewController() {
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 = UIApplication.topViewController() {
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 = UIApplication.topViewController() {
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 = UIApplication.topViewController() {
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.7",
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.0.0",
85
- "@capacitor/cli": "^8.0.0",
86
- "@capacitor/core": "^8.0.0",
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.0.0",
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",