@capgo/capacitor-updater 6.40.5 → 6.42.3
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 +2 -2
- package/README.md +27 -0
- package/android/build.gradle +4 -2
- package/android/src/main/java/ee/forgr/capacitor_updater/AppLifecycleObserver.java +88 -0
- package/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java +82 -16
- package/android/src/main/java/ee/forgr/capacitor_updater/CapgoUpdater.java +181 -11
- package/android/src/main/java/ee/forgr/capacitor_updater/CryptoCipher.java +19 -5
- package/android/src/main/java/ee/forgr/capacitor_updater/DownloadService.java +21 -13
- package/android/src/main/java/ee/forgr/capacitor_updater/Logger.java +36 -14
- package/dist/docs.json +16 -0
- package/dist/esm/definitions.d.ts +14 -1
- package/dist/esm/definitions.js +0 -1
- package/dist/esm/definitions.js.map +1 -1
- package/dist/plugin.cjs.js +0 -1
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/CapacitorUpdaterPlugin/CapacitorUpdaterPlugin.swift +42 -2
- package/ios/Sources/CapacitorUpdaterPlugin/CapgoUpdater.swift +447 -168
- package/ios/Sources/CapacitorUpdaterPlugin/CryptoCipher.swift +15 -5
- package/ios/Sources/CapacitorUpdaterPlugin/InternalUtils.swift +70 -0
- package/package.json +1 -1
|
@@ -63,13 +63,21 @@ public struct CryptoCipher {
|
|
|
63
63
|
detectedFormat = "base64"
|
|
64
64
|
}
|
|
65
65
|
// swiftlint:disable:next line_length
|
|
66
|
-
logger.debug("Received
|
|
66
|
+
logger.debug("Received checksum format: \(detectedFormat) (length: \(checksum.count) chars, \(checksumBytes.count) bytes)")
|
|
67
67
|
|
|
68
68
|
if checksumBytes.isEmpty {
|
|
69
69
|
logger.error("Decoded checksum is empty")
|
|
70
70
|
throw CustomError.cannotDecode
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
// RSA-2048 encrypted data must be exactly 256 bytes
|
|
74
|
+
// If the checksum is not 256 bytes, the bundle was not encrypted properly
|
|
75
|
+
if checksumBytes.count != 256 {
|
|
76
|
+
// swiftlint:disable:next line_length
|
|
77
|
+
logger.error("Checksum is not RSA encrypted (size: \(checksumBytes.count) bytes, expected 256 for RSA-2048). Bundle must be uploaded with encryption when public key is configured.")
|
|
78
|
+
throw CustomError.cannotDecode
|
|
79
|
+
}
|
|
80
|
+
|
|
73
81
|
guard let rsaPublicKey = RSAPublicKey.load(rsaPublicKey: publicKey) else {
|
|
74
82
|
logger.error("The public key is not a valid RSA Public key")
|
|
75
83
|
throw CustomError.cannotDecode
|
|
@@ -278,8 +286,10 @@ public struct CryptoCipher {
|
|
|
278
286
|
}
|
|
279
287
|
}
|
|
280
288
|
|
|
281
|
-
/// Get first
|
|
282
|
-
/// Returns
|
|
289
|
+
/// Get first 20 characters of the public key for identification
|
|
290
|
+
/// Returns 20-character string or empty string if key is invalid/empty
|
|
291
|
+
/// The first 12 chars are always "MIIBCgKCAQEA" for RSA 2048-bit keys,
|
|
292
|
+
/// so the unique part starts at character 13
|
|
283
293
|
public static func calcKeyId(publicKey: String) -> String {
|
|
284
294
|
if publicKey.isEmpty {
|
|
285
295
|
return ""
|
|
@@ -293,7 +303,7 @@ public struct CryptoCipher {
|
|
|
293
303
|
.replacingOccurrences(of: "\r", with: "")
|
|
294
304
|
.replacingOccurrences(of: " ", with: "")
|
|
295
305
|
|
|
296
|
-
// Return first
|
|
297
|
-
return String(cleanedKey.prefix(
|
|
306
|
+
// Return first 20 characters of the base64-encoded key
|
|
307
|
+
return String(cleanedKey.prefix(20))
|
|
298
308
|
}
|
|
299
309
|
}
|
|
@@ -135,6 +135,28 @@ struct InfoObject: Codable {
|
|
|
135
135
|
}
|
|
136
136
|
// swiftlint:enable identifier_name
|
|
137
137
|
|
|
138
|
+
// swiftlint:disable identifier_name
|
|
139
|
+
struct StatsEvent: Codable {
|
|
140
|
+
let platform: String?
|
|
141
|
+
let device_id: String?
|
|
142
|
+
let app_id: String?
|
|
143
|
+
let custom_id: String?
|
|
144
|
+
let version_build: String?
|
|
145
|
+
let version_code: String?
|
|
146
|
+
let version_os: String?
|
|
147
|
+
let version_name: String?
|
|
148
|
+
let old_version_name: String?
|
|
149
|
+
let plugin_version: String?
|
|
150
|
+
let is_emulator: Bool?
|
|
151
|
+
let is_prod: Bool?
|
|
152
|
+
let action: String?
|
|
153
|
+
let channel: String?
|
|
154
|
+
let defaultChannel: String?
|
|
155
|
+
let key_id: String?
|
|
156
|
+
let timestamp: Int64
|
|
157
|
+
}
|
|
158
|
+
// swiftlint:enable identifier_name
|
|
159
|
+
|
|
138
160
|
// swiftlint:disable identifier_name
|
|
139
161
|
public struct ManifestEntry: Codable {
|
|
140
162
|
let file_name: String?
|
|
@@ -263,6 +285,7 @@ enum CustomError: Error {
|
|
|
263
285
|
case cannotDeleteDirectory
|
|
264
286
|
case cannotDecryptSessionKey
|
|
265
287
|
case invalidBase64
|
|
288
|
+
case insufficientDiskSpace
|
|
266
289
|
|
|
267
290
|
// Throw in all other cases
|
|
268
291
|
case unexpected(code: Int)
|
|
@@ -316,6 +339,53 @@ extension CustomError: LocalizedError {
|
|
|
316
339
|
"Decrypting the base64 failed",
|
|
317
340
|
comment: "Invalid checksum key"
|
|
318
341
|
)
|
|
342
|
+
case .insufficientDiskSpace:
|
|
343
|
+
return NSLocalizedString(
|
|
344
|
+
"Insufficient disk space for download",
|
|
345
|
+
comment: "Not enough storage"
|
|
346
|
+
)
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/// Thread-safe atomic counter for concurrent operations
|
|
352
|
+
final class AtomicCounter {
|
|
353
|
+
private var value: Int = 0
|
|
354
|
+
private let lock = NSLock()
|
|
355
|
+
|
|
356
|
+
func increment() -> Int {
|
|
357
|
+
lock.lock()
|
|
358
|
+
defer { lock.unlock() }
|
|
359
|
+
value += 1
|
|
360
|
+
return value
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
var current: Int {
|
|
364
|
+
lock.lock()
|
|
365
|
+
defer { lock.unlock() }
|
|
366
|
+
return value
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/// Thread-safe atomic boolean for concurrent operations
|
|
371
|
+
final class AtomicBool {
|
|
372
|
+
private var _value: Bool
|
|
373
|
+
private let lock = NSLock()
|
|
374
|
+
|
|
375
|
+
init(initialValue: Bool = false) {
|
|
376
|
+
_value = initialValue
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
var value: Bool {
|
|
380
|
+
get {
|
|
381
|
+
lock.lock()
|
|
382
|
+
defer { lock.unlock() }
|
|
383
|
+
return _value
|
|
384
|
+
}
|
|
385
|
+
set {
|
|
386
|
+
lock.lock()
|
|
387
|
+
defer { lock.unlock() }
|
|
388
|
+
_value = newValue
|
|
319
389
|
}
|
|
320
390
|
}
|
|
321
391
|
}
|