mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 20:15:21 +00:00
Hook up onboarding logic
This commit is contained in:
parent
f42e69388e
commit
d4db46aeca
@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/MediumProminentFilledButton"
|
style="@style/MediumProminentFilledButton"
|
||||||
|
android:id="@+id/registerButton"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/medium_button_height"
|
android:layout_height="@dimen/medium_button_height"
|
||||||
android:layout_marginLeft="@dimen/massive_spacing"
|
android:layout_marginLeft="@dimen/massive_spacing"
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
style="@style/SessionIDTextView"
|
style="@style/SessionIDTextView"
|
||||||
|
android:id="@+id/publicKeyTextView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="@dimen/very_large_spacing"
|
android:layout_marginLeft="@dimen/very_large_spacing"
|
||||||
@ -46,8 +47,8 @@
|
|||||||
android:layout_weight="1"/>
|
android:layout_weight="1"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/registerButton"
|
|
||||||
style="@style/MediumProminentFilledButton"
|
style="@style/MediumProminentFilledButton"
|
||||||
|
android:id="@+id/registerButton"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/medium_button_height"
|
android:layout_height="@dimen/medium_button_height"
|
||||||
android:layout_marginLeft="@dimen/massive_spacing"
|
android:layout_marginLeft="@dimen/massive_spacing"
|
||||||
@ -56,6 +57,7 @@
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/MediumProminentOutlineButton"
|
style="@style/MediumProminentOutlineButton"
|
||||||
|
android:id="@+id/copyButton"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/medium_button_height"
|
android:layout_height="@dimen/medium_button_height"
|
||||||
android:layout_marginLeft="@dimen/massive_spacing"
|
android:layout_marginLeft="@dimen/massive_spacing"
|
||||||
@ -64,7 +66,7 @@
|
|||||||
android:text="Copy" />
|
android:text="Copy" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/legalButton"
|
android:id="@+id/termsButton"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/onboarding_button_bottom_offset"
|
android:layout_height="@dimen/onboarding_button_bottom_offset"
|
||||||
android:layout_marginLeft="@dimen/massive_spacing"
|
android:layout_marginLeft="@dimen/massive_spacing"
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
style="@style/MediumProminentFilledButton"
|
style="@style/MediumProminentFilledButton"
|
||||||
|
android:id="@+id/restoreButton"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/medium_button_height"
|
android:layout_height="@dimen/medium_button_height"
|
||||||
android:layout_marginLeft="@dimen/massive_spacing"
|
android:layout_marginLeft="@dimen/massive_spacing"
|
||||||
@ -57,7 +58,7 @@
|
|||||||
android:text="Continue" />
|
android:text="Continue" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/legalButton"
|
android:id="@+id/termsButton"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/onboarding_button_bottom_offset"
|
android:layout_height="@dimen/onboarding_button_bottom_offset"
|
||||||
android:layout_marginLeft="@dimen/massive_spacing"
|
android:layout_marginLeft="@dimen/massive_spacing"
|
||||||
|
@ -1652,4 +1652,10 @@
|
|||||||
<string name="dialog_device_unlink_title">Device unlinked</string>
|
<string name="dialog_device_unlink_title">Device unlinked</string>
|
||||||
<string name="dialog_device_unlink_message">This device has been successfully unlinked</string>
|
<string name="dialog_device_unlink_message">This device has been successfully unlinked</string>
|
||||||
|
|
||||||
|
<!-- Loki -->
|
||||||
|
|
||||||
|
<!-- Session -->
|
||||||
|
<string name="activity_register_public_key_copied_message">Copied to clipboard</string>
|
||||||
|
<!-- Session -->
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -37,6 +37,7 @@ import android.support.v4.content.ContextCompat;
|
|||||||
import android.support.v4.graphics.drawable.DrawableCompat;
|
import android.support.v4.graphics.drawable.DrawableCompat;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
||||||
@ -365,7 +366,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredActionBarA
|
|||||||
.setNeutralButton(R.string.activity_settings_seed_dialog_ok_button_title, null)
|
.setNeutralButton(R.string.activity_settings_seed_dialog_ok_button_title, null)
|
||||||
.show();
|
.show();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Do nothing
|
Log.d("Loki", e.getMessage());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -49,8 +49,8 @@ public class IdentityKeyUtil {
|
|||||||
private static final String IDENTITY_PUBLIC_KEY_CIPHERTEXT_LEGACY_PREF = "pref_identity_public_curve25519";
|
private static final String IDENTITY_PUBLIC_KEY_CIPHERTEXT_LEGACY_PREF = "pref_identity_public_curve25519";
|
||||||
private static final String IDENTITY_PRIVATE_KEY_CIPHERTEXT_LEGACY_PREF = "pref_identity_private_curve25519";
|
private static final String IDENTITY_PRIVATE_KEY_CIPHERTEXT_LEGACY_PREF = "pref_identity_private_curve25519";
|
||||||
|
|
||||||
private static final String IDENTITY_PUBLIC_KEY_PREF = "pref_identity_public_v3";
|
public static final String IDENTITY_PUBLIC_KEY_PREF = "pref_identity_public_v3";
|
||||||
private static final String IDENTITY_PRIVATE_KEY_PREF = "pref_identity_private_v3";
|
public static final String IDENTITY_PRIVATE_KEY_PREF = "pref_identity_private_v3";
|
||||||
|
|
||||||
public static final String lokiSeedKey = "loki_seed";
|
public static final String lokiSeedKey = "loki_seed";
|
||||||
|
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
package org.thoughtcrime.securesms.loki.redesign
|
package org.thoughtcrime.securesms.loki.redesign
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.inputmethod.InputMethodManager
|
||||||
|
import android.widget.Toast
|
||||||
import kotlinx.android.synthetic.main.activity_display_name_v2.*
|
import kotlinx.android.synthetic.main.activity_display_name_v2.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||||
|
import org.thoughtcrime.securesms.ConversationListActivity
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
|
import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
|
import org.whispersystems.signalservice.api.crypto.ProfileCipher
|
||||||
|
|
||||||
class DisplayNameActivity : BaseActionBarActivity() {
|
class DisplayNameActivity : BaseActionBarActivity() {
|
||||||
|
|
||||||
@ -12,10 +20,40 @@ class DisplayNameActivity : BaseActionBarActivity() {
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setUpActionBarSessionLogo()
|
setUpActionBarSessionLogo()
|
||||||
setContentView(R.layout.activity_display_name_v2)
|
setContentView(R.layout.activity_display_name_v2)
|
||||||
|
registerButton.setOnClickListener { register() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
displayNameEditText.requestFocus()
|
displayNameEditText.requestFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun register() {
|
||||||
|
val displayName = displayNameEditText.text.toString().trim()
|
||||||
|
if (displayName.isEmpty()) {
|
||||||
|
return Toast.makeText(this, "Please pick a display name", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
if (!displayName.matches(Regex("[a-zA-Z0-9_]+"))) {
|
||||||
|
return Toast.makeText(this, "Please pick a display name that consists of only a-z, A-Z, 0-9 and _ characters", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
if (displayName.toByteArray().size > ProfileCipher.NAME_PADDED_LENGTH) {
|
||||||
|
return Toast.makeText(this, "Please pick a shorter display name", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
|
inputMethodManager.hideSoftInputFromWindow(displayNameEditText.windowToken, 0)
|
||||||
|
TextSecurePreferences.setProfileName(this, displayName)
|
||||||
|
TextSecurePreferences.setHasSeenWelcomeScreen(this, true)
|
||||||
|
TextSecurePreferences.setPromptedPushRegistration(this, true)
|
||||||
|
val publicChatAPI = ApplicationContext.getInstance(this).lokiPublicChatAPI
|
||||||
|
if (publicChatAPI != null) {
|
||||||
|
// TODO: This won't be necessary anymore when we don't auto-join the Loki Public Chat anymore
|
||||||
|
val application = ApplicationContext.getInstance(this)
|
||||||
|
application.setUpStorageAPIIfNeeded()
|
||||||
|
application.createDefaultPublicChatsIfNeeded()
|
||||||
|
val servers = DatabaseFactory.getLokiThreadDatabase(this).getAllPublicChatServers()
|
||||||
|
servers.forEach { publicChatAPI.setDisplayName(displayName, it) }
|
||||||
|
}
|
||||||
|
startActivity(Intent(this, ConversationListActivity::class.java))
|
||||||
|
finish()
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,32 +1,125 @@
|
|||||||
package org.thoughtcrime.securesms.loki.redesign
|
package org.thoughtcrime.securesms.loki.redesign
|
||||||
|
|
||||||
|
import android.content.ClipData
|
||||||
|
import android.content.ClipboardManager
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import android.text.SpannableStringBuilder
|
import android.text.SpannableStringBuilder
|
||||||
import android.text.style.StyleSpan
|
import android.text.style.StyleSpan
|
||||||
|
import android.widget.Toast
|
||||||
import kotlinx.android.synthetic.main.activity_register.*
|
import kotlinx.android.synthetic.main.activity_register.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||||
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||||
|
import org.thoughtcrime.securesms.database.Address
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
|
import org.thoughtcrime.securesms.database.IdentityDatabase
|
||||||
import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
|
import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
|
||||||
|
import org.thoughtcrime.securesms.util.Base64
|
||||||
|
import org.thoughtcrime.securesms.util.Hex
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
|
import org.whispersystems.curve25519.Curve25519
|
||||||
|
import org.whispersystems.libsignal.ecc.Curve
|
||||||
|
import org.whispersystems.libsignal.ecc.ECKeyPair
|
||||||
|
import org.whispersystems.libsignal.util.KeyHelper
|
||||||
|
import org.whispersystems.signalservice.loki.utilities.hexEncodedPublicKey
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
|
||||||
class RegisterActivity : BaseActionBarActivity() {
|
class RegisterActivity : BaseActionBarActivity() {
|
||||||
|
private var seed: ByteArray? = null
|
||||||
|
private var keyPair: ECKeyPair? = null
|
||||||
|
set(value) { field = value; updatePublicKeyTextView() }
|
||||||
|
|
||||||
|
// region Lifecycle
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_register)
|
setContentView(R.layout.activity_register)
|
||||||
|
setUpLanguageFileDirectory()
|
||||||
setUpActionBarSessionLogo()
|
setUpActionBarSessionLogo()
|
||||||
registerButton.setOnClickListener { register() }
|
registerButton.setOnClickListener { register() }
|
||||||
|
copyButton.setOnClickListener { copyPublicKey() }
|
||||||
val termsExplanation = SpannableStringBuilder("By using this service, you agree to our Terms and Conditions and Privacy Statement")
|
val termsExplanation = SpannableStringBuilder("By using this service, you agree to our Terms and Conditions and Privacy Statement")
|
||||||
termsExplanation.setSpan(StyleSpan(Typeface.BOLD), 40, 60, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
termsExplanation.setSpan(StyleSpan(Typeface.BOLD), 40, 60, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
termsExplanation.setSpan(StyleSpan(Typeface.BOLD), 65, 82, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
termsExplanation.setSpan(StyleSpan(Typeface.BOLD), 65, 82, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
legalButton.text = termsExplanation
|
termsButton.text = termsExplanation
|
||||||
|
termsButton.setOnClickListener { showTerms() }
|
||||||
|
updateKeyPair()
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region General
|
||||||
|
private fun setUpLanguageFileDirectory() {
|
||||||
|
val languages = listOf( "english", "japanese", "portuguese", "spanish" )
|
||||||
|
val directory = File(applicationInfo.dataDir)
|
||||||
|
for (language in languages) {
|
||||||
|
val fileName = "$language.txt"
|
||||||
|
if (directory.list().contains(fileName)) { continue }
|
||||||
|
val inputStream = assets.open("mnemonic/$fileName")
|
||||||
|
val file = File(directory, fileName)
|
||||||
|
val outputStream = FileOutputStream(file)
|
||||||
|
val buffer = ByteArray(1024)
|
||||||
|
while (true) {
|
||||||
|
val count = inputStream.read(buffer)
|
||||||
|
if (count < 0) { break }
|
||||||
|
outputStream.write(buffer, 0, count)
|
||||||
|
}
|
||||||
|
inputStream.close()
|
||||||
|
outputStream.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Updating
|
||||||
|
private fun updateKeyPair() {
|
||||||
|
val seedCandidate = Curve25519.getInstance(Curve25519.BEST).generateSeed(16)
|
||||||
|
try {
|
||||||
|
this.keyPair = Curve.generateKeyPair(seedCandidate + seedCandidate) // Validate the seed
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
return updateKeyPair()
|
||||||
|
}
|
||||||
|
seed = seedCandidate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updatePublicKeyTextView() {
|
||||||
|
publicKeyTextView.text = keyPair!!.hexEncodedPublicKey
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Interaction
|
||||||
private fun register() {
|
private fun register() {
|
||||||
|
IdentityKeyUtil.save(this, IdentityKeyUtil.lokiSeedKey, Hex.toStringCondensed(seed))
|
||||||
|
IdentityKeyUtil.save(this, IdentityKeyUtil.IDENTITY_PUBLIC_KEY_PREF, Base64.encodeBytes(keyPair!!.publicKey.serialize()))
|
||||||
|
IdentityKeyUtil.save(this, IdentityKeyUtil.IDENTITY_PRIVATE_KEY_PREF, Base64.encodeBytes(keyPair!!.privateKey.serialize()))
|
||||||
|
val userHexEncodedPublicKey = keyPair!!.hexEncodedPublicKey
|
||||||
|
val registrationID = KeyHelper.generateRegistrationId(false)
|
||||||
|
TextSecurePreferences.setLocalRegistrationId(this, registrationID)
|
||||||
|
DatabaseFactory.getIdentityDatabase(this).saveIdentity(Address.fromSerialized(userHexEncodedPublicKey),
|
||||||
|
IdentityKeyUtil.getIdentityKeyPair(this).publicKey, IdentityDatabase.VerifiedStatus.VERIFIED,
|
||||||
|
true, System.currentTimeMillis(), true)
|
||||||
|
TextSecurePreferences.setLocalNumber(this, userHexEncodedPublicKey)
|
||||||
val intent = Intent(this, DisplayNameActivity::class.java)
|
val intent = Intent(this, DisplayNameActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun copyPublicKey() {
|
||||||
|
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
val clip = ClipData.newPlainText("Session ID", keyPair!!.hexEncodedPublicKey)
|
||||||
|
clipboard.primaryClip = clip
|
||||||
|
Toast.makeText(this, R.string.activity_register_public_key_copied_message, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showTerms() {
|
||||||
|
try {
|
||||||
|
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/loki-project/loki-messenger-android/blob/master/privacy-policy.md"))
|
||||||
|
startActivity(intent)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Toast.makeText(this, "Couldn't open link", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
}
|
}
|
@ -1,29 +1,111 @@
|
|||||||
package org.thoughtcrime.securesms.loki.redesign
|
package org.thoughtcrime.securesms.loki.redesign
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import android.text.SpannableStringBuilder
|
import android.text.SpannableStringBuilder
|
||||||
import android.text.style.StyleSpan
|
import android.text.style.StyleSpan
|
||||||
|
import android.widget.Toast
|
||||||
import kotlinx.android.synthetic.main.activity_restore.*
|
import kotlinx.android.synthetic.main.activity_restore.*
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||||
|
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||||
|
import org.thoughtcrime.securesms.database.Address
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
|
import org.thoughtcrime.securesms.database.IdentityDatabase
|
||||||
import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
|
import org.thoughtcrime.securesms.loki.redesign.utilities.setUpActionBarSessionLogo
|
||||||
|
import org.thoughtcrime.securesms.util.Base64
|
||||||
|
import org.thoughtcrime.securesms.util.Hex
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||||
|
import org.whispersystems.libsignal.ecc.Curve
|
||||||
|
import org.whispersystems.libsignal.util.KeyHelper
|
||||||
|
import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
|
||||||
|
import org.whispersystems.signalservice.loki.utilities.hexEncodedPublicKey
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
|
||||||
class RestoreActivity : BaseActionBarActivity() {
|
class RestoreActivity : BaseActionBarActivity() {
|
||||||
|
private lateinit var languageFileDirectory: File
|
||||||
|
|
||||||
|
// region Lifecycle
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
setUpLanguageFileDirectory()
|
||||||
setUpActionBarSessionLogo()
|
setUpActionBarSessionLogo()
|
||||||
setContentView(R.layout.activity_restore)
|
setContentView(R.layout.activity_restore)
|
||||||
|
mnemonicEditText.imeOptions = mnemonicEditText.imeOptions or 16777216 // Always use incognito keyboard
|
||||||
|
restoreButton.setOnClickListener { restore() }
|
||||||
val termsExplanation = SpannableStringBuilder("By using this service, you agree to our Terms and Conditions and Privacy Statement")
|
val termsExplanation = SpannableStringBuilder("By using this service, you agree to our Terms and Conditions and Privacy Statement")
|
||||||
termsExplanation.setSpan(StyleSpan(Typeface.BOLD), 40, 60, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
termsExplanation.setSpan(StyleSpan(Typeface.BOLD), 40, 60, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
termsExplanation.setSpan(StyleSpan(Typeface.BOLD), 65, 82, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
termsExplanation.setSpan(StyleSpan(Typeface.BOLD), 65, 82, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||||
legalButton.text = termsExplanation
|
termsButton.text = termsExplanation
|
||||||
|
termsButton.setOnClickListener { showTerms() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
mnemonicEditText.requestFocus()
|
mnemonicEditText.requestFocus()
|
||||||
}
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region General
|
||||||
|
private fun setUpLanguageFileDirectory() {
|
||||||
|
val languages = listOf( "english", "japanese", "portuguese", "spanish" )
|
||||||
|
val directory = File(applicationInfo.dataDir)
|
||||||
|
for (language in languages) {
|
||||||
|
val fileName = "$language.txt"
|
||||||
|
if (directory.list().contains(fileName)) { continue }
|
||||||
|
val inputStream = assets.open("mnemonic/$fileName")
|
||||||
|
val file = File(directory, fileName)
|
||||||
|
val outputStream = FileOutputStream(file)
|
||||||
|
val buffer = ByteArray(1024)
|
||||||
|
while (true) {
|
||||||
|
val count = inputStream.read(buffer)
|
||||||
|
if (count < 0) { break }
|
||||||
|
outputStream.write(buffer, 0, count)
|
||||||
|
}
|
||||||
|
inputStream.close()
|
||||||
|
outputStream.close()
|
||||||
|
}
|
||||||
|
languageFileDirectory = directory
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Interaction
|
||||||
|
private fun restore() {
|
||||||
|
val mnemonic = mnemonicEditText.text.toString()
|
||||||
|
try {
|
||||||
|
val hexEncodedSeed = MnemonicCodec(languageFileDirectory).decode(mnemonic)
|
||||||
|
var seed = Hex.fromStringCondensed(hexEncodedSeed)
|
||||||
|
IdentityKeyUtil.save(this, IdentityKeyUtil.lokiSeedKey, Hex.toStringCondensed(seed))
|
||||||
|
if (seed.size == 16) { seed = seed + seed }
|
||||||
|
val keyPair = Curve.generateKeyPair(seed)
|
||||||
|
IdentityKeyUtil.save(this, IdentityKeyUtil.IDENTITY_PUBLIC_KEY_PREF, Base64.encodeBytes(keyPair.publicKey.serialize()))
|
||||||
|
IdentityKeyUtil.save(this, IdentityKeyUtil.IDENTITY_PRIVATE_KEY_PREF, Base64.encodeBytes(keyPair.privateKey.serialize()))
|
||||||
|
val userHexEncodedPublicKey = keyPair.hexEncodedPublicKey
|
||||||
|
val registrationID = KeyHelper.generateRegistrationId(false)
|
||||||
|
TextSecurePreferences.setLocalRegistrationId(this, registrationID)
|
||||||
|
DatabaseFactory.getIdentityDatabase(this).saveIdentity(Address.fromSerialized(userHexEncodedPublicKey),
|
||||||
|
IdentityKeyUtil.getIdentityKeyPair(this).publicKey, IdentityDatabase.VerifiedStatus.VERIFIED,
|
||||||
|
true, System.currentTimeMillis(), true)
|
||||||
|
TextSecurePreferences.setLocalNumber(this, userHexEncodedPublicKey)
|
||||||
|
val intent = Intent(this, DisplayNameActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
val message = if (e is MnemonicCodec.DecodingError) e.description else MnemonicCodec.DecodingError.Generic.description
|
||||||
|
return Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showTerms() {
|
||||||
|
try {
|
||||||
|
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/loki-project/loki-messenger-android/blob/master/privacy-policy.md"))
|
||||||
|
startActivity(intent)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Toast.makeText(this, "Couldn't open link", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user