Match identities by regex

pull/162/head
M66B 5 years ago
parent bb4eb51d17
commit 50f48fb4c6

File diff suppressed because it is too large Load Diff

@ -1817,7 +1817,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
return null;
for (Address sender : senders)
if (MessageHelper.similarAddress(sender, identity.email)) {
if (identity.similarAddress(sender)) {
outgoing = true;
break;
}
@ -2187,7 +2187,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
if (amessage == null || !amessage.id.equals(message.id))
return;
Address[] recipients = message.getAllRecipients(identity == null ? null : identity.email);
Address[] recipients = message.getAllRecipients(identity);
View anchor = bnvActions.findViewById(R.id.action_reply);
PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, powner, anchor);

@ -2031,16 +2031,16 @@ class Core {
}
// Search for matching identity
List<EntityIdentity> identities = db.identity().getIdentities(folder.account);
List<EntityIdentity> identities = db.identity().getSynchronizingIdentities(folder.account);
if (identities != null) {
for (Address address : addresses)
for (EntityIdentity identity : identities)
if (MessageHelper.sameAddress(address, identity.email))
if (identity.sameAddress(address))
return identity;
for (Address address : addresses)
for (EntityIdentity identity : identities)
if (MessageHelper.similarAddress(address, identity.email))
if (identity.similarAddress(address))
return identity;
}
@ -2092,11 +2092,11 @@ class Core {
// Check if from self
if (type == EntityContact.TYPE_FROM && recipients != null && recipients.length > 0) {
boolean me = false;
List<EntityIdentity> identities = db.identity().getIdentities(folder.account);
List<EntityIdentity> identities = db.identity().getSynchronizingIdentities(folder.account);
if (identities != null)
for (Address recipient : recipients) {
for (EntityIdentity identity : identities)
if (MessageHelper.similarAddress(recipient, identity.email)) {
if (identity.similarAddress(recipient)) {
me = true;
break;
}

@ -58,7 +58,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
// https://developer.android.com/topic/libraries/architecture/room.html
@Database(
version = 100,
version = 101,
entities = {
EntityIdentity.class,
EntityAccount.class,
@ -1006,6 +1006,13 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `message` ADD COLUMN `unsubscribe` TEXT");
}
})
.addMigrations(new Migration(100, 101) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
Log.i("DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `identity` ADD COLUMN `sender_extra_regex` TEXT");
}
})
.build();
}

@ -49,6 +49,12 @@ public interface DaoIdentity {
" ORDER BY name COLLATE NOCASE")
List<EntityIdentity> getIdentities(long account);
@Query("SELECT identity.* FROM identity" +
" JOIN account ON account.id = identity.account" +
" WHERE identity.account = :account" +
" AND identity.synchronize AND account.synchronize")
List<EntityIdentity> getSynchronizingIdentities(long account);
@Query("SELECT * FROM identity WHERE id = :id")
EntityIdentity getIdentity(long id);

