BIMI: added selector

pull/200/head
M66B 4 years ago
parent dd9045dd28
commit 6c4fe61caf

File diff suppressed because it is too large Load Diff

@ -942,6 +942,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
boolean outgoing = isOutgoing(message);
boolean reverse = (outgoing && viewType != ViewType.THREAD &&
(EntityFolder.isOutgoing(type) || viewType == ViewType.SEARCH));
String selector = (reverse ? null : message.bimi_selector);
Address[] addresses = (reverse ? message.to : message.from);
Address[] senders = ContactInfo.fillIn(
reverse && !show_recipients ? message.to : message.senders, prefer_contact, only_contact);
@ -1226,7 +1227,8 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
}
// Contact info
ContactInfo[] info = ContactInfo.getCached(context, message.account, message.folderType, addresses);
ContactInfo[] info = ContactInfo.getCached(context,
message.account, message.folderType, selector, addresses);
if (info == null) {
if (taskContactInfo != null)
taskContactInfo.cancel(context);
@ -1235,6 +1237,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
aargs.putLong("id", message.id);
aargs.putLong("account", message.account);
aargs.putString("folderType", message.folderType);
aargs.putString("selector", selector);
aargs.putSerializable("addresses", addresses);
taskContactInfo = new SimpleTask<ContactInfo[]>() {
@ -1242,8 +1245,9 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
protected ContactInfo[] onExecute(Context context, Bundle args) {
long account = args.getLong("account");
String folderType = args.getString("folderType");
String selector = args.getString("selector");
Address[] addresses = (Address[]) args.getSerializable("addresses");
return ContactInfo.get(context, account, folderType, addresses);
return ContactInfo.get(context, account, folderType, selector, addresses);
}
@Override
@ -5045,6 +5049,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
args.putLong("id", message.id);
args.putLong("account", message.account);
args.putString("folderType", message.folderType);
args.putString("selector", message.bimi_selector);
args.putSerializable("addresses", message.from);
new SimpleTask<ContactInfo[]>() {
@ -5052,8 +5057,9 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
protected ContactInfo[] onExecute(Context context, Bundle args) {
long account = args.getLong("account");
String folderType = args.getString("folderType");
String selector = args.getString("selector");
Address[] addresses = (Address[]) args.getSerializable("addresses");
return ContactInfo.get(context, account, folderType, addresses);
return ContactInfo.get(context, account, folderType, selector, addresses);
}
@Override
@ -5704,6 +5710,10 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
same = false;
log("receipt_to changed", next.id);
}
if (!Objects.equals(prev.bimi_selector, next.bimi_selector)) {
same = false;
log("bimi_selector changed", next.id);
}
if (!Objects.equals(prev.dkim, next.dkim)) {
same = false;
log("dkim changed", next.id);

@ -77,6 +77,9 @@ public class Bimi {
Bitmap bitmap = null;
boolean verified = false;
if (TextUtils.isEmpty(selector))
selector = "default";
// Get DNS record
String txt = selector + "._bimi." + domain;
Log.i("BIMI fetch TXT=" + txt);

@ -214,21 +214,21 @@ public class ContactInfo {
}
@NonNull
static ContactInfo[] get(Context context, long account, String folderType, Address[] addresses) {
return get(context, account, folderType, addresses, false);
static ContactInfo[] get(Context context, long account, String folderType, String selector, Address[] addresses) {
return get(context, account, folderType, selector, addresses, false);
}
static ContactInfo[] getCached(Context context, long account, String folderType, Address[] addresses) {
return get(context, account, folderType, addresses, true);
static ContactInfo[] getCached(Context context, long account, String folderType, String selector, Address[] addresses) {
return get(context, account, folderType, selector, addresses, true);
}
private static ContactInfo[] get(Context context, long account, String folderType, Address[] addresses, boolean cacheOnly) {
private static ContactInfo[] get(Context context, long account, String folderType, String selector, Address[] addresses, boolean cacheOnly) {
if (addresses == null || addresses.length == 0)
return new ContactInfo[]{new ContactInfo()};
ContactInfo[] result = new ContactInfo[addresses.length];
for (int i = 0; i < addresses.length; i++) {
result[i] = _get(context, account, folderType, (InternetAddress) addresses[i], cacheOnly);
result[i] = _get(context, account, folderType, selector, (InternetAddress) addresses[i], cacheOnly);
if (result[i] == null)
return null;
}
@ -236,7 +236,10 @@ public class ContactInfo {
return result;
}
private static ContactInfo _get(Context context, long account, String folderType, InternetAddress address, boolean cacheOnly) {
private static ContactInfo _get(
Context context,
long account, String folderType,
String selector, InternetAddress address, boolean cacheOnly) {
String key = MessageHelper.formatAddresses(new Address[]{address});
synchronized (emailContactInfo) {
ContactInfo info = emailContactInfo.get(key);
@ -362,9 +365,8 @@ public class ContactInfo {
futures.add(executorFavicon.submit(new Callable<Favicon>() {
@Override
public Favicon call() throws Exception {
// TODO: BIMI selector
Pair<Bitmap, Boolean> bimi =
Bimi.get(context, domain, "default", scaleToPixels);
Bimi.get(context, domain, selector, scaleToPixels);
return (bimi == null ? null : new Favicon(bimi.first, "vmc", bimi.second));
}
}));

@ -2435,6 +2435,7 @@ class Core {
message.auto_submitted = helper.getAutoSubmitted();
message.receipt_request = helper.getReceiptRequested();
message.receipt_to = helper.getReceiptTo();
message.bimi_selector = helper.getBimiSelector();
message.dkim = MessageHelper.getAuthentication("dkim", authentication);
message.spf = MessageHelper.getAuthentication("spf", authentication);
message.dmarc = MessageHelper.getAuthentication("dmarc", authentication);
@ -3276,6 +3277,7 @@ class Core {
message.auto_submitted = helper.getAutoSubmitted();
message.receipt_request = helper.getReceiptRequested();
message.receipt_to = helper.getReceiptTo();
message.bimi_selector = helper.getBimiSelector();
message.dkim = MessageHelper.getAuthentication("dkim", authentication);
message.spf = MessageHelper.getAuthentication("spf", authentication);
message.dmarc = MessageHelper.getAuthentication("dmarc", authentication);
@ -4188,7 +4190,9 @@ class Core {
Map<Long, ContactInfo[]> messageInfo = new HashMap<>();
for (int m = 0; m < messages.size() && m < MAX_NOTIFICATION_DISPLAY; m++) {
TupleMessageEx message = messages.get(m);
ContactInfo[] info = ContactInfo.get(context, message.account, message.folderType, message.from);
ContactInfo[] info = ContactInfo.get(context,
message.account, message.folderType,
message.bimi_selector, message.from);
Address[] modified = (message.from == null
? new InternetAddress[0]

@ -65,7 +65,7 @@ import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_PASSWORD;
// https://developer.android.com/topic/libraries/architecture/room.html
@Database(
version = 200,
version = 201,
entities = {
EntityIdentity.class,
EntityAccount.class,
@ -2041,6 +2041,12 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `message` ADD COLUMN `blocklist` INTEGER");
}
}).addMigrations(new Migration(200, 201) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
Log.i("DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `message` ADD COLUMN `bimi_selector` TEXT");
}
}).addMigrations(new Migration(998, 999) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
Log.i("DB migration from version " + startVersion + " to " + endVersion);

@ -140,6 +140,7 @@ public class EntityMessage implements Serializable {
public Integer dsn;
public Boolean receipt_request;
public Address[] receipt_to;
public String bimi_selector;
public Boolean dkim;
public Boolean spf;
public Boolean dmarc;
@ -526,6 +527,7 @@ public class EntityMessage implements Serializable {
Objects.equals(this.dsn, other.dsn) &&
Objects.equals(this.receipt_request, other.receipt_request) &&
MessageHelper.equal(this.receipt_to, other.receipt_to) &&
Objects.equals(this.bimi_selector, other.bimi_selector) &&
Objects.equals(this.dkim, other.dkim) &&
Objects.equals(this.spf, other.spf) &&
Objects.equals(this.dmarc, other.dmarc) &&

@ -1217,6 +1217,32 @@ public class MessageHelper {
return getAddressHeader("Disposition-Notification-To");
}
String getBimiSelector() throws MessagingException {
ensureHeaders();
// BIMI-Selector: v=BIMI1; s=selector;
String header = imessage.getHeader("BIMI-Selector", null);
if (header == null)
return null;
header = header.toLowerCase(Locale.ROOT);
int s = header.indexOf("s=");
if (s < 0)
return null;
int e = header.indexOf(';', s + 2);
if (e < 0)
e = header.length();
String selector = header.substring(s + 2, e);
if (TextUtils.isEmpty(selector))
return null;
Log.i("BIMI selector=" + selector);
return selector;
}
String[] getAuthentication() throws MessagingException {
ensureHeaders();

Loading…
Cancel
Save