diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f98f6750d8..60bbad9dbf 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -441,6 +441,11 @@
android:windowSoftInputMode="stateUnchanged"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
+
diff --git a/res/layout/activity_key_pair.xml b/res/layout/activity_key_pair.xml
new file mode 100644
index 0000000000..a5a09e996d
--- /dev/null
+++ b/res/layout/activity_key_pair.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e8af9651d8..01c67e9737 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1518,8 +1518,14 @@
+
+
Create Your Loki Messenger Account
Enter a name to be shown to your contacts
Next
+
+ Create Your Loki Messenger Account
+ Please save the seed below in a safe location. It can be used to restore your account if you lose access, or to migrate to a new device.
+ Register
diff --git a/src/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java b/src/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java
index b1bf51bab9..901b607252 100644
--- a/src/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java
+++ b/src/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java
@@ -12,14 +12,11 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.libsignal.IdentityKeyPair;
-import org.whispersystems.libsignal.state.PreKeyRecord;
-import org.whispersystems.libsignal.state.SignedPreKeyRecord;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import java.io.IOException;
-import java.util.List;
import javax.inject.Inject;
@@ -60,21 +57,19 @@ public class RefreshPreKeysJob extends BaseJob implements InjectableType {
if (!TextSecurePreferences.isPushRegistered(context)) return;
if (TextSecurePreferences.isSignedPreKeyRegistered(context)) {
- Log.i(TAG, "Already have a signed pre key set");
+ Log.i(TAG, "Already have a signed pre key registered.");
return;
}
Log.i(TAG, "Registering new signed pre key...");
- IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context);
+ IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context);
PreKeyUtil.generateSignedPreKey(context, identityKey, true);
TextSecurePreferences.setSignedPreKeyRegistered(context, true);
- ApplicationContext.getInstance(context)
- .getJobManager()
- .add(new CleanPreKeysJob());
+ ApplicationContext.getInstance(context).getJobManager().add(new CleanPreKeysJob());
}
- /* Loki - Original Code
+ /* Loki - Original code
@Override
public void onRun() throws IOException {
if (!TextSecurePreferences.isPushRegistered(context)) return;
@@ -101,7 +96,7 @@ public class RefreshPreKeysJob extends BaseJob implements InjectableType {
.getJobManager()
.add(new CleanPreKeysJob());
}
- */
+ */
@Override
public boolean onShouldRetry(Exception exception) {
diff --git a/src/org/thoughtcrime/securesms/loki/AccountDetailsActivity.kt b/src/org/thoughtcrime/securesms/loki/AccountDetailsActivity.kt
index 3bd1d154b7..4d5af4794c 100644
--- a/src/org/thoughtcrime/securesms/loki/AccountDetailsActivity.kt
+++ b/src/org/thoughtcrime/securesms/loki/AccountDetailsActivity.kt
@@ -1,13 +1,26 @@
package org.thoughtcrime.securesms.loki
+import android.content.Intent
import android.os.Bundle
+import kotlinx.android.synthetic.main.activity_account_details.*
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.R
+import org.whispersystems.signalservice.api.crypto.ProfileCipher
class AccountDetailsActivity : BaseActionBarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_account_details)
+ nextButton.setOnClickListener { continueIfPossible() }
+ }
+
+ private fun continueIfPossible() {
+ val uncheckedName = nameEditText.text.toString()
+ val name = if (uncheckedName.isNotEmpty()) { uncheckedName.trim() } else { null }
+ if (name != null && name.toByteArray().size > ProfileCipher.NAME_PADDED_LENGTH) {
+ return nameEditText.input.setError("Too Long")
+ }
+ startActivity(Intent(this, KeyPairActivity::class.java))
}
}
\ No newline at end of file
diff --git a/src/org/thoughtcrime/securesms/loki/KeyPairActivity.kt b/src/org/thoughtcrime/securesms/loki/KeyPairActivity.kt
new file mode 100644
index 0000000000..e87f1a30f5
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/loki/KeyPairActivity.kt
@@ -0,0 +1,67 @@
+package org.thoughtcrime.securesms.loki
+
+import android.os.Bundle
+import kotlinx.android.synthetic.main.activity_key_pair.*
+import org.thoughtcrime.securesms.BaseActionBarActivity
+import org.thoughtcrime.securesms.R
+import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
+import org.whispersystems.libsignal.IdentityKeyPair
+import org.whispersystems.signalservice.loki.crypto.MnemonicCodec
+import java.io.File
+import java.io.FileOutputStream
+
+class KeyPairActivity : BaseActionBarActivity() {
+ private lateinit var languageFileDirectory: File
+ private var keyPair: IdentityKeyPair? = null
+ set(newValue) { field = newValue; updateMnemonic() }
+ private var mnemonic: String? = null
+ set(newValue) { field = newValue; updateMnemonicTextView() }
+
+ // region Lifecycle
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_key_pair)
+ setUpLanguageFileDirectory()
+ 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()
+ }
+ languageFileDirectory = directory
+ }
+ // endregion
+
+ // region Updating
+ private fun updateKeyPair() {
+ IdentityKeyUtil.generateIdentityKeys(this)
+ keyPair = IdentityKeyUtil.getIdentityKeyPair(this)
+ }
+
+ private fun updateMnemonic() {
+ val hexEncodedPrivateKey = ("67982927" + "aaaabbbb" + "8926bfgd" + "0bfbba33" + "67982927" + "aaaabbbb" + "8926bfgd" + "0bfbba33").toUpperCase() // Hex.toString(keyPair!!.privateKey.serialize())
+ mnemonic = MnemonicCodec(languageFileDirectory).encode(hexEncodedPrivateKey)
+ }
+
+ private fun updateMnemonicTextView() {
+ mnemonicTextView.text = mnemonic!!
+ }
+ // endregion
+}
\ No newline at end of file