Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: upgrade WatermelonDB to 0.27.1 #5865

Merged
merged 20 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
iOS building
  • Loading branch information
diegolmello committed Sep 11, 2024
commit 85389035c4000ffb0992fed59d93c69e1613ba52
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,4 @@
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTViewManager.h>
#import <React/RCTBridgeModule.h>

// Silence warning
#import "../../node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/SupportingFiles/Bridging.h"
#import <React/RCTBridgeModule.h>
10 changes: 5 additions & 5 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1306,12 +1306,12 @@ PODS:
- SDWebImageWebPCoder (0.13.0):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.17)
- simdjson (1.0.0)
- simdjson (3.1.0-wmelon1)
- SocketRocket (0.6.1)
- TOCropViewController (2.6.1)
- WatermelonDB (0.25.5):
- WatermelonDB (0.27.1):
- React
- React-jsi
- simdjson
- Yoga (1.14.0)
- ZXingObjC/Core (3.6.9)
- ZXingObjC/OneD (3.6.9):
Expand Down Expand Up @@ -1773,10 +1773,10 @@ SPEC CHECKSUMS:
RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8
SDWebImage: 750adf017a315a280c60fde706ab1e552a3ae4e9
SDWebImageWebPCoder: af09429398d99d524cae2fe00f6f0f6e491ed102
simdjson: c96317b3a50dff3468a42f586ab7ed22c6ab2fd9
simdjson: e6bfae9ce4bcdc80452d388d593816f1ca2106f3
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
WatermelonDB: 6ae836b52d11281d87187ff2283480e44b111771
WatermelonDB: 842d22ba555425aa9f3ce551239a001200c539bc
Yoga: d17d2cc8105eed528474683b42e2ea310e1daf61
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5

Expand Down
600 changes: 293 additions & 307 deletions ios/RocketChatRN.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

41 changes: 23 additions & 18 deletions ios/SSLPinning/SSLPinning.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import WatermelonDB

