use of co.krypt.krypton.me.MeStorage in project krypton-android by kryptco.
the class OnboardingVerifyEmailFragment method onCreateView.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_teams_onboarding_verify_email, container, false);
Button cancelButton = rootView.findViewById(R.id.cancelButton);
cancelButton.setOnClickListener(v -> {
progress.reset();
getActivity().finish();
});
ProgressBar progressBar = rootView.findViewById(R.id.progressBar);
progressBar.setAlpha(0);
Button changeButton = rootView.findViewById(R.id.changeButton);
changeButton.setEnabled(false);
Button resendButton = rootView.findViewById(R.id.resendButton);
resendButton.setEnabled(false);
ConstraintLayout checkYourEmailContainer = rootView.findViewById(R.id.checkYourEmailContainer);
checkYourEmailContainer.setAlpha(0);
AppCompatTextView teamName = rootView.findViewById(R.id.teamName);
teamName.setText(progress.getTeamOnboardingData().name);
emailEditText = rootView.findViewById(R.id.profileEmail);
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
Runnable focusEmail = () -> {
emailEditText.setEnabled(true);
emailEditText.requestFocus();
if (imm != null) {
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
progressBar.animate().alpha(0).setDuration(500).start();
};
focusEmail.run();
Runnable requestEmailChallenge = () -> {
emailEditText.setEnabled(false);
emailEditText.clearFocus();
if (imm != null) {
imm.hideSoftInputFromWindow(emailEditText.getWindowToken(), 0);
}
progressBar.animate().alpha(1).setDuration(1000).start();
final String email = emailEditText.getEditableText().toString();
new Thread(() -> {
MeStorage meStorage = Silo.shared(getContext()).meStorage();
try {
meStorage.setEmail(email);
} catch (CryptoException e) {
Error.shortToast(getContext(), "Failed to set email: " + e.getMessage());
e.printStackTrace();
return;
}
Profile me = meStorage.load();
progress.updateTeamData((s, d) -> {
if (s.equals(CreateStage.VERIFY_EMAIL) || s.equals(CreateStage.EMAIL_CHALLENGE_SENT)) {
d.creatorProfile = me;
Log.i(TAG, "requesting email challenge...");
try {
final Sigchain.NativeResult<JsonObject> result = TeamDataProvider.requestEmailChallenge(getContext(), email);
emailEditText.post(() -> {
if (result.success != null) {
Log.i(TAG, "request email challenge success");
progressBar.animate().alpha(0).setDuration(500).start();
checkYourEmailContainer.animate().alpha(1).setDuration(1000).start();
changeButton.setEnabled(true);
resendButton.setEnabled(true);
} else {
Log.i(TAG, "request email challenge failure: " + result.error);
Error.shortToast(getContext(), "Error sending email: " + result.error);
focusEmail.run();
}
});
if (result.success != null) {
return CreateStage.EMAIL_CHALLENGE_SENT;
} else {
return s;
}
} catch (Native.NotLinked notLinked) {
notLinked.printStackTrace();
}
}
return s;
});
}).start();
};
emailEditText.setOnEditorActionListener((v, i, ev) -> {
requestEmailChallenge.run();
return false;
});
emailEditText.setOnFocusChangeListener((view, b) -> {
if (view.isEnabled() && !b) {
requestEmailChallenge.run();
}
});
resendButton.setOnClickListener(v -> {
requestEmailChallenge.run();
});
changeButton.setOnClickListener(v -> {
focusEmail.run();
});
Button submitButton = rootView.findViewById(R.id.submitButton);
submitButton.setEnabled(false);
submitButton.setAlpha(0);
submitButton.setOnClickListener(v -> {
FragmentManager fragmentManager = getFragmentManager();
if (fragmentManager != null) {
fragmentManager.beginTransaction().setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_right, R.anim.exit_to_left).replace(R.id.fragment_teams, new OnboardingLoadTeamFragment()).commitNowAllowingStateLoss();
}
});
EventBus.getDefault().register(this);
EventBus.getDefault().post(new IdentityService.GetProfile(getContext()));
return rootView;
}
use of co.krypt.krypton.me.MeStorage in project krypton-android by kryptco.
the class VerifyEmailFragment method onCreateView.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_teams_onboarding_verify_email, container, false);
Button cancelButton = rootView.findViewById(R.id.cancelButton);
cancelButton.setOnClickListener(v -> {
progress.resetAndDeleteTeam(v.getContext());
getActivity().finish();
});
ProgressBar progressBar = rootView.findViewById(R.id.progressBar);
progressBar.setAlpha(0);
Button submitButton = rootView.findViewById(R.id.submitButton);
Button changeButton = rootView.findViewById(R.id.changeButton);
Button resendButton = rootView.findViewById(R.id.resendButton);
AppCompatTextView checkYourEmailText = rootView.findViewById(R.id.checkYourEmailText);
AppCompatTextView checkYourEmailSubtext = rootView.findViewById(R.id.checkYourEmailSubtext);
AppCompatEditText emailEditText = rootView.findViewById(R.id.profileEmail);
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
Runnable onSubmitUI = () -> {
emailEditText.setEnabled(false);
emailEditText.clearFocus();
if (imm != null) {
imm.hideSoftInputFromWindow(emailEditText.getWindowToken(), 0);
}
progressBar.animate().alpha(1).setDuration(1000).start();
submitButton.setEnabled(false);
submitButton.animate().alpha(0).setDuration(500).start();
checkYourEmailSubtext.animate().alpha(0).setDuration(500).start();
checkYourEmailText.animate().alpha(0).setDuration(500).start();
};
Runnable onEditUI = () -> {
emailEditText.setEnabled(true);
submitButton.animate().alpha(1).setDuration(500).start();
changeButton.animate().alpha(0).setDuration(500).start();
resendButton.animate().alpha(0).setDuration(500).start();
submitButton.setEnabled(true);
changeButton.setEnabled(false);
resendButton.setEnabled(false);
checkYourEmailSubtext.animate().alpha(0).setDuration(500).start();
checkYourEmailText.animate().alpha(0).setDuration(500).start();
progressBar.animate().alpha(0).setDuration(500).start();
};
Runnable onSuccessUI = () -> {
progressBar.animate().alpha(0).setDuration(500).start();
changeButton.animate().alpha(1).setDuration(1000).start();
resendButton.animate().alpha(1).setDuration(1000).start();
submitButton.animate().alpha(0).setDuration(500).start();
changeButton.setEnabled(true);
resendButton.setEnabled(true);
checkYourEmailSubtext.animate().alpha(1).setDuration(500).start();
checkYourEmailText.animate().alpha(1).setDuration(500).start();
};
Runnable focusEmail = () -> {
onEditUI.run();
emailEditText.requestFocus();
if (imm != null) {
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
};
Runnable onErrorUI = () -> {
focusEmail.run();
Toast.makeText(getContext(), "Error sending email verification.", Toast.LENGTH_SHORT).show();
};
submitButton.setAlpha(1);
changeButton.setAlpha(0);
resendButton.setAlpha(0);
checkYourEmailSubtext.setAlpha(0);
checkYourEmailText.setAlpha(0);
changeButton.setEnabled(false);
resendButton.setEnabled(false);
AppCompatTextView teamName = rootView.findViewById(R.id.teamName);
teamName.setText(progress.getTeamOnboardingData().decryptInviteOutput.teamName);
String initialEmail = Silo.shared(getContext().getApplicationContext()).meStorage().load().email;
emailEditText.setText(initialEmail);
final Sigchain.IndirectInvitationRestriction restriction = progress.getTeamOnboardingData().decryptInviteOutput.indirectInvitationSecret.restriction;
Runnable requestEmailChallenge = () -> {
final String email = emailEditText.getEditableText().toString();
if (!Email.verifyEmailPattern.matcher(email).matches()) {
Toast.makeText(getContext(), "Please enter a valid email.", Toast.LENGTH_SHORT).show();
return;
}
if (!restriction.isSatisfiedByEmail(email)) {
if (restriction.domain != null) {
Toast.makeText(getContext(), "Email must end with @" + restriction.domain, Toast.LENGTH_SHORT).show();
} else if (restriction.emails != null) {
Toast.makeText(getContext(), "Invite link not valid for this email address.", Toast.LENGTH_SHORT).show();
}
return;
}
onSubmitUI.run();
new Thread(() -> {
MeStorage meStorage = Silo.shared(getContext()).meStorage();
try {
meStorage.setEmail(email);
} catch (CryptoException e) {
co.krypt.krypton.uiutils.Error.shortToast(getContext(), "Failed to set email: " + e.getMessage());
e.printStackTrace();
return;
}
Profile me = meStorage.load();
progress.updateTeamData((s, d) -> {
if (s.equals(JoinStage.VERIFY_EMAIL)) {
d.profile = me;
Log.i(TAG, "requesting email challenge...");
try {
final Sigchain.NativeResult<JsonObject> result = TeamDataProvider.requestEmailChallenge(getContext(), email);
emailEditText.post(() -> {
if (result.success != null) {
Log.i(TAG, "request email challenge success");
onSuccessUI.run();
} else {
Log.i(TAG, "request email challenge failure");
onErrorUI.run();
}
});
if (result.success != null) {
return JoinStage.CHALLENGE_EMAIL_SENT;
} else {
return s;
}
} catch (Native.NotLinked notLinked) {
notLinked.printStackTrace();
}
}
return s;
});
}).start();
};
final Runnable setSelectionBeforeDomain = () -> {
String currentEmail = emailEditText.getText().toString();
if (restriction.domain != null) {
String domainSuffix = "@" + restriction.domain;
if (currentEmail.length() >= domainSuffix.length()) {
if (emailEditText.getSelectionStart() == emailEditText.getSelectionEnd()) {
if (emailEditText.getSelectionStart() > currentEmail.length() - domainSuffix.length()) {
emailEditText.setSelection(currentEmail.length() - domainSuffix.length());
}
}
}
}
};
emailEditText.setOnEditorActionListener((v, i, ev) -> {
requestEmailChallenge.run();
return false;
});
// focus before adding listener
focusEmail.run();
setSelectionBeforeDomain.run();
emailEditText.setOnFocusChangeListener((view, b) -> {
if (view.isEnabled()) {
if (b) {
setSelectionBeforeDomain.run();
}
}
});
emailEditText.setOnClickListener(v -> setSelectionBeforeDomain.run());
final AtomicReference<String> lastEmail = new AtomicReference<>(new String(emailEditText.getText().toString()));
if (!restriction.isSatisfiedByEmail(lastEmail.get())) {
if (restriction.domain != null) {
lastEmail.set("@" + restriction.domain);
} else if (restriction.emails != null && restriction.emails.length == 1) {
lastEmail.set(restriction.emails[0]);
} else {
lastEmail.set("");
}
emailEditText.setText(lastEmail.get());
}
final Runnable updateTextColor = () -> {
if (Email.verifyEmailPattern.matcher(emailEditText.getText()).matches()) {
emailEditText.setTextColor(getContext().getColor(R.color.appGreen));
} else {
emailEditText.setTextColor(getContext().getColor(R.color.appGray));
}
};
updateTextColor.run();
final TextWatcher domainCheck = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
lastEmail.set(s.toString());
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
updateTextColor.run();
}
@Override
public void afterTextChanged(Editable s) {
if (restriction.domain != null) {
if (!s.toString().endsWith("@" + restriction.domain)) {
emailEditText.removeTextChangedListener(this);
s.clear();
s.append(lastEmail.get());
setSelectionBeforeDomain.run();
emailEditText.addTextChangedListener(this);
Toast.makeText(getContext(), "Email must end with @" + restriction.domain, Toast.LENGTH_SHORT).show();
}
}
}
};
emailEditText.addTextChangedListener(domainCheck);
resendButton.setOnClickListener(v -> {
requestEmailChallenge.run();
});
changeButton.setOnClickListener(v -> {
focusEmail.run();
});
submitButton.setOnClickListener(v -> requestEmailChallenge.run());
return rootView;
}
use of co.krypt.krypton.me.MeStorage in project krypton-android by kryptco.
the class MainActivity method onCreate.
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
CrashReporting.startANRReporting();
Notifications.setupNotificationChannels(getApplicationContext());
silo = Silo.shared(getApplicationContext());
startService(new Intent(this, BluetoothService.class));
OnboardingProgress progress = new OnboardingProgress(getApplicationContext());
if (new MeStorage(getApplicationContext()).load() == null || progress.inProgress()) {
startActivity(new Intent(this, OnboardingActivity.class));
finish();
return;
}
if (ConnectionResult.SUCCESS != GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(getApplicationContext())) {
// TODO: warn about no push notifications, prompt to install google play services
}
setContentView(R.layout.activity_main);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setOffscreenPageLimit(4);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
ImageButton settingsButton = (ImageButton) findViewById(R.id.settingsButton);
settingsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
SettingsFragment settingsFragment = new SettingsFragment();
transaction.setCustomAnimations(R.anim.enter_from_bottom, R.anim.exit_to_bottom, R.anim.enter_from_bottom, R.anim.exit_to_bottom).addToBackStack(null).replace(R.id.fragmentOverlay, settingsFragment).commit();
new Analytics(getApplicationContext()).postPageView("About");
}
});
ImageButton infoButton = (ImageButton) findViewById(R.id.infoButton);
infoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
HelpFragment helpFragment = new HelpFragment();
transaction.setCustomAnimations(R.anim.enter_from_bottom, R.anim.exit_to_bottom, R.anim.enter_from_bottom, R.anim.exit_to_bottom).addToBackStack(null).replace(R.id.fragmentOverlay, helpFragment).commit();
new Analytics(getApplicationContext()).postPageView("Help");
}
});
if (getIntent() != null) {
onNewIntent(getIntent());
}
}
use of co.krypt.krypton.me.MeStorage in project krypton-android by kryptco.
the class EnterEmailFragment method onCreateView.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_enter_email, container, false);
nextButton = (Button) root.findViewById(R.id.nextButton);
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
next();
}
});
profileEmail = (EditText) root.findViewById(R.id.profileEmail);
profileEmail.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int keyCode, KeyEvent event) {
v.clearFocus();
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
return false;
}
});
profileEmail.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
onEmailChanged();
}
});
Profile me = new MeStorage(getContext()).load();
if (me != null && me.email != null) {
profileEmail.setText(me.email);
} else {
profileEmail.setText("");
}
return root;
}
use of co.krypt.krypton.me.MeStorage in project krypton-android by kryptco.
the class GenerateFragment method next.
private void next() {
KeyType keyType = null;
if (keyTypeButton.getText().equals(getString(R.string.ed25519_key_type))) {
keyType = KeyType.Ed25519;
} else if (keyTypeButton.getText().equals(getString(R.string.rsa_key_type))) {
keyType = KeyType.RSA;
} else {
keyType = KeyType.RSA;
}
final KeyType finalKeyType = keyType;
final FragmentActivity context = getActivity();
final OnboardingProgress progress = new OnboardingProgress(getContext());
progress.setStage(OnboardingStage.GENERATING);
new Analytics(context).postEvent("onboard", "generate tapped", null, null, false);
final long startMillis = System.currentTimeMillis();
final GeneratingFragment generatingFragment = new GeneratingFragment();
getActivity().getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left).replace(R.id.activity_onboarding, generatingFragment).commit();
final Fragment self = this;
new Thread(new Runnable() {
@Override
public void run() {
try {
final long start = System.currentTimeMillis();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
SSHKeyPairI pair = KeyManager.loadOrGenerateKeyPair(context, finalKeyType, KeyManager.ME_TAG);
new MeStorage(context).set(new Profile("", pair.publicKeySSHWireFormat(), null, null));
final long genTime = System.currentTimeMillis() - start;
new Analytics(context).postEvent("keypair", "generate", null, (int) (genTime / 1000), false);
if (genTime < 5000) {
try {
Thread.sleep(5000 - genTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
generatingFragment.onGenerate();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
progress.setStage(OnboardingStage.ENTER_EMAIL);
EnterEmailFragment enterEmailFragment = new EnterEmailFragment();
final FragmentActivity activity = context;
if (activity != null && !activity.isDestroyed() && !activity.isFinishing()) {
activity.getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left).hide(generatingFragment).add(R.id.activity_onboarding, enterEmailFragment).show(enterEmailFragment).commitAllowingStateLoss();
}
} catch (InvalidKeyException | IOException | CryptoException | UnsupportedOperationException | IllegalArgumentException e) {
e.printStackTrace();
progress.reset();
final FragmentActivity activity = context;
if (activity != null && !activity.isDestroyed() && !activity.isFinishing()) {
GenerateFragment generateFragment = new GenerateFragment();
if (finalKeyType == KeyType.RSA) {
Bundle args = new Bundle();
args.putString(DEFAULT_KEY_TYPE_KEY, activity.getString(R.string.ed25519_key_type));
generateFragment.setArguments(args);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(activity, "Error generating rsa key, try again to generate an ed25519 key.", Toast.LENGTH_LONG).show();
}
});
}
activity.getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left).replace(R.id.activity_onboarding, generateFragment).commitAllowingStateLoss();
}
}
}
}).start();
}
Aggregations