diff --git a/composeApp/src/androidMain/kotlin/com/github/familyvault/MainActivity.kt b/composeApp/src/androidMain/kotlin/com/github/familyvault/MainActivity.kt index 9769bce5..20d87162 100644 --- a/composeApp/src/androidMain/kotlin/com/github/familyvault/MainActivity.kt +++ b/composeApp/src/androidMain/kotlin/com/github/familyvault/MainActivity.kt @@ -1,5 +1,6 @@ package com.github.familyvault +import android.content.Context import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.SystemBarStyle @@ -13,14 +14,16 @@ import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.tooling.preview.Preview import com.github.familyvault.services.ImagePickerService import com.github.familyvault.services.DocumentPickerService +import com.github.familyvault.utils.UnpackCerts import org.koin.android.ext.android.get import org.koin.android.ext.koin.androidContext +import java.net.URI class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - - initKoin { + val path = extractCerts(this) + initKoin(path) { androidContext(this@MainActivity) } @@ -60,6 +63,14 @@ class MainActivity : ComponentActivity() { } } } + + private fun extractCerts(context: Context): String { + return URI(context.filesDir.path).resolve("files/cacert.pem").path.also { path -> + println(path) + UnpackCerts.extractCerts(path) + } + } + } @Preview diff --git a/composeApp/src/androidMain/kotlin/com/github/familyvault/utils/UnpackCerts.android.kt b/composeApp/src/androidMain/kotlin/com/github/familyvault/utils/UnpackCerts.android.kt new file mode 100644 index 00000000..c007e2eb --- /dev/null +++ b/composeApp/src/androidMain/kotlin/com/github/familyvault/utils/UnpackCerts.android.kt @@ -0,0 +1,23 @@ +package com.github.familyvault.utils + +import familyvault.composeapp.generated.resources.Res +import kotlinx.coroutines.runBlocking +import java.io.File + + +actual object UnpackCerts { + actual fun extractCerts(toFile: String){ + val file = File(toFile) + if (!file.exists()) { + file.parentFile?.mkdirs() + file.createNewFile() + } + runBlocking { + val data = Res.readBytes("files/cacert.pem") + file.outputStream().apply { + write(data) + close() + } + } + } +} \ No newline at end of file diff --git a/composeApp/src/commonMain/composeResources/files/cacert.pem b/composeApp/src/commonMain/composeResources/files/cacert.pem new file mode 100644 index 00000000..459da489 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/files/cacert.pem @@ -0,0 +1,79 @@ +-----BEGIN CERTIFICATE----- +MIIDlDCCAxmgAwIBAgISBb0srQW366HZMxrgNnjELyjqMAoGCCqGSM49BAMDMDIx +CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF +NTAeFw0yNTA4MTAwMTQzNDBaFw0yNTExMDgwMTQzMzlaMB4xHDAaBgNVBAMMEyou +dGVzdC5zaW1wbGl0by5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmVgCw +doZEIFT+X41iWVfPZRE3oSOMkFChKTKDTJn9jbxFVREKNTiv4pQGjGtI6b+TuLjL +FWXrF/sBsCZKRffUo4ICITCCAh0wDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQG +CCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRAhB/p +jKoNpTyXNEMZC9gOPSeN7TAfBgNVHSMEGDAWgBSfK1/PPCFPnQS37SssxMZwi9LX +DTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly9lNS5pLmxlbmNy +Lm9yZy8wHgYDVR0RBBcwFYITKi50ZXN0LnNpbXBsaXRvLmNvbTATBgNVHSAEDDAK +MAgGBmeBDAECATAuBgNVHR8EJzAlMCOgIaAfhh1odHRwOi8vZTUuYy5sZW5jci5v +cmcvMTA3LmNybDCCAQMGCisGAQQB1nkCBAIEgfQEgfEA7wB2AN3cyjSV1+EWBeeV +MvrHn/g9HFDf2wA6FBJ2Ciysu8gqAAABmJHbYwgAAAQDAEcwRQIhAI6zAccINQel +lTBq86lbJOpSArpx7r3dD2G0sa+/eHBEAiBEuKxhuS22Oc/tfjhQnqDzJ4QNGxmp +ziPNBSeVHpyymAB1AMz7D2qFcQll/pWbU87psnwi6YVcDZeNtql+VMD+TA2wAAAB +mJHbatwAAAQDAEYwRAIgdoeIZiT1iblYSzQ2k3m1mWI0hVWtJOEnnbLt0ccfzPoC +IEq1qIV7gNp/S3z/Bw0cc55MH+tNIaoFt5AfGj4WiYpAMAoGCCqGSM49BAMDA2kA +MGYCMQCegOk9GgOZ2a/eRHOb1WwWB5ga1FzsOkWKVoIZZPCCwU+kRsR5Dj0pu/13 +AWMm9usCMQCr9bpEoJiGhmtr3tlkPSi01ZKNfEn0EJJ9em/DB53WFWJn0ohWBgUz +hpLOAcYTbBM= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEVzCCAj+gAwIBAgIRAIOPbGPOsTmMYgZigxXJ/d4wDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw +WhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg +RW5jcnlwdDELMAkGA1UEAxMCRTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNCzqK +a2GOtu/cX1jnxkJFVKtj9mZhSAouWXW0gQI3ULc/FnncmOyhKJdyIBwsz9V8UiBO +VHhbhBRrwJCuhezAUUE8Wod/Bk3U/mDR+mwt4X2VEIiiCFQPmRpM5uoKrNijgfgw +gfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD +ATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSfK1/PPCFPnQS37SssxMZw +i9LXDTAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB +AQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g +BAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu +Y3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAH3KdNEVCQdqk0LKyuNImTKdRJY1C +2uw2SJajuhqkyGPY8C+zzsufZ+mgnhnq1A2KVQOSykOEnUbx1cy637rBAihx97r+ +bcwbZM6sTDIaEriR/PLk6LKs9Be0uoVxgOKDcpG9svD33J+G9Lcfv1K9luDmSTgG +6XNFIN5vfI5gs/lMPyojEMdIzK9blcl2/1vKxO8WGCcjvsQ1nJ/Pwt8LQZBfOFyV +XP8ubAp/au3dc4EKWG9MO5zcx1qT9+NXRGdVWxGvmBFRAajciMfXME1ZuGmk3/GO +koAM7ZkjZmleyokP1LGzmfJcUd9s7eeu1/9/eg5XlXd/55GtYjAM+C4DG5i7eaNq +cm2F+yxYIPt6cbbtYVNJCGfHWqHEQ4FYStUyFnv8sjyqU8ypgZaNJ9aVcWSICLOI +E1/Qv/7oKsnZCWJ926wU6RqG1OYPGOi1zuABhLw61cuPVDT28nQS/e6z95cJXq0e +K1BcaJ6fJZsmbjRgD5p3mvEf5vdQM7MCEvU0tHbsx2I5mHHJoABHb8KVBgWp/lcX +GWiWaeOyB7RP+OfDtvi2OsapxXiV7vNVs7fMlrRjY1joKaqmmycnBvAq14AEbtyL +sVfOS66B8apkeFX2NY4XPEYV4ZSCe8VHPrdrERk2wILG3T/EGmSIkCYVUMSnjmJd +VQD9F6Na/+zmXCc= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- diff --git a/composeApp/src/commonMain/kotlin/com/github/familyvault/DI.kt b/composeApp/src/commonMain/kotlin/com/github/familyvault/DI.kt index 9b583986..abaadebb 100644 --- a/composeApp/src/commonMain/kotlin/com/github/familyvault/DI.kt +++ b/composeApp/src/commonMain/kotlin/com/github/familyvault/DI.kt @@ -66,9 +66,9 @@ import org.koin.dsl.module expect fun getPlatformModules(): Module -val sharedModules = module { +private fun getSharedModules(certsPath: String) = module { /* PrivMx */ - single { PrivMxClient() }.bind() + single { PrivMxClient(certsPath) }.bind() // Repositories single { FamilyGroupCredentialsRepository(get()) }.bind() @@ -143,11 +143,15 @@ val sharedModules = module { } -fun initKoin(config: KoinAppDeclaration? = null) { +fun initKoin( + certsPath: String = "", + config: KoinAppDeclaration? = null +) { startKoin { config?.invoke(this) modules( - sharedModules, getPlatformModules() + getSharedModules(certsPath), + getPlatformModules() ) } } \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/github/familyvault/backend/client/PrivMxClient.kt b/composeApp/src/commonMain/kotlin/com/github/familyvault/backend/client/PrivMxClient.kt index cd5f91ae..5297b756 100644 --- a/composeApp/src/commonMain/kotlin/com/github/familyvault/backend/client/PrivMxClient.kt +++ b/composeApp/src/commonMain/kotlin/com/github/familyvault/backend/client/PrivMxClient.kt @@ -17,10 +17,8 @@ import com.github.familyvault.backend.utils.ThreadMetaDecoder import com.github.familyvault.backend.utils.ThreadMetaEncoder import com.github.familyvault.models.PublicEncryptedPrivateKeyPair import com.github.familyvault.models.enums.chat.ThreadIconType -import com.github.familyvault.utils.EncryptUtils import com.github.familyvault.utils.EncryptUtils.decryptData import com.github.familyvault.utils.EncryptUtils.encryptData -//import com.github.familyvault.utils.EncryptUtils import com.github.familyvault.utils.mappers.PrivMxMessageToMessageItemMapper import com.github.familyvault.utils.mappers.PrivMxStoreToStoreItemMapper import com.github.familyvault.utils.mappers.PrivMxThreadToThreadItemMapper @@ -38,16 +36,17 @@ import com.simplito.kotlin.privmx_endpoint_extra.storeFileStream.StoreFileStream import com.simplito.kotlin.privmx_endpoint_extra.storeFileStream.StoreFileStreamReader import com.simplito.kotlin.privmx_endpoint_extra.storeFileStream.StoreFileStreamWriter import kotlinx.coroutines.DelicateCoroutinesApi -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking import kotlin.random.Random -class PrivMxClient : IPrivMxClient, AutoCloseable { +class PrivMxClient( + val certsPath: String, +) : IPrivMxClient, AutoCloseable { private val initModules = setOf( Modules.THREAD, Modules.STORE, Modules.INBOX ) private val container: PrivmxEndpointContainer = PrivmxEndpointContainer().also { + it.setCertsPath(certsPath) it.startListening() } private var connection: PrivmxEndpoint? = null diff --git a/composeApp/src/commonMain/kotlin/com/github/familyvault/utils/UnpackCerts.kt b/composeApp/src/commonMain/kotlin/com/github/familyvault/utils/UnpackCerts.kt new file mode 100644 index 00000000..de91047c --- /dev/null +++ b/composeApp/src/commonMain/kotlin/com/github/familyvault/utils/UnpackCerts.kt @@ -0,0 +1,5 @@ +package com.github.familyvault.utils + +expect object UnpackCerts { + fun extractCerts(toFile: String) +} \ No newline at end of file diff --git a/composeApp/src/iosMain/kotlin/com/github/familyvault/utils/UnpackCerts.ios.kt b/composeApp/src/iosMain/kotlin/com/github/familyvault/utils/UnpackCerts.ios.kt new file mode 100644 index 00000000..8360ec72 --- /dev/null +++ b/composeApp/src/iosMain/kotlin/com/github/familyvault/utils/UnpackCerts.ios.kt @@ -0,0 +1,30 @@ +package com.github.familyvault.utils + +import familyvault.composeapp.generated.resources.Res +import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.cinterop.addressOf +import kotlinx.cinterop.usePinned +import kotlinx.coroutines.runBlocking +import platform.Foundation.NSData +import platform.Foundation.NSFileManager +import platform.Foundation.NSURL +import platform.Foundation.dataWithBytes +import kotlin.experimental.ExperimentalObjCName + +@OptIn(ExperimentalObjCName::class) +actual object UnpackCerts { + @OptIn(ExperimentalForeignApi::class) + actual fun extractCerts(toFile: String){ + val url = NSURL.fileURLWithPath(toFile) + runBlocking { + val content = Res.readBytes("files/cacert.pem").asData() + NSFileManager.defaultManager.createDirectoryAtURL(url.URLByDeletingLastPathComponent!!,true,null,null) + NSFileManager.defaultManager.createFileAtPath(url.path!!, content,null) + } + } +} + +@OptIn(ExperimentalForeignApi::class) +fun ByteArray.asData(): NSData = usePinned { + NSData.dataWithBytes(it.addressOf(0), size.toULong()) +} \ No newline at end of file diff --git a/iosApp/iosApp/iOSApp.swift b/iosApp/iosApp/iOSApp.swift index 9de56595..81729e06 100644 --- a/iosApp/iosApp/iOSApp.swift +++ b/iosApp/iosApp/iOSApp.swift @@ -5,7 +5,13 @@ import ComposeApp struct iOSApp: App { init(){ - DIKt.doInitKoin() + do { + let path = try FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("certs/cacert.pem") + UnpackCerts.shared.extractCerts(toFile: path.path) + DIKt.doInitKoin(certsPath: path.path) + }catch let e{ + print(e) + } } var body: some Scene {