@otakit/capacitor-updater 1.0.0

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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +183 -0
  3. package/UpdatekitUpdater.podspec +18 -0
  4. package/android/build.gradle +49 -0
  5. package/android/src/main/AndroidManifest.xml +3 -0
  6. package/android/src/main/java/com/updatekit/updater/BundleInfo.java +100 -0
  7. package/android/src/main/java/com/updatekit/updater/BundleStatus.java +28 -0
  8. package/android/src/main/java/com/updatekit/updater/BundleStore.java +264 -0
  9. package/android/src/main/java/com/updatekit/updater/DateUtils.java +17 -0
  10. package/android/src/main/java/com/updatekit/updater/HashUtils.java +32 -0
  11. package/android/src/main/java/com/updatekit/updater/HostedManifestKeys.java +37 -0
  12. package/android/src/main/java/com/updatekit/updater/ManifestClient.java +209 -0
  13. package/android/src/main/java/com/updatekit/updater/ManifestVerifier.java +146 -0
  14. package/android/src/main/java/com/updatekit/updater/StatsClient.java +80 -0
  15. package/android/src/main/java/com/updatekit/updater/UpdaterPlugin.java +963 -0
  16. package/android/src/main/java/com/updatekit/updater/ZipUtils.java +72 -0
  17. package/dist/esm/definitions.d.ts +229 -0
  18. package/dist/esm/definitions.d.ts.map +1 -0
  19. package/dist/esm/definitions.js +17 -0
  20. package/dist/esm/definitions.js.map +1 -0
  21. package/dist/esm/index.d.ts +5 -0
  22. package/dist/esm/index.d.ts.map +1 -0
  23. package/dist/esm/index.js +85 -0
  24. package/dist/esm/index.js.map +1 -0
  25. package/dist/esm/web.d.ts +25 -0
  26. package/dist/esm/web.d.ts.map +1 -0
  27. package/dist/esm/web.js +56 -0
  28. package/dist/esm/web.js.map +1 -0
  29. package/dist/plugin.cjs.js +165 -0
  30. package/dist/plugin.cjs.js.map +1 -0
  31. package/dist/plugin.js +168 -0
  32. package/dist/plugin.js.map +1 -0
  33. package/ios/Sources/UpdaterPlugin/BundleInfo.swift +39 -0
  34. package/ios/Sources/UpdaterPlugin/BundleStatus.swift +9 -0
  35. package/ios/Sources/UpdaterPlugin/BundleStore.swift +233 -0
  36. package/ios/Sources/UpdaterPlugin/Downloader.swift +120 -0
  37. package/ios/Sources/UpdaterPlugin/HashUtils.swift +33 -0
  38. package/ios/Sources/UpdaterPlugin/HostedManifestKeys.swift +23 -0
  39. package/ios/Sources/UpdaterPlugin/ManifestClient.swift +161 -0
  40. package/ios/Sources/UpdaterPlugin/ManifestVerifier.swift +115 -0
  41. package/ios/Sources/UpdaterPlugin/StatsClient.swift +66 -0
  42. package/ios/Sources/UpdaterPlugin/UpdaterPlugin.m +15 -0
  43. package/ios/Sources/UpdaterPlugin/UpdaterPlugin.swift +913 -0
  44. package/ios/Sources/UpdaterPlugin/ZipUtils.swift +90 -0
  45. package/package.json +85 -0