@objc(SSLPinning)
final class SSLPinning: NSObject {
private struct Constants {
static let certificateKey = "ssl_pinning_certificate"
static let passwordKey = "ssl_pinning_password"
}

private let database = WatermelonDB.Database(name: "default")
private let database = Database(name: "default")
private let mmkv = MMKV.build()

@objc func setCertificate(_ server: String, _ path: String, _ password: String) {
Expand All @@ -23,21 +21,28 @@ final class SSLPinning: NSObject {
mmkv.set(password, forKey: Constants.passwordKey.appending(server))
}

@objc func migrate() {
let serversQuery = database.query(raw: "select * from servers") as [DBServer]

serversQuery.forEach { server in
guard let clientSSL = mmkv.clientSSL(for: server.url) else {
return
}

setCertificate(
server.url.absoluteString.removeTrailingSlash(),
clientSSL.path,
clientSSL.password
)
}
}
@objc func migrate() {
// Safely unwrap the result of the database query
guard let serversQuery = database.query("SELECT * FROM servers") else {
print("No servers found")
return
}

// Proceed with iterating over the servers
serversQuery.forEach { server in
guard let serverUrlString = server["url"] as? String,
let serverUrl = URL(string: serverUrlString), // Convert String to URL
let clientSSL = mmkv.clientSSL(for: serverUrl) else {
return
}

setCertificate(
serverUrl.absoluteString.removeTrailingSlash(),
clientSSL.path,
clientSSL.password
)
}
}

func getCertificate(server: String) -> (certificate: Data, password: String)? {
guard let certificate = mmkv.data(forKey: Constants.certificateKey.appending(server)) else {
Expand Down
33 changes: 0 additions & 33 deletions ios/Shared/Extensions/WatermelonDB+Extensions.swift

This file was deleted.

159 changes: 118 additions & 41 deletions ios/Shared/RocketChat/Database.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,45 +7,122 @@
//

import Foundation
import WatermelonDB

final class Database {
private let database: WatermelonDB.Database

init(server: String) {
let domain = URL(string: server)?.domain ?? ""
database = .init(name: domain)
}

func readRoomEncryptionKey(rid: String) -> String? {
if let results = try? database.queryRaw("select * from subscriptions where id == ? limit 1", [rid]) {
guard let record = results.next() else {
return nil
}

if let room = record.resultDictionary as? [String: Any] {
if let e2eKey = room["e2e_key"] as? String {
return e2eKey
}
}
}

return nil
}

func readRoomEncrypted(rid: String) -> Bool {
if let results = try? database.queryRaw("select * from subscriptions where id == ? limit 1", [rid]) {
guard let record = results.next() else {
return false
}

if let room = record.resultDictionary as? [String: Any] {
if let encrypted = room["encrypted"] as? Bool {
return encrypted
}
}
}

return false
}
import SQLite3

class Database {
var db: OpaquePointer?

// Initialize the database with a name (which gets converted to a path)
init(name: String) {
if let dbPath = self.getDatabasePath(databaseName: name) {
openDatabase(databasePath: dbPath)
} else {
print("Could not resolve database path for name: \(name)")
}
}

// Initialize the database using the server's domain
init(server: String) {
// Extract domain from server URL
let domain = URL(string: server)?.host ?? ""
if let dbPath = self.getDatabasePath(databaseName: domain) {
openDatabase(databasePath: dbPath)
} else {
print("Could not resolve database path for server: \(server)")
}
}

// Get the path to the SQLite database file based on its name
func getDatabasePath(databaseName: String) -> String? {
let fileManager = FileManager.default
if let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
let dbURL = documentDirectory.appendingPathComponent("\(databaseName).db")
return dbURL.path
}
return nil
}

// Open the SQLite database
func openDatabase(databasePath: String) {
if sqlite3_open(databasePath, &db) == SQLITE_OK {
print("Successfully opened database at \(databasePath)")
} else {
print("Unable to open database.")
}
}

// Close the SQLite database
func closeDatabase() {
if sqlite3_close(db) != SQLITE_OK {
print("Error closing database")
} else {
print("Database closed successfully")
}
db = nil
}

deinit {
closeDatabase()
}

// Execute a query and return results as an array of dictionaries
func query(_ query: String, args: [String] = []) -> [[String: Any]]? {
var statement: OpaquePointer?
var results: [[String: Any]] = []

if sqlite3_prepare_v2(db, query, -1, &statement, nil) == SQLITE_OK {
// Bind arguments to the prepared statement
for (index, arg) in args.enumerated() {
sqlite3_bind_text(statement, Int32(index + 1), arg, -1, nil)
}

// Process each row in the result set
while sqlite3_step(statement) == SQLITE_ROW {
var row: [String: Any] = [:]
for columnIndex in 0..<sqlite3_column_count(statement) {
let columnName = String(cString: sqlite3_column_name(statement, columnIndex))
let columnType = sqlite3_column_type(statement, columnIndex)

// Extract the value based on its type
switch columnType {
case SQLITE_INTEGER:
let value = sqlite3_column_int64(statement, columnIndex)
row[columnName] = Int(value)
case SQLITE_FLOAT:
let value = sqlite3_column_double(statement, columnIndex)
row[columnName] = Double(value)
case SQLITE_TEXT:
let value = String(cString: sqlite3_column_text(statement, columnIndex))
row[columnName] = value
default:
row[columnName] = nil
}
}
results.append(row)
}
} else {
print("Failed to prepare query: \(query)")
}

sqlite3_finalize(statement)
return results
}

// Fetch the encryption key for a room (subscriptions table)
func readRoomEncryptionKey(for roomId: String) -> String? {
let query = "SELECT e2e_key FROM subscriptions WHERE id = ? LIMIT 1"
if let results = self.query(query, args: [roomId]), let firstResult = results.first {
return firstResult["e2e_key"] as? String
}
return nil
}

// Example method to fetch encrypted status for a room
func readRoomEncrypted(for roomId: String) -> Bool {
let query = "SELECT encrypted FROM subscriptions WHERE id = ? LIMIT 1"
if let results = self.query(query, args: [roomId]), let firstResult = results.first {
return firstResult["encrypted"] as? Bool ?? false
}
return false
}
}
2 changes: 1 addition & 1 deletion ios/Shared/RocketChat/Encryption.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ final class Encryption {
self.server = server
self.rid = rid

if let E2EKey = Database(server: server).readRoomEncryptionKey(rid: rid) {
if let E2EKey = Database(server: server).readRoomEncryptionKey(for: rid) {
self.roomKey = decryptRoomKey(E2EKey: E2EKey)
}
}
Expand Down
2 changes: 1 addition & 1 deletion ios/Shared/RocketChat/RocketChat.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ final class RocketChat {
let id = String.random(length: 17)

var msg = message
let encrypted = Database(server: server).readRoomEncrypted(rid: rid)
let encrypted = Database(server: server).readRoomEncrypted(for: rid)
if encrypted {
msg = encryptMessage(rid: rid, id: id, message: message)
}
Expand Down
Loading