@capgo/capacitor-updater 6.1.17 → 6.1.19

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.
@@ -16,14 +16,13 @@ import SwiftyRSA
16
16
  @objc(CapacitorUpdaterPlugin)
17
17
  public class CapacitorUpdaterPlugin: CAPPlugin {
18
18
  public var implementation = CapacitorUpdater()
19
- private let PLUGIN_VERSION: String = "6.1.17"
19
+ private let PLUGIN_VERSION: String = "6.1.19"
20
20
  static let updateUrlDefault = "https://api.capgo.app/updates"
21
21
  static let statsUrlDefault = "https://api.capgo.app/stats"
22
22
  static let channelUrlDefault = "https://api.capgo.app/channel_self"
23
23
  let DELAY_CONDITION_PREFERENCES = ""
24
24
  private var updateUrl = ""
25
25
  private var statsUrl = ""
26
- private var defaultPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEA4pW9olT0FBXXivRCzd3xcImlWZrqkwcF2xTkX/FwXmj9eh9H\nkBLrsQmfsC+PJisRXIOGq6a0z3bsGq6jBpp3/Jr9jiaW5VuPGaKeMaZZBRvi/N5f\nIMG3hZXSOcy0IYg+E1Q7RkYO1xq5GLHseqG+PXvJsNe4R8R/Bmd/ngq0xh/cvcrH\nHpXwO0Aj9tfprlb+rHaVV79EkVRWYPidOLnK1n0EFHFJ1d/MyDIp10TEGm2xHpf/\nBrlb1an8wXEuzoC0DgYaczgTjovwR+ewSGhSHJliQdM0Qa3o1iN87DldWtydImMs\nPjJ3DUwpsjAMRe5X8Et4+udFW2ciYnQo9H0CkwIDAQABAoIBAQCtjlMV/4qBxAU4\nu0ZcWA9yywwraX0aJ3v1xrfzQYV322Wk4Ea5dbSxA5UcqCE29DA1M824t1Wxv/6z\npWbcTP9xLuresnJMtmgTE7umfiubvTONy2sENT20hgDkIwcq1CfwOEm61zjQzPhQ\nkSB5AmEsyR/BZEsUNc+ygR6AWOUFB7tj4yMc32LOTWSbE/znnF2BkmlmnQykomG1\n2oVqM3lUFP7+m8ux1O7scO6IMts+Z/eFXjWfxpbebUSvSIR83GXPQZ34S/c0ehOg\nyHdmCSOel1r3VvInMe+30j54Jr+Ml/7Ee6axiwyE2e/bd85MsK9sVdp0OtelXaqA\nOZZqWvN5AoGBAP2Hn3lSq+a8GsDH726mHJw60xM0LPbVJTYbXsmQkg1tl3NKJTMM\nQqz41+5uys+phEgLHI9gVJ0r+HaGHXnJ4zewlFjsudstb/0nfctUvTqnhEhfNo9I\ny4kufVKPRF3sMEeo7CDVJs4GNBLycEyIBy6Mbv0VcO7VaZqggRwu4no9AoGBAOTK\n6NWYs1BWlkua2wmxexGOzehNGedInp0wGr2l4FDayWjkZLqvB+nNXUQ63NdHlSs4\nWB2Z1kQXZxVaI2tPYexGUKXEo2uFob63uflbuE029ovDXIIPFTPtGNdNXwhHT5a+\nPhmy3sMc+s2BSNM5qaNmfxQxhdd6gRU6oikE+c0PAoGAMn3cKNFqIt27hkFLUgIL\nGKIuf1iYy9/PNWNmEUaVj88PpopRtkTu0nwMpROzmH/uNFriKTvKHjMvnItBO4wV\nkHW+VadvrFL0Rrqituf9d7z8/1zXBNo+juePVe3qc7oiM2NVA4Tv4YAixtM5wkQl\nCgQ15nlqsGYYTg9BJ1e/CxECgYEAjEYPzO2reuUrjr0p8F59ev1YJ0YmTJRMk0ks\nC/yIdGo/tGzbiU3JB0LfHPcN8Xu07GPGOpfYM7U5gXDbaG6qNgfCaHAQVdr/mQPi\nJQ1kCQtay8QCkscWk9iZM1//lP7LwDtxraXqSCwbZSYP9VlUNZeg8EuQqNU2EUL6\nqzWexmcCgYEA0prUGNBacraTYEknB1CsbP36UPWsqFWOvevlz+uEC5JPxPuW5ZHh\nSQN7xl6+PHyjPBM7ttwPKyhgLOVTb3K7ex/PXnudojMUK5fh7vYfChVTSlx2p6r0\nDi58PdD+node08cJH+ie0Yphp7m+D4+R9XD0v0nEvnu4BtAW6DrJasw=\n-----END RSA PRIVATE KEY-----\n"
27
26
  private var backgroundTaskID: UIBackgroundTaskIdentifier = UIBackgroundTaskIdentifier.invalid
28
27
  private var currentVersionNative: Version = "0.0.0"
29
28
  private var autoUpdate = false
@@ -43,7 +42,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
43
42
  print("\(self.implementation.TAG) ::::: SIMULATOR :::::")
44
43
  print("\(self.implementation.TAG) Application directory: \(NSHomeDirectory())")
45
44
  #endif
46
-
45
+
47
46
  self.semaphoreUp()
48
47
  self.implementation.deviceID = UserDefaults.standard.string(forKey: "appUUID") ?? UUID().uuidString
49
48
  UserDefaults.standard.set( self.implementation.deviceID, forKey: "appUUID")
@@ -76,7 +75,11 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
76
75
  periodCheckDelay = periodCheckDelayValue
77
76
  }
