native-update 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.
- package/CapacitorNativeUpdate.podspec +18 -0
- package/LICENSE +21 -0
- package/Readme.md +451 -0
- package/android/build.gradle +92 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +8 -0
- package/android/gradle.properties +17 -0
- package/android/proguard-rules.pro +29 -0
- package/android/settings.gradle +2 -0
- package/android/src/main/AndroidManifest.xml +34 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/AppReviewPlugin.kt +153 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/AppUpdatePlugin.kt +275 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundNotificationManager.kt +390 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateManager.kt +46 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdatePlugin.kt +333 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateWorker.kt +251 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/CapacitorNativeUpdatePlugin.kt +265 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/LiveUpdatePlugin.kt +526 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/NotificationActionReceiver.kt +99 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/SecurityManager.kt +249 -0
- package/dist/esm/__tests__/bundle-manager.test.d.ts +1 -0
- package/dist/esm/__tests__/bundle-manager.test.js +123 -0
- package/dist/esm/__tests__/bundle-manager.test.js.map +1 -0
- package/dist/esm/__tests__/config.test.d.ts +1 -0
- package/dist/esm/__tests__/config.test.js +69 -0
- package/dist/esm/__tests__/config.test.js.map +1 -0
- package/dist/esm/__tests__/integration.test.d.ts +1 -0
- package/dist/esm/__tests__/integration.test.js +78 -0
- package/dist/esm/__tests__/integration.test.js.map +1 -0
- package/dist/esm/__tests__/security.test.d.ts +1 -0
- package/dist/esm/__tests__/security.test.js +54 -0
- package/dist/esm/__tests__/security.test.js.map +1 -0
- package/dist/esm/__tests__/version-manager.test.d.ts +1 -0
- package/dist/esm/__tests__/version-manager.test.js +45 -0
- package/dist/esm/__tests__/version-manager.test.js.map +1 -0
- package/dist/esm/app-review/app-review-manager.d.ts +24 -0
- package/dist/esm/app-review/app-review-manager.js +195 -0
- package/dist/esm/app-review/app-review-manager.js.map +1 -0
- package/dist/esm/app-review/index.d.ts +5 -0
- package/dist/esm/app-review/index.js +6 -0
- package/dist/esm/app-review/index.js.map +1 -0
- package/dist/esm/app-review/platform-review-handler.d.ts +20 -0
- package/dist/esm/app-review/platform-review-handler.js +138 -0
- package/dist/esm/app-review/platform-review-handler.js.map +1 -0
- package/dist/esm/app-review/review-conditions-checker.d.ts +22 -0
- package/dist/esm/app-review/review-conditions-checker.js +155 -0
- package/dist/esm/app-review/review-conditions-checker.js.map +1 -0
- package/dist/esm/app-review/review-rate-limiter.d.ts +23 -0
- package/dist/esm/app-review/review-rate-limiter.js +164 -0
- package/dist/esm/app-review/review-rate-limiter.js.map +1 -0
- package/dist/esm/app-review/types.d.ts +41 -0
- package/dist/esm/app-review/types.js +2 -0
- package/dist/esm/app-review/types.js.map +1 -0
- package/dist/esm/app-update/app-update-checker.d.ts +13 -0
- package/dist/esm/app-update/app-update-checker.js +104 -0
- package/dist/esm/app-update/app-update-checker.js.map +1 -0
- package/dist/esm/app-update/app-update-installer.d.ts +19 -0
- package/dist/esm/app-update/app-update-installer.js +123 -0
- package/dist/esm/app-update/app-update-installer.js.map +1 -0
- package/dist/esm/app-update/app-update-manager.d.ts +28 -0
- package/dist/esm/app-update/app-update-manager.js +199 -0
- package/dist/esm/app-update/app-update-manager.js.map +1 -0
- package/dist/esm/app-update/app-update-notifier.d.ts +14 -0
- package/dist/esm/app-update/app-update-notifier.js +100 -0
- package/dist/esm/app-update/app-update-notifier.js.map +1 -0
- package/dist/esm/app-update/index.d.ts +6 -0
- package/dist/esm/app-update/index.js +7 -0
- package/dist/esm/app-update/index.js.map +1 -0
- package/dist/esm/app-update/platform-app-update.d.ts +19 -0
- package/dist/esm/app-update/platform-app-update.js +129 -0
- package/dist/esm/app-update/platform-app-update.js.map +1 -0
- package/dist/esm/app-update/types.d.ts +58 -0
- package/dist/esm/app-update/types.js +12 -0
- package/dist/esm/app-update/types.js.map +1 -0
- package/dist/esm/background-update/background-scheduler.d.ts +17 -0
- package/dist/esm/background-update/background-scheduler.js +195 -0
- package/dist/esm/background-update/background-scheduler.js.map +1 -0
- package/dist/esm/background-update/index.d.ts +3 -0
- package/dist/esm/background-update/index.js +3 -0
- package/dist/esm/background-update/index.js.map +1 -0
- package/dist/esm/background-update/notification-manager.d.ts +29 -0
- package/dist/esm/background-update/notification-manager.js +89 -0
- package/dist/esm/background-update/notification-manager.js.map +1 -0
- package/dist/esm/core/analytics.d.ts +70 -0
- package/dist/esm/core/analytics.js +137 -0
- package/dist/esm/core/analytics.js.map +1 -0
- package/dist/esm/core/cache-manager.d.ts +72 -0
- package/dist/esm/core/cache-manager.js +275 -0
- package/dist/esm/core/cache-manager.js.map +1 -0
- package/dist/esm/core/config.d.ts +48 -0
- package/dist/esm/core/config.js +83 -0
- package/dist/esm/core/config.js.map +1 -0
- package/dist/esm/core/errors.d.ts +51 -0
- package/dist/esm/core/errors.js +80 -0
- package/dist/esm/core/errors.js.map +1 -0
- package/dist/esm/core/logger.d.ts +21 -0
- package/dist/esm/core/logger.js +109 -0
- package/dist/esm/core/logger.js.map +1 -0
- package/dist/esm/core/performance.d.ts +53 -0
- package/dist/esm/core/performance.js +140 -0
- package/dist/esm/core/performance.js.map +1 -0
- package/dist/esm/core/plugin-manager.d.ts +66 -0
- package/dist/esm/core/plugin-manager.js +148 -0
- package/dist/esm/core/plugin-manager.js.map +1 -0
- package/dist/esm/core/security.d.ts +93 -0
- package/dist/esm/core/security.js +315 -0
- package/dist/esm/core/security.js.map +1 -0
- package/dist/esm/definitions.d.ts +639 -0
- package/dist/esm/definitions.js +103 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/live-update/bundle-manager.d.ts +94 -0
- package/dist/esm/live-update/bundle-manager.js +310 -0
- package/dist/esm/live-update/bundle-manager.js.map +1 -0
- package/dist/esm/live-update/certificate-pinning.d.ts +38 -0
- package/dist/esm/live-update/certificate-pinning.js +78 -0
- package/dist/esm/live-update/certificate-pinning.js.map +1 -0
- package/dist/esm/live-update/download-manager.d.ts +67 -0
- package/dist/esm/live-update/download-manager.js +319 -0
- package/dist/esm/live-update/download-manager.js.map +1 -0
- package/dist/esm/live-update/update-manager.d.ts +52 -0
- package/dist/esm/live-update/update-manager.js +294 -0
- package/dist/esm/live-update/update-manager.js.map +1 -0
- package/dist/esm/live-update/version-manager.d.ts +84 -0
- package/dist/esm/live-update/version-manager.js +335 -0
- package/dist/esm/live-update/version-manager.js.map +1 -0
- package/dist/esm/plugin.d.ts +6 -0
- package/dist/esm/plugin.js +283 -0
- package/dist/esm/plugin.js.map +1 -0
- package/dist/esm/security/crypto.d.ts +25 -0
- package/dist/esm/security/crypto.js +70 -0
- package/dist/esm/security/crypto.js.map +1 -0
- package/dist/esm/security/validator.d.ts +60 -0
- package/dist/esm/security/validator.js +143 -0
- package/dist/esm/security/validator.js.map +1 -0
- package/dist/esm/web.d.ts +74 -0
- package/dist/esm/web.js +595 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +2 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.esm.js +2 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/plugin.js +3 -0
- package/dist/plugin.js.map +1 -0
- package/docs/APP_REVIEW_GUIDE.md +768 -0
- package/docs/BUNDLE_SIGNING.md +264 -0
- package/docs/LIVE_UPDATES_GUIDE.md +650 -0
- package/docs/MIGRATION.md +192 -0
- package/docs/NATIVE_UPDATES_GUIDE.md +694 -0
- package/docs/QUICK_START.md +606 -0
- package/docs/README.md +111 -0
- package/docs/REMAINING_FEATURES.md +139 -0
- package/docs/api/app-review-api.md +259 -0
- package/docs/api/app-update-api.md +238 -0
- package/docs/api/events-api.md +451 -0
- package/docs/api/live-update-api.md +265 -0
- package/docs/background-updates.md +392 -0
- package/docs/examples/advanced-scenarios.md +410 -0
- package/docs/examples/basic-usage.md +185 -0
- package/docs/features/app-reviews.md +975 -0
- package/docs/features/app-updates.md +785 -0
- package/docs/features/live-updates.md +633 -0
- package/docs/getting-started/configuration.md +468 -0
- package/docs/getting-started/installation.md +209 -0
- package/docs/getting-started/quick-start.md +379 -0
- package/docs/guides/deployment-guide.md +333 -0
- package/docs/guides/migration-from-codepush.md +142 -0
- package/docs/guides/security-best-practices.md +1057 -0
- package/docs/guides/testing-guide.md +373 -0
- package/docs/production-readiness.md +478 -0
- package/docs/security/certificate-pinning.md +122 -0
- package/docs/server-requirements.md +147 -0
- package/ios/Plugin/AppReview/AppReviewPlugin.swift +158 -0
- package/ios/Plugin/AppUpdate/AppUpdatePlugin.swift +234 -0
- package/ios/Plugin/BackgroundUpdate/BackgroundNotificationManager.swift +329 -0
- package/ios/Plugin/BackgroundUpdate/BackgroundUpdatePlugin.swift +396 -0
- package/ios/Plugin/CapacitorNativeUpdatePlugin.m +45 -0
- package/ios/Plugin/CapacitorNativeUpdatePlugin.swift +190 -0
- package/ios/Plugin/Info.plist +43 -0
- package/ios/Plugin/LiveUpdate/LiveUpdatePlugin.swift +689 -0
- package/ios/Plugin/LiveUpdate/WebViewConfiguration.swift +45 -0
- package/ios/Plugin/Security/SecurityManager.swift +289 -0
- package/package.json +90 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cryptographic utilities for bundle verification
|
|
3
|
+
*/
|
|
4
|
+
export class CryptoUtils {
|
|
5
|
+
/**
|
|
6
|
+
* Calculate SHA-256 checksum of data
|
|
7
|
+
*/
|
|
8
|
+
static async calculateChecksum(data) {
|
|
9
|
+
const encoder = new TextEncoder();
|
|
10
|
+
const dataBuffer = typeof data === 'string' ? encoder.encode(data) : data;
|
|
11
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', dataBuffer);
|
|
12
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
13
|
+
return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Verify signature using public key
|
|
17
|
+
*/
|
|
18
|
+
static async verifySignature(data, signature, publicKey) {
|
|
19
|
+
try {
|
|
20
|
+
// Convert base64 strings to ArrayBuffer
|
|
21
|
+
const signatureBuffer = this.base64ToArrayBuffer(signature);
|
|
22
|
+
const publicKeyBuffer = this.base64ToArrayBuffer(publicKey);
|
|
23
|
+
// Import public key
|
|
24
|
+
const key = await crypto.subtle.importKey('spki', publicKeyBuffer, {
|
|
25
|
+
name: 'RSA-PSS',
|
|
26
|
+
hash: 'SHA-256',
|
|
27
|
+
}, false, ['verify']);
|
|
28
|
+
// Prepare data
|
|
29
|
+
const encoder = new TextEncoder();
|
|
30
|
+
const dataBuffer = typeof data === 'string' ? encoder.encode(data) : data;
|
|
31
|
+
// Verify signature
|
|
32
|
+
return await crypto.subtle.verify({
|
|
33
|
+
name: 'RSA-PSS',
|
|
34
|
+
saltLength: 32,
|
|
35
|
+
}, key, signatureBuffer, dataBuffer);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.error('Signature verification failed:', error);
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Convert base64 string to ArrayBuffer
|
|
44
|
+
*/
|
|
45
|
+
static base64ToArrayBuffer(base64) {
|
|
46
|
+
const binaryString = atob(base64);
|
|
47
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
48
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
49
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
50
|
+
}
|
|
51
|
+
return bytes.buffer;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Generate a random nonce
|
|
55
|
+
*/
|
|
56
|
+
static generateNonce(length = 16) {
|
|
57
|
+
const array = new Uint8Array(length);
|
|
58
|
+
crypto.getRandomValues(array);
|
|
59
|
+
return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join('');
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Validate checksum format
|
|
63
|
+
*/
|
|
64
|
+
static isValidChecksum(checksum, algorithm = 'SHA-256') {
|
|
65
|
+
const expectedLength = algorithm === 'SHA-256' ? 64 : 128;
|
|
66
|
+
const hexPattern = /^[a-f0-9]+$/i;
|
|
67
|
+
return checksum.length === expectedLength && hexPattern.test(checksum);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../../src/security/crypto.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { LiveUpdateConfig } from '../definitions';
|
|
2
|
+
/**
|
|
3
|
+
* Input validation utilities
|
|
4
|
+
*/
|
|
5
|
+
export declare class Validator {
|
|
6
|
+
/**
|
|
7
|
+
* Validate URL
|
|
8
|
+
*/
|
|
9
|
+
static validateUrl(url: string, enforceHttps?: boolean): {
|
|
10
|
+
valid: boolean;
|
|
11
|
+
error?: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Validate version string
|
|
15
|
+
*/
|
|
16
|
+
static validateVersion(version: string): {
|
|
17
|
+
valid: boolean;
|
|
18
|
+
error?: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Compare versions
|
|
22
|
+
*/
|
|
23
|
+
static compareVersions(version1: string, version2: string): number;
|
|
24
|
+
/**
|
|
25
|
+
* Validate bundle ID
|
|
26
|
+
*/
|
|
27
|
+
static validateBundleId(bundleId: string): {
|
|
28
|
+
valid: boolean;
|
|
29
|
+
error?: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Validate file size
|
|
33
|
+
*/
|
|
34
|
+
static validateFileSize(size: number, maxSize: number): {
|
|
35
|
+
valid: boolean;
|
|
36
|
+
error?: string;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Validate configuration
|
|
40
|
+
*/
|
|
41
|
+
static validateLiveUpdateConfig(config: LiveUpdateConfig): {
|
|
42
|
+
valid: boolean;
|
|
43
|
+
errors: string[];
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Validate host
|
|
47
|
+
*/
|
|
48
|
+
static isValidHost(host: string): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Sanitize input string
|
|
51
|
+
*/
|
|
52
|
+
static sanitizeInput(input: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Validate path (prevent directory traversal)
|
|
55
|
+
*/
|
|
56
|
+
static validatePath(path: string): {
|
|
57
|
+
valid: boolean;
|
|
58
|
+
error?: string;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validation utilities
|
|
3
|
+
*/
|
|
4
|
+
export class Validator {
|
|
5
|
+
/**
|
|
6
|
+
* Validate URL
|
|
7
|
+
*/
|
|
8
|
+
static validateUrl(url, enforceHttps = true) {
|
|
9
|
+
try {
|
|
10
|
+
const parsed = new URL(url);
|
|
11
|
+
if (enforceHttps && parsed.protocol !== 'https:') {
|
|
12
|
+
return { valid: false, error: 'URL must use HTTPS protocol' };
|
|
13
|
+
}
|
|
14
|
+
return { valid: true };
|
|
15
|
+
}
|
|
16
|
+
catch (_a) {
|
|
17
|
+
return { valid: false, error: 'Invalid URL format' };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Validate version string
|
|
22
|
+
*/
|
|
23
|
+
static validateVersion(version) {
|
|
24
|
+
// Semantic versioning pattern
|
|
25
|
+
const semverPattern = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
|
26
|
+
if (!semverPattern.test(version)) {
|
|
27
|
+
return { valid: false, error: 'Invalid semantic version format' };
|
|
28
|
+
}
|
|
29
|
+
return { valid: true };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Compare versions
|
|
33
|
+
*/
|
|
34
|
+
static compareVersions(version1, version2) {
|
|
35
|
+
const v1Parts = version1.split('.').map(Number);
|
|
36
|
+
const v2Parts = version2.split('.').map(Number);
|
|
37
|
+
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
|
|
38
|
+
const v1 = v1Parts[i] || 0;
|
|
39
|
+
const v2 = v2Parts[i] || 0;
|
|
40
|
+
if (v1 > v2)
|
|
41
|
+
return 1;
|
|
42
|
+
if (v1 < v2)
|
|
43
|
+
return -1;
|
|
44
|
+
}
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Validate bundle ID
|
|
49
|
+
*/
|
|
50
|
+
static validateBundleId(bundleId) {
|
|
51
|
+
const pattern = /^[a-zA-Z0-9._-]+$/;
|
|
52
|
+
if (!pattern.test(bundleId)) {
|
|
53
|
+
return { valid: false, error: 'Bundle ID contains invalid characters' };
|
|
54
|
+
}
|
|
55
|
+
if (bundleId.length > 255) {
|
|
56
|
+
return { valid: false, error: 'Bundle ID is too long' };
|
|
57
|
+
}
|
|
58
|
+
return { valid: true };
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Validate file size
|
|
62
|
+
*/
|
|
63
|
+
static validateFileSize(size, maxSize) {
|
|
64
|
+
if (size <= 0) {
|
|
65
|
+
return { valid: false, error: 'Invalid file size' };
|
|
66
|
+
}
|
|
67
|
+
if (size > maxSize) {
|
|
68
|
+
const maxSizeMB = Math.round(maxSize / (1024 * 1024));
|
|
69
|
+
return {
|
|
70
|
+
valid: false,
|
|
71
|
+
error: `File size exceeds maximum allowed size of ${maxSizeMB}MB`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return { valid: true };
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Validate configuration
|
|
78
|
+
*/
|
|
79
|
+
static validateLiveUpdateConfig(config) {
|
|
80
|
+
const errors = [];
|
|
81
|
+
// Required fields
|
|
82
|
+
if (!config.appId) {
|
|
83
|
+
errors.push('App ID is required');
|
|
84
|
+
}
|
|
85
|
+
if (!config.serverUrl) {
|
|
86
|
+
errors.push('Server URL is required');
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
const urlValidation = this.validateUrl(config.serverUrl);
|
|
90
|
+
if (!urlValidation.valid) {
|
|
91
|
+
errors.push(urlValidation.error);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Optional fields validation
|
|
95
|
+
if (config.maxBundleSize && config.maxBundleSize <= 0) {
|
|
96
|
+
errors.push('Max bundle size must be positive');
|
|
97
|
+
}
|
|
98
|
+
if (config.checkInterval && config.checkInterval < 60000) {
|
|
99
|
+
errors.push('Check interval must be at least 60 seconds');
|
|
100
|
+
}
|
|
101
|
+
if (config.allowedHosts) {
|
|
102
|
+
for (const host of config.allowedHosts) {
|
|
103
|
+
if (!this.isValidHost(host)) {
|
|
104
|
+
errors.push(`Invalid host: ${host}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
valid: errors.length === 0,
|
|
110
|
+
errors,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Validate host
|
|
115
|
+
*/
|
|
116
|
+
static isValidHost(host) {
|
|
117
|
+
// Basic hostname validation
|
|
118
|
+
const hostPattern = /^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)*[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/;
|
|
119
|
+
return hostPattern.test(host);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Sanitize input string
|
|
123
|
+
*/
|
|
124
|
+
static sanitizeInput(input) {
|
|
125
|
+
// Remove potentially dangerous characters
|
|
126
|
+
return input.replace(/[^\w\s.-]/gi, '');
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Validate path (prevent directory traversal)
|
|
130
|
+
*/
|
|
131
|
+
static validatePath(path) {
|
|
132
|
+
if (path.includes('..') || path.includes('//')) {
|
|
133
|
+
return { valid: false, error: 'Path contains invalid sequences' };
|
|
134
|
+
}
|
|
135
|
+
// Check for absolute paths on web
|
|
136
|
+
if (typeof window !== 'undefined' &&
|
|
137
|
+
(path.startsWith('/') || path.includes(':'))) {
|
|
138
|
+
return { valid: false, error: 'Absolute paths are not allowed' };
|
|
139
|
+
}
|
|
140
|
+
return { valid: true };
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../src/security/validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { WebPlugin } from '@capacitor/core';
|
|
2
|
+
import type { NativeUpdateCombinedPlugin, SecurityInfo, SyncOptions, SyncResult, DownloadOptions, BundleInfo, DeleteOptions, LatestVersion, ValidateOptions, ValidationResult, AppUpdateInfo, OpenAppStoreOptions, ReviewResult, CanRequestReviewResult, BackgroundUpdateConfig, BackgroundUpdateStatus, BackgroundCheckResult, NotificationPreferences, NotificationPermissionStatus } from './definitions';
|
|
3
|
+
import type { PluginInitConfig } from './definitions';
|
|
4
|
+
export declare class NativeUpdateWeb extends WebPlugin implements NativeUpdateCombinedPlugin {
|
|
5
|
+
private config;
|
|
6
|
+
private currentBundle;
|
|
7
|
+
private bundles;
|
|
8
|
+
private lastReviewRequest;
|
|
9
|
+
private launchCount;
|
|
10
|
+
private backgroundUpdateStatus;
|
|
11
|
+
private backgroundCheckInterval;
|
|
12
|
+
constructor();
|
|
13
|
+
/**
|
|
14
|
+
* Configuration and Core Methods
|
|
15
|
+
*/
|
|
16
|
+
configure(options: {
|
|
17
|
+
config: PluginInitConfig;
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
getSecurityInfo(): Promise<SecurityInfo>;
|
|
20
|
+
/**
|
|
21
|
+
* Live Update Methods
|
|
22
|
+
*/
|
|
23
|
+
sync(_options?: SyncOptions): Promise<SyncResult>;
|
|
24
|
+
download(options: DownloadOptions): Promise<BundleInfo>;
|
|
25
|
+
set(bundle: BundleInfo): Promise<void>;
|
|
26
|
+
reload(): Promise<void>;
|
|
27
|
+
reset(): Promise<void>;
|
|
28
|
+
current(): Promise<BundleInfo>;
|
|
29
|
+
list(): Promise<BundleInfo[]>;
|
|
30
|
+
delete(options: DeleteOptions): Promise<void>;
|
|
31
|
+
notifyAppReady(): Promise<void>;
|
|
32
|
+
getLatest(): Promise<LatestVersion>;
|
|
33
|
+
setChannel(channel: string): Promise<void>;
|
|
34
|
+
setUpdateUrl(url: string): Promise<void>;
|
|
35
|
+
validateUpdate(options: ValidateOptions): Promise<ValidationResult>;
|
|
36
|
+
/**
|
|
37
|
+
* App Update Methods
|
|
38
|
+
*/
|
|
39
|
+
getAppUpdateInfo(): Promise<AppUpdateInfo>;
|
|
40
|
+
performImmediateUpdate(): Promise<void>;
|
|
41
|
+
startFlexibleUpdate(): Promise<void>;
|
|
42
|
+
completeFlexibleUpdate(): Promise<void>;
|
|
43
|
+
openAppStore(_options?: OpenAppStoreOptions): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* App Review Methods
|
|
46
|
+
*/
|
|
47
|
+
requestReview(): Promise<ReviewResult>;
|
|
48
|
+
canRequestReview(): Promise<CanRequestReviewResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Background Update Methods
|
|
51
|
+
*/
|
|
52
|
+
enableBackgroundUpdates(config: BackgroundUpdateConfig): Promise<void>;
|
|
53
|
+
disableBackgroundUpdates(): Promise<void>;
|
|
54
|
+
getBackgroundUpdateStatus(): Promise<BackgroundUpdateStatus>;
|
|
55
|
+
scheduleBackgroundCheck(interval: number): Promise<void>;
|
|
56
|
+
triggerBackgroundCheck(): Promise<BackgroundCheckResult>;
|
|
57
|
+
setNotificationPreferences(preferences: NotificationPreferences): Promise<void>;
|
|
58
|
+
getNotificationPermissions(): Promise<NotificationPermissionStatus>;
|
|
59
|
+
requestNotificationPermissions(): Promise<boolean>;
|
|
60
|
+
private sendWebNotification;
|
|
61
|
+
/**
|
|
62
|
+
* Helper Methods
|
|
63
|
+
*/
|
|
64
|
+
private createError;
|
|
65
|
+
private createDefaultBundle;
|
|
66
|
+
private validateChecksum;
|
|
67
|
+
private validateSignature;
|
|
68
|
+
private loadStoredData;
|
|
69
|
+
private saveStoredData;
|
|
70
|
+
private saveConfiguration;
|
|
71
|
+
private getInstallDate;
|
|
72
|
+
private incrementLaunchCount;
|
|
73
|
+
}
|
|
74
|
+
export { NativeUpdateWeb as CapacitorNativeUpdateWeb };
|