2FA codes can now be scanned.

This commit is contained in:
2020-07-07 15:10:36 +02:00
parent 576e16a2fc
commit a6a9d95042
14 changed files with 464 additions and 56 deletions

View File

@@ -1,25 +1,42 @@
package com.github.mondei1.offpass
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.ColorFilter
import android.net.Uri
import android.os.Bundle
import android.text.Editable
import android.util.Log
import android.view.View
import android.view.animation.LinearInterpolator
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import com.google.zxing.integration.android.IntentIntegrator
import com.google.zxing.integration.android.IntentResult
import dev.turingcomplete.kotlinonetimepassword.GoogleAuthenticator
import kotlinx.android.synthetic.main.activity_create.*
import kotlinx.coroutines.*
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
class CreateActivity : AppCompatActivity() {
private var fragment_title: TextInput? = null
private var fragment_username: TextInput? = null
private var schema: QRSchema? = null
private var fa_coroutine: Job? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
fragment_title = TextInput.newInstance("Title", "ENTER TITLE", "30dp")
fragment_username = TextInput.newInstance("Username", "ENTER USERNAME", "30dp")
supportFragmentManager.beginTransaction()
.replace(R.id.title_box, fragment_title!!)
.replace(R.id.username, fragment_username!!)
.commit()
//this.schema = QRSchema(this)
//this.schema!!.decrypted_raw = "%JtuB4O9M42%Gitea|Nicolas|542superGoOD_pW&|klier.nicolas@protonmail.com|\$ul|(\$vb)\$O4|()What's your favorite series%Rick and morty|(2fa)otpauth://totp/OffPass%20Test?secret=d34gfkki5dkd5knifysrpgndd5xb2c7eddwki7ya4pvoisfa5c3ko5pv&issuer=Nicolas%20Klier"
//this.schema!!.parse(this)
@@ -34,6 +51,80 @@ class CreateActivity : AppCompatActivity() {
Log.i("CREATE", "Back got clicked!")
finish()
}
fa_input.isFocusable = false
fa_input.setOnClickListener {
if (fa_coroutine != null) {
if (fa_coroutine!!.isActive) {
// Copy code if already scanend
Toast.makeText(this, "Copied!", Toast.LENGTH_SHORT).show()
val clip: ClipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clip.setPrimaryClip(ClipData.newPlainText("2FA code", fa_input.text))
return@setOnClickListener
}
}
// Open QR-Code scanner
IntentIntegrator(this)
.setPrompt("Scan 2FA secret")
.setBeepEnabled(false)
.setBarcodeImageEnabled(false)
.initiateScan()
}
}
@SuppressLint("SimpleDateFormat", "SetTextI18n")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
var result: IntentResult =
IntentIntegrator.parseActivityResult(requestCode, resultCode, data)
if (result.contents == null) {
Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show()
} else {
// We scanned a 2FA code
if (result.contents.startsWith("otpauth://totp/")) {
fa_progress.visibility = View.VISIBLE
val fa_uri = Uri.parse(result.contents)
val fa_generator = GoogleAuthenticator(base32secret = fa_uri.getQueryParameter("secret").toString())
/*val objAnim: ObjectAnimator = ObjectAnimator.ofInt(fa_progress, "progress")
objAnim.duration = 300
objAnim.interpolator = LinearInterpolator()
objAnim.start()*/
// TODO: There is a bug. When the user changes his current app, this coroutine stops.
fa_coroutine = GlobalScope.launch(Dispatchers.Main) {
while (true) {
fa_input.setText(fa_generator.generate())
var seconds_remaining = CryptoOperations().getRemainingTOTPTime()
Log.i("2FA Generator", "Remaining: $seconds_remaining")
if (seconds_remaining == 0) seconds_remaining = 30
// Change color
if (seconds_remaining >= 15) {
fa_progress.progressTintList = ColorStateList.valueOf(Color.GREEN)
} else if (seconds_remaining < 15 && seconds_remaining >= 8) {
fa_progress.progressTintList = ColorStateList.valueOf(Color.YELLOW)
} else {
fa_progress.progressTintList = ColorStateList.valueOf(Color.RED)
}
fa_progress.progress = seconds_remaining
delay(1000)
}
}
fa_label.text = "${fa_uri.path?.replace("/", "")} (${fa_uri.getQueryParameter("issuer")})"
}
}
}
override fun onStop() {
super.onStop()
fa_coroutine?.cancel(CancellationException("Activity is stopping"))
}
}