78
77
 
79
- implementation.privateKey = getConfig().getString("privateKey", self.defaultPrivateKey)!
78
+ implementation.privateKey = getConfig().getString("privateKey", "")!
79
+ implementation.publicKey = getConfig().getString("publicKey", "")!
80
+ if !implementation.privateKey.isEmpty {
81
+ implementation.hasOldPrivateKeyPropertyInConfig = true
82
+ }
80
83
  implementation.notifyDownloadRaw = notifyDownload
81
84
  implementation.PLUGIN_VERSION = self.PLUGIN_VERSION
82
85
  let config = (self.bridge?.viewController as? CAPBridgeViewController)?.instanceDescriptor().legacyConfig
@@ -90,15 +93,6 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
90
93
  implementation.statsUrl = getConfig().getString("statsUrl", CapacitorUpdaterPlugin.statsUrlDefault)!
91
94
  implementation.channelUrl = getConfig().getString("channelUrl", CapacitorUpdaterPlugin.channelUrlDefault)!
92
95
  implementation.defaultChannel = getConfig().getString("defaultChannel", "")!
93
- do {
94
- let signKeyString = getConfig().getString("signKey", "")!
95
- if (!signKeyString.isEmpty) {
96
- implementation.signKey = try PublicKey(base64Encoded: signKeyString)
97
- }
98
- } catch {
99
- print("\(self.implementation.TAG) Cannot get signKey, invalid key")
100
- fatalError("Invalid signKey in capacitor config")
101
- }
102
96
  self.implementation.autoReset()
103
97
 
104
98
  // Load the server
@@ -255,21 +249,18 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
255
249
  call.reject("Download called without version")
256
250
  return
257
251
  }
258
- let signature = call.getString("signature", "")
259
- if (self.implementation.signKey != nil && signature.isEmpty) {
260
- print("\(self.implementation.TAG) Signature required but none provided for download call")
261
- call.reject("Signature required but none provided")
262
- return
263
- }
264
-
252
+
265
253
  let sessionKey = call.getString("sessionKey", "")
266
- let checksum = call.getString("checksum", "")
254
+ var checksum = call.getString("checksum", "")
267
255
  let url = URL(string: urlString)
