mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-30 12:56:17 +00:00
Update pin opt-out strings and behavior.
This commit is contained in:
@@ -164,7 +164,7 @@ public abstract class PassphraseRequiredActivity extends BaseActivity implements
|
||||
}
|
||||
|
||||
private boolean userMustCreateSignalPin() {
|
||||
return !SignalStore.registrationValues().isRegistrationComplete() && !SignalStore.kbsValues().hasPin() && !SignalStore.kbsValues().lastPinCreateFailed();
|
||||
return !SignalStore.registrationValues().isRegistrationComplete() && !SignalStore.kbsValues().hasPin() && !SignalStore.kbsValues().lastPinCreateFailed() && !SignalStore.kbsValues().hasOptedOut();
|
||||
}
|
||||
|
||||
private boolean userMustSetProfileName() {
|
||||
|
||||
@@ -62,6 +62,7 @@ public final class KbsValues extends SignalStoreValues {
|
||||
.putString(LOCK_LOCAL_PIN_HASH, PinHashing.localPinHash(pin))
|
||||
.putString(PIN, pin)
|
||||
.putLong(LAST_CREATE_FAILED_TIMESTAMP, -1)
|
||||
.putBoolean(OPTED_OUT, false)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@@ -144,27 +145,16 @@ public final class KbsValues extends SignalStoreValues {
|
||||
return getLocalPinHash() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should only be called by {@link org.thoughtcrime.securesms.pin.PinState}.
|
||||
*/
|
||||
public synchronized void optIn() {
|
||||
putBoolean(OPTED_OUT, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should only be called by {@link org.thoughtcrime.securesms.pin.PinState}.
|
||||
*/
|
||||
/** Should only be called by {@link org.thoughtcrime.securesms.pin.PinState}. */
|
||||
public synchronized void optOut() {
|
||||
putBoolean(OPTED_OUT, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should only be called by {@link org.thoughtcrime.securesms.pin.PinState}.
|
||||
*/
|
||||
public synchronized void resetMasterKey() {
|
||||
getStore().beginWrite()
|
||||
.remove(MASTER_KEY)
|
||||
.apply();
|
||||
.putBoolean(OPTED_OUT, true)
|
||||
.remove(TOKEN_RESPONSE)
|
||||
.putBlob(MASTER_KEY, MasterKey.createNew(new SecureRandom()).serialize())
|
||||
.remove(LOCK_LOCAL_PIN_HASH)
|
||||
.remove(PIN)
|
||||
.putLong(LAST_CREATE_FAILED_TIMESTAMP, -1)
|
||||
.commit();
|
||||
}
|
||||
|
||||
public synchronized boolean hasOptedOut() {
|
||||
|
||||
@@ -100,7 +100,8 @@ abstract class BaseKbsPinFragment<ViewModel extends BaseKbsPinViewModel> extends
|
||||
@Override
|
||||
public void onPrepareOptionsMenu(@NonNull Menu menu) {
|
||||
if (RegistrationLockUtil.userHasRegistrationLock(requireContext()) ||
|
||||
SignalStore.kbsValues().hasPin())
|
||||
SignalStore.kbsValues().hasPin() ||
|
||||
SignalStore.kbsValues().hasOptedOut())
|
||||
{
|
||||
menu.clear();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ public class LogSectionPin implements LogSection {
|
||||
.append("ReglockV1: ").append(TextSecurePreferences.isV1RegistrationLockEnabled(context)).append("\n")
|
||||
.append("ReglockV2: ").append(SignalStore.kbsValues().isV2RegistrationLockEnabled()).append("\n")
|
||||
.append("Signal PIN: ").append(SignalStore.kbsValues().hasPin()).append("\n")
|
||||
.append("Opted Out: ").append(SignalStore.kbsValues().hasOptedOut()).append("\n")
|
||||
.append("Last Creation Failed: ").append(SignalStore.kbsValues().lastPinCreateFailed()).append("\n")
|
||||
.append("Needs Account Restore: ").append(SignalStore.storageServiceValues().needsAccountRestore()).append("\n")
|
||||
.append("PIN Required at Registration: ").append(SignalStore.registrationValues().pinWasRequiredAtRegistration()).append("\n")
|
||||
|
||||
@@ -34,30 +34,25 @@ public final class PinOptOutDialog {
|
||||
}
|
||||
|
||||
private static void show(@NonNull Context context,
|
||||
boolean skip,
|
||||
boolean isForSkip,
|
||||
@NonNull Runnable onSuccess,
|
||||
@NonNull Runnable onFailed)
|
||||
{
|
||||
AlertDialog dialog = new AlertDialog.Builder(context)
|
||||
.setTitle(R.string.PinOptOutDialog_warning)
|
||||
.setMessage(R.string.PinOptOutDialog_disabling_pins_will_create_a_hidden_high_entropy_pin)
|
||||
.setMessage(R.string.PinOptOutDialog_if_you_disable_the_pin_you_will_lose_all_data)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.PinOptOutDialog_disable_pin, (d, which) -> {
|
||||
d.dismiss();
|
||||
AlertDialog progress = SimpleProgressDialog.show(context);
|
||||
|
||||
SimpleTask.run(() -> {
|
||||
try {
|
||||
if (skip) {
|
||||
PinState.onPinCreationSkipped(context);
|
||||
} else {
|
||||
PinState.onPinOptOut(context);
|
||||
}
|
||||
return true;
|
||||
} catch (IOException | UnauthenticatedResponseException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
if (isForSkip) {
|
||||
PinState.onPinCreationSkipped();
|
||||
} else {
|
||||
PinState.onPinOptOut();
|
||||
}
|
||||
return true;
|
||||
}, success -> {
|
||||
if (success) {
|
||||
onSuccess.run();
|
||||
|
||||
@@ -18,9 +18,7 @@ import org.thoughtcrime.securesms.lock.v2.PinKeyboardType;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.megaphone.Megaphones;
|
||||
import org.thoughtcrime.securesms.registration.service.KeyBackupSystemWrongPinException;
|
||||
import org.thoughtcrime.securesms.util.Hex;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.KbsPinData;
|
||||
import org.whispersystems.signalservice.api.KeyBackupService;
|
||||
@@ -32,6 +30,7 @@ import org.whispersystems.signalservice.internal.contacts.crypto.Unauthenticated
|
||||
import org.whispersystems.signalservice.internal.contacts.entities.TokenResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -156,10 +155,19 @@ public final class PinState {
|
||||
{
|
||||
Log.i(TAG, "onPinChangedOrCreated()");
|
||||
|
||||
boolean isFirstPin = !SignalStore.kbsValues().hasPin() || SignalStore.kbsValues().hasOptedOut();
|
||||
KbsValues kbsValues = SignalStore.kbsValues();
|
||||
boolean isFirstPin = !kbsValues.hasPin() || kbsValues.hasOptedOut();
|
||||
MasterKey masterKey = kbsValues.getOrCreateMasterKey();
|
||||
KeyBackupService keyBackupService = ApplicationDependencies.getKeyBackupService();
|
||||
KeyBackupService.PinChangeSession pinChangeSession = keyBackupService.newPinChangeSession();
|
||||
HashedPin hashedPin = PinHashing.hashPin(pin, pinChangeSession);
|
||||
KbsPinData kbsData = pinChangeSession.setPin(hashedPin, masterKey);
|
||||
|
||||
setPin(context, pin, keyboard);
|
||||
SignalStore.kbsValues().optIn();
|
||||
kbsValues.setKbsMasterKey(kbsData, pin);
|
||||
TextSecurePreferences.clearRegistrationLockV1(context);
|
||||
SignalStore.pinValues().setKeyboardType(keyboard);
|
||||
SignalStore.pinValues().resetPinReminders();
|
||||
ApplicationDependencies.getMegaphoneRepository().markFinished(Megaphones.Event.PINS_FOR_ALL);
|
||||
|
||||
if (isFirstPin) {
|
||||
Log.i(TAG, "First time setting a PIN. Refreshing attributes to set the 'storage' capability.");
|
||||
@@ -185,13 +193,11 @@ public final class PinState {
|
||||
* Invoked when the user has enabled the "PIN opt out" setting.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static synchronized void onPinOptOut(@NonNull Context context)
|
||||
throws IOException, UnauthenticatedResponseException
|
||||
{
|
||||
public static synchronized void onPinOptOut() {
|
||||
Log.i(TAG, "onPinOptOutEnabled()");
|
||||
assertState(State.PIN_WITH_REGISTRATION_LOCK_DISABLED, State.NO_REGISTRATION_LOCK);
|
||||
|
||||
optOutOfPin(context);
|
||||
optOutOfPin();
|
||||
|
||||
updateState(buildInferredStateFromOtherFields());
|
||||
}
|
||||
@@ -200,13 +206,11 @@ public final class PinState {
|
||||
* Invoked when the user has chosen to skip PIN creation.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static synchronized void onPinCreationSkipped(@NonNull Context context)
|
||||
throws IOException, UnauthenticatedResponseException
|
||||
{
|
||||
public static synchronized void onPinCreationSkipped() {
|
||||
Log.i(TAG, "onPinCreationSkipped()");
|
||||
assertState(State.NO_REGISTRATION_LOCK);
|
||||
|
||||
optOutOfPin(context);
|
||||
optOutOfPin();
|
||||
|
||||
updateState(buildInferredStateFromOtherFields());
|
||||
}
|
||||
@@ -295,6 +299,20 @@ public final class PinState {
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private static void bestEffortForcePushStorage() {
|
||||
Optional<JobTracker.JobState> result = ApplicationDependencies.getJobManager().runSynchronously(new StorageForcePushJob(), TimeUnit.SECONDS.toMillis(10));
|
||||
|
||||
if (result.isPresent() && result.get() == JobTracker.JobState.SUCCESS) {
|
||||
Log.i(TAG, "Storage was force-pushed successfully.");
|
||||
} else if (result.isPresent()) {
|
||||
Log.w(TAG, "Storage force-pushed finished, but was not successful. Enqueuing one for later. (Result: " + result.get() + ")");
|
||||
ApplicationDependencies.getJobManager().add(new RefreshAttributesJob());
|
||||
} else {
|
||||
Log.w(TAG, "Storage fore push did not finish in the allotted time. It'll finish later.");
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private static void resetPinRetryCount(@NonNull Context context, @Nullable String pin, @NonNull KbsPinData kbsData) {
|
||||
if (pin == null) {
|
||||
@@ -322,34 +340,13 @@ public final class PinState {
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private static void setPin(@NonNull Context context, @NonNull String pin, @NonNull PinKeyboardType keyboard)
|
||||
throws IOException, UnauthenticatedResponseException
|
||||
{
|
||||
KbsValues kbsValues = SignalStore.kbsValues();
|
||||
MasterKey masterKey = kbsValues.getOrCreateMasterKey();
|
||||
KeyBackupService keyBackupService = ApplicationDependencies.getKeyBackupService();
|
||||
KeyBackupService.PinChangeSession pinChangeSession = keyBackupService.newPinChangeSession();
|
||||
HashedPin hashedPin = PinHashing.hashPin(pin, pinChangeSession);
|
||||
KbsPinData kbsData = pinChangeSession.setPin(hashedPin, masterKey);
|
||||
|
||||
kbsValues.setKbsMasterKey(kbsData, pin);
|
||||
TextSecurePreferences.clearRegistrationLockV1(context);
|
||||
SignalStore.pinValues().setKeyboardType(keyboard);
|
||||
SignalStore.pinValues().resetPinReminders();
|
||||
ApplicationDependencies.getMegaphoneRepository().markFinished(Megaphones.Event.PINS_FOR_ALL);
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private static void optOutOfPin(@NonNull Context context)
|
||||
throws IOException, UnauthenticatedResponseException
|
||||
{
|
||||
SignalStore.kbsValues().resetMasterKey();
|
||||
|
||||
setPin(context, Hex.toStringCondensed(Util.getSecretBytes(32)), PinKeyboardType.ALPHA_NUMERIC);
|
||||
private static void optOutOfPin() {
|
||||
SignalStore.kbsValues().optOut();
|
||||
|
||||
ApplicationDependencies.getJobManager().add(new StorageForcePushJob());
|
||||
ApplicationDependencies.getMegaphoneRepository().markFinished(Megaphones.Event.PINS_FOR_ALL);
|
||||
|
||||
bestEffortRefreshAttributes();
|
||||
bestEffortForcePushStorage();
|
||||
}
|
||||
|
||||
private static @NonNull State assertState(State... allowed) {
|
||||
|
||||
Reference in New Issue
Block a user