diff --git a/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/Main.kt b/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/Main.kt index 24784e8ba8a1a0c2b205a4ed2282a68950c36e82..cb2abda0e79e9e6fb4f6ea9125b93a18f0bb2d9f 100644 --- a/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/Main.kt +++ b/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/Main.kt @@ -8,7 +8,10 @@ import com.github.ajalt.clikt.parameters.options.flag import com.github.ajalt.clikt.parameters.options.option import org.briarproject.mailbox.core.CoreEagerSingletons import org.briarproject.mailbox.core.JavaCliEagerSingletons +import org.briarproject.mailbox.core.db.Database import org.briarproject.mailbox.core.lifecycle.LifecycleManager +import org.briarproject.mailbox.core.setup.QrCodeEncoder +import org.briarproject.mailbox.core.setup.SetupManager import org.slf4j.LoggerFactory.getLogger import java.util.logging.Level.ALL import java.util.logging.Level.INFO @@ -38,6 +41,15 @@ class Main : CliktCommand( @Inject internal lateinit var lifecycleManager: LifecycleManager + @Inject + internal lateinit var db: Database + + @Inject + internal lateinit var setupManager: SetupManager + + @Inject + internal lateinit var qrCodeEncoder: QrCodeEncoder + override fun run() { // logging val levelSlf4j = if (debug) Level.DEBUG else when (verbosity) { @@ -68,6 +80,18 @@ class Main : CliktCommand( lifecycleManager.startServices() lifecycleManager.waitForStartup() + + // TODO this is obviously not the final code, just a stub to get us started + val setupTokenExists = db.transactionWithResult(true) { txn -> + setupManager.getSetupToken(txn) != null + } + val ownerTokenExists = db.transactionWithResult(true) { txn -> + setupManager.getOwnerToken(txn) != null + } + if (!setupTokenExists && !ownerTokenExists) setupManager.restartSetup() + qrCodeEncoder.getQrCodeBitMatrix()?.let { + println(QrCodeRenderer.getQrString(it)) + } } } diff --git a/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/QrCodeRenderer.kt b/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/QrCodeRenderer.kt new file mode 100644 index 0000000000000000000000000000000000000000..c96f6123b021fb36a270a23d9d587e5f22bf7e5e --- /dev/null +++ b/mailbox-cli/src/main/java/org/briarproject/mailbox/cli/QrCodeRenderer.kt @@ -0,0 +1,20 @@ +package org.briarproject.mailbox.cli + +import com.google.zxing.common.BitMatrix + +object QrCodeRenderer { + + private const val SET = "██" + private const val UNSET = " " + + internal fun getQrString(bitMatrix: BitMatrix): String = StringBuilder().apply { + append(System.lineSeparator()) + for (y in 0 until bitMatrix.height) { + for (x in 0 until bitMatrix.width) { + append(if (bitMatrix[x, y]) SET else UNSET) + } + append(System.lineSeparator()) + } + }.toString() + +} diff --git a/mailbox-core/build.gradle b/mailbox-core/build.gradle index 43bc03c273d58bb1bc2f4c32dc23e030d7016e00..7d4568cd69a806bef811c46100ca126db6a57f0c 100644 --- a/mailbox-core/build.gradle +++ b/mailbox-core/build.gradle @@ -30,6 +30,8 @@ dependencies { // Base 32 implementation 'dev.keiji.rfc4648:rfc4648:1.0.0' + // QrCode + implementation 'com.google.zxing:core:3.4.1' testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version" diff --git a/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/QrCodeEncoder.kt b/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/QrCodeEncoder.kt index 4857bcc1d1158e0bd55eaf29adee76d3e5fb021e..334482d378562efaa5e64ce376ae791b75c8933c 100644 --- a/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/QrCodeEncoder.kt +++ b/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/QrCodeEncoder.kt @@ -1,5 +1,8 @@ package org.briarproject.mailbox.core.setup +import com.google.zxing.BarcodeFormat.QR_CODE +import com.google.zxing.common.BitMatrix +import com.google.zxing.qrcode.QRCodeWriter import dev.keiji.util.Base32 import org.briarproject.mailbox.core.db.Database import org.briarproject.mailbox.core.db.DbException @@ -8,6 +11,7 @@ import org.briarproject.mailbox.core.util.LogUtils.logException import org.briarproject.mailbox.core.util.StringUtils.fromHexString import org.slf4j.LoggerFactory.getLogger import java.nio.ByteBuffer +import java.nio.charset.Charset import javax.inject.Inject private const val VERSION = 32 @@ -19,7 +23,14 @@ class QrCodeEncoder @Inject constructor( private val torPlugin: TorPlugin, ) { - fun getQrCodeBytes(): ByteArray? { + fun getQrCodeBitMatrix(edgeLen: Int = 0): BitMatrix? { + val bytes = getQrCodeBytes() ?: return null + // Use ISO 8859-1 to encode bytes directly as a string + val content = String(bytes, Charset.forName("ISO-8859-1")) + return QRCodeWriter().encode(content, QR_CODE, edgeLen, edgeLen) + } + + private fun getQrCodeBytes(): ByteArray? { val hiddenServiceBytes = getHiddenServiceBytes() ?: return null val setupTokenBytes = getSetupTokenBytes() ?: return null return ByteBuffer.allocate(65)