268
256
  print("\(self.implementation.TAG) Downloading \(String(describing: url))")
269
257
  DispatchQueue.global(qos: .background).async {
270
258
  do {
271
- let next = try self.implementation.download(url: url!, version: version, sessionKey: sessionKey, signature: signature)
272
- if checksum != "" && next.getChecksum() != checksum {
259
+ let next = try self.implementation.download(url: url!, version: version, sessionKey: sessionKey)
260
+ if !self.implementation.hasOldPrivateKeyPropertyInConfig {
261
+ checksum = try self.implementation.decryptChecksum(checksum: checksum, version: version)
262
+ }
263
+ if (checksum != "" || self.implementation.publicKey != "") && next.getChecksum() != checksum {
273
264
  print("\(self.implementation.TAG) Error checksum", next.getChecksum(), checksum)
274
265
  self.implementation.sendStats(action: "checksum_fail", versionName: next.getVersionName())
275
266
  let id = next.getId()
@@ -278,6 +269,8 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
278
269
  print("\(self.implementation.TAG) Delete failed, id \(id) doesn't exist")
279
270
  }
280
271
  throw ObjectSavableError.checksum
272
+ } else {
273
+ print("\(self.implementation.TAG) Good checksum", next.getChecksum(), checksum)
281
274
  }
282
275
  self.notifyListeners("updateAvailable", data: ["bundle": next.toJSON()])
283
276
  call.resolve(next.toJSON())
@@ -547,15 +540,13 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
547
540
  if !killed {
548
541
  self._cancelDelay(source: "background check")
549
542
  }
550
- break
551
- case "kill":
543
+ case "kill":
552
544
  if killed {
553
545
  self._cancelDelay(source: "kill check")
554
546
  // instant install for kill action
555
547
  self.installNext()
556
548
  }
557
- break
558
- case "date":
549
+ case "date":
559
550
  if value != nil && value != "" {
560
551
  let dateFormatter = ISO8601DateFormatter()
561
552
  dateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
@@ -569,8 +560,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
569
560
  } else {
570
561
  self._cancelDelay(source: "delayVal absent")
571
562
  }
572
- break
573
- case "nativeVersion":
563
+ case "nativeVersion":
574
564
  if value != nil && value != "" {
575
565
  do {
576
566
  let versionLimit = try Version(value!)
@@ -583,7 +573,6 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
583
573
  } else {
584
574
  self._cancelDelay(source: "delayVal absent")
585
575
  }
586
- break
587
576
  case .none:
588
577
  print("\(self.implementation.TAG) _checkCancelDelay switch case none error")
589
578
  case .some:
@@ -703,7 +692,6 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
703
692
  return
704
693
  }
705
694
  let sessionKey = res.sessionKey ?? ""
706
- let signature = res.signature ?? ""
707
695
  guard let downloadUrl = URL(string: res.url) else {
708
696
  print("\(self.implementation.TAG) Error no url or wrong format")
709
697
  self.endBackGroundTaskWithNotif(msg: "Error no url or wrong format", latestVersionName: res.version, current: current)
@@ -724,7 +712,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
724
712
  print("\(self.implementation.TAG) Failed to delete failed bundle: \(nextImpl!.toString())")
725
713
  }
726
714
  }
727
- nextImpl = try self.implementation.download(url: downloadUrl, version: latestVersionName, sessionKey: sessionKey, signature: signature)
715
+ nextImpl = try self.implementation.download(url: downloadUrl, version: latestVersionName, sessionKey: sessionKey)
728
716
  }
