@capgo/capacitor-updater 8.1.0 → 8.2.1

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.
@@ -72,7 +72,7 @@ public class CapacitorUpdaterPlugin extends Plugin {
72
72
  private static final String[] BREAKING_EVENT_NAMES = { "breakingAvailable", "majorAvailable" };
73
73
  private static final String LAST_FAILED_BUNDLE_PREF_KEY = "CapacitorUpdater.lastFailedBundle";
74
74
 
75
- private final String pluginVersion = "8.0.0";
75
+ private final String pluginVersion = "8.2.1";
76
76
  private static final String DELAY_CONDITION_PREFERENCES = "";
77
77
 
78
78
  private SharedPreferences.Editor editor;
@@ -304,7 +304,12 @@ public class CapacitorUpdaterPlugin extends Plugin {
304
304
  this.persistCustomId = this.getConfig().getBoolean("persistCustomId", false);
305
305
  this.persistModifyUrl = this.getConfig().getBoolean("persistModifyUrl", false);
306
306
  this.allowSetDefaultChannel = this.getConfig().getBoolean("allowSetDefaultChannel", true);
307
- this.implementation.publicKey = this.getConfig().getString("publicKey", "");
307
+ this.implementation.setPublicKey(this.getConfig().getString("publicKey", ""));
308
+ // Log public key prefix if encryption is enabled
309
+ String keyId = this.implementation.getKeyId();
310
+ if (keyId != null && !keyId.isEmpty()) {
311
+ logger.info("Public key prefix: " + keyId);
312
+ }
308
313
  this.implementation.statsUrl = this.getConfig().getString("statsUrl", statsUrlDefault);
309
314
  this.implementation.channelUrl = this.getConfig().getString("channelUrl", channelUrlDefault);
310
315
  if (Boolean.TRUE.equals(this.persistModifyUrl)) {
@@ -81,6 +81,9 @@ public class CapgoUpdater {
81
81
  public String deviceID = "";
82
82
  public int timeout = 20000;
83
83
 
84
+ // Cached key ID calculated once from publicKey
85
+ private String cachedKeyId = "";
86
+
84
87
  // Flag to track if we received a 429 response - stops requests until app restart
85
88
  private static volatile boolean rateLimitExceeded = false;
86
89
 
@@ -145,6 +148,19 @@ public class CapgoUpdater {
145
148
  return sb.toString();
146
149
  }
147
150
 
151
+ public void setPublicKey(String publicKey) {
152
+ this.publicKey = publicKey;
153
+ if (!publicKey.isEmpty()) {
154
+ this.cachedKeyId = CryptoCipher.calcKeyId(publicKey);
155
+ } else {
156
+ this.cachedKeyId = "";
157
+ }
158
+ }
159
+
160
+ public String getKeyId() {
161
+ return this.cachedKeyId;
162
+ }
163
+
148
164
  private File unzip(final String id, final File zipFile, final String dest) throws IOException {
149
165
  final File targetDirectory = new File(this.documentsDir, dest);
150
166
  try (
@@ -806,6 +822,12 @@ public class CapgoUpdater {
806
822
  json.put("is_emulator", this.isEmulator());
807
823
  json.put("is_prod", this.isProd());
808
824
  json.put("defaultChannel", this.defaultChannel);
825
+
826
+ // Add encryption key ID if encryption is enabled (use cached value)
827
+ if (!this.cachedKeyId.isEmpty()) {
828
+ json.put("key_id", this.cachedKeyId);
829
+ }
830
+
809
831
  return json;
810
832
  }
811
833
 
@@ -359,4 +359,23 @@ public class CryptoCipher {
359
359
 
360
360
  throw new IllegalArgumentException("size too large, only up to 64KiB length encoding supported: " + size);
361
361
  }
362
+
363
+ /**
364
+ * Get first 4 characters of the public key for identification.
365
+ * Returns 4-character string or empty string if key is invalid/empty.
366
+ */
367
+ public static String calcKeyId(String publicKey) {
368
+ if (publicKey == null || publicKey.isEmpty()) {
369
+ return "";
370
+ }
371
+
372
+ // Remove PEM headers and whitespace to get the raw key data
373
+ String cleanedKey = publicKey
374
+ .replaceAll("\\s+", "")
375
+ .replace("-----BEGINRSAPUBLICKEY-----", "")
376
+ .replace("-----ENDRSAPUBLICKEY-----", "");
377
+
378
+ // Return first 4 characters of the base64-encoded key
379
+ return cleanedKey.length() >= 4 ? cleanedKey.substring(0, 4) : cleanedKey;
380
+ }
362
381
  }
@@ -54,7 +54,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
54
54
  CAPPluginMethod(name: "isShakeMenuEnabled", returnType: CAPPluginReturnPromise)
55
55
  ]
56
56
  public var implementation = CapgoUpdater()
57
- private let pluginVersion: String = "8.0.0"
57
+ private let pluginVersion: String = "8.2.1"
58
58
  static let updateUrlDefault = "https://plugin.capgo.app/updates"
59
59
  static let statsUrlDefault = "https://plugin.capgo.app/stats"
60
60
  static let channelUrlDefault = "https://plugin.capgo.app/channel_self"
@@ -196,7 +196,7 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
196
196
  periodCheckDelay = periodCheckDelayValue
197
197
  }
198
198
 
199
- implementation.publicKey = getConfig().getString("publicKey", "")!
199
+ implementation.setPublicKey(getConfig().getString("publicKey") ?? "")
200
200
  implementation.notifyDownloadRaw = notifyDownload
201
201
  implementation.pluginVersion = self.pluginVersion
202
202
 
@@ -204,6 +204,11 @@ public class CapacitorUpdaterPlugin: CAPPlugin, CAPBridgedPlugin {
204
204
  implementation.setLogger(logger)
205
205
  CryptoCipher.setLogger(logger)
206
206
 
207
+ // Log public key prefix if encryption is enabled
208
+ if let keyId = implementation.getKeyId(), !keyId.isEmpty {
209
+ logger.info("Public key prefix: \(keyId)")
210
+ }
211
+
207
212
  // Initialize DelayUpdateUtils
208
213
  self.delayUpdateUtils = DelayUpdateUtils(currentVersionNative: currentVersionNative, logger: logger)
209
214
  let config = (self.bridge?.viewController as? CAPBridgeViewController)?.instanceDescriptor().legacyConfig
@@ -42,6 +42,9 @@ import UIKit
42
42
  public var deviceID = ""
43
43
  public var publicKey: String = ""
44
44
 
45
+ // Cached key ID calculated once from publicKey
46
+ private var cachedKeyId: String?
47
+
45
48
  // Flag to track if we received a 429 response - stops requests until app restart
46
49
  private static var rateLimitExceeded = false
47
50
 
@@ -79,6 +82,19 @@ import UIKit
79
82
  return String((0..<length).map { _ in letters.randomElement()! })
80
83
  }
81
84
 
85
+ public func setPublicKey(_ publicKey: String) {
86
+ self.publicKey = publicKey
87
+ if !publicKey.isEmpty {
88
+ self.cachedKeyId = CryptoCipher.calcKeyId(publicKey: publicKey)
89
+ } else {
90
+ self.cachedKeyId = nil
91
+ }
92
+ }
93
+
94
+ public func getKeyId() -> String? {
95
+ return self.cachedKeyId
96
+ }
97
+
82
98
  private var isDevEnvironment: Bool {
83
99
  #if DEBUG
84
100
  return true
@@ -324,7 +340,8 @@ import UIKit
324
340
  is_prod: self.isProd(),
325
341
  action: nil,
326
342
  channel: nil,
327
- defaultChannel: self.defaultChannel
343
+ defaultChannel: self.defaultChannel,
344
+ key_id: self.cachedKeyId
328
345
  )
329
346
  }
330
347
 
@@ -264,4 +264,23 @@ public struct CryptoCipher {
264
264
  throw CustomError.cannotDecode
265
265
  }
266
266
  }
267
+
268
+ /// Get first 4 characters of the public key for identification
269
+ /// Returns 4-character string or empty string if key is invalid/empty
270
+ public static func calcKeyId(publicKey: String) -> String {
271
+ if publicKey.isEmpty {
272
+ return ""
273
+ }
274
+
275
+ // Remove PEM headers and whitespace to get the raw key data
276
+ let cleanedKey = publicKey
277
+ .replacingOccurrences(of: "-----BEGIN RSA PUBLIC KEY-----", with: "")
278
+ .replacingOccurrences(of: "-----END RSA PUBLIC KEY-----", with: "")
279
+ .replacingOccurrences(of: "\n", with: "")
280
+ .replacingOccurrences(of: "\r", with: "")
281
+ .replacingOccurrences(of: " ", with: "")
282
+
283
+ // Return first 4 characters of the base64-encoded key
284
+ return String(cleanedKey.prefix(4))
285
+ }
267
286
  }
@@ -128,6 +128,7 @@ struct InfoObject: Codable {
128
128
  var action: String?
129
129
  var channel: String?
130
130
  var defaultChannel: String?
131
+ var key_id: String?
131
132
  }
132
133
 
133
134
  public struct ManifestEntry: Codable {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-updater",
3
- "version": "8.1.0",
3
+ "version": "8.2.1",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Live update for capacitor apps",
6
6
  "main": "dist/plugin.cjs.js",