Browse Source

Added RFC 6186 support

Fixes #129
main
M66B 6 years ago
parent
commit
31a8731c21
8 changed files with 201 additions and 4 deletions
  1. BIN
      .idea/caches/build_file_checksums.ser
  2. +1
    -0
      README.md
  3. +4
    -0
      app/build.gradle
  4. +55
    -0
      app/src/main/java/eu/faircode/email/FragmentAccount.java
  5. +63
    -0
      app/src/main/java/eu/faircode/email/FragmentIdentity.java
  6. +39
    -2
      app/src/main/res/layout/fragment_account.xml
  7. +36
    -2
      app/src/main/res/layout/fragment_identity.xml
  8. +3
    -0
      app/src/main/res/values/strings.xml

BIN
.idea/caches/build_file_checksums.ser View File


+ 1
- 0
README.md View File

@ -108,6 +108,7 @@ FairEmail uses:
* [Android Support Library](https://developer.android.com/tools/support-library/). Copyright (C) 2011 The Android Open Source Project. [Apache license](https://android.googlesource.com/platform/frameworks/support/+/master/LICENSE.txt). * [Android Support Library](https://developer.android.com/tools/support-library/). Copyright (C) 2011 The Android Open Source Project. [Apache license](https://android.googlesource.com/platform/frameworks/support/+/master/LICENSE.txt).
* [Android Architecture Components](https://developer.android.com/topic/libraries/architecture/). Copyright 2018 The Android Open Source Project, Inc. [Apache license](https://github.com/googlesamples/android-architecture-components/blob/master/LICENSE). * [Android Architecture Components](https://developer.android.com/topic/libraries/architecture/). Copyright 2018 The Android Open Source Project, Inc. [Apache license](https://github.com/googlesamples/android-architecture-components/blob/master/LICENSE).
* [colorpicker](https://android.googlesource.com/platform/frameworks/opt/colorpicker). Copyright (C) 2013 The Android Open Source Project. [Apache license](https://android.googlesource.com/platform/frameworks/opt/colorpicker/+/master/src/com/android/colorpicker/ColorPickerDialog.java). * [colorpicker](https://android.googlesource.com/platform/frameworks/opt/colorpicker). Copyright (C) 2013 The Android Open Source Project. [Apache license](https://android.googlesource.com/platform/frameworks/opt/colorpicker/+/master/src/com/android/colorpicker/ColorPickerDialog.java).
* [dnsjava](http://www.xbill.org/dnsjava/). Copyright (c) 1998-2011, Brian Wellington. [BSD License](https://sourceforge.net/p/dnsjava/code/HEAD/tree/trunk/LICENSE).
## License ## License


+ 4
- 0
app/build.gradle View File

@ -80,6 +80,7 @@ dependencies {
def javamail_version = "1.6.2" def javamail_version = "1.6.2"
def jsoup_version = "1.11.3" def jsoup_version = "1.11.3"
def jcharset_version = "2.0" def jcharset_version = "2.0"
def dnsjava_version = "2.1.8"
implementation "androidx.appcompat:appcompat:$androidx_version" implementation "androidx.appcompat:appcompat:$androidx_version"
implementation "androidx.recyclerview:recyclerview:$androidx_version" implementation "androidx.recyclerview:recyclerview:$androidx_version"
@ -105,6 +106,9 @@ dependencies {
implementation "net.freeutils:jcharset:$jcharset_version" implementation "net.freeutils:jcharset:$jcharset_version"
// http://www.xbill.org/dnsjava/
implementation "dnsjava:dnsjava:$dnsjava_version"
// git clone https://android.googlesource.com/platform/frameworks/opt/colorpicker // git clone https://android.googlesource.com/platform/frameworks/opt/colorpicker
implementation project(path: ':colorpicker') implementation project(path: ':colorpicker')
} }

+ 55
- 0
app/src/main/java/eu/faircode/email/FragmentAccount.java View File

@ -62,6 +62,11 @@ import com.google.android.material.textfield.TextInputLayout;
import com.sun.mail.imap.IMAPFolder; import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore; import com.sun.mail.imap.IMAPStore;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record;
import org.xbill.DNS.SRVRecord;
import org.xbill.DNS.Type;
import java.text.Collator; import java.text.Collator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -88,6 +93,8 @@ public class FragmentAccount extends FragmentEx {
private ViewGroup view; private ViewGroup view;
private Spinner spProvider; private Spinner spProvider;
private EditText etHost; private EditText etHost;
private EditText etDomain;
private Button btnAutoConfig;
private EditText etPort; private EditText etPort;
private Button btnAuthorize; private Button btnAuthorize;
private EditText etUser; private EditText etUser;
@ -139,6 +146,10 @@ public class FragmentAccount extends FragmentEx {
// Get controls // Get controls
spProvider = view.findViewById(R.id.spProvider); spProvider = view.findViewById(R.id.spProvider);
etDomain = view.findViewById(R.id.etDomain);
btnAutoConfig = view.findViewById(R.id.btnAutoConfig);
etHost = view.findViewById(R.id.etHost); etHost = view.findViewById(R.id.etHost);
etPort = view.findViewById(R.id.etPort); etPort = view.findViewById(R.id.etPort);
@ -217,6 +228,50 @@ public class FragmentAccount extends FragmentEx {
} }
}); });
btnAutoConfig.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
btnAutoConfig.setEnabled(false);
Bundle args = new Bundle();
args.putString("domain", etDomain.getText().toString());
new SimpleTask<SRVRecord>() {
@Override
protected SRVRecord onLoad(Context context, Bundle args) throws Throwable {
String domain = args.getString("domain");
Record[] records = new Lookup("_imaps._tcp." + domain, Type.SRV).run();
if (records != null)
for (int i = 0; i < records.length; i++) {
SRVRecord srv = (SRVRecord) records[i];
Log.i(Helper.TAG, "SRV=" + srv);
return srv;
}
throw new IllegalArgumentException(getString(R.string.title_no_settings));
}
@Override
protected void onLoaded(Bundle args, SRVRecord srv) {
btnAutoConfig.setEnabled(true);
if (srv != null) {
etHost.setText(srv.getTarget().toString(true));
etPort.setText(Integer.toString(srv.getPort()));
}
}
@Override
protected void onException(Bundle args, Throwable ex) {
btnAutoConfig.setEnabled(true);
if (ex instanceof IllegalArgumentException)
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
else
Helper.unexpectedError(getContext(), ex);
}
}.load(FragmentAccount.this, args);
}
});
tilPassword.getEditText().addTextChangedListener(new TextWatcher() { tilPassword.getEditText().addTextChangedListener(new TextWatcher() {
@Override @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { public void beforeTextChanged(CharSequence s, int start, int count, int after) {


+ 63
- 0
app/src/main/java/eu/faircode/email/FragmentIdentity.java View File

@ -23,6 +23,7 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -36,8 +37,14 @@ import android.widget.ImageButton;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.Spinner; import android.widget.Spinner;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
import org.xbill.DNS.Lookup;
import org.xbill.DNS.Record;
import org.xbill.DNS.SRVRecord;
import org.xbill.DNS.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
@ -59,6 +66,8 @@ public class FragmentIdentity extends FragmentEx {
private EditText etEmail; private EditText etEmail;
private EditText etReplyTo; private EditText etReplyTo;
private Spinner spProvider; private Spinner spProvider;
private EditText etDomain;
private Button btnAutoConfig;
private EditText etHost; private EditText etHost;
private CheckBox cbStartTls; private CheckBox cbStartTls;
private EditText etPort; private EditText etPort;
@ -94,18 +103,27 @@ public class FragmentIdentity extends FragmentEx {
// Get controls // Get controls
etName = view.findViewById(R.id.etName); etName = view.findViewById(R.id.etName);
spAccount = view.findViewById(R.id.spAccount); spAccount = view.findViewById(R.id.spAccount);
btnAdvanced = view.findViewById(R.id.btnAdvanced); btnAdvanced = view.findViewById(R.id.btnAdvanced);
etEmail = view.findViewById(R.id.etEmail); etEmail = view.findViewById(R.id.etEmail);
etReplyTo = view.findViewById(R.id.etReplyTo); etReplyTo = view.findViewById(R.id.etReplyTo);
spProvider = view.findViewById(R.id.spProvider); spProvider = view.findViewById(R.id.spProvider);
etDomain = view.findViewById(R.id.etDomain);
btnAutoConfig = view.findViewById(R.id.btnAutoConfig);
etHost = view.findViewById(R.id.etHost); etHost = view.findViewById(R.id.etHost);
cbStartTls = view.findViewById(R.id.cbStartTls); cbStartTls = view.findViewById(R.id.cbStartTls);
etPort = view.findViewById(R.id.etPort); etPort = view.findViewById(R.id.etPort);
etUser = view.findViewById(R.id.etUser); etUser = view.findViewById(R.id.etUser);
tilPassword = view.findViewById(R.id.tilPassword); tilPassword = view.findViewById(R.id.tilPassword);
cbSynchronize = view.findViewById(R.id.cbSynchronize); cbSynchronize = view.findViewById(R.id.cbSynchronize);
cbPrimary = view.findViewById(R.id.cbPrimary); cbPrimary = view.findViewById(R.id.cbPrimary);
cbStoreSent = view.findViewById(R.id.cbStoreSent); cbStoreSent = view.findViewById(R.id.cbStoreSent);
btnSave = view.findViewById(R.id.btnSave); btnSave = view.findViewById(R.id.btnSave);
pbSave = view.findViewById(R.id.pbSave); pbSave = view.findViewById(R.id.pbSave);
ibDelete = view.findViewById(R.id.ibDelete); ibDelete = view.findViewById(R.id.ibDelete);
@ -197,6 +215,51 @@ public class FragmentIdentity extends FragmentEx {
} }
}); });
btnAutoConfig.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
btnAutoConfig.setEnabled(false);
Bundle args = new Bundle();
args.putString("domain", etDomain.getText().toString());
new SimpleTask<SRVRecord>() {
@Override
protected SRVRecord onLoad(Context context, Bundle args) throws Throwable {
String domain = args.getString("domain");
Record[] records = new Lookup("_submission._tcp." + domain, Type.SRV).run();
if (records != null)
for (int i = 0; i < records.length; i++) {
SRVRecord srv = (SRVRecord) records[i];
Log.i(Helper.TAG, "SRV=" + srv);
return srv;
}
throw new IllegalArgumentException(getString(R.string.title_no_settings));
}
@Override
protected void onLoaded(Bundle args, SRVRecord srv) {
btnAutoConfig.setEnabled(true);
if (srv != null) {
etHost.setText(srv.getTarget().toString(true));
etPort.setText(Integer.toString(srv.getPort()));
cbStartTls.setChecked(srv.getPort() == 587);
}
}
@Override
protected void onException(Bundle args, Throwable ex) {
btnAutoConfig.setEnabled(true);
if (ex instanceof IllegalArgumentException)
Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show();
else
Helper.unexpectedError(getContext(), ex);
}
}.load(FragmentIdentity.this, args);
}
});
cbStartTls.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { cbStartTls.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {


+ 39
- 2
app/src/main/res/layout/fragment_account.xml View File

@ -30,6 +30,40 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvProvider" /> app:layout_constraintTop_toBottomOf="@id/tvProvider" />
<!-- auto config -->
<TextView
android:id="@+id/tvDomain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_domain"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/spProvider" />
<EditText
android:id="@+id/etDomain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="domain.tld"
android:inputType="textNoSuggestions"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvDomain" />
<Button
android:id="@+id/btnAutoConfig"
style="@style/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:minHeight="0dp"
android:minWidth="0dp"
android:text="@string/title_autoconfig"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etDomain" />
<!-- IMAP --> <!-- IMAP -->
<TextView <TextView
@ -40,7 +74,7 @@
android:text="@string/title_imap" android:text="@string/title_imap"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/spProvider" />
app:layout_constraintTop_toBottomOf="@id/btnAutoConfig" />
<TextView <TextView
android:id="@+id/tvPop" android:id="@+id/tvPop"
@ -108,9 +142,12 @@
<Button <Button
android:id="@+id/btnAuthorize" android:id="@+id/btnAuthorize"
style="@style/buttonStyleSmall"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:minHeight="0dp"
android:minWidth="0dp"
android:text="@string/title_authorize" android:text="@string/title_authorize"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etPort" /> app:layout_constraintTop_toBottomOf="@id/etPort" />
@ -450,7 +487,7 @@
android:id="@+id/grpServer" android:id="@+id/grpServer"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
app:constraint_referenced_ids="tvImap,tvPop,tvInsecure,tvHost,etHost,tvPort,etPort" />
app:constraint_referenced_ids="tvDomain,etDomain,btnAutoConfig,tvImap,tvPop,tvInsecure,tvHost,etHost,tvPort,etPort" />
<androidx.constraintlayout.widget.Group <androidx.constraintlayout.widget.Group
android:id="@+id/grpAuthorize" android:id="@+id/grpAuthorize"


+ 36
- 2
app/src/main/res/layout/fragment_identity.xml View File

@ -127,6 +127,40 @@
<!-- SMTP --> <!-- SMTP -->
<!-- auto config -->
<TextView
android:id="@+id/tvDomain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_domain"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/spProvider" />
<EditText
android:id="@+id/etDomain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="domain.tld"
android:inputType="textNoSuggestions"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvDomain" />
<Button
android:id="@+id/btnAutoConfig"
style="@style/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:minHeight="0dp"
android:minWidth="0dp"
android:text="@string/title_autoconfig"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/etDomain" />
<TextView <TextView
android:id="@+id/tvSmtp" android:id="@+id/tvSmtp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -135,7 +169,7 @@
android:text="@string/title_smtp" android:text="@string/title_smtp"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/spProvider" />
app:layout_constraintTop_toBottomOf="@id/btnAutoConfig" />
<TextView <TextView
android:id="@+id/tvInsecure" android:id="@+id/tvInsecure"
@ -322,6 +356,6 @@
android:id="@+id/grpAdvanced" android:id="@+id/grpAdvanced"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
app:constraint_referenced_ids="tvEmail,etEmail,tvReplyTo,etReplyTo,tvProvider,spProvider,tvSmtp,tvInsecure,tvHost,etHost,cbStartTls,tvPort,etPort,tvUser,etUser,tvPassword,tilPassword,cbSynchronize,cbPrimary,cbStoreSent" />
app:constraint_referenced_ids="tvEmail,etEmail,tvReplyTo,etReplyTo,tvProvider,spProvider,tvDomain,etDomain,btnAutoConfig,tvSmtp,tvInsecure,tvHost,etHost,cbStartTls,tvPort,etPort,tvUser,etUser,tvPassword,tilPassword,cbSynchronize,cbPrimary,cbStoreSent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView> </ScrollView>

+ 3
- 0
app/src/main/res/values/strings.xml View File

@ -92,6 +92,9 @@
<string name="title_account_name_hint">Used to differentiate folders</string> <string name="title_account_name_hint">Used to differentiate folders</string>
<string name="title_account_signature">Signature text</string> <string name="title_account_signature">Signature text</string>
<string name="title_account_color">Color</string> <string name="title_account_color">Color</string>
<string name="title_domain">Domain name</string>
<string name="title_autoconfig">Get settings</string>
<string name="title_no_settings">Settings not found</string>
<string name="title_imap">IMAP</string> <string name="title_imap">IMAP</string>
<string name="title_smtp">SMTP</string> <string name="title_smtp">SMTP</string>
<string name="title_provider">Provider</string> <string name="title_provider">Provider</string>


Loading…
Cancel
Save