@@ -0,0 +1,90 @@
1
+ import Foundation
2
+ import ZIPFoundation
3
+
4
+ enum ZipUtilsError: Error {
5
+ case invalidZip
6
+ case pathTraversal(String)
7
+ case absolutePath(String)
8
+ case symlinkNotAllowed(String)
9
+ case unsupportedEntry(String)
10
+ case fileCountExceeded(Int)
11
+ case totalSizeExceeded(UInt64)
12
+ }
13
+
14
+ final class ZipUtils {
15
+ private let maxFiles = 10_000
16
+ private let maxTotalSize: UInt64 = 500_000_000 // 500 MB
17
+
18
+ func extractSecurely(zipURL: URL, to destination: URL) throws {
19
+ guard let archive = Archive(url: zipURL, accessMode: .read) else {
20
+ throw ZipUtilsError.invalidZip
21
+ }
22
+
23
+ let destinationPath = destination.standardizedFileURL.path
24
+ let destinationPrefix =
25
+ destinationPath.hasSuffix("/") ? destinationPath : "\(destinationPath)/"
26
+
27
+ var fileCount = 0
28
+ var totalSize: UInt64 = 0
29
+
30
+ for entry in archive {
31
+ if entry.path.hasPrefix("/") {
32
+ throw ZipUtilsError.absolutePath(entry.path)
33
+ }
34
+ if entry.path.contains("..") {
35
+ throw ZipUtilsError.pathTraversal(entry.path)
36
+ }
37
+ if entry.type == .symlink {
38
+ throw ZipUtilsError.symlinkNotAllowed(entry.path)
39
+ }
40
+ if entry.type != .directory && entry.type != .file {
41
+ throw ZipUtilsError.unsupportedEntry(entry.path)
42
+ }
43
+
44
+ let outputURL = destination
45
+ .appendingPathComponent(entry.path)
46
+ .standardizedFileURL
47
+ let outputPath = outputURL.path
48
+ if !(outputPath == destinationPath || outputPath.hasPrefix(destinationPrefix))
49
+ {
50
+ throw ZipUtilsError.pathTraversal(entry.path)
51
+ }
52
+
53
+ if entry.type == .file {
54
+ fileCount += 1
55
+ if fileCount > maxFiles {
56
+ throw ZipUtilsError.fileCountExceeded(fileCount)
57
+ }
58
+ totalSize += entry.uncompressedSize
59
+ if totalSize > maxTotalSize {
60
+ throw ZipUtilsError.totalSizeExceeded(totalSize)
61
+ }
62
+ }
63
+ }
64
+
65
+ try FileManager.default.createDirectory(
66
+ at: destination,
67
+ withIntermediateDirectories: true
68
+ )
69
+
70
+ for entry in archive {
71
+ let outputURL = destination.appendingPathComponent(entry.path)
72
+ switch entry.type {
73
+ case .directory:
74
+ try FileManager.default.createDirectory(
75
+ at: outputURL,
76
+ withIntermediateDirectories: true
77
+ )
78
+ case .file:
79
+ let parent = outputURL.deletingLastPathComponent()
80
+ try FileManager.default.createDirectory(
81
+ at: parent,
82
+ withIntermediateDirectories: true
83
+ )
84
+ _ = try archive.extract(entry, to: outputURL)
85
+ default:
86
+ throw ZipUtilsError.unsupportedEntry(entry.path)
87
+ }
88
+ }
89
+ }
90
+ }
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@otakit/capacitor-updater",
3
+ "version": "1.0.0",
4
+ "description": "Capacitor plugin for OTA updates",
5
+ "main": "dist/plugin.cjs.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/esm/index.d.ts",
8
+ "unpkg": "dist/plugin.js",
9
+ "publishConfig": {
10
+ "access": "public"
11
+ },
12
+ "files": [
13
+ "LICENSE",
14
+ "android/src/main/",
15
+ "android/build.gradle",
16
+ "dist/",
17
+ "ios/Sources/",
18
+ "ios/Tests/",
19
+ "UpdatekitUpdater.podspec"
20
+ ],
21
+ "author": "OtaKit",
22
+ "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/OtaKit/otakit.git"
26
+ },
27
+ "bugs": {
28
+ "url": "https://github.com/OtaKit/otakit/issues"
29
+ },
30
+ "homepage": "https://github.com/OtaKit/otakit/tree/main/packages/capacitor-plugin#readme",
31
+ "keywords": [
32
+ "capacitor",
33
+ "plugin",
34
+ "native",
35
+ "ota",
36
+ "update"
37
+ ],
38
+ "scripts": {
39
+ "verify": "npm run verify:minimal",
40
+ "verify:minimal": "node -e \"console.log('Native verification is not wired yet')\"",
41
+ "verify:web": "npm run build",
42
+ "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
43
+ "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
44
+ "eslint": "eslint src",
45
+ "prettier": "prettier \"src/**/*.{ts,js}\" \"android/src/main/java/**/*.java\" --plugin=prettier-plugin-java",
46
+ "swiftlint": "node-swiftlint",
47
+ "docgen": "docgen --api UpdaterPlugin --output-readme README.md --output-json dist/docs.json",
48
+ "build": "npm run clean && tsc && rollup -c rollup.config.mjs",
49
+ "clean": "rimraf ./dist",
50
+ "watch": "tsc --watch",
51
+ "prepublishOnly": "npm run build",
52
+ "typecheck": "tsc --noEmit"
53
+ },
54
+ "devDependencies": {
55
+ "@capacitor/android": "^8.0.2",
56
+ "@capacitor/core": "8.0.2",
57
+ "@capacitor/docgen": "^0.3.1",
58
+ "@capacitor/ios": "^8.0.2",
59
+ "@eslint/js": "^9.18.0",
60
+ "@ionic/prettier-config": "^4.0.0",
61
+ "@ionic/swiftlint-config": "^2.0.0",
62
+ "eslint": "^9.39.2",
63
+ "typescript-eslint": "^8.32.1",
64
+ "prettier": "^3.8.1",
65
+ "prettier-plugin-java": "^2.8.1",
66
+ "rimraf": "^6.1.2",
67
+ "rollup": "^4.57.1",
68
+ "swiftlint": "^2.0.0",
69
+ "typescript": "^5.9.3"
70
+ },
71
+ "peerDependencies": {
72
+ "@capacitor/core": "^8.0.2"
73
+ },
74
+ "engines": {
75
+ "node": ">=20.0.0"
76
+ },
77
+ "capacitor": {
78
+ "ios": {
79
+ "src": "ios"
80
+ },
81
+ "android": {
82
+ "src": "android"
83
+ }
84
+ }
85
+ }