729
717
  guard let next = nextImpl else {
730
718
  print("\(self.implementation.TAG) Error downloading file")
@@ -736,6 +724,9 @@ public class CapacitorUpdaterPlugin: CAPPlugin {
736
724
  self.endBackGroundTaskWithNotif(msg: "Latest version is in error state. Aborting update.", latestVersionName: latestVersionName, current: current)
737
725
  return
738
726
  }
727
+ if !self.implementation.hasOldPrivateKeyPropertyInConfig {
728
+ res.checksum = try self.implementation.decryptChecksum(checksum: res.checksum, version: latestVersionName)
729
+ }
739
730
  if res.checksum != "" && next.getChecksum() != res.checksum {
740
731
  print("\(self.implementation.TAG) Error checksum", next.getChecksum(), res.checksum)
741
732
  self.implementation.sendStats(action: "checksum_fail", versionName: next.getVersionName())
@@ -83,10 +83,6 @@ public struct RSAKeyPair {
83
83
  self.publicKey = publicKey
84
84
  }
85
85
 
86
- public func extractPublicKey() -> RSAPublicKey {
87
- RSAPublicKey(publicKey: publicKey)
88
- }
89
-
90
86
  ///
91
87
  /// Takes the data and uses the private key to decrypt it.
92
88
  /// Returns the decrypted data.
@@ -103,21 +99,7 @@ public struct RSAKeyPair {
103
99
  return nil
104
100
  }
105
101
  }
106
- }
107
-
108
- ///
109
- /// The RSA public key.
110
- ///
111
- public struct RSAPublicKey {
112
- private let publicKey: SecKey
113
102
 
114
- #if DEBUG
115
- public var __debug_publicKey: SecKey { self.publicKey }
116
- #endif
117
-
118
- fileprivate init(publicKey: SecKey) {
119
- self.publicKey = publicKey
120
- }
121
103
  ///
122
104
  /// Takes the data and uses the public key to encrypt it.
123
105
  /// Returns the encrypted data.
@@ -134,24 +116,7 @@ public struct RSAPublicKey {
134
116
  return nil
135
117
  }
136
118
  }
137
- ///
138
- /// Allows you to export the RSA public key to a format (so you can send over the net).
139
- ///
140
- public func export() -> Data? {
141
- return publicKey.exportToData()
142
- }
143
- //
144
119
 
145
- ///
146
- /// Allows you to load an RSA public key (i.e. one downloaded from the net).
147
- ///
148
- public static func load(rsaPublicKeyData: Data) -> RSAPublicKey? {
149
- if let publicKey: SecKey = .loadPublicFromData(rsaPublicKeyData) {
150
- return RSAPublicKey(publicKey: publicKey)
151
- } else {
152
- return nil
153
- }
154
- }
155
120
  }
156
121
  ///
157
122
  /// The RSA public key.
@@ -233,7 +198,7 @@ fileprivate extension SecKey {
233
198
  kSecAttrKeyClass: kSecAttrKeyClassPublic,
234
199
  kSecAttrKeySizeInBits: CryptoCipherConstants.rsaKeySizeInBits
235
200
  ]
236
- return SecKeyCreateWithData(data as CFData, keyDict as CFDictionary, nil)
201
+ return SecKeyCreateWithData(data as NSData, keyDict as CFDictionary, nil)
237
202
  }
