@capacitor-community/sqlite 3.4.0 → 3.4.1-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/README.md +7 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +134 -89
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLitePlugin.java +449 -264
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +41 -27
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ExportToJson.java +5 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/ImportFromJson.java +24 -15
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/JsonSQLite.java +4 -1
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/ImportExportJson/UtilsJson.java +23 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/SqliteConfig.java +9 -0
- package/dist/esm/definitions.js +1 -1
- package/dist/esm/definitions.js.map +1 -1
- package/dist/plugin.cjs.js +1 -1
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +1 -1
- package/dist/plugin.js.map +1 -1
- package/electron/dist/plugin.js +228 -176
- package/electron/dist/plugin.js.map +1 -1
- package/ios/Plugin/CapacitorSQLite.swift +150 -109
- package/ios/Plugin/CapacitorSQLitePlugin.swift +17 -10
- package/ios/Plugin/Database.swift +50 -20
- package/ios/Plugin/ImportExportJson/ExportToJson.swift +8 -0
- package/ios/Plugin/ImportExportJson/ImportFromJson.swift +20 -14
- package/ios/Plugin/SqliteConfig.swift +1 -0
- package/ios/Plugin/Utils/UtilsJson.swift +28 -0
- package/package.json +9 -6
package/README.md
CHANGED
|
@@ -28,6 +28,13 @@
|
|
|
28
28
|
|
|
29
29
|
## CAPACITOR 3 (Master)
|
|
30
30
|
|
|
31
|
+
🚨 Since release 3.4.1-1 ->> 🚨
|
|
32
|
+
|
|
33
|
+
- add iosIsEncryption, androidIsEncryption in capacitor.config.ts
|
|
34
|
+
When your application use only `non-encrypted dzatabases` set those parameter to false then iOS KeyChain & Android MasterKey are not defined.
|
|
35
|
+
|
|
36
|
+
🚨 Since release 3.4.1-1 <<- 🚨
|
|
37
|
+
|
|
31
38
|
🚨 Since release 3.4.0-2 ->> 🚨
|
|
32
39
|
|
|
33
40
|
- iOS & Android only
|
package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java
CHANGED
|
@@ -29,6 +29,7 @@ import java.io.IOException;
|
|
|
29
29
|
import java.nio.charset.Charset;
|
|
30
30
|
import java.nio.charset.StandardCharsets;
|
|
31
31
|
import java.security.GeneralSecurityException;
|
|
32
|
+
import java.security.KeyStore;
|
|
32
33
|
import java.util.ArrayList;
|
|
33
34
|
import java.util.Arrays;
|
|
34
35
|
import java.util.Collections;
|
|
@@ -55,14 +56,15 @@ public class CapacitorSQLite {
|
|
|
55
56
|
private UtilsMigrate uMigrate = new UtilsMigrate();
|
|
56
57
|
private UtilsNCDatabase uNCDatabase = new UtilsNCDatabase();
|
|
57
58
|
private UtilsSecret uSecret;
|
|
58
|
-
private SharedPreferences sharedPreferences;
|
|
59
|
+
private SharedPreferences sharedPreferences = null;
|
|
59
60
|
private MasterKey masterKeyAlias;
|
|
60
61
|
private BiometricManager biometricManager;
|
|
61
62
|
private SqliteConfig config;
|
|
63
|
+
private Boolean isEncryption = true;
|
|
62
64
|
private Boolean biometricAuth = false;
|
|
63
65
|
private String biometricTitle;
|
|
64
66
|
private String biometricSubTitle;
|
|
65
|
-
private int VALIDITY_DURATION =
|
|
67
|
+
private int VALIDITY_DURATION = 5;
|
|
66
68
|
private RetHandler rHandler = new RetHandler();
|
|
67
69
|
private PluginCall call;
|
|
68
70
|
|
|
@@ -70,53 +72,63 @@ public class CapacitorSQLite {
|
|
|
70
72
|
this.context = context;
|
|
71
73
|
this.call = call;
|
|
72
74
|
this.config = config;
|
|
75
|
+
this.isEncryption = this.config.getIsEncryption();
|
|
73
76
|
this.biometricAuth = this.config.getBiometricAuth();
|
|
74
77
|
this.biometricTitle = this.config.getBiometricTitle();
|
|
75
78
|
this.biometricSubTitle = this.config.getBiometricSubTitle();
|
|
76
79
|
try {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
80
|
+
if (isEncryption) {
|
|
81
|
+
// create or retrieve masterkey from Android keystore
|
|
82
|
+
// it will be used to encrypt the passphrase for a database
|
|
83
|
+
|
|
84
|
+
if (biometricAuth) {
|
|
85
|
+
biometricManager = BiometricManager.from(this.context);
|
|
86
|
+
BiometricListener listener = new BiometricListener() {
|
|
87
|
+
@Override
|
|
88
|
+
public void onSuccess(BiometricPrompt.AuthenticationResult result) {
|
|
89
|
+
try {
|
|
90
|
+
KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
|
|
91
|
+
ks.load(null);
|
|
92
|
+
Enumeration<String> aliases = ks.aliases();
|
|
93
|
+
if (aliases.hasMoreElements()) {
|
|
94
|
+
masterKeyAlias =
|
|
95
|
+
new MasterKey.Builder(context)
|
|
96
|
+
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
|
|
97
|
+
.setUserAuthenticationRequired(true, VALIDITY_DURATION)
|
|
98
|
+
.build();
|
|
99
|
+
} else {
|
|
100
|
+
masterKeyAlias = new MasterKey.Builder(context).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build();
|
|
101
|
+
}
|
|
102
|
+
setSharedPreferences();
|
|
103
|
+
notifyBiometricEvent(true, null);
|
|
104
|
+
return;
|
|
105
|
+
} catch (Exception e) {
|
|
106
|
+
String input = e.getMessage();
|
|
107
|
+
Log.e("MY_APP_TAG", input);
|
|
108
|
+
// Toast.makeText(context, input, Toast.LENGTH_LONG).show();
|
|
109
|
+
notifyBiometricEvent(false, input);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@Override
|
|
114
|
+
public void onFailed() {
|
|
115
|
+
String input = "Error in authenticating biometric";
|
|
96
116
|
Log.e("MY_APP_TAG", input);
|
|
97
|
-
//
|
|
117
|
+
// Toast.makeText(context, input, Toast.LENGTH_LONG).show();
|
|
98
118
|
notifyBiometricEvent(false, input);
|
|
99
119
|
}
|
|
120
|
+
};
|
|
121
|
+
UtilsBiometric uBiom = new UtilsBiometric(context, biometricManager, listener);
|
|
122
|
+
if (uBiom.checkBiometricIsAvailable()) {
|
|
123
|
+
uBiom.showBiometricDialog(this.biometricTitle, this.biometricSubTitle);
|
|
124
|
+
} else {
|
|
125
|
+
masterKeyAlias = new MasterKey.Builder(context).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build();
|
|
126
|
+
setSharedPreferences();
|
|
100
127
|
}
|
|
101
|
-
|
|
102
|
-
@Override
|
|
103
|
-
public void onFailed() {
|
|
104
|
-
String input = "Error in authenticating biometric";
|
|
105
|
-
Log.e("MY_APP_TAG", input);
|
|
106
|
-
// Toast.makeText(context, input, Toast.LENGTH_LONG).show();
|
|
107
|
-
notifyBiometricEvent(false, input);
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
UtilsBiometric uBiom = new UtilsBiometric(context, biometricManager, listener);
|
|
111
|
-
if (uBiom.checkBiometricIsAvailable()) {
|
|
112
|
-
uBiom.showBiometricDialog(this.biometricTitle, this.biometricSubTitle);
|
|
113
128
|
} else {
|
|
114
129
|
masterKeyAlias = new MasterKey.Builder(context).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build();
|
|
115
130
|
setSharedPreferences();
|
|
116
131
|
}
|
|
117
|
-
} else {
|
|
118
|
-
masterKeyAlias = new MasterKey.Builder(context).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build();
|
|
119
|
-
setSharedPreferences();
|
|
120
132
|
}
|
|
121
133
|
} catch (Exception e) {
|
|
122
134
|
throw new Exception(e.getMessage());
|
|
@@ -162,12 +174,16 @@ public class CapacitorSQLite {
|
|
|
162
174
|
|
|
163
175
|
public Boolean isSecretStored() throws Exception {
|
|
164
176
|
Boolean ret = false;
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
177
|
+
if (isEncryption) {
|
|
178
|
+
try {
|
|
179
|
+
String secret = uSecret.getPassphrase();
|
|
180
|
+
if (secret.length() > 0) ret = true;
|
|
181
|
+
return ret;
|
|
182
|
+
} catch (Exception e) {
|
|
183
|
+
throw new Exception(e.getMessage());
|
|
184
|
+
}
|
|
185
|
+
} else {
|
|
186
|
+
throw new Exception("No Encryption set in capacitor.config");
|
|
171
187
|
}
|
|
172
188
|
}
|
|
173
189
|
|
|
@@ -177,13 +193,17 @@ public class CapacitorSQLite {
|
|
|
177
193
|
* @throws Exception
|
|
178
194
|
*/
|
|
179
195
|
public void setEncryptionSecret(String passphrase) throws Exception {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
196
|
+
if (isEncryption) {
|
|
197
|
+
try {
|
|
198
|
+
// close all connections
|
|
199
|
+
closeAllConnections();
|
|
200
|
+
// set encryption secret
|
|
201
|
+
uSecret.setEncryptionSecret(passphrase);
|
|
202
|
+
} catch (Exception e) {
|
|
203
|
+
throw new Exception(e.getMessage());
|
|
204
|
+
}
|
|
205
|
+
} else {
|
|
206
|
+
throw new Exception("No Encryption set in capacitor.config");
|
|
187
207
|
}
|
|
188
208
|
}
|
|
189
209
|
|
|
@@ -195,47 +215,51 @@ public class CapacitorSQLite {
|
|
|
195
215
|
*/
|
|
196
216
|
public void changeEncryptionSecret(PluginCall call, String passphrase, String oldPassphrase) throws Exception {
|
|
197
217
|
this.call = call;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
218
|
+
if (isEncryption) {
|
|
219
|
+
try {
|
|
220
|
+
// close all connections
|
|
221
|
+
closeAllConnections();
|
|
222
|
+
if (biometricAuth) {
|
|
223
|
+
BiometricListener listener = new BiometricListener() {
|
|
224
|
+
@Override
|
|
225
|
+
public void onSuccess(BiometricPrompt.AuthenticationResult result) {
|
|
226
|
+
try {
|
|
227
|
+
// change encryption secret
|
|
228
|
+
uSecret.changeEncryptionSecret(passphrase, oldPassphrase);
|
|
229
|
+
rHandler.retResult(call, null, null);
|
|
230
|
+
return;
|
|
231
|
+
} catch (Exception e) {
|
|
232
|
+
String input = e.getMessage();
|
|
233
|
+
Log.e("MY_APP_TAG", input);
|
|
234
|
+
Toast.makeText(context, input, Toast.LENGTH_LONG).show();
|
|
235
|
+
rHandler.retResult(call, null, e.getMessage());
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
@Override
|
|
240
|
+
public void onFailed() {
|
|
241
|
+
String input = "Error in authenticating biometric";
|
|
212
242
|
Log.e("MY_APP_TAG", input);
|
|
213
243
|
Toast.makeText(context, input, Toast.LENGTH_LONG).show();
|
|
214
|
-
rHandler.retResult(call, null,
|
|
244
|
+
rHandler.retResult(call, null, input);
|
|
215
245
|
}
|
|
216
|
-
}
|
|
246
|
+
};
|
|
217
247
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
rHandler.retResult(call, null, input);
|
|
248
|
+
UtilsBiometric uBiom = new UtilsBiometric(context, biometricManager, listener);
|
|
249
|
+
if (uBiom.checkBiometricIsAvailable()) {
|
|
250
|
+
uBiom.showBiometricDialog(biometricTitle, biometricSubTitle);
|
|
251
|
+
} else {
|
|
252
|
+
throw new Exception("Biometric features are currently unavailable.");
|
|
224
253
|
}
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
UtilsBiometric uBiom = new UtilsBiometric(context, biometricManager, listener);
|
|
228
|
-
if (uBiom.checkBiometricIsAvailable()) {
|
|
229
|
-
uBiom.showBiometricDialog(biometricTitle, biometricSubTitle);
|
|
230
254
|
} else {
|
|
231
|
-
|
|
255
|
+
// change encryption secret
|
|
256
|
+
uSecret.changeEncryptionSecret(passphrase, oldPassphrase);
|
|
232
257
|
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
uSecret.changeEncryptionSecret(passphrase, oldPassphrase);
|
|
258
|
+
} catch (Exception e) {
|
|
259
|
+
throw new Exception(e.getMessage());
|
|
236
260
|
}
|
|
237
|
-
}
|
|
238
|
-
throw new Exception(
|
|
261
|
+
} else {
|
|
262
|
+
throw new Exception("No Encryption set in capacitor.config");
|
|
239
263
|
}
|
|
240
264
|
}
|
|
241
265
|
|
|
@@ -266,8 +290,20 @@ public class CapacitorSQLite {
|
|
|
266
290
|
String msg = "Connection " + dbName + " already exists";
|
|
267
291
|
throw new Exception(msg);
|
|
268
292
|
}
|
|
293
|
+
if (encrypted && !isEncryption) {
|
|
294
|
+
throw new Exception("Database cannot be encrypted as 'No Encryption' set in capacitor.config");
|
|
295
|
+
}
|
|
269
296
|
try {
|
|
270
|
-
Database db = new Database(
|
|
297
|
+
Database db = new Database(
|
|
298
|
+
context,
|
|
299
|
+
dbName + "SQLite.db",
|
|
300
|
+
encrypted,
|
|
301
|
+
mode,
|
|
302
|
+
version,
|
|
303
|
+
isEncryption,
|
|
304
|
+
vUpgObject,
|
|
305
|
+
sharedPreferences
|
|
306
|
+
);
|
|
271
307
|
if (db != null) {
|
|
272
308
|
dbDict.put(dbName, db);
|
|
273
309
|
return;
|
|
@@ -281,7 +317,7 @@ public class CapacitorSQLite {
|
|
|
281
317
|
}
|
|
282
318
|
|
|
283
319
|
/**
|
|
284
|
-
*
|
|
320
|
+
* CreateNCConnection
|
|
285
321
|
* @param dbPath
|
|
286
322
|
* @param version
|
|
287
323
|
* @throws Exception
|
|
@@ -299,7 +335,16 @@ public class CapacitorSQLite {
|
|
|
299
335
|
String msg = "Database " + dbPath + " does not exist";
|
|
300
336
|
throw new Exception(msg);
|
|
301
337
|
}
|
|
302
|
-
Database db = new Database(
|
|
338
|
+
Database db = new Database(
|
|
339
|
+
context,
|
|
340
|
+
dbPath,
|
|
341
|
+
false,
|
|
342
|
+
"no-encryption",
|
|
343
|
+
version,
|
|
344
|
+
isEncryption,
|
|
345
|
+
new Hashtable<>(),
|
|
346
|
+
sharedPreferences
|
|
347
|
+
);
|
|
303
348
|
if (db != null) {
|
|
304
349
|
dbDict.put(dbPath, db);
|
|
305
350
|
return;
|
|
@@ -874,7 +919,7 @@ public class CapacitorSQLite {
|
|
|
874
919
|
try {
|
|
875
920
|
JSObject jsonObject = new JSObject(parsingData);
|
|
876
921
|
JsonSQLite jsonSQL = new JsonSQLite();
|
|
877
|
-
Boolean isValid = jsonSQL.isJsonSQLite(jsonObject);
|
|
922
|
+
Boolean isValid = jsonSQL.isJsonSQLite(jsonObject, isEncryption);
|
|
878
923
|
return isValid;
|
|
879
924
|
} catch (Exception e) {
|
|
880
925
|
throw new Exception(e.getMessage());
|
|
@@ -885,7 +930,7 @@ public class CapacitorSQLite {
|
|
|
885
930
|
try {
|
|
886
931
|
JSObject jsonObject = new JSObject(parsingData);
|
|
887
932
|
JsonSQLite jsonSQL = new JsonSQLite();
|
|
888
|
-
Boolean isValid = jsonSQL.isJsonSQLite(jsonObject);
|
|
933
|
+
Boolean isValid = jsonSQL.isJsonSQLite(jsonObject, isEncryption);
|
|
889
934
|
if (!isValid) {
|
|
890
935
|
String msg = "Stringify Json Object not Valid";
|
|
891
936
|
throw new Exception(msg);
|
|
@@ -899,7 +944,7 @@ public class CapacitorSQLite {
|
|
|
899
944
|
if (encrypted) {
|
|
900
945
|
inMode = "secret";
|
|
901
946
|
}
|
|
902
|
-
Database db = new Database(context, dbName, encrypted, inMode, dbVersion, new Hashtable<>(), sharedPreferences);
|
|
947
|
+
Database db = new Database(context, dbName, encrypted, inMode, dbVersion, isEncryption, new Hashtable<>(), sharedPreferences);
|
|
903
948
|
db.open();
|
|
904
949
|
if (!db.isOpen()) {
|
|
905
950
|
String msg = dbName + "SQLite.db not opened";
|