@capacitor-community/sqlite 3.3.3-test211 → 3.4.0-2
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 +37 -14
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLite.java +127 -6
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/CapacitorSQLitePlugin.java +95 -13
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/BiometricListener.java +8 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/Database.java +5 -3
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/SqliteConfig.java +32 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsBiometric.java +123 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSQLite.java +19 -0
- package/android/src/main/java/com/getcapacitor/community/database/sqlite/SQLite/UtilsSecret.java +7 -2
- package/dist/esm/definitions.d.ts +7 -0
- package/dist/esm/definitions.js.map +1 -1
- package/electron/dist/plugin.js +14 -21
- package/electron/dist/plugin.js.map +1 -1
- package/ios/Plugin/BiometricIDAuthentication.swift +79 -0
- package/ios/Plugin/CapacitorSQLite.swift +144 -24
- package/ios/Plugin/CapacitorSQLitePlugin.swift +52 -9
- package/ios/Plugin/Database.swift +17 -4
- package/ios/Plugin/Extensions/Notification.Name.swift +6 -2
- package/ios/Plugin/Models/KeychainServices.swift +1 -1
- package/ios/Plugin/SqliteConfig.swift +3 -0
- package/ios/Plugin/Utils/UtilsSQLCipher.swift +5 -4
- package/ios/Plugin/Utils/UtilsSecret.swift +54 -22
- package/package.json +6 -6
- package/CHANGELOG.md +0 -1247
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
//
|
|
2
|
+
// BiometricIDAuthentication.swift
|
|
3
|
+
// CapacitorCommunitySqlite
|
|
4
|
+
//
|
|
5
|
+
// Created by Quéau Jean Pierre on 21/02/2022.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import LocalAuthentication
|
|
10
|
+
|
|
11
|
+
enum BiometricIDAuthenticationError: Error {
|
|
12
|
+
case biometricType(message: String)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
enum BiometricType {
|
|
16
|
+
case none
|
|
17
|
+
case touchID
|
|
18
|
+
case faceID
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class BiometricIDAuthentication {
|
|
22
|
+
var mBiometricTitle: String = ""
|
|
23
|
+
|
|
24
|
+
var biometricTitle: String {
|
|
25
|
+
get {
|
|
26
|
+
return mBiometricTitle
|
|
27
|
+
}
|
|
28
|
+
set(newValue) {
|
|
29
|
+
self.mBiometricTitle = newValue
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
func biometricType() throws -> BiometricType {
|
|
33
|
+
let context = LAContext()
|
|
34
|
+
_ = context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
|
|
35
|
+
switch context.biometryType {
|
|
36
|
+
case .none:
|
|
37
|
+
return .none
|
|
38
|
+
case .touchID:
|
|
39
|
+
return .touchID
|
|
40
|
+
case .faceID:
|
|
41
|
+
return .faceID
|
|
42
|
+
@unknown default:
|
|
43
|
+
let msg = "Biometric type not implemented"
|
|
44
|
+
throw BiometricIDAuthenticationError.biometricType(message: msg)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
func authenticateUser(completion: @escaping (String?) -> Void) {
|
|
48
|
+
let context = LAContext()
|
|
49
|
+
context.touchIDAuthenticationAllowableReuseDuration = 10
|
|
50
|
+
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
|
|
51
|
+
localizedReason: biometricTitle) {(success, evaluateError) in if success {
|
|
52
|
+
DispatchQueue.main.async {
|
|
53
|
+
// User authenticated successfully
|
|
54
|
+
completion(nil)
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
let message: String
|
|
58
|
+
|
|
59
|
+
switch evaluateError {
|
|
60
|
+
case LAError.authenticationFailed?:
|
|
61
|
+
message = "There was a problem verifying your identity."
|
|
62
|
+
case LAError.userCancel?:
|
|
63
|
+
message = "You pressed cancel."
|
|
64
|
+
case LAError.userFallback?:
|
|
65
|
+
message = "You pressed password."
|
|
66
|
+
case LAError.biometryNotAvailable?:
|
|
67
|
+
message = "Face ID/Touch ID is not available."
|
|
68
|
+
case LAError.biometryNotEnrolled?:
|
|
69
|
+
message = "Face ID/Touch ID is not set up."
|
|
70
|
+
case LAError.biometryLockout?:
|
|
71
|
+
message = "Face ID/Touch ID is locked."
|
|
72
|
+
default:
|
|
73
|
+
message = "Face ID/Touch ID may not be configured"
|
|
74
|
+
}
|
|
75
|
+
completion(message)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
|
|
2
4
|
enum CapacitorSQLiteError: Error {
|
|
3
5
|
case failed(message: String)
|
|
4
6
|
}
|
|
@@ -7,17 +9,72 @@ enum CapacitorSQLiteError: Error {
|
|
|
7
9
|
@objc public class CapacitorSQLite: NSObject {
|
|
8
10
|
private var config: SqliteConfig
|
|
9
11
|
private var dbDict: [String: Database] = [:]
|
|
10
|
-
private var databaseLocation: String
|
|
12
|
+
private var databaseLocation: String = "Documents"
|
|
11
13
|
private var initMessage: String = ""
|
|
12
14
|
private var isInit: Bool = false
|
|
15
|
+
private var isBiometricAuth: Bool = false
|
|
16
|
+
private var biometricTitle: String = ""
|
|
17
|
+
private var bioIdAuth: BiometricIDAuthentication =
|
|
18
|
+
BiometricIDAuthentication()
|
|
19
|
+
private var authMessage: String = ""
|
|
20
|
+
private var internalBiometricObserver: Any?
|
|
21
|
+
private var intBioMessage: String = ""
|
|
22
|
+
private var call: CAPPluginCall?
|
|
23
|
+
private var account: String = oldAccount
|
|
24
|
+
private var prefixKeychain: String = ""
|
|
13
25
|
|
|
26
|
+
// swiftlint:disable function_body_length
|
|
27
|
+
// swiftlint:disable cyclomatic_complexity
|
|
14
28
|
init(config: SqliteConfig) {
|
|
15
29
|
self.config = config
|
|
16
|
-
|
|
17
|
-
|
|
30
|
+
super.init()
|
|
31
|
+
if let kcPrefix: String = config.iosKeychainPrefix {
|
|
32
|
+
account = "\(kcPrefix)_\(oldAccount)"
|
|
33
|
+
prefixKeychain = kcPrefix
|
|
34
|
+
}
|
|
35
|
+
if let isBioAuth = config.biometricAuth {
|
|
36
|
+
if isBioAuth == 1 {
|
|
37
|
+
if let bTitle = config.biometricTitle {
|
|
38
|
+
biometricTitle = bTitle
|
|
39
|
+
bioIdAuth.biometricTitle = bTitle
|
|
40
|
+
}
|
|
41
|
+
do {
|
|
42
|
+
let bioType: BiometricType = try
|
|
43
|
+
bioIdAuth.biometricType()
|
|
44
|
+
if bioType == BiometricType.faceID ||
|
|
45
|
+
bioType == BiometricType.touchID {
|
|
46
|
+
isBiometricAuth = true
|
|
47
|
+
isInit = true
|
|
48
|
+
bioIdAuth.authenticateUser { [weak self] message in
|
|
49
|
+
if let message = message {
|
|
50
|
+
self?.notifyBiometricEvents(name: .biometricEvent,
|
|
51
|
+
result: false,
|
|
52
|
+
msg: message)
|
|
53
|
+
} else {
|
|
54
|
+
self?.notifyBiometricEvents(name: .biometricEvent,
|
|
55
|
+
result: true,
|
|
56
|
+
msg: "")
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
self.notifyBiometricEvents(name: .biometricEvent,
|
|
61
|
+
result: false,
|
|
62
|
+
msg: "Biometric not set-up")
|
|
63
|
+
}
|
|
64
|
+
} catch BiometricIDAuthenticationError
|
|
65
|
+
.biometricType(let message) {
|
|
66
|
+
initMessage = message
|
|
67
|
+
} catch let error {
|
|
68
|
+
initMessage = "Init Plugin failed :"
|
|
69
|
+
initMessage.append(" \(error.localizedDescription)")
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if let dbLocation = config.iosDatabaseLocation {
|
|
74
|
+
self.databaseLocation = dbLocation
|
|
18
75
|
// create the databaseLocation directory
|
|
19
76
|
do {
|
|
20
|
-
try UtilsFile.createDatabaseLocation(location:
|
|
77
|
+
try UtilsFile.createDatabaseLocation(location: dbLocation)
|
|
21
78
|
isInit = true
|
|
22
79
|
} catch UtilsFileError.createDatabaseLocationFailed(let message) {
|
|
23
80
|
initMessage = message
|
|
@@ -30,8 +87,9 @@ enum CapacitorSQLiteError: Error {
|
|
|
30
87
|
self.databaseLocation = "Documents"
|
|
31
88
|
isInit = true
|
|
32
89
|
}
|
|
33
|
-
super.init()
|
|
34
90
|
}
|
|
91
|
+
// swiftlint:enable cyclomatic_complexity
|
|
92
|
+
// swiftlint:enable function_body_length
|
|
35
93
|
|
|
36
94
|
// MARK: - Echo
|
|
37
95
|
|
|
@@ -43,12 +101,18 @@ enum CapacitorSQLiteError: Error {
|
|
|
43
101
|
|
|
44
102
|
@objc public func isSecretStored() throws -> NSNumber {
|
|
45
103
|
if isInit {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
104
|
+
do {
|
|
105
|
+
let isSecretExists: Bool = try UtilsSecret.isPassphrase(
|
|
106
|
+
account: account)
|
|
107
|
+
if isSecretExists {
|
|
108
|
+
return 1
|
|
109
|
+
} else {
|
|
110
|
+
return 0
|
|
111
|
+
}
|
|
112
|
+
} catch UtilsSecretError.prefixPassphrase(let message) {
|
|
113
|
+
throw CapacitorSQLiteError.failed(message: message)
|
|
51
114
|
}
|
|
115
|
+
|
|
52
116
|
} else {
|
|
53
117
|
throw CapacitorSQLiteError.failed(message: initMessage)
|
|
54
118
|
}
|
|
@@ -63,7 +127,8 @@ enum CapacitorSQLiteError: Error {
|
|
|
63
127
|
try closeAllConnections()
|
|
64
128
|
// set encryption secret
|
|
65
129
|
try UtilsSecret
|
|
66
|
-
.setEncryptionSecret(
|
|
130
|
+
.setEncryptionSecret(prefix: prefixKeychain,
|
|
131
|
+
passphrase: passphrase,
|
|
67
132
|
databaseLocation: databaseLocation)
|
|
68
133
|
return
|
|
69
134
|
} catch UtilsSecretError.setEncryptionSecret(let message) {
|
|
@@ -78,28 +143,70 @@ enum CapacitorSQLiteError: Error {
|
|
|
78
143
|
|
|
79
144
|
// MARK: - ChangeEncryptionSecret
|
|
80
145
|
|
|
81
|
-
|
|
146
|
+
// swiftlint:disable function_body_length
|
|
147
|
+
@objc public func changeEncryptionSecret(call: CAPPluginCall, passphrase: String,
|
|
82
148
|
oldPassphrase: String) throws {
|
|
83
149
|
if isInit {
|
|
150
|
+
self.call = call
|
|
151
|
+
let retHandler: ReturnHandler = ReturnHandler()
|
|
84
152
|
do {
|
|
85
153
|
// close all connections
|
|
86
154
|
try closeAllConnections()
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
155
|
+
if isBiometricAuth {
|
|
156
|
+
let dbLocation = databaseLocation
|
|
157
|
+
let mPrefixKeychain = prefixKeychain
|
|
158
|
+
bioIdAuth.authenticateUser { [weak self] message in
|
|
159
|
+
if let message = message {
|
|
160
|
+
self?.intBioMessage = message
|
|
161
|
+
return
|
|
162
|
+
} else {
|
|
163
|
+
do {
|
|
164
|
+
try UtilsSecret.changeEncryptionSecret(
|
|
165
|
+
prefix: mPrefixKeychain,
|
|
166
|
+
passphrase: passphrase,
|
|
167
|
+
oldPassphrase: oldPassphrase,
|
|
168
|
+
databaseLocation: dbLocation)
|
|
169
|
+
retHandler.rResult(call: call)
|
|
170
|
+
return
|
|
171
|
+
} catch UtilsSecretError.changeEncryptionSecret(let message) {
|
|
172
|
+
let msg = "ChangeEncryptionSecret: \(message)"
|
|
173
|
+
retHandler.rResult(call: call, message: msg)
|
|
174
|
+
return
|
|
175
|
+
} catch let error {
|
|
176
|
+
retHandler.rResult(
|
|
177
|
+
call: call,
|
|
178
|
+
message: "ChangeEncryptionSecret: \(error.localizedDescription)")
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
} else {
|
|
184
|
+
// set encryption secret
|
|
185
|
+
try UtilsSecret
|
|
186
|
+
.changeEncryptionSecret(prefix: prefixKeychain,
|
|
187
|
+
passphrase: passphrase,
|
|
188
|
+
oldPassphrase: oldPassphrase,
|
|
189
|
+
databaseLocation: databaseLocation)
|
|
190
|
+
retHandler.rResult(call: call)
|
|
191
|
+
return
|
|
192
|
+
}
|
|
93
193
|
} catch UtilsSecretError.changeEncryptionSecret(let message) {
|
|
94
|
-
|
|
194
|
+
let msg = "ChangeEncryptionSecret: \(message)"
|
|
195
|
+
retHandler.rResult(call: call, message: msg)
|
|
196
|
+
return
|
|
95
197
|
} catch let error {
|
|
96
|
-
|
|
198
|
+
retHandler.rResult(
|
|
199
|
+
call: call,
|
|
200
|
+
message: "ChangeEncryptionSecret: \(error.localizedDescription)")
|
|
201
|
+
return
|
|
97
202
|
}
|
|
98
203
|
} else {
|
|
99
204
|
throw CapacitorSQLiteError.failed(message: initMessage)
|
|
100
205
|
}
|
|
101
206
|
|
|
102
207
|
}
|
|
208
|
+
// swiftlint:enable function_body_length
|
|
209
|
+
|
|
103
210
|
// MARK: - getNCDatabasePath
|
|
104
211
|
|
|
105
212
|
@objc public func getNCDatabasePath(_ folderPath: String, dbName: String ) throws -> String {
|
|
@@ -140,7 +247,8 @@ enum CapacitorSQLiteError: Error {
|
|
|
140
247
|
let mDb: Database = try Database(
|
|
141
248
|
databaseLocation: databaseLocation,
|
|
142
249
|
databaseName: databasePath,
|
|
143
|
-
encrypted: false,
|
|
250
|
+
encrypted: false, account: account,
|
|
251
|
+
mode: "no-encryption", version: version,
|
|
144
252
|
vUpgDict: [:])
|
|
145
253
|
dbDict[databasePath] = mDb
|
|
146
254
|
return
|
|
@@ -194,7 +302,8 @@ enum CapacitorSQLiteError: Error {
|
|
|
194
302
|
let mDb: Database = try Database(
|
|
195
303
|
databaseLocation: databaseLocation,
|
|
196
304
|
databaseName: "\(mDbName)SQLite.db",
|
|
197
|
-
encrypted: encrypted,
|
|
305
|
+
encrypted: encrypted, account: account,
|
|
306
|
+
mode: mode, version: version,
|
|
198
307
|
vUpgDict: vUpgDict)
|
|
199
308
|
dbDict[mDbName] = mDb
|
|
200
309
|
return
|
|
@@ -699,8 +808,8 @@ enum CapacitorSQLiteError: Error {
|
|
|
699
808
|
// open the database
|
|
700
809
|
do {
|
|
701
810
|
mDb = try Database(
|
|
702
|
-
databaseLocation: databaseLocation,
|
|
703
|
-
|
|
811
|
+
databaseLocation: databaseLocation, databaseName: dbName,
|
|
812
|
+
encrypted: encrypted, account: account,
|
|
704
813
|
mode: inMode, version: version, vUpgDict: [:])
|
|
705
814
|
try mDb.open()
|
|
706
815
|
} catch DatabaseError.open(let message) {
|
|
@@ -1087,6 +1196,17 @@ enum CapacitorSQLiteError: Error {
|
|
|
1087
1196
|
}
|
|
1088
1197
|
return
|
|
1089
1198
|
}
|
|
1199
|
+
|
|
1200
|
+
func notifyBiometricEvents(name: Notification.Name, result: Bool, msg: String) {
|
|
1201
|
+
var vId: [String: Any] = [:]
|
|
1202
|
+
vId["result"] = result
|
|
1203
|
+
if msg.count > 0 {
|
|
1204
|
+
vId["message"] = msg
|
|
1205
|
+
}
|
|
1206
|
+
NotificationCenter.default.post(name: name, object: nil,
|
|
1207
|
+
userInfo: vId)
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1090
1210
|
}
|
|
1091
1211
|
// swiftlint:enable type_body_length
|
|
1092
1212
|
// swiftlint:enable file_length
|
|
@@ -11,14 +11,23 @@ public class CapacitorSQLitePlugin: CAPPlugin {
|
|
|
11
11
|
private var versionUpgrades: [String: [Int: [String: Any]]] = [:]
|
|
12
12
|
var importObserver: Any?
|
|
13
13
|
var exportObserver: Any?
|
|
14
|
+
var biometricObserver: Any?
|
|
15
|
+
var config: SqliteConfig?
|
|
14
16
|
|
|
15
17
|
override public func load() {
|
|
16
|
-
|
|
18
|
+
let mConfig = sqliteConfig()
|
|
19
|
+
self.config = mConfig
|
|
17
20
|
self.addObserversToNotificationCenter()
|
|
21
|
+
self.implementation = CapacitorSQLite(config: mConfig)
|
|
18
22
|
}
|
|
19
23
|
deinit {
|
|
20
24
|
NotificationCenter.default.removeObserver(importObserver as Any)
|
|
21
25
|
NotificationCenter.default.removeObserver(exportObserver as Any)
|
|
26
|
+
if let biometricAuth = config?.biometricAuth {
|
|
27
|
+
if biometricAuth == 1 {
|
|
28
|
+
NotificationCenter.default.removeObserver(biometricObserver as Any)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
22
31
|
}
|
|
23
32
|
|
|
24
33
|
// MARK: - Echo
|
|
@@ -99,8 +108,7 @@ public class CapacitorSQLitePlugin: CAPPlugin {
|
|
|
99
108
|
return
|
|
100
109
|
}
|
|
101
110
|
do {
|
|
102
|
-
try implementation?.changeEncryptionSecret(passphrase: passphrase, oldPassphrase: oldPassphrase)
|
|
103
|
-
retHandler.rResult(call: call)
|
|
111
|
+
try implementation?.changeEncryptionSecret(call: call, passphrase: passphrase, oldPassphrase: oldPassphrase)
|
|
104
112
|
return
|
|
105
113
|
} catch CapacitorSQLiteError.failed(let message) {
|
|
106
114
|
let msg = "ChangeEncryptionSecret: \(message)"
|
|
@@ -1167,10 +1175,19 @@ public class CapacitorSQLitePlugin: CAPPlugin {
|
|
|
1167
1175
|
|
|
1168
1176
|
@objc func addObserversToNotificationCenter() {
|
|
1169
1177
|
// add Observers
|
|
1170
|
-
importObserver = NotificationCenter.default.addObserver(
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1178
|
+
importObserver = NotificationCenter.default.addObserver(
|
|
1179
|
+
forName: .importJsonProgress, object: nil, queue: nil,
|
|
1180
|
+
using: importJsonProgress)
|
|
1181
|
+
exportObserver = NotificationCenter.default.addObserver(
|
|
1182
|
+
forName: .exportJsonProgress, object: nil, queue: nil,
|
|
1183
|
+
using: exportJsonProgress)
|
|
1184
|
+
if let biometricAuth = config?.biometricAuth {
|
|
1185
|
+
if biometricAuth == 1 {
|
|
1186
|
+
biometricObserver = NotificationCenter.default.addObserver(
|
|
1187
|
+
forName: .biometricEvent, object: nil, queue: nil,
|
|
1188
|
+
using: biometricEvent)
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1174
1191
|
}
|
|
1175
1192
|
|
|
1176
1193
|
// MARK: - Handle Notifications
|
|
@@ -1189,12 +1206,38 @@ public class CapacitorSQLitePlugin: CAPPlugin {
|
|
|
1189
1206
|
return
|
|
1190
1207
|
}
|
|
1191
1208
|
}
|
|
1209
|
+
@objc func biometricEvent(notification: Notification) {
|
|
1210
|
+
guard let info = notification.userInfo as? [String: Any] else { return }
|
|
1211
|
+
DispatchQueue.main.async {
|
|
1212
|
+
self.notifyListeners("sqliteBiometricEvent", data: info, retainUntilConsumed: true)
|
|
1213
|
+
return
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1192
1216
|
private func sqliteConfig() -> SqliteConfig {
|
|
1193
1217
|
var config = SqliteConfig()
|
|
1194
|
-
|
|
1195
|
-
|
|
1218
|
+
config.biometricAuth = 0
|
|
1219
|
+
config.iosKeychainPrefix = ""
|
|
1220
|
+
if let keychainPrefix = getConfigValue("iosKeychainPrefix") as? String {
|
|
1221
|
+
config.iosKeychainPrefix = keychainPrefix
|
|
1222
|
+
}
|
|
1223
|
+
if let iosDatabaseLocation = getConfigValue("iosDatabaseLocation")
|
|
1224
|
+
as? String {
|
|
1196
1225
|
config.iosDatabaseLocation = iosDatabaseLocation
|
|
1197
1226
|
}
|
|
1227
|
+
|
|
1228
|
+
if let iosBiometric = getConfigValue("iosBiometric") as? [String: Any] {
|
|
1229
|
+
if let bioAuth = iosBiometric["biometricAuth"] as? Bool {
|
|
1230
|
+
if bioAuth {
|
|
1231
|
+
config.biometricAuth = 1
|
|
1232
|
+
if let bioTitle = iosBiometric["biometricTitle"] as? String {
|
|
1233
|
+
config.biometricTitle = bioTitle.count > 0
|
|
1234
|
+
? bioTitle
|
|
1235
|
+
: "Biometric login for capacitor sqlite"
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
}
|
|
1198
1241
|
return config
|
|
1199
1242
|
}
|
|
1200
1243
|
|
|
@@ -34,6 +34,7 @@ class Database {
|
|
|
34
34
|
var mode: String
|
|
35
35
|
var vUpgDict: [Int: [String: Any]]
|
|
36
36
|
var databaseLocation: String
|
|
37
|
+
var account: String
|
|
37
38
|
var path: String = ""
|
|
38
39
|
var mDb: OpaquePointer?
|
|
39
40
|
let globalData: GlobalSQLite = GlobalSQLite()
|
|
@@ -43,10 +44,11 @@ class Database {
|
|
|
43
44
|
|
|
44
45
|
// MARK: - Init
|
|
45
46
|
init(databaseLocation: String, databaseName: String, encrypted: Bool,
|
|
46
|
-
mode: String, version: Int,
|
|
47
|
+
account: String, mode: String, version: Int,
|
|
47
48
|
vUpgDict: [Int: [String: Any]] = [:]) throws {
|
|
48
49
|
self.dbVersion = version
|
|
49
50
|
self.encrypted = encrypted
|
|
51
|
+
self.account = account
|
|
50
52
|
self.dbName = databaseName
|
|
51
53
|
self.mode = mode
|
|
52
54
|
self.vUpgDict = vUpgDict
|
|
@@ -94,7 +96,7 @@ class Database {
|
|
|
94
96
|
func open () throws {
|
|
95
97
|
var password: String = ""
|
|
96
98
|
if encrypted && (mode == "secret" || mode == "encryption") {
|
|
97
|
-
password = UtilsSecret.getPassphrase()
|
|
99
|
+
password = UtilsSecret.getPassphrase(account: account)
|
|
98
100
|
}
|
|
99
101
|
if mode == "encryption" {
|
|
100
102
|
do {
|
|
@@ -264,6 +266,16 @@ class Database {
|
|
|
264
266
|
throw DatabaseError.executeSQL(
|
|
265
267
|
message: "Failed in executeSQL : \(msg)" )
|
|
266
268
|
}
|
|
269
|
+
} else {
|
|
270
|
+
if transaction {
|
|
271
|
+
do {
|
|
272
|
+
try UtilsSQLCipher
|
|
273
|
+
.rollbackTransaction(mDB: self)
|
|
274
|
+
} catch UtilsSQLCipherError
|
|
275
|
+
.rollbackTransaction(let message) {
|
|
276
|
+
msg.append(" rollback: \(message)")
|
|
277
|
+
}
|
|
278
|
+
}
|
|
267
279
|
}
|
|
268
280
|
return changes
|
|
269
281
|
}
|
|
@@ -310,7 +322,7 @@ class Database {
|
|
|
310
322
|
msg.append(" \(message)")
|
|
311
323
|
throw DatabaseError.execSet(message: msg )
|
|
312
324
|
}
|
|
313
|
-
if changes
|
|
325
|
+
if changes >= 0 && transaction {
|
|
314
326
|
// commit the transaction
|
|
315
327
|
do {
|
|
316
328
|
try UtilsSQLCipher.commitTransaction(mDB: self)
|
|
@@ -321,6 +333,7 @@ class Database {
|
|
|
321
333
|
}
|
|
322
334
|
return changesDict
|
|
323
335
|
}
|
|
336
|
+
// swiftlint:enable function_body_length
|
|
324
337
|
|
|
325
338
|
// MARK: - RunSQL
|
|
326
339
|
|
|
@@ -368,8 +381,8 @@ class Database {
|
|
|
368
381
|
throw DatabaseError.runSQL(message: msg )
|
|
369
382
|
}
|
|
370
383
|
}
|
|
371
|
-
changes = UtilsSQLCipher.dbChanges(mDB: mDb) - initChanges
|
|
372
384
|
}
|
|
385
|
+
changes = UtilsSQLCipher.dbChanges(mDB: mDb) - initChanges
|
|
373
386
|
let result: [String: Int64] = ["changes": Int64(changes),
|
|
374
387
|
"lastId": lastId]
|
|
375
388
|
return result
|
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
//
|
|
8
8
|
import Foundation
|
|
9
9
|
extension NSNotification.Name {
|
|
10
|
-
static var importJsonProgress: Notification.Name {
|
|
11
|
-
|
|
10
|
+
static var importJsonProgress: Notification.Name {
|
|
11
|
+
return .init(rawValue: "importJsonProgress")}
|
|
12
|
+
static var exportJsonProgress: Notification.Name {
|
|
13
|
+
return .init(rawValue: "exportJsonProgress")}
|
|
14
|
+
static var biometricEvent: Notification.Name {
|
|
15
|
+
return .init(rawValue: "biometricEvent")}
|
|
12
16
|
}
|
|
@@ -52,7 +52,6 @@ class KeychainWrapper {
|
|
|
52
52
|
print("Error converting value to data.")
|
|
53
53
|
throw KeychainWrapperError(type: .badData)
|
|
54
54
|
}
|
|
55
|
-
|
|
56
55
|
// 1
|
|
57
56
|
let query: [String: Any] = [
|
|
58
57
|
// 2
|
|
@@ -91,6 +90,7 @@ class KeychainWrapper {
|
|
|
91
90
|
// 2
|
|
92
91
|
kSecMatchLimit as String: kSecMatchLimitOne,
|
|
93
92
|
kSecReturnAttributes as String: true,
|
|
93
|
+
|
|
94
94
|
// 3
|
|
95
95
|
kSecReturnData as String: true
|
|
96
96
|
]
|
|
@@ -44,7 +44,8 @@ enum State: String {
|
|
|
44
44
|
class UtilsSQLCipher {
|
|
45
45
|
|
|
46
46
|
class func getDatabaseState(databaseLocation: String,
|
|
47
|
-
databaseName: String
|
|
47
|
+
databaseName: String,
|
|
48
|
+
account: String) -> State {
|
|
48
49
|
do {
|
|
49
50
|
let path: String = try UtilsFile
|
|
50
51
|
.getFilePath(databaseLocation: databaseLocation,
|
|
@@ -56,7 +57,7 @@ class UtilsSQLCipher {
|
|
|
56
57
|
} catch UtilsSQLCipherError.openDBNoPassword(let message) {
|
|
57
58
|
if message == "Open" {
|
|
58
59
|
do {
|
|
59
|
-
try openDBStoredPassword(dBPath: path)
|
|
60
|
+
try openDBStoredPassword(dBPath: path, account: account)
|
|
60
61
|
return State.ENCRYPTEDSECRET
|
|
61
62
|
} catch UtilsSQLCipherError.openDBStoredPassword(let message) {
|
|
62
63
|
if message == "Open" {
|
|
@@ -100,9 +101,9 @@ class UtilsSQLCipher {
|
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
}
|
|
103
|
-
class func openDBStoredPassword(dBPath: String) throws {
|
|
104
|
+
class func openDBStoredPassword(dBPath: String, account: String) throws {
|
|
104
105
|
do {
|
|
105
|
-
let password: String = UtilsSecret.getPassphrase()
|
|
106
|
+
let password: String = UtilsSecret.getPassphrase(account: account)
|
|
106
107
|
let oDb: OpaquePointer? = try openOrCreateDatabase(
|
|
107
108
|
filename: dBPath, password: password, readonly: true)
|
|
108
109
|
try close(oDB: oDb)
|