@ -19,6 +19,8 @@ package eu.faircode.email;
Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.room.Entity;
import androidx.room.ForeignKey;
@ -29,6 +31,10 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.util.Objects;
import java.util.regex.Pattern;
import javax.mail.Address;
import javax.mail.internet.InternetAddress;
import static androidx.room.ForeignKey.CASCADE;
@ -79,6 +85,7 @@ public class EntityIdentity {
public Boolean primary;
@NonNull
public Boolean sender_extra = false;
public String sender_extra_regex;
public String replyto;
public String bcc;
@NonNull
@ -102,6 +109,45 @@ public class EntityIdentity {
return (starttls ? "smtp" : "smtps");
}
boolean sameAddress(Address address) {
String other = ((InternetAddress) address).getAddress();
if (other == null)
return false;
return other.equalsIgnoreCase(email);
}
boolean similarAddress(Address address) {
String other = ((InternetAddress) address).getAddress();
if (other == null)
return false;
if (!other.contains("@") || !email.contains("@"))
return false;
String[] cother = other.split("@");
String[] cemail = email.split("@");
if (cother.length != 2 || cemail.length != 2)
return false;
// Domain
if (!cother[1].equalsIgnoreCase(cemail[1]))
return false;
// User
if (TextUtils.isEmpty(sender_extra_regex)) {
String user = (cother[0].contains("+") ? cother[0].split("\\+")[0] : cother[0]);
if (user.equalsIgnoreCase(cemail[0]))
return true;
} else {
if (Pattern.matches(sender_extra_regex, cother[0]))
return true;
}
return false;
}
public JSONObject toJSON() throws JSONException {
JSONObject json = new JSONObject();
json.put("id", id);

@ -162,32 +162,32 @@ public class EntityMessage implements Serializable {
return "<" + UUID.randomUUID() + "@localhost" + '>';
}
boolean replySelf(String via) {
if (via == null)
boolean replySelf(EntityIdentity identity) {
if (identity == null)
return false;
Address[] senders = (reply == null || reply.length == 0 ? from : reply);
if (senders != null)
for (Address sender : senders)
if (MessageHelper.similarAddress(sender, via))
if (identity.similarAddress(sender))
return true;
return false;
}
Address[] getAllRecipients(String via) {
Address[] getAllRecipients(EntityIdentity identity) {
List<Address> addresses = new ArrayList<>();
if (to != null && !replySelf(via))
if (to != null && !replySelf(identity))
addresses.addAll(Arrays.asList(to));
if (cc != null)
addresses.addAll(Arrays.asList(cc));
// Filter self
if (via != null)
if (identity != null)
for (Address address : new ArrayList<>(addresses))
if (MessageHelper.similarAddress(address, via))
if (identity.similarAddress(address))
addresses.remove(address);
return addresses.toArray(new Address[0]);

@ -2096,13 +2096,11 @@ public class FragmentCompose extends FragmentBase {
data.draft.inreplyto = ref.msgid;
data.draft.thread = ref.thread;
String via = null;
EntityIdentity identity = null;
if (ref.identity != null) {
EntityIdentity identity = db.identity().getIdentity(ref.identity);
if (identity != null) {
identity = db.identity().getIdentity(ref.identity);
if (identity != null)
data.draft.from = new Address[]{new InternetAddress(identity.email, identity.name)};
via = identity.email;
}
}
if ("list".equals(action) && ref.list_post != null)
@ -2111,7 +2109,7 @@ public class FragmentCompose extends FragmentBase {
data.draft.to = ref.receipt_to;
else {
// Prevent replying to self
if (ref.replySelf(via)) {
if (ref.replySelf(identity)) {
data.draft.to = ref.to;
data.draft.from = ref.from;
} else
@ -2119,7 +2117,7 @@ public class FragmentCompose extends FragmentBase {
}
if ("reply_all".equals(action))
data.draft.cc = ref.getAllRecipients(via);
data.draft.cc = ref.getAllRecipients(identity);
else if ("receipt".equals(action))
data.draft.receipt_request = true;
@ -2176,7 +2174,7 @@ public class FragmentCompose extends FragmentBase {
for (Address sender : data.draft.from)
for (EntityIdentity identity : data.identities)
if (identity.account.equals(aid) &&
MessageHelper.sameAddress(sender, identity.email)) {
identity.sameAddress(sender)) {
selected = identity;
break;
}
@ -2185,7 +2183,7 @@ public class FragmentCompose extends FragmentBase {
for (Address sender : data.draft.from)
for (EntityIdentity identity : data.identities)
if (identity.account.equals(aid) &&
MessageHelper.similarAddress(sender, identity.email)) {
identity.similarAddress(sender)) {
selected = identity;
break;
}
@ -2193,7 +2191,7 @@ public class FragmentCompose extends FragmentBase {
if (selected == null)
for (Address sender : data.draft.from)
for (EntityIdentity identity : data.identities)
if (MessageHelper.sameAddress(sender, identity.email)) {
if (identity.sameAddress(sender)) {
selected = identity;
break;
}
@ -2201,7 +2199,7 @@ public class FragmentCompose extends FragmentBase {
if (selected == null)
for (Address sender : data.draft.from)
for (EntityIdentity identity : data.identities)
if (MessageHelper.similarAddress(sender, identity.email)) {
if (identity.similarAddress(sender)) {
selected = identity;
break;
}

@ -109,6 +109,7 @@ public class FragmentIdentity extends FragmentBase {
private CheckBox cbPrimary;
private CheckBox cbSenderExtra;
private TextView etSenderExtra;
private EditText etReplyTo;
private EditText etBcc;
private TextView tvEncryptPro;
@ -192,6 +193,7 @@ public class FragmentIdentity extends FragmentBase {
cbPrimary = view.findViewById(R.id.cbPrimary);
cbSenderExtra = view.findViewById(R.id.cbSenderExtra);
etSenderExtra = view.findViewById(R.id.etSenderExtra);
etReplyTo = view.findViewById(R.id.etReplyTo);
etBcc = view.findViewById(R.id.etBcc);
tvEncryptPro = view.findViewById(R.id.tvEncryptPro);
@ -528,6 +530,7 @@ public class FragmentIdentity extends FragmentBase {
args.putString("email", etEmail.getText().toString().trim());
args.putString("display", etDisplay.getText().toString());
args.putBoolean("sender_extra", cbSenderExtra.isChecked());
args.putString("sender_extra_regex", etSenderExtra.getText().toString());
args.putString("replyto", etReplyTo.getText().toString().trim());
args.putString("bcc", etBcc.getText().toString().trim());
args.putBoolean("encrypt", cbEncrypt.isChecked());
@ -595,6 +598,7 @@ public class FragmentIdentity extends FragmentBase {
boolean primary = args.getBoolean("primary");
boolean sender_extra = args.getBoolean("sender_extra");
String sender_extra_regex = args.getString("sender_extra_regex");
String replyto = args.getString("replyto");
String bcc = args.getString("bcc");
boolean encrypt = args.getBoolean("encrypt");
@ -645,6 +649,9 @@ public class FragmentIdentity extends FragmentBase {
if (TextUtils.isEmpty(realm))
realm = null;
if (TextUtils.isEmpty(sender_extra_regex))
sender_extra_regex = null;
if (TextUtils.isEmpty(replyto))
replyto = null;
@ -699,6 +706,8 @@ public class FragmentIdentity extends FragmentBase {
return true;
if (!Objects.equals(identity.sender_extra, sender_extra))
return true;
if (!Objects.equals(identity.sender_extra_regex, sender_extra_regex))
return true;
if (!Objects.equals(identity.replyto, replyto))
return true;
if (!Objects.equals(identity.bcc, bcc))
@ -768,6 +777,7 @@ public class FragmentIdentity extends FragmentBase {
identity.primary = (identity.synchronize && primary);
identity.sender_extra = sender_extra;
identity.sender_extra_regex = sender_extra_regex;
identity.replyto = replyto;
identity.bcc = bcc;
identity.encrypt = encrypt;
@ -904,6 +914,7 @@ public class FragmentIdentity extends FragmentBase {
cbPrimary.setChecked(identity == null ? true : identity.primary);
cbSenderExtra.setChecked(identity != null && identity.sender_extra);
etSenderExtra.setText(identity == null ? null : identity.sender_extra_regex);
etReplyTo.setText(identity == null ? null : identity.replyto);
etBcc.setText(identity == null ? null : identity.bcc);
cbEncrypt.setChecked(identity == null ? false : identity.encrypt);

@ -456,7 +456,7 @@ public class FragmentRule extends FragmentBase {
if (data.folders.size() > 0)
Collections.sort(data.folders, data.folders.get(0).getComparator(null));
data.identities = db.identity().getIdentities(aid);
data.identities = db.identity().getSynchronizingIdentities(aid);
data.answers = db.answer().getAnswers(false);
return data;

@ -713,37 +713,6 @@ public class MessageHelper {
return TextUtils.join(", ", formatted);
}
static boolean sameAddress(Address address1, String email2) {
String email1 = ((InternetAddress) address1).getAddress();
if (email1 == null)
return false;
return email1.equalsIgnoreCase(email2);
}
static boolean similarAddress(Address address1, String email2) {
String email1 = ((InternetAddress) address1).getAddress();
if (email1 == null)
return false;
if (!email1.contains("@") || !email2.contains("@"))
return false;
String[] e1 = email1.split("@");
String[] e2 = email2.split("@");
if (e1.length != 2 || e2.length != 2)
return false;
// Domain
if (!e1[1].equalsIgnoreCase(e2[1]))
return false;
String user1 = (e1[0].contains("+") ? e1[0].split("\\+")[0] : e1[0]);
return user1.equalsIgnoreCase(e2[0]);
}
static String decodeMime(String text) {
if (text == null)
return null;

@ -495,6 +495,25 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbPrimary" />
<TextView
android:id="@+id/tvSenderExtra"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_sender_regex"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbSenderExtra" />
<EditText
android:id="@+id/etSenderExtra"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/title_optional"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvSenderExtra" />
<TextView
android:id="@+id/tvSenderExtraHint"
android:layout_width="wrap_content"
@ -503,7 +522,7 @@
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textStyle="italic"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbSenderExtra" />
app:layout_constraintTop_toBottomOf="@id/etSenderExtra" />
<!-- reply to -->
@ -699,7 +718,7 @@
tvRealm,etRealm,
cbUseIp,tvUseIpHint,
cbSynchronize,cbPrimary,
cbSenderExtra,tvSenderExtraHint,
cbSenderExtra,tvSenderExtra,etSenderExtra,tvSenderExtraHint,
tvReplyTo,etReplyTo,tvBcc,etBcc,
cbEncrypt,tvEncryptPro,
cbDeliveryReceipt,cbReadReceipt,tvReceipt" />

@ -357,6 +357,7 @@
<string name="title_identity_email">Your email address</string>
<string name="title_identity_color_hint">Identity colors take precedence over account colors</string>
<string name="title_advanced_sender">Allow editing sender address</string>
<string name="title_advanced_sender_regex">Regex to match edited addresses</string>
<string name="title_identity_reply_to">Reply to address</string>
<string name="title_identity_encrypt">Encrypt by default</string>
<string name="title_identity_use_ip_hint">In case of \'invalid greeting\', \'requires valid address\' or a similar error, try to change this setting</string>

Loading…
Cancel
Save