238
203
  static func loadPrivateFromData(_ data: Data) -> SecKey? {
239
204
  let keyDict: [NSObject: NSObject] = [
@@ -10,62 +10,12 @@ import CommonCrypto
10
10
  ///
11
11
  /// Constants
12
12
  ///
13
- private enum CryptoCipherConstantsV2 {
13
+ private enum CryptoCipherConstants {
14
14
  static let rsaKeySizeInBits: NSNumber = 2048
15
15
  static let aesAlgorithm: CCAlgorithm = CCAlgorithm(kCCAlgorithmAES)
16
16
  static let aesOptions: CCOptions = CCOptions(kCCOptionPKCS7Padding)
17
- static let rsaAlgorithm: SecKeyAlgorithm = .rsaEncryptionPKCS1
17
+ static let rsaAlgorithm: SecKeyAlgorithm = .rsaEncryptionOAEPSHA256
18
18
  }
19
- ///
20
- /// The AES key. Contains both the initialization vector and secret key.
21
- ///
22
- public struct AES128KeyV2 {
23
- /// Initialization vector
24
- private let iv: Data
25
- private let aes128Key: Data
26
- #if DEBUG
27
- public var __debug_iv: Data { iv }
28
- public var __debug_aes128Key: Data { aes128Key }
29
- #endif
30
- init(iv: Data, aes128Key: Data) {
31
- self.iv = iv
32
- self.aes128Key = aes128Key
33
- }
34
- ///
35
- /// Takes the data and uses the private key to decrypt it. Will call `CCCrypt` in CommonCrypto
36
- /// and provide it `ivData` for the initialization vector. Will use cipher block chaining (CBC) as
37
- /// the mode of operation.
38
- ///
39
- /// Returns the decrypted data.
40
- ///
41
- public func decrypt(data: Data) -> Data? {
42
- let encryptedData: UnsafePointer<UInt8> = (data as NSData).bytes.bindMemory(to: UInt8.self, capacity: data.count)
43
- let encryptedDataLength: Int = data.count
44
-
45
- if let result: NSMutableData = NSMutableData(length: encryptedDataLength) {
46
- let keyData: UnsafePointer<UInt8> = (self.aes128Key as NSData).bytes.bindMemory(to: UInt8.self, capacity: self.aes128Key.count)
47
- let keyLength: size_t = size_t(self.aes128Key.count)
48
- let ivData: UnsafePointer<UInt8> = (iv as NSData).bytes.bindMemory(to: UInt8.self, capacity: self.iv.count)
49
-
50
- let decryptedData: UnsafeMutablePointer<UInt8> = UnsafeMutablePointer<UInt8>(result.mutableBytes.assumingMemoryBound(to: UInt8.self))
51
- let decryptedDataLength: size_t = size_t(result.length)
52
-
53
- var decryptedLength: size_t = 0
54
-
55
- let status: CCCryptorStatus = CCCrypt(CCOperation(kCCDecrypt), CryptoCipherConstants.aesAlgorithm, CryptoCipherConstants.aesOptions, keyData, keyLength, ivData, encryptedData, encryptedDataLength, decryptedData, decryptedDataLength, &decryptedLength)
56
-
57
- if Int32(status) == Int32(kCCSuccess) {
58
- result.length = Int(decryptedLength)
59
- return result as Data
60
- } else {
61
- return nil
62
- }
63
- } else {
64
- return nil
65
- }
66
- }
67
- }
68
-
69
19
  ///
70
20
  /// The RSA keypair. Includes both private and public key.
71
21
  ///
@@ -108,7 +58,7 @@ public struct RSAKeyPairV2 {
108
58
  ///
109
59
  /// The RSA public key.
110
60
  ///
111
- public struct RSAPublicKeyV2 {
61
+ public struct RSAPublicKey {
112
62
  private let publicKey: SecKey
113
63
 
114
64
  #if DEBUG
@@ -136,14 +86,6 @@ public struct RSAPublicKeyV2 {
136
86
  }
137
87
  }
138
88
 
139
- ///
140
- /// Allows you to export the RSA public key to a format (so you can send over the net).
141
- ///
142
- public func export() -> Data? {
143
- return publicKey.exportToData()
144
- }
145
- //
146
-
147
89
  ///
148
90
  /// Allows you to load an RSA public key (i.e. one downloaded from the net).
149
91
  ///
@@ -231,7 +173,7 @@ public struct RSAPublicKeyV2 {
231
173
  }
232
174
  }
233
175
 
234
- fileprivate extension SecKeyV2 {
176
+ fileprivate extension SecKey {
235
177
  func exportToData() -> Data? {
236
178
  var error: Unmanaged<CFError>?
237
179
  if let cfData: CFData = SecKeyCopyExternalRepresentation(self, &error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-updater",
3
- "version": "6.1.17",
3
+ "version": "6.1.19",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Live update for capacitor apps",
6
6
  "main": "dist/plugin.cjs.js",