get rid of legacy Jid wrapper around jxmpp
This commit is contained in:
parent
6845380be5
commit
3c42066a7c
|
@ -5,7 +5,6 @@ import androidx.room.Room;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.IDs;
|
import im.conversations.android.IDs;
|
||||||
import im.conversations.android.database.ConversationsDatabase;
|
import im.conversations.android.database.ConversationsDatabase;
|
||||||
import im.conversations.android.database.entity.AccountEntity;
|
import im.conversations.android.database.entity.AccountEntity;
|
||||||
|
@ -28,12 +27,16 @@ import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class TransformationTest {
|
public class TransformationTest {
|
||||||
|
|
||||||
private static final Jid ACCOUNT = Jid.of("user@example.com");
|
private static final BareJid ACCOUNT = JidCreate.bareFromOrThrowUnchecked("user@example.com");
|
||||||
private static final Jid REMOTE = Jid.of("juliet@example.com");
|
private static final BareJid REMOTE = JidCreate.bareFromOrThrowUnchecked("juliet@example.com");
|
||||||
|
|
||||||
private static final String GREETING = "Hi Juliet. How are you?";
|
private static final String GREETING = "Hi Juliet. How are you?";
|
||||||
|
|
||||||
|
@ -55,11 +58,11 @@ public class TransformationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void reactionBeforeOriginal() {
|
public void reactionBeforeOriginal() throws XmppStringprepException {
|
||||||
final var reactionMessage = new Message();
|
final var reactionMessage = new Message();
|
||||||
reactionMessage.setId("2");
|
reactionMessage.setId("2");
|
||||||
reactionMessage.setTo(ACCOUNT);
|
reactionMessage.setTo(ACCOUNT);
|
||||||
reactionMessage.setFrom(REMOTE.withResource("junit"));
|
reactionMessage.setFrom(JidCreate.fullFrom(REMOTE, Resourcepart.from("junit")));
|
||||||
final var reactions = reactionMessage.addExtension(new Reactions());
|
final var reactions = reactionMessage.addExtension(new Reactions());
|
||||||
reactions.setId("1");
|
reactions.setId("1");
|
||||||
final var reaction = reactions.addExtension(new Reaction());
|
final var reaction = reactions.addExtension(new Reaction());
|
||||||
|
@ -69,7 +72,7 @@ public class TransformationTest {
|
||||||
final var originalMessage = new Message();
|
final var originalMessage = new Message();
|
||||||
originalMessage.setId("1");
|
originalMessage.setId("1");
|
||||||
originalMessage.setTo(REMOTE);
|
originalMessage.setTo(REMOTE);
|
||||||
originalMessage.setFrom(ACCOUNT.withResource("junit"));
|
originalMessage.setFrom(JidCreate.fullFrom(ACCOUNT, Resourcepart.from(("junit"))));
|
||||||
final var body = originalMessage.addExtension(new Body());
|
final var body = originalMessage.addExtension(new Body());
|
||||||
body.setContent(GREETING);
|
body.setContent(GREETING);
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
|
@ -86,28 +89,28 @@ public class TransformationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void multipleReactions() {
|
public void multipleReactions() throws XmppStringprepException {
|
||||||
final var group = Jid.ofEscaped("a@group.example.com");
|
final var group = JidCreate.bareFrom("a@group.example.com");
|
||||||
final var message = new Message(Message.Type.GROUPCHAT);
|
final var message = new Message(Message.Type.GROUPCHAT);
|
||||||
message.addExtension(new Body("Please give me a thumbs up"));
|
message.addExtension(new Body("Please give me a thumbs up"));
|
||||||
message.setFrom(group.withResource("user-a"));
|
message.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-a")));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(message, Instant.now(), REMOTE, "stanza-a", "id-user-a"));
|
Transformation.of(message, Instant.now(), REMOTE, "stanza-a", "id-user-a"));
|
||||||
|
|
||||||
final var reactionA = new Message(Message.Type.GROUPCHAT);
|
final var reactionA = new Message(Message.Type.GROUPCHAT);
|
||||||
reactionA.setFrom(group.withResource("user-b"));
|
reactionA.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-b")));
|
||||||
reactionA.addExtension(Reactions.to("stanza-a")).addExtension(new Reaction("Y"));
|
reactionA.addExtension(Reactions.to("stanza-a")).addExtension(new Reaction("Y"));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(reactionA, Instant.now(), REMOTE, "stanza-b", "id-user-b"));
|
Transformation.of(reactionA, Instant.now(), REMOTE, "stanza-b", "id-user-b"));
|
||||||
|
|
||||||
final var reactionB = new Message(Message.Type.GROUPCHAT);
|
final var reactionB = new Message(Message.Type.GROUPCHAT);
|
||||||
reactionB.setFrom(group.withResource("user-c"));
|
reactionB.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-c")));
|
||||||
reactionB.addExtension(Reactions.to("stanza-a")).addExtension(new Reaction("Y"));
|
reactionB.addExtension(Reactions.to("stanza-a")).addExtension(new Reaction("Y"));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(reactionB, Instant.now(), REMOTE, "stanza-c", "id-user-c"));
|
Transformation.of(reactionB, Instant.now(), REMOTE, "stanza-c", "id-user-c"));
|
||||||
|
|
||||||
final var reactionC = new Message(Message.Type.GROUPCHAT);
|
final var reactionC = new Message(Message.Type.GROUPCHAT);
|
||||||
reactionC.setFrom(group.withResource("user-d"));
|
reactionC.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-d")));
|
||||||
final var reactions = reactionC.addExtension(Reactions.to("stanza-a"));
|
final var reactions = reactionC.addExtension(Reactions.to("stanza-a"));
|
||||||
reactions.addExtension(new Reaction("Y"));
|
reactions.addExtension(new Reaction("Y"));
|
||||||
reactions.addExtension(new Reaction("Z"));
|
reactions.addExtension(new Reaction("Z"));
|
||||||
|
@ -128,12 +131,12 @@ public class TransformationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void correctionBeforeOriginal() {
|
public void correctionBeforeOriginal() throws XmppStringprepException {
|
||||||
|
|
||||||
final var messageCorrection = new Message();
|
final var messageCorrection = new Message();
|
||||||
messageCorrection.setId("2");
|
messageCorrection.setId("2");
|
||||||
messageCorrection.setTo(ACCOUNT);
|
messageCorrection.setTo(ACCOUNT);
|
||||||
messageCorrection.setFrom(REMOTE.withResource("junit"));
|
messageCorrection.setFrom(JidCreate.fullFrom(REMOTE, Resourcepart.from("junit")));
|
||||||
messageCorrection.addExtension(new Body()).setContent("Hi example!");
|
messageCorrection.addExtension(new Body()).setContent("Hi example!");
|
||||||
messageCorrection.addExtension(new Replace()).setId("1");
|
messageCorrection.addExtension(new Replace()).setId("1");
|
||||||
|
|
||||||
|
@ -146,7 +149,7 @@ public class TransformationTest {
|
||||||
final var messageWithTypo = new Message();
|
final var messageWithTypo = new Message();
|
||||||
messageWithTypo.setId("1");
|
messageWithTypo.setId("1");
|
||||||
messageWithTypo.setTo(ACCOUNT);
|
messageWithTypo.setTo(ACCOUNT);
|
||||||
messageWithTypo.setFrom(REMOTE.withResource("junit"));
|
messageWithTypo.setFrom(JidCreate.fullFrom(REMOTE, Resourcepart.from("junit")));
|
||||||
messageWithTypo.addExtension(new Body()).setContent("Hii example!");
|
messageWithTypo.addExtension(new Body()).setContent("Hii example!");
|
||||||
|
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
|
@ -163,12 +166,12 @@ public class TransformationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void correctionAfterOriginal() {
|
public void correctionAfterOriginal() throws XmppStringprepException {
|
||||||
|
|
||||||
final var messageWithTypo = new Message();
|
final var messageWithTypo = new Message();
|
||||||
messageWithTypo.setId("1");
|
messageWithTypo.setId("1");
|
||||||
messageWithTypo.setTo(ACCOUNT);
|
messageWithTypo.setTo(ACCOUNT);
|
||||||
messageWithTypo.setFrom(REMOTE.withResource("junit"));
|
messageWithTypo.setFrom(JidCreate.fullFrom(REMOTE, Resourcepart.from("junit")));
|
||||||
messageWithTypo.addExtension(new Body()).setContent("Hii example!");
|
messageWithTypo.addExtension(new Body()).setContent("Hii example!");
|
||||||
|
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
|
@ -179,7 +182,7 @@ public class TransformationTest {
|
||||||
final var messageCorrection = new Message();
|
final var messageCorrection = new Message();
|
||||||
messageCorrection.setId("2");
|
messageCorrection.setId("2");
|
||||||
messageCorrection.setTo(ACCOUNT);
|
messageCorrection.setTo(ACCOUNT);
|
||||||
messageCorrection.setFrom(REMOTE.withResource("junit"));
|
messageCorrection.setFrom(JidCreate.fullFrom(REMOTE, Resourcepart.from("junit")));
|
||||||
messageCorrection.addExtension(new Body()).setContent("Hi example!");
|
messageCorrection.addExtension(new Body()).setContent("Hi example!");
|
||||||
messageCorrection.addExtension(new Replace()).setId("1");
|
messageCorrection.addExtension(new Replace()).setId("1");
|
||||||
|
|
||||||
|
@ -197,22 +200,22 @@ public class TransformationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void replacingReactions() {
|
public void replacingReactions() throws XmppStringprepException {
|
||||||
final var group = Jid.ofEscaped("a@group.example.com");
|
final var group = JidCreate.bareFrom("a@group.example.com");
|
||||||
final var message = new Message(Message.Type.GROUPCHAT);
|
final var message = new Message(Message.Type.GROUPCHAT);
|
||||||
message.addExtension(new Body("Please give me a thumbs up"));
|
message.addExtension(new Body("Please give me a thumbs up"));
|
||||||
message.setFrom(group.withResource("user-a"));
|
message.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-a")));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(message, Instant.now(), REMOTE, "stanza-a", "id-user-a"));
|
Transformation.of(message, Instant.now(), REMOTE, "stanza-a", "id-user-a"));
|
||||||
|
|
||||||
final var reactionA = new Message(Message.Type.GROUPCHAT);
|
final var reactionA = new Message(Message.Type.GROUPCHAT);
|
||||||
reactionA.setFrom(group.withResource("user-b"));
|
reactionA.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-b")));
|
||||||
reactionA.addExtension(Reactions.to("stanza-a")).addExtension(new Reaction("N"));
|
reactionA.addExtension(Reactions.to("stanza-a")).addExtension(new Reaction("N"));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(reactionA, Instant.now(), REMOTE, "stanza-b", "id-user-b"));
|
Transformation.of(reactionA, Instant.now(), REMOTE, "stanza-b", "id-user-b"));
|
||||||
|
|
||||||
final var reactionB = new Message(Message.Type.GROUPCHAT);
|
final var reactionB = new Message(Message.Type.GROUPCHAT);
|
||||||
reactionB.setFrom(group.withResource("user-b"));
|
reactionB.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-b")));
|
||||||
reactionB.addExtension(Reactions.to("stanza-a")).addExtension(new Reaction("Y"));
|
reactionB.addExtension(Reactions.to("stanza-a")).addExtension(new Reaction("Y"));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(reactionB, Instant.now(), REMOTE, "stanza-c", "id-user-b"));
|
Transformation.of(reactionB, Instant.now(), REMOTE, "stanza-c", "id-user-b"));
|
||||||
|
@ -224,8 +227,9 @@ public class TransformationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void twoCorrectionsOneReactionBeforeOriginalInGroupChat() {
|
public void twoCorrectionsOneReactionBeforeOriginalInGroupChat()
|
||||||
final var group = Jid.ofEscaped("a@group.example.com");
|
throws XmppStringprepException {
|
||||||
|
final var group = JidCreate.bareFrom("a@group.example.com");
|
||||||
final var ogStanzaId = "og-stanza-id";
|
final var ogStanzaId = "og-stanza-id";
|
||||||
final var ogMessageId = "og-message-id";
|
final var ogMessageId = "og-message-id";
|
||||||
|
|
||||||
|
@ -234,7 +238,7 @@ public class TransformationTest {
|
||||||
// m1.setId(ogMessageId);
|
// m1.setId(ogMessageId);
|
||||||
m1.addExtension(new Body("Please give me an thumbs up"));
|
m1.addExtension(new Body("Please give me an thumbs up"));
|
||||||
m1.addExtension(new Replace()).setId(ogMessageId);
|
m1.addExtension(new Replace()).setId(ogMessageId);
|
||||||
m1.setFrom(group.withResource("user-a"));
|
m1.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-a")));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(
|
Transformation.of(
|
||||||
m1,
|
m1,
|
||||||
|
@ -248,7 +252,7 @@ public class TransformationTest {
|
||||||
// m2.setId(ogMessageId);
|
// m2.setId(ogMessageId);
|
||||||
m2.addExtension(new Body("Please give me a thumbs up"));
|
m2.addExtension(new Body("Please give me a thumbs up"));
|
||||||
m2.addExtension(new Replace()).setId(ogMessageId);
|
m2.addExtension(new Replace()).setId(ogMessageId);
|
||||||
m2.setFrom(group.withResource("user-a"));
|
m2.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-a")));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(
|
Transformation.of(
|
||||||
m2,
|
m2,
|
||||||
|
@ -259,7 +263,7 @@ public class TransformationTest {
|
||||||
|
|
||||||
// a reaction
|
// a reaction
|
||||||
final var reactionB = new Message(Message.Type.GROUPCHAT);
|
final var reactionB = new Message(Message.Type.GROUPCHAT);
|
||||||
reactionB.setFrom(group.withResource("user-b"));
|
reactionB.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-b")));
|
||||||
reactionB.addExtension(Reactions.to(ogStanzaId)).addExtension(new Reaction("Y"));
|
reactionB.addExtension(Reactions.to(ogStanzaId)).addExtension(new Reaction("Y"));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(
|
Transformation.of(
|
||||||
|
@ -269,7 +273,7 @@ public class TransformationTest {
|
||||||
final var m4 = new Message(Message.Type.GROUPCHAT);
|
final var m4 = new Message(Message.Type.GROUPCHAT);
|
||||||
m4.setId(ogMessageId);
|
m4.setId(ogMessageId);
|
||||||
m4.addExtension(new Body("Please give me thumbs up"));
|
m4.addExtension(new Body("Please give me thumbs up"));
|
||||||
m4.setFrom(group.withResource("user-a"));
|
m4.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-a")));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(m4, Instant.ofEpochMilli(1000), REMOTE, ogStanzaId, "id-user-a"));
|
Transformation.of(m4, Instant.ofEpochMilli(1000), REMOTE, ogStanzaId, "id-user-a"));
|
||||||
|
|
||||||
|
@ -283,14 +287,15 @@ public class TransformationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void twoReactionsOneCorrectionBeforeOriginalInGroupChat() {
|
public void twoReactionsOneCorrectionBeforeOriginalInGroupChat()
|
||||||
final var group = Jid.ofEscaped("a@group.example.com");
|
throws XmppStringprepException {
|
||||||
|
final var group = JidCreate.bareFrom("a@group.example.com");
|
||||||
final var ogStanzaId = "og-stanza-id";
|
final var ogStanzaId = "og-stanza-id";
|
||||||
final var ogMessageId = "og-message-id";
|
final var ogMessageId = "og-message-id";
|
||||||
|
|
||||||
// first reaction
|
// first reaction
|
||||||
final var reactionA = new Message(Message.Type.GROUPCHAT);
|
final var reactionA = new Message(Message.Type.GROUPCHAT);
|
||||||
reactionA.setFrom(group.withResource("user-b"));
|
reactionA.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-b")));
|
||||||
reactionA.addExtension(Reactions.to(ogStanzaId)).addExtension(new Reaction("Y"));
|
reactionA.addExtension(Reactions.to(ogStanzaId)).addExtension(new Reaction("Y"));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(
|
Transformation.of(
|
||||||
|
@ -298,7 +303,7 @@ public class TransformationTest {
|
||||||
|
|
||||||
// second reaction
|
// second reaction
|
||||||
final var reactionB = new Message(Message.Type.GROUPCHAT);
|
final var reactionB = new Message(Message.Type.GROUPCHAT);
|
||||||
reactionB.setFrom(group.withResource("user-c"));
|
reactionB.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-c")));
|
||||||
reactionB.addExtension(Reactions.to(ogStanzaId)).addExtension(new Reaction("Y"));
|
reactionB.addExtension(Reactions.to(ogStanzaId)).addExtension(new Reaction("Y"));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(
|
Transformation.of(
|
||||||
|
@ -308,7 +313,7 @@ public class TransformationTest {
|
||||||
final var m1 = new Message(Message.Type.GROUPCHAT);
|
final var m1 = new Message(Message.Type.GROUPCHAT);
|
||||||
m1.addExtension(new Body("Please give me a thumbs up"));
|
m1.addExtension(new Body("Please give me a thumbs up"));
|
||||||
m1.addExtension(new Replace()).setId(ogMessageId);
|
m1.addExtension(new Replace()).setId(ogMessageId);
|
||||||
m1.setFrom(group.withResource("user-a"));
|
m1.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-a")));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(
|
Transformation.of(
|
||||||
m1,
|
m1,
|
||||||
|
@ -321,7 +326,7 @@ public class TransformationTest {
|
||||||
final var m4 = new Message(Message.Type.GROUPCHAT);
|
final var m4 = new Message(Message.Type.GROUPCHAT);
|
||||||
m4.setId(ogMessageId);
|
m4.setId(ogMessageId);
|
||||||
m4.addExtension(new Body("Please give me thumbs up (Typo)"));
|
m4.addExtension(new Body("Please give me thumbs up (Typo)"));
|
||||||
m4.setFrom(group.withResource("user-a"));
|
m4.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-a")));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(m4, Instant.ofEpochMilli(1000), REMOTE, ogStanzaId, "id-user-a"));
|
Transformation.of(m4, Instant.ofEpochMilli(1000), REMOTE, ogStanzaId, "id-user-a"));
|
||||||
|
|
||||||
|
@ -337,8 +342,8 @@ public class TransformationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void twoReactionsInGroupChat() {
|
public void twoReactionsInGroupChat() throws XmppStringprepException {
|
||||||
final var group = Jid.ofEscaped("a@group.example.com");
|
final var group = JidCreate.bareFrom("a@group.example.com");
|
||||||
final var ogStanzaId = "og-stanza-id";
|
final var ogStanzaId = "og-stanza-id";
|
||||||
final var ogMessageId = "og-message-id";
|
final var ogMessageId = "og-message-id";
|
||||||
|
|
||||||
|
@ -346,13 +351,13 @@ public class TransformationTest {
|
||||||
final var m4 = new Message(Message.Type.GROUPCHAT);
|
final var m4 = new Message(Message.Type.GROUPCHAT);
|
||||||
m4.setId(ogMessageId);
|
m4.setId(ogMessageId);
|
||||||
m4.addExtension(new Body("Please give me a thumbs up"));
|
m4.addExtension(new Body("Please give me a thumbs up"));
|
||||||
m4.setFrom(group.withResource("user-a"));
|
m4.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-a")));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(m4, Instant.ofEpochMilli(1000), REMOTE, ogStanzaId, "id-user-a"));
|
Transformation.of(m4, Instant.ofEpochMilli(1000), REMOTE, ogStanzaId, "id-user-a"));
|
||||||
|
|
||||||
// first reaction
|
// first reaction
|
||||||
final var reactionA = new Message(Message.Type.GROUPCHAT);
|
final var reactionA = new Message(Message.Type.GROUPCHAT);
|
||||||
reactionA.setFrom(group.withResource("user-b"));
|
reactionA.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-b")));
|
||||||
reactionA.addExtension(Reactions.to(ogStanzaId)).addExtension(new Reaction("Y"));
|
reactionA.addExtension(Reactions.to(ogStanzaId)).addExtension(new Reaction("Y"));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(
|
Transformation.of(
|
||||||
|
@ -360,7 +365,7 @@ public class TransformationTest {
|
||||||
|
|
||||||
// second reaction
|
// second reaction
|
||||||
final var reactionB = new Message(Message.Type.GROUPCHAT);
|
final var reactionB = new Message(Message.Type.GROUPCHAT);
|
||||||
reactionB.setFrom(group.withResource("user-c"));
|
reactionB.setFrom(JidCreate.fullFrom(group, Resourcepart.from("user-c")));
|
||||||
reactionB.addExtension(Reactions.to(ogStanzaId)).addExtension(new Reaction("Y"));
|
reactionB.addExtension(Reactions.to(ogStanzaId)).addExtension(new Reaction("Y"));
|
||||||
this.transformer.transform(
|
this.transformer.transform(
|
||||||
Transformation.of(
|
Transformation.of(
|
||||||
|
@ -378,11 +383,11 @@ public class TransformationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void inReplyTo() {
|
public void inReplyTo() throws XmppStringprepException {
|
||||||
final var m1 = new Message();
|
final var m1 = new Message();
|
||||||
m1.setId("1");
|
m1.setId("1");
|
||||||
m1.setTo(ACCOUNT);
|
m1.setTo(ACCOUNT);
|
||||||
m1.setFrom(REMOTE.withResource("junit"));
|
m1.setFrom(JidCreate.fullFrom(REMOTE, Resourcepart.from("junit")));
|
||||||
m1.addExtension(new Body("Hi. How are you?"));
|
m1.addExtension(new Body("Hi. How are you?"));
|
||||||
|
|
||||||
this.transformer.transform(Transformation.of(m1, Instant.now(), REMOTE, "stanza-a", null));
|
this.transformer.transform(Transformation.of(m1, Instant.now(), REMOTE, "stanza-a", null));
|
||||||
|
@ -411,18 +416,18 @@ public class TransformationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void messageWithReceipt() {
|
public void messageWithReceipt() throws XmppStringprepException {
|
||||||
final var m1 = new Message();
|
final var m1 = new Message();
|
||||||
m1.setId("1");
|
m1.setId("1");
|
||||||
m1.setTo(REMOTE);
|
m1.setTo(REMOTE);
|
||||||
m1.setFrom(ACCOUNT.withResource("junit"));
|
m1.setFrom(JidCreate.fullFrom(ACCOUNT, Resourcepart.from("junit")));
|
||||||
m1.addExtension(new Body("Hi. How are you?"));
|
m1.addExtension(new Body("Hi. How are you?"));
|
||||||
|
|
||||||
this.transformer.transform(Transformation.of(m1, Instant.now(), REMOTE, null, null));
|
this.transformer.transform(Transformation.of(m1, Instant.now(), REMOTE, null, null));
|
||||||
|
|
||||||
final var m2 = new Message();
|
final var m2 = new Message();
|
||||||
m2.setTo(ACCOUNT.withResource("junit"));
|
m2.setTo(JidCreate.fullFrom(ACCOUNT, Resourcepart.from("junit")));
|
||||||
m2.setFrom(REMOTE.withResource("junit"));
|
m2.setFrom(JidCreate.fullFrom(REMOTE, Resourcepart.from("junit")));
|
||||||
m2.addExtension(new Received()).setId("1");
|
m2.addExtension(new Received()).setId("1");
|
||||||
|
|
||||||
this.transformer.transform(Transformation.of(m2, Instant.now(), REMOTE, null, null));
|
this.transformer.transform(Transformation.of(m2, Instant.now(), REMOTE, null, null));
|
||||||
|
@ -434,10 +439,10 @@ public class TransformationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void messageAndRetraction() {
|
public void messageAndRetraction() throws XmppStringprepException {
|
||||||
final var m1 = new Message();
|
final var m1 = new Message();
|
||||||
m1.setTo(ACCOUNT);
|
m1.setTo(ACCOUNT);
|
||||||
m1.setFrom(REMOTE.withResource("junit"));
|
m1.setFrom(JidCreate.fullFrom(REMOTE, Resourcepart.from("junit")));
|
||||||
m1.setId("m1");
|
m1.setId("m1");
|
||||||
m1.addExtension(new Body("It is raining outside"));
|
m1.addExtension(new Body("It is raining outside"));
|
||||||
|
|
||||||
|
@ -445,7 +450,7 @@ public class TransformationTest {
|
||||||
|
|
||||||
final var m2 = new Message();
|
final var m2 = new Message();
|
||||||
m2.setTo(ACCOUNT);
|
m2.setTo(ACCOUNT);
|
||||||
m2.setFrom(REMOTE.withResource("junit"));
|
m2.setFrom(JidCreate.fullFrom(REMOTE, Resourcepart.from("junit")));
|
||||||
m2.addExtension(new Retract()).setId("m1");
|
m2.addExtension(new Retract()).setId("m1");
|
||||||
|
|
||||||
this.transformer.transform(Transformation.of(m2, Instant.now(), REMOTE, null, null));
|
this.transformer.transform(Transformation.of(m2, Instant.now(), REMOTE, null, null));
|
||||||
|
|
|
@ -10,6 +10,12 @@ public class IDs {
|
||||||
|
|
||||||
private static final long UUID_VERSION_MASK = 4 << 12;
|
private static final long UUID_VERSION_MASK = 4 << 12;
|
||||||
|
|
||||||
|
public static String huge() {
|
||||||
|
final var random = new byte[96];
|
||||||
|
Conversations.SECURE_RANDOM.nextBytes(random);
|
||||||
|
return BaseEncoding.base64Url().encode(random);
|
||||||
|
}
|
||||||
|
|
||||||
public static String medium() {
|
public static String medium() {
|
||||||
final var random = new byte[9];
|
final var random = new byte[9];
|
||||||
Conversations.SECURE_RANDOM.nextBytes(random);
|
Conversations.SECURE_RANDOM.nextBytes(random);
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package im.conversations.android.database;
|
package im.conversations.android.database;
|
||||||
|
|
||||||
import androidx.room.TypeConverter;
|
import androidx.room.TypeConverter;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import com.google.common.base.Strings;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
import org.whispersystems.libsignal.IdentityKey;
|
import org.whispersystems.libsignal.IdentityKey;
|
||||||
import org.whispersystems.libsignal.IdentityKeyPair;
|
import org.whispersystems.libsignal.IdentityKeyPair;
|
||||||
import org.whispersystems.libsignal.InvalidKeyException;
|
import org.whispersystems.libsignal.InvalidKeyException;
|
||||||
|
@ -26,13 +30,35 @@ public final class Converters {
|
||||||
}
|
}
|
||||||
|
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
public static Jid toJid(final String input) {
|
public static BareJid toBareJid(final String input) {
|
||||||
return input == null ? null : Jid.ofEscaped(input);
|
return input == null ? null : JidCreate.bareFromOrThrowUnchecked(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
public static String fromBareJid(final BareJid jid) {
|
||||||
|
return jid == null ? null : jid.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
public static String fromJid(final Jid jid) {
|
public static String fromJid(final Jid jid) {
|
||||||
return jid == null ? null : jid.toEscapedString();
|
return jid == null ? null : jid.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
public static Jid toJid(final String input) {
|
||||||
|
return input == null ? null : JidCreate.fromOrThrowUnchecked(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
public static Resourcepart toResourcePart(final String input) {
|
||||||
|
return Strings.isNullOrEmpty(input)
|
||||||
|
? Resourcepart.EMPTY
|
||||||
|
: Resourcepart.fromOrThrowUnchecked(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
public static String fromResourcePart(final Resourcepart resourcepart) {
|
||||||
|
return resourcepart == null ? null : resourcepart.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
|
|
|
@ -159,14 +159,14 @@ public class CredentialStore {
|
||||||
|
|
||||||
private Credential getOrEmpty(final Account account) {
|
private Credential getOrEmpty(final Account account) {
|
||||||
final Map<String, Credential> store = loadOrEmpty();
|
final Map<String, Credential> store = loadOrEmpty();
|
||||||
final Credential credential = store.get(account.address.toEscapedString());
|
final Credential credential = store.get(account.address.toString());
|
||||||
return credential == null ? Credential.empty() : credential;
|
return credential == null ? Credential.empty() : credential;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void set(@NonNull final Account account, @NonNull final Credential credential)
|
private void set(@NonNull final Account account, @NonNull final Credential credential)
|
||||||
throws GeneralSecurityException, IOException {
|
throws GeneralSecurityException, IOException {
|
||||||
final HashMap<String, Credential> credentialStore = new HashMap<>(loadOrEmpty());
|
final HashMap<String, Credential> credentialStore = new HashMap<>(loadOrEmpty());
|
||||||
credentialStore.put(account.address.toEscapedString(), credential);
|
credentialStore.put(account.address.toString(), credential);
|
||||||
store(credentialStore);
|
store(credentialStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,11 @@ import androidx.room.Insert;
|
||||||
import androidx.room.OnConflictStrategy;
|
import androidx.room.OnConflictStrategy;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.AccountEntity;
|
import im.conversations.android.database.entity.AccountEntity;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
import im.conversations.android.database.model.Connection;
|
import im.conversations.android.database.model.Connection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
public interface AccountDao {
|
public interface AccountDao {
|
||||||
|
@ -21,7 +21,7 @@ public interface AccountDao {
|
||||||
ListenableFuture<List<Account>> getEnabledAccounts();
|
ListenableFuture<List<Account>> getEnabledAccounts();
|
||||||
|
|
||||||
@Query("SELECT id,address,randomSeed FROM account WHERE address=:address AND enabled=1")
|
@Query("SELECT id,address,randomSeed FROM account WHERE address=:address AND enabled=1")
|
||||||
ListenableFuture<Account> getEnabledAccount(Jid address);
|
ListenableFuture<Account> getEnabledAccount(BareJid address);
|
||||||
|
|
||||||
@Query("SELECT id,address,randomSeed FROM account WHERE id=:id AND enabled=1")
|
@Query("SELECT id,address,randomSeed FROM account WHERE id=:id AND enabled=1")
|
||||||
ListenableFuture<Account> getEnabledAccount(long id);
|
ListenableFuture<Account> getEnabledAccount(long id);
|
||||||
|
|
|
@ -4,12 +4,12 @@ import androidx.room.Dao;
|
||||||
import androidx.room.Insert;
|
import androidx.room.Insert;
|
||||||
import androidx.room.OnConflictStrategy;
|
import androidx.room.OnConflictStrategy;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.AvatarAdditionalEntity;
|
import im.conversations.android.database.entity.AvatarAdditionalEntity;
|
||||||
import im.conversations.android.database.entity.AvatarEntity;
|
import im.conversations.android.database.entity.AvatarEntity;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
import im.conversations.android.xmpp.model.avatar.Info;
|
import im.conversations.android.xmpp.model.avatar.Info;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
public abstract class AvatarDao {
|
public abstract class AvatarDao {
|
||||||
|
@ -22,7 +22,7 @@ public abstract class AvatarDao {
|
||||||
|
|
||||||
public void set(
|
public void set(
|
||||||
final Account account,
|
final Account account,
|
||||||
final Jid address,
|
final BareJid address,
|
||||||
final Info thumbnail,
|
final Info thumbnail,
|
||||||
final Collection<Info> additional) {
|
final Collection<Info> additional) {
|
||||||
final long id = insert(AvatarEntity.of(account, address, thumbnail));
|
final long id = insert(AvatarEntity.of(account, address, thumbnail));
|
||||||
|
|
|
@ -6,7 +6,6 @@ import androidx.room.OnConflictStrategy;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
import androidx.room.Transaction;
|
import androidx.room.Transaction;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.AxolotlDeviceListEntity;
|
import im.conversations.android.database.entity.AxolotlDeviceListEntity;
|
||||||
import im.conversations.android.database.entity.AxolotlDeviceListItemEntity;
|
import im.conversations.android.database.entity.AxolotlDeviceListItemEntity;
|
||||||
import im.conversations.android.database.entity.AxolotlIdentityEntity;
|
import im.conversations.android.database.entity.AxolotlIdentityEntity;
|
||||||
|
@ -19,6 +18,7 @@ import im.conversations.android.xmpp.model.error.Condition;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
import org.whispersystems.libsignal.IdentityKey;
|
import org.whispersystems.libsignal.IdentityKey;
|
||||||
import org.whispersystems.libsignal.IdentityKeyPair;
|
import org.whispersystems.libsignal.IdentityKeyPair;
|
||||||
import org.whispersystems.libsignal.ecc.Curve;
|
import org.whispersystems.libsignal.ecc.Curve;
|
||||||
|
@ -36,7 +36,7 @@ public abstract class AxolotlDao {
|
||||||
protected abstract void insert(Collection<AxolotlDeviceListItemEntity> entities);
|
protected abstract void insert(Collection<AxolotlDeviceListItemEntity> entities);
|
||||||
|
|
||||||
@Transaction
|
@Transaction
|
||||||
public void setDeviceList(Account account, Jid from, Set<Integer> deviceIds) {
|
public void setDeviceList(Account account, BareJid from, Set<Integer> deviceIds) {
|
||||||
final var listId = insert(AxolotlDeviceListEntity.of(account.id, from));
|
final var listId = insert(AxolotlDeviceListEntity.of(account.id, from));
|
||||||
insert(
|
insert(
|
||||||
Collections2.transform(
|
Collections2.transform(
|
||||||
|
@ -47,15 +47,17 @@ public abstract class AxolotlDao {
|
||||||
"SELECT EXISTS(SELECT deviceId FROM axolotl_device_list JOIN axolotl_device_list_item"
|
"SELECT EXISTS(SELECT deviceId FROM axolotl_device_list JOIN axolotl_device_list_item"
|
||||||
+ " ON axolotl_device_list.id=axolotl_device_list_item.deviceListId WHERE"
|
+ " ON axolotl_device_list.id=axolotl_device_list_item.deviceListId WHERE"
|
||||||
+ " accountId=:account AND address=:address AND deviceId=:deviceId)")
|
+ " accountId=:account AND address=:address AND deviceId=:deviceId)")
|
||||||
public abstract boolean hasDeviceId(final long account, final Jid address, final int deviceId);
|
public abstract boolean hasDeviceId(
|
||||||
|
final long account, final BareJid address, final int deviceId);
|
||||||
|
|
||||||
@Transaction
|
@Transaction
|
||||||
public void setDeviceListError(final Account account, final Jid address, Condition condition) {
|
public void setDeviceListError(
|
||||||
|
final Account account, final BareJid address, Condition condition) {
|
||||||
insert(AxolotlDeviceListEntity.of(account.id, address, condition.getName()));
|
insert(AxolotlDeviceListEntity.of(account.id, address, condition.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transaction
|
@Transaction
|
||||||
public void setDeviceListParsingError(final Account account, final Jid address) {
|
public void setDeviceListParsingError(final Account account, final BareJid address) {
|
||||||
insert(AxolotlDeviceListEntity.ofParsingIssue(account.id, address));
|
insert(AxolotlDeviceListEntity.ofParsingIssue(account.id, address));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +98,7 @@ public abstract class AxolotlDao {
|
||||||
|
|
||||||
@Transaction
|
@Transaction
|
||||||
public boolean setIdentity(
|
public boolean setIdentity(
|
||||||
Account account, Jid address, int deviceId, IdentityKey identityKey) {
|
Account account, BareJid address, int deviceId, IdentityKey identityKey) {
|
||||||
final var existing = getIdentityKey(account.id, address, deviceId);
|
final var existing = getIdentityKey(account.id, address, deviceId);
|
||||||
if (existing == null || !existing.equals(identityKey)) {
|
if (existing == null || !existing.equals(identityKey)) {
|
||||||
insert(AxolotlIdentityEntity.of(account, address, deviceId, identityKey));
|
insert(AxolotlIdentityEntity.of(account, address, deviceId, identityKey));
|
||||||
|
@ -112,7 +114,7 @@ public abstract class AxolotlDao {
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT identityKey FROM AXOLOTL_IDENTITY WHERE accountId=:account AND"
|
"SELECT identityKey FROM AXOLOTL_IDENTITY WHERE accountId=:account AND"
|
||||||
+ " address=:address AND deviceId=:deviceId")
|
+ " address=:address AND deviceId=:deviceId")
|
||||||
protected abstract IdentityKey getIdentityKey(long account, Jid address, int deviceId);
|
protected abstract IdentityKey getIdentityKey(long account, BareJid address, int deviceId);
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT preKeyRecord FROM axolotl_pre_key WHERE accountId=:account AND"
|
"SELECT preKeyRecord FROM axolotl_pre_key WHERE accountId=:account AND"
|
||||||
|
@ -165,24 +167,25 @@ public abstract class AxolotlDao {
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT sessionRecord FROM axolotl_session WHERE accountId=:account AND"
|
"SELECT sessionRecord FROM axolotl_session WHERE accountId=:account AND"
|
||||||
+ " address=:address AND deviceId=:deviceId")
|
+ " address=:address AND deviceId=:deviceId")
|
||||||
public abstract SessionRecord getSessionRecord(long account, Jid address, int deviceId);
|
public abstract SessionRecord getSessionRecord(long account, BareJid address, int deviceId);
|
||||||
|
|
||||||
@Query("SELECT deviceId FROM axolotl_session WHERE accountId=:account AND address=:address")
|
@Query("SELECT deviceId FROM axolotl_session WHERE accountId=:account AND address=:address")
|
||||||
public abstract List<Integer> getSessionDeviceIds(long account, String address);
|
public abstract List<Integer> getSessionDeviceIds(long account, String address);
|
||||||
|
|
||||||
public void setSessionRecord(Account account, Jid address, int deviceId, SessionRecord record) {
|
public void setSessionRecord(
|
||||||
|
Account account, BareJid address, int deviceId, SessionRecord record) {
|
||||||
insert(AxolotlSessionEntity.of(account, address, deviceId, record));
|
insert(AxolotlSessionEntity.of(account, address, deviceId, record));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT EXISTS(SELECT id FROM axolotl_session WHERE accountId=:account AND"
|
"SELECT EXISTS(SELECT id FROM axolotl_session WHERE accountId=:account AND"
|
||||||
+ " address=:address AND deviceId=:deviceId)")
|
+ " address=:address AND deviceId=:deviceId)")
|
||||||
public abstract boolean hasSession(long account, Jid address, int deviceId);
|
public abstract boolean hasSession(long account, BareJid address, int deviceId);
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"DELETE FROM axolotl_session WHERE accountId=:account AND address=:address AND"
|
"DELETE FROM axolotl_session WHERE accountId=:account AND address=:address AND"
|
||||||
+ " deviceId=:deviceId")
|
+ " deviceId=:deviceId")
|
||||||
public abstract void deleteSession(long account, Jid address, int deviceId);
|
public abstract void deleteSession(long account, BareJid address, int deviceId);
|
||||||
|
|
||||||
@Query("DELETE FROM axolotl_session WHERE accountId=:account AND address=:address")
|
@Query("DELETE FROM axolotl_session WHERE accountId=:account AND address=:address")
|
||||||
public abstract void deleteSessions(long account, String address);
|
public abstract void deleteSessions(long account, String address);
|
||||||
|
|
|
@ -6,11 +6,11 @@ import androidx.room.OnConflictStrategy;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
import androidx.room.Transaction;
|
import androidx.room.Transaction;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.BlockedItemEntity;
|
import im.conversations.android.database.entity.BlockedItemEntity;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
import im.conversations.android.xmpp.model.blocking.Item;
|
import im.conversations.android.xmpp.model.blocking.Item;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
public abstract class BlockingDao {
|
public abstract class BlockingDao {
|
||||||
|
|
|
@ -5,13 +5,14 @@ import androidx.room.Insert;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
import androidx.room.Transaction;
|
import androidx.room.Transaction;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.BookmarkEntity;
|
import im.conversations.android.database.entity.BookmarkEntity;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
import im.conversations.android.xmpp.model.bookmark.Conference;
|
import im.conversations.android.xmpp.model.bookmark.Conference;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
public abstract class BookmarkDao {
|
public abstract class BookmarkDao {
|
||||||
|
@ -28,7 +29,7 @@ public abstract class BookmarkDao {
|
||||||
@Transaction
|
@Transaction
|
||||||
public void updateItems(final Account account, Map<String, Conference> items) {
|
public void updateItems(final Account account, Map<String, Conference> items) {
|
||||||
final Collection<Jid> addresses =
|
final Collection<Jid> addresses =
|
||||||
Collections2.transform(items.keySet(), BookmarkEntity::jidOrNull);
|
Collections2.transform(items.keySet(), JidCreate::fromOrNull);
|
||||||
delete(account.id, addresses);
|
delete(account.id, addresses);
|
||||||
final var entities =
|
final var entities =
|
||||||
Collections2.transform(
|
Collections2.transform(
|
||||||
|
|
|
@ -4,13 +4,13 @@ import androidx.room.Dao;
|
||||||
import androidx.room.Insert;
|
import androidx.room.Insert;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
import androidx.room.Transaction;
|
import androidx.room.Transaction;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.ChatEntity;
|
import im.conversations.android.database.entity.ChatEntity;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
import im.conversations.android.database.model.ChatIdentifier;
|
import im.conversations.android.database.model.ChatIdentifier;
|
||||||
import im.conversations.android.database.model.ChatType;
|
import im.conversations.android.database.model.ChatType;
|
||||||
import im.conversations.android.xmpp.model.stanza.Message;
|
import im.conversations.android.xmpp.model.stanza.Message;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
public abstract class ChatDao {
|
public abstract class ChatDao {
|
||||||
|
@ -38,7 +38,7 @@ public abstract class ChatDao {
|
||||||
// TODO do not create entity for 'error'
|
// TODO do not create entity for 'error'
|
||||||
final var entity = new ChatEntity();
|
final var entity = new ChatEntity();
|
||||||
entity.accountId = account.id;
|
entity.accountId = account.id;
|
||||||
entity.address = address.toEscapedString();
|
entity.address = address.toString();
|
||||||
entity.type = chatType;
|
entity.type = chatType;
|
||||||
entity.archived = true;
|
entity.archived = true;
|
||||||
final long id = insert(entity);
|
final long id = insert(entity);
|
||||||
|
|
|
@ -8,7 +8,6 @@ import androidx.room.Query;
|
||||||
import androidx.room.Transaction;
|
import androidx.room.Transaction;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.DiscoEntity;
|
import im.conversations.android.database.entity.DiscoEntity;
|
||||||
import im.conversations.android.database.entity.DiscoExtensionEntity;
|
import im.conversations.android.database.entity.DiscoExtensionEntity;
|
||||||
import im.conversations.android.database.entity.DiscoExtensionFieldEntity;
|
import im.conversations.android.database.entity.DiscoExtensionFieldEntity;
|
||||||
|
@ -27,6 +26,8 @@ import im.conversations.android.xmpp.model.disco.info.Identity;
|
||||||
import im.conversations.android.xmpp.model.disco.info.InfoQuery;
|
import im.conversations.android.xmpp.model.disco.info.InfoQuery;
|
||||||
import im.conversations.android.xmpp.model.disco.items.Item;
|
import im.conversations.android.xmpp.model.disco.items.Item;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
public abstract class DiscoDao {
|
public abstract class DiscoDao {
|
||||||
|
@ -56,7 +57,7 @@ public abstract class DiscoDao {
|
||||||
"UPDATE presence SET discoId=:discoId WHERE accountId=:account AND address=:address"
|
"UPDATE presence SET discoId=:discoId WHERE accountId=:account AND address=:address"
|
||||||
+ " AND resource=:resource")
|
+ " AND resource=:resource")
|
||||||
protected abstract void updateDiscoIdInPresence(
|
protected abstract void updateDiscoIdInPresence(
|
||||||
long account, Jid address, String resource, long discoId);
|
long account, Jid address, Resourcepart resource, long discoId);
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"UPDATE disco_item SET discoId=:discoId WHERE accountId=:account AND address=:address"
|
"UPDATE disco_item SET discoId=:discoId WHERE accountId=:account AND address=:address"
|
||||||
|
@ -131,7 +132,7 @@ public abstract class DiscoDao {
|
||||||
updateDiscoIdInPresence(
|
updateDiscoIdInPresence(
|
||||||
account,
|
account,
|
||||||
entity.address.asBareJid(),
|
entity.address.asBareJid(),
|
||||||
Strings.nullToEmpty(entity.address.getResource()),
|
entity.address.getResourceOrEmpty(),
|
||||||
discoId);
|
discoId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import androidx.room.Update;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.MessageContentEntity;
|
import im.conversations.android.database.entity.MessageContentEntity;
|
||||||
import im.conversations.android.database.entity.MessageEntity;
|
import im.conversations.android.database.entity.MessageEntity;
|
||||||
import im.conversations.android.database.entity.MessageReactionEntity;
|
import im.conversations.android.database.entity.MessageReactionEntity;
|
||||||
|
@ -27,6 +26,9 @@ import im.conversations.android.xmpp.model.reactions.Reactions;
|
||||||
import im.conversations.android.xmpp.model.stanza.Message;
|
import im.conversations.android.xmpp.model.stanza.Message;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -38,14 +40,17 @@ public abstract class MessageDao {
|
||||||
@Query(
|
@Query(
|
||||||
"UPDATE message SET acknowledged=1 WHERE messageId=:messageId AND toBare=:toBare AND"
|
"UPDATE message SET acknowledged=1 WHERE messageId=:messageId AND toBare=:toBare AND"
|
||||||
+ " toResource=NULL AND chatId IN (SELECT id FROM chat WHERE accountId=:account)")
|
+ " toResource=NULL AND chatId IN (SELECT id FROM chat WHERE accountId=:account)")
|
||||||
abstract int acknowledge(long account, String messageId, final String toBare);
|
abstract int acknowledge(long account, String messageId, final BareJid toBare);
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"UPDATE message SET acknowledged=1 WHERE messageId=:messageId AND toBare=:toBare AND"
|
"UPDATE message SET acknowledged=1 WHERE messageId=:messageId AND toBare=:toBare AND"
|
||||||
+ " toResource=:toResource AND chatId IN (SELECT id FROM chat WHERE"
|
+ " toResource=:toResource AND chatId IN (SELECT id FROM chat WHERE"
|
||||||
+ " accountId=:account)")
|
+ " accountId=:account)")
|
||||||
abstract int acknowledge(
|
abstract int acknowledge(
|
||||||
long account, final String messageId, final String toBare, final String toResource);
|
long account,
|
||||||
|
final String messageId,
|
||||||
|
final BareJid toBare,
|
||||||
|
final Resourcepart toResource);
|
||||||
|
|
||||||
public boolean acknowledge(
|
public boolean acknowledge(
|
||||||
final Account account, @NonNull final String messageId, @NonNull final Jid to) {
|
final Account account, @NonNull final String messageId, @NonNull final Jid to) {
|
||||||
|
@ -54,12 +59,10 @@ public abstract class MessageDao {
|
||||||
|
|
||||||
public boolean acknowledge(
|
public boolean acknowledge(
|
||||||
final long account, @NonNull final String messageId, @NonNull final Jid to) {
|
final long account, @NonNull final String messageId, @NonNull final Jid to) {
|
||||||
if (to.isBareJid()) {
|
if (to.hasResource()) {
|
||||||
return acknowledge(account, messageId, to.toEscapedString()) > 0;
|
return acknowledge(account, messageId, to.asBareJid(), to.getResourceOrThrow()) > 0;
|
||||||
} else {
|
} else {
|
||||||
return acknowledge(
|
return acknowledge(account, messageId, to.asBareJid()) > 0;
|
||||||
account, messageId, to.asBareJid().toEscapedString(), to.getResource())
|
|
||||||
> 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +195,7 @@ public abstract class MessageDao {
|
||||||
+ " stanzaId=:stanzaId AND (stanzaIdVerified=1 OR latestVersion IS NULL)) OR"
|
+ " stanzaId=:stanzaId AND (stanzaIdVerified=1 OR latestVersion IS NULL)) OR"
|
||||||
+ " (stanzaId IS NULL AND messageId=:messageId AND latestVersion IS NULL))")
|
+ " (stanzaId IS NULL AND messageId=:messageId AND latestVersion IS NULL))")
|
||||||
abstract MessageIdentifier get(
|
abstract MessageIdentifier get(
|
||||||
long chatId, Jid fromBare, String occupantId, String stanzaId, String messageId);
|
long chatId, BareJid fromBare, String occupantId, String stanzaId, String messageId);
|
||||||
|
|
||||||
public MessageIdentifier getOrCreateVersion(
|
public MessageIdentifier getOrCreateVersion(
|
||||||
ChatIdentifier chat,
|
ChatIdentifier chat,
|
||||||
|
@ -257,13 +260,13 @@ public abstract class MessageDao {
|
||||||
+ " chatId=:chatId AND (fromBare=:fromBare OR fromBare IS NULL) AND"
|
+ " chatId=:chatId AND (fromBare=:fromBare OR fromBare IS NULL) AND"
|
||||||
+ " (occupantId=:occupantId OR occupantId IS NULL) AND messageId=:messageId")
|
+ " (occupantId=:occupantId OR occupantId IS NULL) AND messageId=:messageId")
|
||||||
abstract MessageIdentifier getByOccupantIdAndMessageId(
|
abstract MessageIdentifier getByOccupantIdAndMessageId(
|
||||||
long chatId, Jid fromBare, String occupantId, String messageId);
|
long chatId, BareJid fromBare, String occupantId, String messageId);
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT id,stanzaId,messageId,fromBare,latestVersion as version FROM message WHERE"
|
"SELECT id,stanzaId,messageId,fromBare,latestVersion as version FROM message WHERE"
|
||||||
+ " chatId=:chatId AND (fromBare=:fromBare OR fromBare IS NULL) AND"
|
+ " chatId=:chatId AND (fromBare=:fromBare OR fromBare IS NULL) AND"
|
||||||
+ " messageId=:messageId")
|
+ " messageId=:messageId")
|
||||||
abstract MessageIdentifier getByMessageId(long chatId, Jid fromBare, String messageId);
|
abstract MessageIdentifier getByMessageId(long chatId, BareJid fromBare, String messageId);
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT id FROM message_version WHERE messageEntityId=:messageEntityId ORDER BY (CASE"
|
"SELECT id FROM message_version WHERE messageEntityId=:messageEntityId ORDER BY (CASE"
|
||||||
|
@ -393,7 +396,7 @@ public abstract class MessageDao {
|
||||||
@Query(
|
@Query(
|
||||||
"DELETE FROM message_reaction WHERE messageEntityId=:messageEntityId AND"
|
"DELETE FROM message_reaction WHERE messageEntityId=:messageEntityId AND"
|
||||||
+ " reactionBy=:fromBare")
|
+ " reactionBy=:fromBare")
|
||||||
protected abstract void deleteReactionsByFromBare(long messageEntityId, Jid fromBare);
|
protected abstract void deleteReactionsByFromBare(long messageEntityId, BareJid fromBare);
|
||||||
|
|
||||||
@Transaction
|
@Transaction
|
||||||
@Query(
|
@Query(
|
||||||
|
@ -436,7 +439,7 @@ public abstract class MessageDao {
|
||||||
@Query(
|
@Query(
|
||||||
"SELECT id FROM message WHERE chatId=:chatId AND fromBare=:fromBare AND"
|
"SELECT id FROM message WHERE chatId=:chatId AND fromBare=:fromBare AND"
|
||||||
+ " messageId=:messageId")
|
+ " messageId=:messageId")
|
||||||
protected abstract Long getMessageByMessageId(long chatId, Jid fromBare, String messageId);
|
protected abstract Long getMessageByMessageId(long chatId, BareJid fromBare, String messageId);
|
||||||
|
|
||||||
@Query("SELECT id FROM message WHERE chatId=:chatId AND stanzaId=:stanzaId")
|
@Query("SELECT id FROM message WHERE chatId=:chatId AND stanzaId=:stanzaId")
|
||||||
protected abstract Long getMessageByStanzaId(long chatId, String stanzaId);
|
protected abstract Long getMessageByStanzaId(long chatId, String stanzaId);
|
||||||
|
|
|
@ -3,9 +3,9 @@ package im.conversations.android.database.dao;
|
||||||
import androidx.room.Dao;
|
import androidx.room.Dao;
|
||||||
import androidx.room.Insert;
|
import androidx.room.Insert;
|
||||||
import androidx.room.OnConflictStrategy;
|
import androidx.room.OnConflictStrategy;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.NickEntity;
|
import im.conversations.android.database.entity.NickEntity;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
public abstract class NickDao {
|
public abstract class NickDao {
|
||||||
|
|
|
@ -6,12 +6,13 @@ import androidx.room.Dao;
|
||||||
import androidx.room.Insert;
|
import androidx.room.Insert;
|
||||||
import androidx.room.OnConflictStrategy;
|
import androidx.room.OnConflictStrategy;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.PresenceEntity;
|
import im.conversations.android.database.entity.PresenceEntity;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
import im.conversations.android.database.model.PresenceShow;
|
import im.conversations.android.database.model.PresenceShow;
|
||||||
import im.conversations.android.database.model.PresenceType;
|
import im.conversations.android.database.model.PresenceType;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
public abstract class PresenceDao {
|
public abstract class PresenceDao {
|
||||||
|
@ -20,29 +21,29 @@ public abstract class PresenceDao {
|
||||||
public abstract void deletePresences(long account);
|
public abstract void deletePresences(long account);
|
||||||
|
|
||||||
@Query("DELETE FROM presence WHERE accountId=:account AND address=:address")
|
@Query("DELETE FROM presence WHERE accountId=:account AND address=:address")
|
||||||
abstract void deletePresences(long account, Jid address);
|
abstract void deletePresences(long account, BareJid address);
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"DELETE FROM presence WHERE accountId=:account AND address=:address AND"
|
"DELETE FROM presence WHERE accountId=:account AND address=:address AND"
|
||||||
+ " resource=:resource")
|
+ " resource=:resource")
|
||||||
abstract void deletePresence(long account, Jid address, String resource);
|
abstract void deletePresence(long account, BareJid address, Resourcepart resource);
|
||||||
|
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
abstract void insert(PresenceEntity entity);
|
abstract void insert(PresenceEntity entity);
|
||||||
|
|
||||||
public void set(
|
public void set(
|
||||||
@NonNull final Account account,
|
@NonNull final Account account,
|
||||||
@NonNull final Jid address,
|
@NonNull final BareJid address,
|
||||||
@Nullable final String resource,
|
@NonNull final Resourcepart resource,
|
||||||
@Nullable final PresenceType type,
|
@Nullable final PresenceType type,
|
||||||
@Nullable final PresenceShow show,
|
@Nullable final PresenceShow show,
|
||||||
@Nullable final String status) {
|
@Nullable final String status) {
|
||||||
if (resource == null
|
if (resource.equals(Resourcepart.EMPTY)
|
||||||
&& Arrays.asList(PresenceType.ERROR, PresenceType.UNAVAILABLE).contains(type)) {
|
&& Arrays.asList(PresenceType.ERROR, PresenceType.UNAVAILABLE).contains(type)) {
|
||||||
deletePresences(account.id, address);
|
deletePresences(account.id, address);
|
||||||
}
|
}
|
||||||
if (type == PresenceType.UNAVAILABLE) {
|
if (type == PresenceType.UNAVAILABLE) {
|
||||||
if (resource != null) {
|
if (!resource.equals(Resourcepart.EMPTY)) {
|
||||||
deletePresence(account.id, address, resource);
|
deletePresence(account.id, address, resource);
|
||||||
}
|
}
|
||||||
// unavailable presence only delete previous nothing left to do
|
// unavailable presence only delete previous nothing left to do
|
||||||
|
|
|
@ -7,12 +7,12 @@ import androidx.room.Insert;
|
||||||
import androidx.room.Query;
|
import androidx.room.Query;
|
||||||
import androidx.room.Transaction;
|
import androidx.room.Transaction;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.RosterItemEntity;
|
import im.conversations.android.database.entity.RosterItemEntity;
|
||||||
import im.conversations.android.database.entity.RosterItemGroupEntity;
|
import im.conversations.android.database.entity.RosterItemGroupEntity;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
import im.conversations.android.xmpp.model.roster.Item;
|
import im.conversations.android.xmpp.model.roster.Item;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
public abstract class RosterDao {
|
public abstract class RosterDao {
|
||||||
|
|
|
@ -5,9 +5,10 @@ import androidx.room.Embedded;
|
||||||
import androidx.room.Entity;
|
import androidx.room.Entity;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.model.Connection;
|
import im.conversations.android.database.model.Connection;
|
||||||
import im.conversations.android.database.model.Proxy;
|
import im.conversations.android.database.model.Proxy;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "account",
|
tableName = "account",
|
||||||
|
@ -21,8 +22,8 @@ public class AccountEntity {
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
public Long id;
|
public Long id;
|
||||||
|
|
||||||
@NonNull public Jid address;
|
@NonNull public BareJid address;
|
||||||
public String resource;
|
public Resourcepart resource;
|
||||||
public byte[] randomSeed;
|
public byte[] randomSeed;
|
||||||
|
|
||||||
public boolean enabled;
|
public boolean enabled;
|
||||||
|
|
|
@ -6,10 +6,10 @@ import androidx.room.Entity;
|
||||||
import androidx.room.ForeignKey;
|
import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
import im.conversations.android.database.model.AvatarThumbnail;
|
import im.conversations.android.database.model.AvatarThumbnail;
|
||||||
import im.conversations.android.xmpp.model.avatar.Info;
|
import im.conversations.android.xmpp.model.avatar.Info;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "avatar",
|
tableName = "avatar",
|
||||||
|
@ -31,13 +31,13 @@ public class AvatarEntity {
|
||||||
|
|
||||||
@NonNull public Long accountId;
|
@NonNull public Long accountId;
|
||||||
|
|
||||||
@NonNull public Jid address;
|
@NonNull public BareJid address;
|
||||||
|
|
||||||
@Embedded(prefix = "thumb_")
|
@Embedded(prefix = "thumb_")
|
||||||
@NonNull
|
@NonNull
|
||||||
public AvatarThumbnail thumbnail;
|
public AvatarThumbnail thumbnail;
|
||||||
|
|
||||||
public static AvatarEntity of(final Account account, final Jid address, final Info info) {
|
public static AvatarEntity of(final Account account, final BareJid address, final Info info) {
|
||||||
final var entity = new AvatarEntity();
|
final var entity = new AvatarEntity();
|
||||||
entity.accountId = account.id;
|
entity.accountId = account.id;
|
||||||
entity.address = address;
|
entity.address = address;
|
||||||
|
|
|
@ -5,8 +5,8 @@ import androidx.room.Entity;
|
||||||
import androidx.room.ForeignKey;
|
import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "axolotl_device_list",
|
tableName = "axolotl_device_list",
|
||||||
|
@ -28,7 +28,7 @@ public class AxolotlDeviceListEntity {
|
||||||
|
|
||||||
@NonNull public Long accountId;
|
@NonNull public Long accountId;
|
||||||
|
|
||||||
@NonNull public Jid address;
|
@NonNull public BareJid address;
|
||||||
|
|
||||||
@NonNull public Instant receivedAt;
|
@NonNull public Instant receivedAt;
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ public class AxolotlDeviceListEntity {
|
||||||
|
|
||||||
public boolean isParsingIssue;
|
public boolean isParsingIssue;
|
||||||
|
|
||||||
public static AxolotlDeviceListEntity of(long accountId, final Jid address) {
|
public static AxolotlDeviceListEntity of(long accountId, final BareJid address) {
|
||||||
final var entity = new AxolotlDeviceListEntity();
|
final var entity = new AxolotlDeviceListEntity();
|
||||||
entity.accountId = accountId;
|
entity.accountId = accountId;
|
||||||
entity.address = address;
|
entity.address = address;
|
||||||
|
@ -46,7 +46,7 @@ public class AxolotlDeviceListEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AxolotlDeviceListEntity of(
|
public static AxolotlDeviceListEntity of(
|
||||||
final long accountId, final Jid address, final String errorCondition) {
|
final long accountId, final BareJid address, final String errorCondition) {
|
||||||
final var entity = new AxolotlDeviceListEntity();
|
final var entity = new AxolotlDeviceListEntity();
|
||||||
entity.accountId = accountId;
|
entity.accountId = accountId;
|
||||||
entity.address = address;
|
entity.address = address;
|
||||||
|
@ -55,7 +55,7 @@ public class AxolotlDeviceListEntity {
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AxolotlDeviceListEntity ofParsingIssue(final long account, Jid address) {
|
public static AxolotlDeviceListEntity ofParsingIssue(final long account, BareJid address) {
|
||||||
final var entity = new AxolotlDeviceListEntity();
|
final var entity = new AxolotlDeviceListEntity();
|
||||||
entity.accountId = account;
|
entity.accountId = account;
|
||||||
entity.address = address;
|
entity.address = address;
|
||||||
|
|
|
@ -5,8 +5,8 @@ import androidx.room.Entity;
|
||||||
import androidx.room.ForeignKey;
|
import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
import org.whispersystems.libsignal.IdentityKey;
|
import org.whispersystems.libsignal.IdentityKey;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
|
@ -29,14 +29,14 @@ public class AxolotlIdentityEntity {
|
||||||
|
|
||||||
@NonNull public Long accountId;
|
@NonNull public Long accountId;
|
||||||
|
|
||||||
@NonNull public Jid address;
|
@NonNull public BareJid address;
|
||||||
|
|
||||||
@NonNull public Integer deviceId;
|
@NonNull public Integer deviceId;
|
||||||
|
|
||||||
@NonNull public IdentityKey identityKey;
|
@NonNull public IdentityKey identityKey;
|
||||||
|
|
||||||
public static AxolotlIdentityEntity of(
|
public static AxolotlIdentityEntity of(
|
||||||
Account account, Jid address, int deviceId, IdentityKey identityKey) {
|
Account account, BareJid address, int deviceId, IdentityKey identityKey) {
|
||||||
final var entity = new AxolotlIdentityEntity();
|
final var entity = new AxolotlIdentityEntity();
|
||||||
entity.accountId = account.id;
|
entity.accountId = account.id;
|
||||||
entity.address = address;
|
entity.address = address;
|
||||||
|
|
|
@ -5,8 +5,8 @@ import androidx.room.Entity;
|
||||||
import androidx.room.ForeignKey;
|
import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
import org.whispersystems.libsignal.state.SessionRecord;
|
import org.whispersystems.libsignal.state.SessionRecord;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
|
@ -29,14 +29,14 @@ public class AxolotlSessionEntity {
|
||||||
|
|
||||||
@NonNull public Long accountId;
|
@NonNull public Long accountId;
|
||||||
|
|
||||||
@NonNull public Jid address;
|
@NonNull public BareJid address;
|
||||||
|
|
||||||
@NonNull public Integer deviceId;
|
@NonNull public Integer deviceId;
|
||||||
|
|
||||||
@NonNull public SessionRecord sessionRecord;
|
@NonNull public SessionRecord sessionRecord;
|
||||||
|
|
||||||
public static AxolotlSessionEntity of(
|
public static AxolotlSessionEntity of(
|
||||||
Account account, Jid address, int deviceId, SessionRecord record) {
|
Account account, BareJid address, int deviceId, SessionRecord record) {
|
||||||
final var entity = new AxolotlSessionEntity();
|
final var entity = new AxolotlSessionEntity();
|
||||||
entity.accountId = account.id;
|
entity.accountId = account.id;
|
||||||
entity.address = address;
|
entity.address = address;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import androidx.room.Entity;
|
||||||
import androidx.room.ForeignKey;
|
import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "blocked",
|
tableName = "blocked",
|
||||||
|
|
|
@ -5,9 +5,10 @@ import androidx.room.Entity;
|
||||||
import androidx.room.ForeignKey;
|
import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xmpp.model.bookmark.Conference;
|
import im.conversations.android.xmpp.model.bookmark.Conference;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "bookmark",
|
tableName = "bookmark",
|
||||||
|
@ -41,7 +42,7 @@ public class BookmarkEntity {
|
||||||
|
|
||||||
public static BookmarkEntity of(
|
public static BookmarkEntity of(
|
||||||
final long accountId, final Map.Entry<String, Conference> entry) {
|
final long accountId, final Map.Entry<String, Conference> entry) {
|
||||||
final var address = jidOrNull(entry.getKey());
|
final var address = JidCreate.fromOrNull(entry.getKey());
|
||||||
final var conference = entry.getValue();
|
final var conference = entry.getValue();
|
||||||
if (address == null) {
|
if (address == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -53,12 +54,4 @@ public class BookmarkEntity {
|
||||||
entity.name = conference.getConferenceName();
|
entity.name = conference.getConferenceName();
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Jid jidOrNull(final String address) {
|
|
||||||
try {
|
|
||||||
return address == null ? null : Jid.ofEscaped(address);
|
|
||||||
} catch (final IllegalArgumentException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xmpp.model.disco.items.Item;
|
import im.conversations.android.xmpp.model.disco.items.Item;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "disco_item",
|
tableName = "disco_item",
|
||||||
|
@ -57,7 +57,7 @@ public class DiscoItemEntity {
|
||||||
entity.accountId = accountId;
|
entity.accountId = accountId;
|
||||||
entity.address = item.getJid();
|
entity.address = item.getJid();
|
||||||
entity.node = Strings.nullToEmpty(item.getNode());
|
entity.node = Strings.nullToEmpty(item.getNode());
|
||||||
entity.parentAddress = parent.toEscapedString();
|
entity.parentAddress = parent.toString();
|
||||||
entity.parentNode = Strings.nullToEmpty(parentNode);
|
entity.parentNode = Strings.nullToEmpty(parentNode);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,11 @@ import androidx.room.Entity;
|
||||||
import androidx.room.ForeignKey;
|
import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.transformer.Transformation;
|
import im.conversations.android.transformer.Transformation;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "message",
|
tableName = "message",
|
||||||
|
@ -47,10 +48,10 @@ public class MessageEntity {
|
||||||
|
|
||||||
public boolean outgoing;
|
public boolean outgoing;
|
||||||
|
|
||||||
public Jid toBare;
|
public BareJid toBare;
|
||||||
public String toResource;
|
public Resourcepart toResource;
|
||||||
public Jid fromBare;
|
public BareJid fromBare;
|
||||||
public String fromResource;
|
public Resourcepart fromResource;
|
||||||
|
|
||||||
public String occupantId;
|
public String occupantId;
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,10 @@ import androidx.room.Entity;
|
||||||
import androidx.room.ForeignKey;
|
import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.transformer.Transformation;
|
import im.conversations.android.transformer.Transformation;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "message_reaction",
|
tableName = "message_reaction",
|
||||||
|
@ -27,8 +28,8 @@ public class MessageReactionEntity {
|
||||||
|
|
||||||
public String stanzaId;
|
public String stanzaId;
|
||||||
public String messageId;
|
public String messageId;
|
||||||
public Jid reactionBy;
|
public BareJid reactionBy;
|
||||||
public String reactionByResource;
|
public Resourcepart reactionByResource;
|
||||||
public String occupantId;
|
public String occupantId;
|
||||||
|
|
||||||
public Instant receivedAt;
|
public Instant receivedAt;
|
||||||
|
|
|
@ -6,9 +6,10 @@ import androidx.room.Entity;
|
||||||
import androidx.room.ForeignKey;
|
import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.model.MessageState;
|
import im.conversations.android.database.model.MessageState;
|
||||||
import im.conversations.android.database.model.StateType;
|
import im.conversations.android.database.model.StateType;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "message_state",
|
tableName = "message_state",
|
||||||
|
@ -26,9 +27,9 @@ public class MessageStateEntity {
|
||||||
|
|
||||||
@NonNull public Long messageVersionId;
|
@NonNull public Long messageVersionId;
|
||||||
|
|
||||||
@NonNull public Jid fromBare;
|
@NonNull public BareJid fromBare;
|
||||||
|
|
||||||
@Nullable public String fromResource;
|
@Nullable public Resourcepart fromResource;
|
||||||
|
|
||||||
@NonNull public StateType type;
|
@NonNull public StateType type;
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,12 @@ import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.model.Modification;
|
import im.conversations.android.database.model.Modification;
|
||||||
import im.conversations.android.transformer.Transformation;
|
import im.conversations.android.transformer.Transformation;
|
||||||
import im.conversations.android.xmpp.model.stanza.Message;
|
import im.conversations.android.xmpp.model.stanza.Message;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "message_version",
|
tableName = "message_version",
|
||||||
|
@ -31,8 +32,8 @@ public class MessageVersionEntity {
|
||||||
public String messageId;
|
public String messageId;
|
||||||
public String stanzaId;
|
public String stanzaId;
|
||||||
public Modification modification;
|
public Modification modification;
|
||||||
public Jid modifiedBy;
|
public BareJid modifiedBy;
|
||||||
public String modifiedByResource;
|
public Resourcepart modifiedByResource;
|
||||||
public String occupantId;
|
public String occupantId;
|
||||||
public Instant receivedAt;
|
public Instant receivedAt;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import androidx.room.Entity;
|
||||||
import androidx.room.ForeignKey;
|
import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "nick",
|
tableName = "nick",
|
||||||
|
|
|
@ -6,11 +6,12 @@ import androidx.room.Entity;
|
||||||
import androidx.room.ForeignKey;
|
import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import eu.siacs.conversations.entities.MucOptions;
|
import eu.siacs.conversations.entities.MucOptions;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.model.PresenceShow;
|
import im.conversations.android.database.model.PresenceShow;
|
||||||
import im.conversations.android.database.model.PresenceType;
|
import im.conversations.android.database.model.PresenceType;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "presence",
|
tableName = "presence",
|
||||||
|
@ -39,9 +40,9 @@ public class PresenceEntity {
|
||||||
|
|
||||||
@NonNull public Long accountId;
|
@NonNull public Long accountId;
|
||||||
|
|
||||||
@NonNull public Jid address;
|
@NonNull public BareJid address;
|
||||||
|
|
||||||
@NonNull public String resource;
|
@NonNull public Resourcepart resource;
|
||||||
|
|
||||||
@Nullable public PresenceType type;
|
@Nullable public PresenceType type;
|
||||||
|
|
||||||
|
@ -66,15 +67,15 @@ public class PresenceEntity {
|
||||||
|
|
||||||
public static PresenceEntity of(
|
public static PresenceEntity of(
|
||||||
long account,
|
long account,
|
||||||
Jid address,
|
@NonNull BareJid address,
|
||||||
@Nullable String resource,
|
@NonNull Resourcepart resource,
|
||||||
PresenceType type,
|
PresenceType type,
|
||||||
PresenceShow show,
|
PresenceShow show,
|
||||||
String status) {
|
String status) {
|
||||||
final var entity = new PresenceEntity();
|
final var entity = new PresenceEntity();
|
||||||
entity.accountId = account;
|
entity.accountId = account;
|
||||||
entity.address = address;
|
entity.address = address;
|
||||||
entity.resource = Strings.nullToEmpty(resource);
|
entity.resource = resource;
|
||||||
entity.type = type;
|
entity.type = type;
|
||||||
entity.show = show;
|
entity.show = show;
|
||||||
entity.status = status;
|
entity.status = status;
|
||||||
|
|
|
@ -5,8 +5,8 @@ import androidx.room.Entity;
|
||||||
import androidx.room.ForeignKey;
|
import androidx.room.ForeignKey;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xmpp.model.roster.Item;
|
import im.conversations.android.xmpp.model.roster.Item;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
tableName = "roster",
|
tableName = "roster",
|
||||||
|
|
|
@ -6,20 +6,19 @@ import com.google.common.base.Preconditions;
|
||||||
import com.google.common.hash.Hashing;
|
import com.google.common.hash.Hashing;
|
||||||
import com.google.common.io.ByteSource;
|
import com.google.common.io.ByteSource;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.IDs;
|
import im.conversations.android.IDs;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
|
||||||
public class Account {
|
public class Account {
|
||||||
|
|
||||||
public final long id;
|
public final long id;
|
||||||
@NonNull public final Jid address;
|
@NonNull public final BareJid address;
|
||||||
@NonNull public final byte[] randomSeed;
|
@NonNull public final byte[] randomSeed;
|
||||||
|
|
||||||
public Account(final long id, @NonNull final Jid address, @NonNull byte[] randomSeed) {
|
public Account(final long id, @NonNull final BareJid address, @NonNull byte[] randomSeed) {
|
||||||
Preconditions.checkNotNull(address, "Account can not be instantiated without an address");
|
Preconditions.checkNotNull(address, "Account can not be instantiated without an address");
|
||||||
Preconditions.checkArgument(address.isBareJid(), "Account address must be bare");
|
|
||||||
Preconditions.checkArgument(
|
Preconditions.checkArgument(
|
||||||
randomSeed.length == 32, "RandomSeed must have exactly 32 bytes");
|
randomSeed.length == 32, "RandomSeed must have exactly 32 bytes");
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -43,7 +42,7 @@ public class Account {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOnion() {
|
public boolean isOnion() {
|
||||||
final String domain = address.getDomain().toEscapedString();
|
final String domain = address.getDomain().toString();
|
||||||
return domain.endsWith(".onion");
|
return domain.endsWith(".onion");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package im.conversations.android.database.model;
|
package im.conversations.android.database.model;
|
||||||
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public class ChatIdentifier {
|
public class ChatIdentifier {
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package im.conversations.android.database.model;
|
package im.conversations.android.database.model;
|
||||||
|
|
||||||
import androidx.room.Relation;
|
import androidx.room.Relation;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.MessageContentEntity;
|
import im.conversations.android.database.entity.MessageContentEntity;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public class MessageEmbedded {
|
public class MessageEmbedded {
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
package im.conversations.android.database.model;
|
package im.conversations.android.database.model;
|
||||||
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import org.jxmpp.jid.BareJid;
|
||||||
|
|
||||||
public class MessageIdentifier {
|
public class MessageIdentifier {
|
||||||
|
|
||||||
public final long id;
|
public final long id;
|
||||||
public final String stanzaId;
|
public final String stanzaId;
|
||||||
public final String messageId;
|
public final String messageId;
|
||||||
public final Jid fromBare;
|
public final BareJid fromBare;
|
||||||
public final Long version;
|
public final Long version;
|
||||||
|
|
||||||
public MessageIdentifier(
|
public MessageIdentifier(
|
||||||
long id, String stanzaId, String messageId, Jid fromBare, Long version) {
|
long id, String stanzaId, String messageId, BareJid fromBare, Long version) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.stanzaId = stanzaId;
|
this.stanzaId = stanzaId;
|
||||||
this.messageId = messageId;
|
this.messageId = messageId;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package im.conversations.android.database.model;
|
package im.conversations.android.database.model;
|
||||||
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public class MessageReaction {
|
public class MessageReaction {
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
package im.conversations.android.database.model;
|
package im.conversations.android.database.model;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.transformer.Transformation;
|
import im.conversations.android.transformer.Transformation;
|
||||||
import im.conversations.android.xmpp.model.error.Condition;
|
import im.conversations.android.xmpp.model.error.Condition;
|
||||||
import im.conversations.android.xmpp.model.error.Error;
|
import im.conversations.android.xmpp.model.error.Error;
|
||||||
import im.conversations.android.xmpp.model.error.Text;
|
import im.conversations.android.xmpp.model.error.Text;
|
||||||
import im.conversations.android.xmpp.model.stanza.Message;
|
import im.conversations.android.xmpp.model.stanza.Message;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
|
||||||
public class MessageState {
|
public class MessageState {
|
||||||
|
|
||||||
public final Jid fromBare;
|
public final BareJid fromBare;
|
||||||
|
|
||||||
public final String fromResource;
|
public final Resourcepart fromResource;
|
||||||
|
|
||||||
public final StateType type;
|
public final StateType type;
|
||||||
|
|
||||||
|
@ -21,8 +22,8 @@ public class MessageState {
|
||||||
public final String errorText;
|
public final String errorText;
|
||||||
|
|
||||||
public MessageState(
|
public MessageState(
|
||||||
Jid fromBare,
|
BareJid fromBare,
|
||||||
String fromResource,
|
Resourcepart fromResource,
|
||||||
StateType type,
|
StateType type,
|
||||||
String errorCondition,
|
String errorCondition,
|
||||||
String errorText) {
|
String errorText) {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import androidx.room.Relation;
|
||||||
import com.google.common.collect.ImmutableSortedSet;
|
import com.google.common.collect.ImmutableSortedSet;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Multimaps;
|
import com.google.common.collect.Multimaps;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.MessageContentEntity;
|
import im.conversations.android.database.entity.MessageContentEntity;
|
||||||
import im.conversations.android.database.entity.MessageEntity;
|
import im.conversations.android.database.entity.MessageEntity;
|
||||||
import im.conversations.android.database.entity.MessageReactionEntity;
|
import im.conversations.android.database.entity.MessageReactionEntity;
|
||||||
|
@ -14,6 +13,7 @@ import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public class MessageWithContentReactions {
|
public class MessageWithContentReactions {
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import com.google.common.base.Preconditions;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.IDs;
|
import im.conversations.android.IDs;
|
||||||
import im.conversations.android.database.CredentialStore;
|
import im.conversations.android.database.CredentialStore;
|
||||||
import im.conversations.android.database.entity.AccountEntity;
|
import im.conversations.android.database.entity.AccountEntity;
|
||||||
|
@ -14,6 +13,7 @@ import im.conversations.android.database.model.Account;
|
||||||
import im.conversations.android.xmpp.ConnectionPool;
|
import im.conversations.android.xmpp.ConnectionPool;
|
||||||
import im.conversations.android.xmpp.XmppConnection;
|
import im.conversations.android.xmpp.XmppConnection;
|
||||||
import im.conversations.android.xmpp.manager.RegistrationManager;
|
import im.conversations.android.xmpp.manager.RegistrationManager;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
|
||||||
public class AccountRepository extends AbstractRepository {
|
public class AccountRepository extends AbstractRepository {
|
||||||
|
|
||||||
|
@ -22,9 +22,7 @@ public class AccountRepository extends AbstractRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Account createAccount(
|
private Account createAccount(
|
||||||
@NonNull final Jid address, final String password, final boolean loginAndBind) {
|
@NonNull final BareJid address, final String password, final boolean loginAndBind) {
|
||||||
Preconditions.checkArgument(
|
|
||||||
address.isBareJid(), "Account should be specified without resource");
|
|
||||||
Preconditions.checkArgument(password != null, "Missing password");
|
Preconditions.checkArgument(password != null, "Missing password");
|
||||||
final byte[] randomSeed = IDs.seed();
|
final byte[] randomSeed = IDs.seed();
|
||||||
final var entity = new AccountEntity();
|
final var entity = new AccountEntity();
|
||||||
|
@ -44,12 +42,12 @@ public class AccountRepository extends AbstractRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListenableFuture<Account> createAccountAsync(
|
public ListenableFuture<Account> createAccountAsync(
|
||||||
final @NonNull Jid address, final String password, final boolean loginAndBind) {
|
final @NonNull BareJid address, final String password, final boolean loginAndBind) {
|
||||||
return Futures.submit(() -> createAccount(address, password, loginAndBind), IO_EXECUTOR);
|
return Futures.submit(() -> createAccount(address, password, loginAndBind), IO_EXECUTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListenableFuture<Account> createAccountAsync(
|
public ListenableFuture<Account> createAccountAsync(
|
||||||
final @NonNull Jid address, final String password) {
|
final @NonNull BareJid address, final String password) {
|
||||||
return createAccountAsync(address, password, true);
|
return createAccountAsync(address, password, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import androidx.annotation.NonNull;
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xmpp.model.DeliveryReceipt;
|
import im.conversations.android.xmpp.model.DeliveryReceipt;
|
||||||
import im.conversations.android.xmpp.model.DeliveryReceiptRequest;
|
import im.conversations.android.xmpp.model.DeliveryReceiptRequest;
|
||||||
import im.conversations.android.xmpp.model.Extension;
|
import im.conversations.android.xmpp.model.Extension;
|
||||||
|
@ -25,6 +24,9 @@ import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
|
||||||
public class Transformation {
|
public class Transformation {
|
||||||
|
|
||||||
|
@ -83,20 +85,20 @@ public class Transformation {
|
||||||
return this.extensions.size() > 0;
|
return this.extensions.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jid fromBare() {
|
public BareJid fromBare() {
|
||||||
return from == null ? null : from.asBareJid();
|
return from == null ? null : from.asBareJid();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String fromResource() {
|
public Resourcepart fromResource() {
|
||||||
return from == null ? null : from.getResource();
|
return from == null ? null : from.getResourceOrNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jid toBare() {
|
public BareJid toBare() {
|
||||||
return to == null ? null : to.asBareJid();
|
return to == null ? null : to.asBareJid();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toResource() {
|
public Resourcepart toResource() {
|
||||||
return to == null ? null : to.getResource();
|
return to == null ? null : to.getResourceOrNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Instant sentAt() {
|
public Instant sentAt() {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package im.conversations.android.transformer;
|
package im.conversations.android.transformer;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xml.Namespace;
|
import im.conversations.android.xml.Namespace;
|
||||||
import im.conversations.android.xmpp.XmppConnection;
|
import im.conversations.android.xmpp.XmppConnection;
|
||||||
import im.conversations.android.xmpp.manager.DiscoManager;
|
import im.conversations.android.xmpp.manager.DiscoManager;
|
||||||
import im.conversations.android.xmpp.model.occupant.OccupantId;
|
import im.conversations.android.xmpp.model.occupant.OccupantId;
|
||||||
import im.conversations.android.xmpp.model.stanza.Message;
|
import im.conversations.android.xmpp.model.stanza.Message;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public class TransformationFactory extends XmppConnection.Delegate {
|
public class TransformationFactory extends XmppConnection.Delegate {
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import com.google.common.base.Preconditions;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import eu.siacs.conversations.xmpp.InvalidJid;
|
|
||||||
import im.conversations.android.database.ConversationsDatabase;
|
import im.conversations.android.database.ConversationsDatabase;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
import im.conversations.android.database.model.ChatIdentifier;
|
import im.conversations.android.database.model.ChatIdentifier;
|
||||||
|
@ -132,7 +131,7 @@ public class Transformer {
|
||||||
final var reply = transformation.getExtension(Reply.class);
|
final var reply = transformation.getExtension(Reply.class);
|
||||||
if (Objects.nonNull(reply)
|
if (Objects.nonNull(reply)
|
||||||
&& Objects.nonNull(reply.getId())
|
&& Objects.nonNull(reply.getId())
|
||||||
&& InvalidJid.isValid(reply.getTo())) {
|
&& Objects.nonNull(reply.getTo())) {
|
||||||
database.messageDao()
|
database.messageDao()
|
||||||
.setInReplyTo(
|
.setInReplyTo(
|
||||||
chat, messageIdentifier, messageType, reply.getTo(), reply.getId());
|
chat, messageIdentifier, messageType, reply.getTo(), reply.getId());
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package im.conversations.android.xml;
|
package im.conversations.android.xml;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import com.google.common.base.Optional;
|
import com.google.common.base.Optional;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
@ -9,15 +8,14 @@ import com.google.common.collect.Collections2;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
import com.google.common.primitives.Longs;
|
import com.google.common.primitives.Longs;
|
||||||
import eu.siacs.conversations.xmpp.InvalidJid;
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xmpp.ExtensionFactory;
|
import im.conversations.android.xmpp.ExtensionFactory;
|
||||||
import im.conversations.android.xmpp.model.Extension;
|
import im.conversations.android.xmpp.model.Extension;
|
||||||
import im.conversations.android.xmpp.model.stanza.Message;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
|
|
||||||
public class Element {
|
public class Element {
|
||||||
private final String name;
|
private final String name;
|
||||||
|
@ -154,7 +152,7 @@ public class Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element setAttribute(final String name, final Jid value) {
|
public Element setAttribute(final String name, final Jid value) {
|
||||||
return this.setAttribute(name, value == null ? null : value.toEscapedString());
|
return this.setAttribute(name, value == null ? null : value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAttribute(final String name) {
|
public void removeAttribute(final String name) {
|
||||||
|
@ -187,16 +185,12 @@ public class Element {
|
||||||
return Optional.fromNullable(Ints.tryParse(value));
|
return Optional.fromNullable(Ints.tryParse(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jid getAttributeAsJid(String name) {
|
public Jid getAttributeAsJid(final String name) {
|
||||||
final String jid = this.getAttribute(name);
|
final String jid = this.getAttribute(name);
|
||||||
if (Strings.isNullOrEmpty(jid)) {
|
if (Strings.isNullOrEmpty(jid)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
return JidCreate.fromOrThrowUnchecked(jid);
|
||||||
return Jid.ofEscaped(jid);
|
|
||||||
} catch (final IllegalArgumentException e) {
|
|
||||||
return InvalidJid.of(jid, this instanceof Message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Hashtable<String, String> getAttributes() {
|
public Hashtable<String, String> getAttributes() {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package im.conversations.android.xml;
|
package im.conversations.android.xml;
|
||||||
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public class Tag {
|
public class Tag {
|
||||||
public static final int NO = -1;
|
public static final int NO = -1;
|
||||||
|
@ -52,7 +52,7 @@ public class Tag {
|
||||||
|
|
||||||
public Tag setAttribute(final String attrName, final Jid attrValue) {
|
public Tag setAttribute(final String attrName, final Jid attrValue) {
|
||||||
if (attrValue != null) {
|
if (attrValue != null) {
|
||||||
this.attributes.put(attrName, attrValue.toEscapedString());
|
this.attributes.put(attrName, attrValue.toString());
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,7 @@ import com.google.common.primitives.Ints;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.utils.CryptoHelper;
|
|
||||||
import eu.siacs.conversations.utils.PhoneHelper;
|
import eu.siacs.conversations.utils.PhoneHelper;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.Conversations;
|
import im.conversations.android.Conversations;
|
||||||
import im.conversations.android.database.ConversationsDatabase;
|
import im.conversations.android.database.ConversationsDatabase;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
|
@ -26,6 +24,8 @@ import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ public class ConnectionPool {
|
||||||
return setupXmppConnection(context, account);
|
return setupXmppConnection(context, account);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized ListenableFuture<XmppConnection> get(final Jid address) {
|
public synchronized ListenableFuture<XmppConnection> get(final BareJid address) {
|
||||||
final var configured =
|
final var configured =
|
||||||
Iterables.tryFind(this.connections, c -> address.equals(c.getAccount().address));
|
Iterables.tryFind(this.connections, c -> address.equals(c.getAccount().address));
|
||||||
if (configured.isPresent()) {
|
if (configured.isPresent()) {
|
||||||
|
@ -78,8 +78,7 @@ public class ConnectionPool {
|
||||||
if (account == null) {
|
if (account == null) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
String.format(
|
String.format(
|
||||||
"No enabled account with address %s",
|
"No enabled account with address %s", address.toString()));
|
||||||
address.toEscapedString()));
|
|
||||||
}
|
}
|
||||||
return reconfigure(account);
|
return reconfigure(account);
|
||||||
},
|
},
|
||||||
|
@ -231,9 +230,8 @@ public class ConnectionPool {
|
||||||
final String androidId = PhoneHelper.getAndroidId(context);
|
final String androidId = PhoneHelper.getAndroidId(context);
|
||||||
for (final XmppConnection xmppConnection : this.connections) {
|
for (final XmppConnection xmppConnection : this.connections) {
|
||||||
final Account account = xmppConnection.getAccount();
|
final Account account = xmppConnection.getAccount();
|
||||||
final boolean pushWasMeantForThisAccount =
|
// TODO fix me if we bring back FCM push support
|
||||||
CryptoHelper.getFingerprint(account.address, androidId)
|
final boolean pushWasMeantForThisAccount = false;
|
||||||
.equals(pushedAccountHash);
|
|
||||||
if (processAccountState(xmppConnection, pushWasMeantForThisAccount, pingCandidates)) {
|
if (processAccountState(xmppConnection, pushWasMeantForThisAccount, pingCandidates)) {
|
||||||
pingNow++;
|
pingNow++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package im.conversations.android.xmpp;
|
package im.conversations.android.xmpp;
|
||||||
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public abstract class Entity {
|
public abstract class Entity {
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,6 @@ import eu.siacs.conversations.utils.PhoneHelper;
|
||||||
import eu.siacs.conversations.utils.Resolver;
|
import eu.siacs.conversations.utils.Resolver;
|
||||||
import eu.siacs.conversations.utils.SSLSockets;
|
import eu.siacs.conversations.utils.SSLSockets;
|
||||||
import eu.siacs.conversations.utils.SocksSocketFactory;
|
import eu.siacs.conversations.utils.SocksSocketFactory;
|
||||||
import eu.siacs.conversations.xml.LocalizedContent;
|
|
||||||
import eu.siacs.conversations.xmpp.InvalidJid;
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import eu.siacs.conversations.xmpp.bind.Bind2;
|
import eu.siacs.conversations.xmpp.bind.Bind2;
|
||||||
import im.conversations.android.Conversations;
|
import im.conversations.android.Conversations;
|
||||||
import im.conversations.android.IDs;
|
import im.conversations.android.IDs;
|
||||||
|
@ -91,6 +88,7 @@ import java.util.Collections;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
@ -107,6 +105,9 @@ import javax.net.ssl.SSLSocketFactory;
|
||||||
import javax.net.ssl.X509KeyManager;
|
import javax.net.ssl.X509KeyManager;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
|
import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
@ -293,7 +294,7 @@ public class XmppConnection implements Runnable {
|
||||||
final int port;
|
final int port;
|
||||||
final boolean directTls;
|
final boolean directTls;
|
||||||
if (connection == null || account.isOnion()) {
|
if (connection == null || account.isOnion()) {
|
||||||
destination = account.address.getDomain().toEscapedString();
|
destination = account.address.getDomain().toString();
|
||||||
port = 5222;
|
port = 5222;
|
||||||
directTls = false;
|
directTls = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -328,7 +329,7 @@ public class XmppConnection implements Runnable {
|
||||||
throw new IOException("Could not start stream", e);
|
throw new IOException("Could not start stream", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final String domain = account.address.getDomain().toEscapedString();
|
final String domain = account.address.getDomain().toString();
|
||||||
final List<Resolver.Result> results;
|
final List<Resolver.Result> results;
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
results = Resolver.fromHardCoded(connection.hostname, connection.port);
|
results = Resolver.fromHardCoded(connection.hostname, connection.port);
|
||||||
|
@ -497,7 +498,7 @@ public class XmppConnection implements Runnable {
|
||||||
final boolean quickStart;
|
final boolean quickStart;
|
||||||
if (socket instanceof SSLSocket) {
|
if (socket instanceof SSLSocket) {
|
||||||
final SSLSocket sslSocket = (SSLSocket) socket;
|
final SSLSocket sslSocket = (SSLSocket) socket;
|
||||||
SSLSockets.log(account.address, sslSocket);
|
logTlsCipher(sslSocket);
|
||||||
quickStart = establishStream(SSLSockets.version(sslSocket));
|
quickStart = establishStream(SSLSockets.version(sslSocket));
|
||||||
} else {
|
} else {
|
||||||
quickStart = establishStream(SSLSockets.Version.NONE);
|
quickStart = establishStream(SSLSockets.Version.NONE);
|
||||||
|
@ -524,7 +525,7 @@ public class XmppConnection implements Runnable {
|
||||||
} else {
|
} else {
|
||||||
keyManager = new KeyManager[] {new MyKeyManager(context, credential)};
|
keyManager = new KeyManager[] {new MyKeyManager(context, credential)};
|
||||||
}
|
}
|
||||||
final String domain = account.address.getDomain().toEscapedString();
|
final String domain = account.address.getDomain().toString();
|
||||||
// TODO we used to use two different trust managers; interactive and non interactive (to
|
// TODO we used to use two different trust managers; interactive and non interactive (to
|
||||||
// trigger SSL cert prompts)
|
// trigger SSL cert prompts)
|
||||||
// we need a better solution for this using live data or similar
|
// we need a better solution for this using live data or similar
|
||||||
|
@ -719,8 +720,8 @@ public class XmppConnection implements Runnable {
|
||||||
authorizationJid =
|
authorizationJid =
|
||||||
Strings.isNullOrEmpty(authorizationIdentifier)
|
Strings.isNullOrEmpty(authorizationIdentifier)
|
||||||
? null
|
? null
|
||||||
: Jid.ofEscaped(authorizationIdentifier);
|
: JidCreate.from(authorizationIdentifier);
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final XmppStringprepException e) {
|
||||||
Log.d(
|
Log.d(
|
||||||
Config.LOGTAG,
|
Config.LOGTAG,
|
||||||
account.address
|
account.address
|
||||||
|
@ -993,7 +994,9 @@ public class XmppConnection implements Runnable {
|
||||||
private void changeStatusToOnline() {
|
private void changeStatusToOnline() {
|
||||||
Log.d(
|
Log.d(
|
||||||
Config.LOGTAG,
|
Config.LOGTAG,
|
||||||
account.address + ": online with resource " + connectionAddress.getResource());
|
account.address
|
||||||
|
+ ": online with resource "
|
||||||
|
+ connectionAddress.getResourceOrNull());
|
||||||
changeStatus(ConnectionState.ONLINE);
|
changeStatus(ConnectionState.ONLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1058,7 +1061,7 @@ public class XmppConnection implements Runnable {
|
||||||
final S stanza = tagReader.readElement(currentTag, clazz);
|
final S stanza = tagReader.readElement(currentTag, clazz);
|
||||||
if (stanzasReceived == Integer.MAX_VALUE) {
|
if (stanzasReceived == Integer.MAX_VALUE) {
|
||||||
resetStreamId();
|
resetStreamId();
|
||||||
throw new IOException("time to restart the session. cant handle >2 billion pcks");
|
throw new IOException("time to restart the session. cant handle >2 billion stanzas");
|
||||||
}
|
}
|
||||||
if (inSmacksSession) {
|
if (inSmacksSession) {
|
||||||
++stanzasReceived;
|
++stanzasReceived;
|
||||||
|
@ -1071,25 +1074,12 @@ public class XmppConnection implements Runnable {
|
||||||
+ "). Not in smacks session.");
|
+ "). Not in smacks session.");
|
||||||
}
|
}
|
||||||
lastPacketReceived = SystemClock.elapsedRealtime();
|
lastPacketReceived = SystemClock.elapsedRealtime();
|
||||||
if (InvalidJid.invalid(stanza.getTo()) || InvalidJid.invalid(stanza.getFrom())) {
|
// TODO validate to and from
|
||||||
Log.e(
|
|
||||||
Config.LOGTAG,
|
|
||||||
"encountered invalid stanza from "
|
|
||||||
+ stanza.getFrom()
|
|
||||||
+ " to "
|
|
||||||
+ stanza.getTo());
|
|
||||||
}
|
|
||||||
return stanza;
|
return stanza;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processIq(final Tag currentTag) throws IOException {
|
private void processIq(final Tag currentTag) throws IOException {
|
||||||
final Iq packet = processStanza(currentTag, Iq.class);
|
final Iq packet = processStanza(currentTag, Iq.class);
|
||||||
if (InvalidJid.invalid(packet.getTo()) || InvalidJid.invalid(packet.getFrom())) {
|
|
||||||
Log.e(
|
|
||||||
Config.LOGTAG,
|
|
||||||
"encountered invalid IQ from " + packet.getFrom() + " to " + packet.getTo());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final Consumer<Iq> callback;
|
final Consumer<Iq> callback;
|
||||||
synchronized (this.packetCallbacks) {
|
synchronized (this.packetCallbacks) {
|
||||||
final Pair<Iq, Consumer<Iq>> packetCallbackDuple = packetCallbacks.get(packet.getId());
|
final Pair<Iq, Consumer<Iq>> packetCallbackDuple = packetCallbacks.get(packet.getId());
|
||||||
|
@ -1130,29 +1120,11 @@ public class XmppConnection implements Runnable {
|
||||||
|
|
||||||
private void processMessage(final Tag currentTag) throws IOException {
|
private void processMessage(final Tag currentTag) throws IOException {
|
||||||
final var message = processStanza(currentTag, Message.class);
|
final var message = processStanza(currentTag, Message.class);
|
||||||
if (InvalidJid.invalid(message.getTo()) || InvalidJid.invalid(message.getFrom())) {
|
|
||||||
Log.e(
|
|
||||||
Config.LOGTAG,
|
|
||||||
"encountered invalid Message from "
|
|
||||||
+ message.getFrom()
|
|
||||||
+ " to "
|
|
||||||
+ message.getTo());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.messagePacketConsumer.accept(message);
|
this.messagePacketConsumer.accept(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processPresence(final Tag currentTag) throws IOException {
|
private void processPresence(final Tag currentTag) throws IOException {
|
||||||
final var presence = processStanza(currentTag, Presence.class);
|
final var presence = processStanza(currentTag, Presence.class);
|
||||||
if (InvalidJid.invalid(presence.getTo()) || InvalidJid.invalid(presence.getFrom())) {
|
|
||||||
Log.e(
|
|
||||||
Config.LOGTAG,
|
|
||||||
"encountered invalid Presence from "
|
|
||||||
+ presence.getFrom()
|
|
||||||
+ " to "
|
|
||||||
+ presence.getTo());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.presencePacketConsumer.accept(presence);
|
this.presencePacketConsumer.accept(presence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1181,7 +1153,7 @@ public class XmppConnection implements Runnable {
|
||||||
this.encryptionEnabled = true;
|
this.encryptionEnabled = true;
|
||||||
final Tag tag = tagReader.readTag();
|
final Tag tag = tagReader.readTag();
|
||||||
if (tag != null && tag.isStart("stream", Namespace.STREAMS)) {
|
if (tag != null && tag.isStart("stream", Namespace.STREAMS)) {
|
||||||
SSLSockets.log(account.address, sslSocket);
|
logTlsCipher(sslSocket);
|
||||||
processStream();
|
processStream();
|
||||||
} else {
|
} else {
|
||||||
throw new StateChangingException(ConnectionState.STREAM_OPENING_ERROR);
|
throw new StateChangingException(ConnectionState.STREAM_OPENING_ERROR);
|
||||||
|
@ -1189,6 +1161,14 @@ public class XmppConnection implements Runnable {
|
||||||
sslSocket.close();
|
sslSocket.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void logTlsCipher(final SSLSocket sslSocket) {
|
||||||
|
final var session = sslSocket.getSession();
|
||||||
|
LOGGER.info(
|
||||||
|
"TLS session protocol {} cipher {}",
|
||||||
|
session.getProtocol(),
|
||||||
|
session.getCipherSuite());
|
||||||
|
}
|
||||||
|
|
||||||
private SSLSocket upgradeSocketToTls(final Socket socket) throws IOException {
|
private SSLSocket upgradeSocketToTls(final Socket socket) throws IOException {
|
||||||
final SSLSocketFactory sslSocketFactory;
|
final SSLSocketFactory sslSocketFactory;
|
||||||
try {
|
try {
|
||||||
|
@ -1202,13 +1182,12 @@ public class XmppConnection implements Runnable {
|
||||||
sslSocketFactory.createSocket(
|
sslSocketFactory.createSocket(
|
||||||
socket, address.getHostAddress(), socket.getPort(), true);
|
socket, address.getHostAddress(), socket.getPort(), true);
|
||||||
SSLSockets.setSecurity(sslSocket);
|
SSLSockets.setSecurity(sslSocket);
|
||||||
SSLSockets.setHostname(
|
SSLSockets.setHostname(sslSocket, IDN.toASCII(account.address.getDomain().toString()));
|
||||||
sslSocket, IDN.toASCII(account.address.getDomain().toEscapedString()));
|
|
||||||
SSLSockets.setApplicationProtocol(sslSocket, "xmpp-client");
|
SSLSockets.setApplicationProtocol(sslSocket, "xmpp-client");
|
||||||
final XmppDomainVerifier xmppDomainVerifier = new XmppDomainVerifier();
|
final XmppDomainVerifier xmppDomainVerifier = new XmppDomainVerifier();
|
||||||
try {
|
try {
|
||||||
if (!xmppDomainVerifier.verify(
|
if (!xmppDomainVerifier.verify(
|
||||||
account.address.getDomain().toEscapedString(),
|
account.address.getDomain().toString(),
|
||||||
this.verifiedHostname,
|
this.verifiedHostname,
|
||||||
sslSocket.getSession())) {
|
sslSocket.getSession())) {
|
||||||
Log.d(
|
Log.d(
|
||||||
|
@ -1536,8 +1515,8 @@ public class XmppConnection implements Runnable {
|
||||||
}
|
}
|
||||||
final Jid assignedJid;
|
final Jid assignedJid;
|
||||||
try {
|
try {
|
||||||
assignedJid = Jid.ofEscaped(jid);
|
assignedJid = JidCreate.from(jid);
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final XmppStringprepException e) {
|
||||||
Log.d(
|
Log.d(
|
||||||
Config.LOGTAG,
|
Config.LOGTAG,
|
||||||
account.address
|
account.address
|
||||||
|
@ -1675,7 +1654,7 @@ public class XmppConnection implements Runnable {
|
||||||
final var discoManager = getManager(DiscoManager.class);
|
final var discoManager = getManager(DiscoManager.class);
|
||||||
|
|
||||||
final var nodeHash = this.streamFeatures.getCapabilities();
|
final var nodeHash = this.streamFeatures.getCapabilities();
|
||||||
final var domainDiscoItem = Entity.discoItem(account.address.getDomain());
|
final var domainDiscoItem = Entity.discoItem(account.address.asDomainBareJid());
|
||||||
if (nodeHash != null) {
|
if (nodeHash != null) {
|
||||||
discoFutures.add(
|
discoFutures.add(
|
||||||
discoManager.infoOrCache(domainDiscoItem, nodeHash.node, nodeHash.hash));
|
discoManager.infoOrCache(domainDiscoItem, nodeHash.node, nodeHash.hash));
|
||||||
|
@ -1819,12 +1798,13 @@ public class XmppConnection implements Runnable {
|
||||||
|
|
||||||
private void sendStartStream(final boolean from, final boolean flush) throws IOException {
|
private void sendStartStream(final boolean from, final boolean flush) throws IOException {
|
||||||
final Tag stream = Tag.start("stream:stream");
|
final Tag stream = Tag.start("stream:stream");
|
||||||
stream.setAttribute("to", account.address.getDomain());
|
stream.setAttribute("to", account.address.asDomainBareJid());
|
||||||
if (from) {
|
if (from) {
|
||||||
stream.setAttribute("from", account.address);
|
stream.setAttribute("from", account.address);
|
||||||
}
|
}
|
||||||
stream.setAttribute("version", "1.0");
|
stream.setAttribute("version", "1.0");
|
||||||
stream.setAttribute("xml:lang", LocalizedContent.STREAM_LANGUAGE);
|
// TODO use 'en' when privacy mode is enabled
|
||||||
|
stream.setAttribute("xml:lang", Locale.getDefault().getLanguage());
|
||||||
stream.setAttribute("xmlns", "jabber:client");
|
stream.setAttribute("xmlns", "jabber:client");
|
||||||
stream.setAttribute("xmlns:stream", Namespace.STREAMS);
|
stream.setAttribute("xmlns:stream", Namespace.STREAMS);
|
||||||
tagWriter.writeTag(stream, flush);
|
tagWriter.writeTag(stream, flush);
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
package im.conversations.android.xmpp.axolotl;
|
package im.conversations.android.xmpp.axolotl;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import org.jxmpp.jid.BareJid;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import org.whispersystems.libsignal.SignalProtocolAddress;
|
import org.whispersystems.libsignal.SignalProtocolAddress;
|
||||||
|
|
||||||
public class AxolotlAddress extends SignalProtocolAddress {
|
public class AxolotlAddress extends SignalProtocolAddress {
|
||||||
|
|
||||||
private final Jid jid;
|
private final BareJid jid;
|
||||||
|
|
||||||
public AxolotlAddress(final Jid jid, int deviceId) {
|
public AxolotlAddress(final BareJid jid, int deviceId) {
|
||||||
super(jid.toEscapedString(), deviceId);
|
super(jid.toString(), deviceId);
|
||||||
Preconditions.checkArgument(jid.isBareJid(), "AxolotlAddresses must use bare JIDs");
|
|
||||||
this.jid = jid;
|
this.jid = jid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Jid getJid() {
|
public BareJid getJid() {
|
||||||
return this.jid;
|
return this.jid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xmpp.XmppConnection;
|
import im.conversations.android.xmpp.XmppConnection;
|
||||||
import im.conversations.android.xmpp.model.avatar.Data;
|
import im.conversations.android.xmpp.model.avatar.Data;
|
||||||
import im.conversations.android.xmpp.model.avatar.Info;
|
import im.conversations.android.xmpp.model.avatar.Info;
|
||||||
|
@ -21,6 +20,8 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ public class AvatarManager extends AbstractManager {
|
||||||
super(context, connection);
|
super(context, connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleItems(final Jid from, final Items items) {
|
public void handleItems(final BareJid from, final Items items) {
|
||||||
final var itemsMap = items.getItemMap(Metadata.class);
|
final var itemsMap = items.getItemMap(Metadata.class);
|
||||||
final var firstEntry = Iterables.getFirst(itemsMap.entrySet(), null);
|
final var firstEntry = Iterables.getFirst(itemsMap.entrySet(), null);
|
||||||
if (firstEntry == null) {
|
if (firstEntry == null) {
|
||||||
|
@ -142,7 +143,7 @@ public class AvatarManager extends AbstractManager {
|
||||||
new File(
|
new File(
|
||||||
accountCacheDirectory,
|
accountCacheDirectory,
|
||||||
Hashing.sha256()
|
Hashing.sha256()
|
||||||
.hashString(address.toEscapedString(), StandardCharsets.UTF_8)
|
.hashString(address.toString(), StandardCharsets.UTF_8)
|
||||||
.toString());
|
.toString());
|
||||||
if (userCacheDirectory.mkdirs()) {
|
if (userCacheDirectory.mkdirs()) {
|
||||||
LOGGER.debug("Created directory {}", userCacheDirectory.getAbsolutePath());
|
LOGGER.debug("Created directory {}", userCacheDirectory.getAbsolutePath());
|
||||||
|
|
|
@ -7,7 +7,6 @@ import com.google.common.util.concurrent.FutureCallback;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.AxolotlDatabaseStore;
|
import im.conversations.android.database.AxolotlDatabaseStore;
|
||||||
import im.conversations.android.xml.Namespace;
|
import im.conversations.android.xml.Namespace;
|
||||||
import im.conversations.android.xmpp.IqErrorException;
|
import im.conversations.android.xmpp.IqErrorException;
|
||||||
|
@ -22,6 +21,8 @@ import java.util.Collections;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.whispersystems.libsignal.IdentityKey;
|
import org.whispersystems.libsignal.IdentityKey;
|
||||||
|
@ -47,7 +48,7 @@ public class AxolotlManager extends AbstractManager {
|
||||||
this.signalProtocolStore = new AxolotlDatabaseStore(context, connection.getAccount());
|
this.signalProtocolStore = new AxolotlDatabaseStore(context, connection.getAccount());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleItems(final Jid from, final Items items) {
|
public void handleItems(final BareJid from, final Items items) {
|
||||||
final var deviceList = items.getFirstItem(DeviceList.class);
|
final var deviceList = items.getFirstItem(DeviceList.class);
|
||||||
if (from == null || deviceList == null) {
|
if (from == null || deviceList == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -57,7 +58,7 @@ public class AxolotlManager extends AbstractManager {
|
||||||
getDatabase().axolotlDao().setDeviceList(getAccount(), from, deviceIds);
|
getDatabase().axolotlDao().setDeviceList(getAccount(), from, deviceIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListenableFuture<Set<Integer>> fetchDeviceIds(final Jid address) {
|
public ListenableFuture<Set<Integer>> fetchDeviceIds(final BareJid address) {
|
||||||
final var deviceIdsFuture =
|
final var deviceIdsFuture =
|
||||||
Futures.transform(
|
Futures.transform(
|
||||||
getManager(PubSubManager.class)
|
getManager(PubSubManager.class)
|
||||||
|
|
|
@ -7,8 +7,6 @@ import com.google.common.util.concurrent.FutureCallback;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.database.entity.BookmarkEntity;
|
|
||||||
import im.conversations.android.xml.Namespace;
|
import im.conversations.android.xml.Namespace;
|
||||||
import im.conversations.android.xmpp.NodeConfiguration;
|
import im.conversations.android.xmpp.NodeConfiguration;
|
||||||
import im.conversations.android.xmpp.XmppConnection;
|
import im.conversations.android.xmpp.XmppConnection;
|
||||||
|
@ -18,6 +16,8 @@ import im.conversations.android.xmpp.model.pubsub.event.Retract;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ public class BookmarkManager extends AbstractManager {
|
||||||
|
|
||||||
private void deleteItems(Collection<Retract> retractions) {
|
private void deleteItems(Collection<Retract> retractions) {
|
||||||
final Collection<Jid> addresses =
|
final Collection<Jid> addresses =
|
||||||
Collections2.transform(retractions, r -> BookmarkEntity.jidOrNull(r.getId()));
|
Collections2.transform(retractions, r -> JidCreate.fromOrNull(r.getId()));
|
||||||
getDatabase()
|
getDatabase()
|
||||||
.bookmarkDao()
|
.bookmarkDao()
|
||||||
.delete(getAccount().id, Collections2.filter(addresses, Objects::nonNull));
|
.delete(getAccount().id, Collections2.filter(addresses, Objects::nonNull));
|
||||||
|
@ -75,7 +75,7 @@ public class BookmarkManager extends AbstractManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListenableFuture<Void> publishBookmark(final Jid address) {
|
public ListenableFuture<Void> publishBookmark(final Jid address) {
|
||||||
final var itemId = address.toEscapedString();
|
final var itemId = address.toString();
|
||||||
final var conference = new Conference();
|
final var conference = new Conference();
|
||||||
return Futures.transform(
|
return Futures.transform(
|
||||||
getManager(PepManager.class)
|
getManager(PepManager.class)
|
||||||
|
@ -85,7 +85,7 @@ public class BookmarkManager extends AbstractManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ListenableFuture<Void> retractBookmark(final Jid address) {
|
public ListenableFuture<Void> retractBookmark(final Jid address) {
|
||||||
final var itemId = address.toEscapedString();
|
final var itemId = address.toString();
|
||||||
return Futures.transform(
|
return Futures.transform(
|
||||||
getManager(PepManager.class).retract(itemId, Namespace.BOOKMARKS2),
|
getManager(PepManager.class).retract(itemId, Namespace.BOOKMARKS2),
|
||||||
result -> null,
|
result -> null,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package im.conversations.android.xmpp.manager;
|
package im.conversations.android.xmpp.manager;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xmpp.XmppConnection;
|
import im.conversations.android.xmpp.XmppConnection;
|
||||||
import im.conversations.android.xmpp.model.state.ChatStateNotification;
|
import im.conversations.android.xmpp.model.state.ChatStateNotification;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import eu.siacs.conversations.BuildConfig;
|
import eu.siacs.conversations.BuildConfig;
|
||||||
import eu.siacs.conversations.R;
|
import eu.siacs.conversations.R;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xml.Namespace;
|
import im.conversations.android.xml.Namespace;
|
||||||
import im.conversations.android.xmpp.Entity;
|
import im.conversations.android.xmpp.Entity;
|
||||||
import im.conversations.android.xmpp.EntityCapabilities;
|
import im.conversations.android.xmpp.EntityCapabilities;
|
||||||
|
@ -32,6 +31,7 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ public class DiscoManager extends AbstractManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasServerFeature(final String feature) {
|
public boolean hasServerFeature(final String feature) {
|
||||||
return hasFeature(getAccount().address.getDomain(), feature);
|
return hasFeature(getAccount().address.asDomainBareJid(), feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceDescription getServiceDescription() {
|
public ServiceDescription getServiceDescription() {
|
||||||
|
|
|
@ -2,10 +2,10 @@ package im.conversations.android.xmpp.manager;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xmpp.XmppConnection;
|
import im.conversations.android.xmpp.XmppConnection;
|
||||||
import im.conversations.android.xmpp.model.nick.Nick;
|
import im.conversations.android.xmpp.model.nick.Nick;
|
||||||
import im.conversations.android.xmpp.model.pubsub.Items;
|
import im.conversations.android.xmpp.model.pubsub.Items;
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ public class NickManager extends AbstractManager {
|
||||||
super(context, connection);
|
super(context, connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleItems(final Jid from, Items items) {
|
public void handleItems(final BareJid from, Items items) {
|
||||||
final var item = items.getFirstItem(Nick.class);
|
final var item = items.getFirstItem(Nick.class);
|
||||||
final var nick = item == null ? null : item.getContent();
|
final var nick = item == null ? null : item.getContent();
|
||||||
if (from == null || Strings.isNullOrEmpty(nick)) {
|
if (from == null || Strings.isNullOrEmpty(nick)) {
|
||||||
|
|
|
@ -2,12 +2,12 @@ package im.conversations.android.xmpp.manager;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xmpp.NodeConfiguration;
|
import im.conversations.android.xmpp.NodeConfiguration;
|
||||||
import im.conversations.android.xmpp.XmppConnection;
|
import im.conversations.android.xmpp.XmppConnection;
|
||||||
import im.conversations.android.xmpp.model.Extension;
|
import im.conversations.android.xmpp.model.Extension;
|
||||||
import im.conversations.android.xmpp.model.stanza.Iq;
|
import im.conversations.android.xmpp.model.stanza.Iq;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public class PepManager extends AbstractManager {
|
public class PepManager extends AbstractManager {
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import com.google.common.util.concurrent.AsyncFunction;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xml.Namespace;
|
import im.conversations.android.xml.Namespace;
|
||||||
import im.conversations.android.xmpp.ExtensionFactory;
|
import im.conversations.android.xmpp.ExtensionFactory;
|
||||||
import im.conversations.android.xmpp.IqErrorException;
|
import im.conversations.android.xmpp.IqErrorException;
|
||||||
|
@ -29,6 +28,7 @@ import im.conversations.android.xmpp.model.pubsub.owner.PubSubOwner;
|
||||||
import im.conversations.android.xmpp.model.stanza.Iq;
|
import im.conversations.android.xmpp.model.stanza.Iq;
|
||||||
import im.conversations.android.xmpp.model.stanza.Message;
|
import im.conversations.android.xmpp.model.stanza.Message;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -147,6 +147,7 @@ public class PubSubManager extends AbstractManager {
|
||||||
|
|
||||||
private void handleItems(final Message message) {
|
private void handleItems(final Message message) {
|
||||||
final var from = message.getFrom();
|
final var from = message.getFrom();
|
||||||
|
final var bareFrom = from == null ? null : from.asBareJid();
|
||||||
final var event = message.getExtension(Event.class);
|
final var event = message.getExtension(Event.class);
|
||||||
final Items items = event.getItems();
|
final Items items = event.getItems();
|
||||||
final var node = items.getNode();
|
final var node = items.getNode();
|
||||||
|
@ -155,15 +156,15 @@ public class PubSubManager extends AbstractManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Namespace.AVATAR_METADATA.equals(node)) {
|
if (Namespace.AVATAR_METADATA.equals(node)) {
|
||||||
getManager(AvatarManager.class).handleItems(from, items);
|
getManager(AvatarManager.class).handleItems(bareFrom, items);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Namespace.NICK.equals(node)) {
|
if (Namespace.NICK.equals(node)) {
|
||||||
getManager(NickManager.class).handleItems(from, items);
|
getManager(NickManager.class).handleItems(bareFrom, items);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Namespace.AXOLOTL_DEVICE_LIST.equals(node)) {
|
if (Namespace.AXOLOTL_DEVICE_LIST.equals(node)) {
|
||||||
getManager(AxolotlManager.class).handleItems(from, items);
|
getManager(AxolotlManager.class).handleItems(bareFrom, items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package im.conversations.android.xmpp.manager;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xmpp.XmppConnection;
|
import im.conversations.android.xmpp.XmppConnection;
|
||||||
import im.conversations.android.xmpp.model.DeliveryReceiptRequest;
|
import im.conversations.android.xmpp.model.DeliveryReceiptRequest;
|
||||||
import im.conversations.android.xmpp.model.markers.Markable;
|
import im.conversations.android.xmpp.model.markers.Markable;
|
||||||
|
@ -10,6 +9,7 @@ import im.conversations.android.xmpp.model.receipts.Received;
|
||||||
import im.conversations.android.xmpp.model.receipts.Request;
|
import im.conversations.android.xmpp.model.receipts.Request;
|
||||||
import im.conversations.android.xmpp.model.stanza.Message;
|
import im.conversations.android.xmpp.model.stanza.Message;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public class ReceiptManager extends AbstractManager {
|
public class ReceiptManager extends AbstractManager {
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,9 @@ public class RegistrationManager extends AbstractManager {
|
||||||
public ListenableFuture<Void> setPassword(final String password) {
|
public ListenableFuture<Void> setPassword(final String password) {
|
||||||
final var account = getAccount();
|
final var account = getAccount();
|
||||||
final var iq = new Iq(Iq.Type.SET);
|
final var iq = new Iq(Iq.Type.SET);
|
||||||
iq.setTo(account.address.getDomain());
|
iq.setTo(account.address.asDomainBareJid());
|
||||||
final var register = iq.addExtension(new Register());
|
final var register = iq.addExtension(new Register());
|
||||||
register.addUsername(account.address.getEscapedLocal());
|
register.addUsername(account.address.getLocalpartOrThrow());
|
||||||
register.addPassword(password);
|
register.addPassword(password);
|
||||||
return Futures.transform(
|
return Futures.transform(
|
||||||
connection.sendIqPacket(iq), r -> null, MoreExecutors.directExecutor());
|
connection.sendIqPacket(iq), r -> null, MoreExecutors.directExecutor());
|
||||||
|
@ -44,7 +44,7 @@ public class RegistrationManager extends AbstractManager {
|
||||||
|
|
||||||
public ListenableFuture<Void> unregister() {
|
public ListenableFuture<Void> unregister() {
|
||||||
final var iq = new Iq(Iq.Type.SET);
|
final var iq = new Iq(Iq.Type.SET);
|
||||||
iq.setTo(getAccount().address.getDomain());
|
iq.setTo(getAccount().address.asDomainBareJid());
|
||||||
final var register = iq.addExtension(new Register());
|
final var register = iq.addExtension(new Register());
|
||||||
register.addExtension(new Remove());
|
register.addExtension(new Remove());
|
||||||
return Futures.transform(
|
return Futures.transform(
|
||||||
|
@ -53,7 +53,7 @@ public class RegistrationManager extends AbstractManager {
|
||||||
|
|
||||||
public ListenableFuture<Registration> getRegistration() {
|
public ListenableFuture<Registration> getRegistration() {
|
||||||
final var iq = new Iq(Iq.Type.GET);
|
final var iq = new Iq(Iq.Type.GET);
|
||||||
iq.setTo(getAccount().address.getDomain());
|
iq.setTo(getAccount().address.asDomainBareJid());
|
||||||
iq.addExtension(new Register());
|
iq.addExtension(new Register());
|
||||||
return Futures.transform(
|
return Futures.transform(
|
||||||
connection.sendIqPacketUnbound(iq),
|
connection.sendIqPacketUnbound(iq),
|
||||||
|
@ -98,7 +98,7 @@ public class RegistrationManager extends AbstractManager {
|
||||||
|
|
||||||
public ListenableFuture<Void> sendPreAuthentication(final String token) {
|
public ListenableFuture<Void> sendPreAuthentication(final String token) {
|
||||||
final var iq = new Iq(Iq.Type.GET);
|
final var iq = new Iq(Iq.Type.GET);
|
||||||
iq.setTo(getAccount().address.getDomain());
|
iq.setTo(getAccount().address.asDomainBareJid());
|
||||||
final var preAuthentication = iq.addExtension(new PreAuth());
|
final var preAuthentication = iq.addExtension(new PreAuth());
|
||||||
preAuthentication.setToken(token);
|
preAuthentication.setToken(token);
|
||||||
return Futures.transform(
|
return Futures.transform(
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package im.conversations.android.xmpp.manager;
|
package im.conversations.android.xmpp.manager;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xml.Namespace;
|
import im.conversations.android.xml.Namespace;
|
||||||
import im.conversations.android.xmpp.XmppConnection;
|
import im.conversations.android.xmpp.XmppConnection;
|
||||||
import im.conversations.android.xmpp.model.stanza.Message;
|
import im.conversations.android.xmpp.model.stanza.Message;
|
||||||
import im.conversations.android.xmpp.model.unique.StanzaId;
|
import im.conversations.android.xmpp.model.unique.StanzaId;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public class StanzaIdManager extends AbstractManager {
|
public class StanzaIdManager extends AbstractManager {
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package im.conversations.android.xmpp.model.blocking;
|
package im.conversations.android.xmpp.model.blocking;
|
||||||
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.annotation.XmlElement;
|
import im.conversations.android.annotation.XmlElement;
|
||||||
import im.conversations.android.xmpp.model.Extension;
|
import im.conversations.android.xmpp.model.Extension;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
@XmlElement
|
@XmlElement
|
||||||
public class Item extends Extension {
|
public class Item extends Extension {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package im.conversations.android.xmpp.model.disco.items;
|
package im.conversations.android.xmpp.model.disco.items;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.annotation.XmlElement;
|
import im.conversations.android.annotation.XmlElement;
|
||||||
import im.conversations.android.xmpp.model.Extension;
|
import im.conversations.android.xmpp.model.Extension;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
@XmlElement
|
@XmlElement
|
||||||
public class Item extends Extension {
|
public class Item extends Extension {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package im.conversations.android.xmpp.model.register;
|
||||||
|
|
||||||
import im.conversations.android.annotation.XmlElement;
|
import im.conversations.android.annotation.XmlElement;
|
||||||
import im.conversations.android.xmpp.model.Extension;
|
import im.conversations.android.xmpp.model.Extension;
|
||||||
|
import org.jxmpp.jid.parts.Localpart;
|
||||||
|
|
||||||
@XmlElement(name = "query")
|
@XmlElement(name = "query")
|
||||||
public class Register extends Extension {
|
public class Register extends Extension {
|
||||||
|
@ -10,8 +11,8 @@ public class Register extends Extension {
|
||||||
super(Register.class);
|
super(Register.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addUsername(final String username) {
|
public void addUsername(final Localpart username) {
|
||||||
this.addExtension(new Username()).setContent(username);
|
this.addExtension(new Username()).setContent(username.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addPassword(final String password) {
|
public void addPassword(final String password) {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package im.conversations.android.xmpp.model.reply;
|
package im.conversations.android.xmpp.model.reply;
|
||||||
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.annotation.XmlElement;
|
import im.conversations.android.annotation.XmlElement;
|
||||||
import im.conversations.android.xml.Namespace;
|
import im.conversations.android.xml.Namespace;
|
||||||
import im.conversations.android.xmpp.model.Extension;
|
import im.conversations.android.xmpp.model.Extension;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
@XmlElement(namespace = Namespace.REPLY)
|
@XmlElement(namespace = Namespace.REPLY)
|
||||||
public class Reply extends Extension {
|
public class Reply extends Extension {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package im.conversations.android.xmpp.model.roster;
|
package im.conversations.android.xmpp.model.roster;
|
||||||
|
|
||||||
import com.google.common.collect.Collections2;
|
import com.google.common.collect.Collections2;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.annotation.XmlElement;
|
import im.conversations.android.annotation.XmlElement;
|
||||||
import im.conversations.android.xml.Element;
|
import im.conversations.android.xml.Element;
|
||||||
import im.conversations.android.xmpp.model.Extension;
|
import im.conversations.android.xmpp.model.Extension;
|
||||||
|
@ -10,6 +9,7 @@ import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
@XmlElement
|
@XmlElement
|
||||||
public class Item extends Extension {
|
public class Item extends Extension {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package im.conversations.android.xmpp.model.stanza;
|
package im.conversations.android.xmpp.model.stanza;
|
||||||
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xmpp.model.Extension;
|
import im.conversations.android.xmpp.model.Extension;
|
||||||
import im.conversations.android.xmpp.model.StreamElement;
|
import im.conversations.android.xmpp.model.StreamElement;
|
||||||
import im.conversations.android.xmpp.model.error.Error;
|
import im.conversations.android.xmpp.model.error.Error;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public abstract class Stanza extends StreamElement {
|
public abstract class Stanza extends StreamElement {
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package im.conversations.android.xmpp.model.unique;
|
package im.conversations.android.xmpp.model.unique;
|
||||||
|
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.annotation.XmlElement;
|
import im.conversations.android.annotation.XmlElement;
|
||||||
import im.conversations.android.xmpp.model.Extension;
|
import im.conversations.android.xmpp.model.Extension;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
@XmlElement
|
@XmlElement
|
||||||
public class StanzaId extends Extension {
|
public class StanzaId extends Extension {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package im.conversations.android.xmpp.processor;
|
package im.conversations.android.xmpp.processor;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xml.Namespace;
|
import im.conversations.android.xml.Namespace;
|
||||||
import im.conversations.android.xmpp.Entity;
|
import im.conversations.android.xmpp.Entity;
|
||||||
import im.conversations.android.xmpp.XmppConnection;
|
import im.conversations.android.xmpp.XmppConnection;
|
||||||
|
@ -12,6 +11,7 @@ import im.conversations.android.xmpp.manager.DiscoManager;
|
||||||
import im.conversations.android.xmpp.manager.PresenceManager;
|
import im.conversations.android.xmpp.manager.PresenceManager;
|
||||||
import im.conversations.android.xmpp.manager.RosterManager;
|
import im.conversations.android.xmpp.manager.RosterManager;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public class BindProcessor extends XmppConnection.Delegate implements Consumer<Jid> {
|
public class BindProcessor extends XmppConnection.Delegate implements Consumer<Jid> {
|
||||||
|
|
||||||
|
@ -35,7 +35,8 @@ public class BindProcessor extends XmppConnection.Delegate implements Consumer<J
|
||||||
}
|
}
|
||||||
|
|
||||||
if (discoManager.hasServerFeature(Namespace.COMMANDS)) {
|
if (discoManager.hasServerFeature(Namespace.COMMANDS)) {
|
||||||
discoManager.items(Entity.discoItem(account.address.getDomain()), Namespace.COMMANDS);
|
discoManager.items(
|
||||||
|
Entity.discoItem(account.address.asDomainBareJid()), Namespace.COMMANDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
getManager(BookmarkManager.class).fetch();
|
getManager(BookmarkManager.class).fetch();
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package im.conversations.android.xmpp.processor;
|
package im.conversations.android.xmpp.processor;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import eu.siacs.conversations.xmpp.Jid;
|
|
||||||
import im.conversations.android.xmpp.XmppConnection;
|
import im.conversations.android.xmpp.XmppConnection;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
public class MessageAcknowledgeProcessor extends XmppConnection.Delegate
|
public class MessageAcknowledgeProcessor extends XmppConnection.Delegate
|
||||||
implements BiFunction<Jid, String, Boolean> {
|
implements BiFunction<Jid, String, Boolean> {
|
||||||
|
|
|
@ -19,7 +19,7 @@ public class PresenceProcessor extends XmppConnection.Delegate implements Consum
|
||||||
public void accept(final Presence presencePacket) {
|
public void accept(final Presence presencePacket) {
|
||||||
final var from = presencePacket.getFrom();
|
final var from = presencePacket.getFrom();
|
||||||
final var address = from == null ? null : from.asBareJid();
|
final var address = from == null ? null : from.asBareJid();
|
||||||
final var resource = from == null ? null : from.getResource();
|
final var resource = from == null ? null : from.getResourceOrEmpty();
|
||||||
final var typeAttribute = presencePacket.getAttribute("type");
|
final var typeAttribute = presencePacket.getAttribute("type");
|
||||||
final PresenceType type;
|
final PresenceType type;
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class DigestMd5 extends SaslMechanism {
|
||||||
final String digestUri = "xmpp/" + account.address.getDomain();
|
final String digestUri = "xmpp/" + account.address.getDomain();
|
||||||
final String nonceCount = "00000001";
|
final String nonceCount = "00000001";
|
||||||
final String x =
|
final String x =
|
||||||
account.address.getEscapedLocal()
|
account.address.getLocalpartOrNull().toString()
|
||||||
+ ":"
|
+ ":"
|
||||||
+ account.address.getDomain()
|
+ account.address.getDomain()
|
||||||
+ ":"
|
+ ":"
|
||||||
|
@ -60,7 +60,7 @@ public class DigestMd5 extends SaslMechanism {
|
||||||
final byte[] y = md.digest(x.getBytes(Charset.defaultCharset()));
|
final byte[] y = md.digest(x.getBytes(Charset.defaultCharset()));
|
||||||
final String cNonce = CryptoHelper.random(100);
|
final String cNonce = CryptoHelper.random(100);
|
||||||
final byte[] a1 =
|
final byte[] a1 =
|
||||||
CryptoHelper.concatenateByteArrays(
|
concatenate(
|
||||||
y,
|
y,
|
||||||
(":" + nonce + ":" + cNonce)
|
(":" + nonce + ":" + cNonce)
|
||||||
.getBytes(Charset.defaultCharset()));
|
.getBytes(Charset.defaultCharset()));
|
||||||
|
@ -76,7 +76,7 @@ public class DigestMd5 extends SaslMechanism {
|
||||||
md.digest(kd.getBytes(Charset.defaultCharset())));
|
md.digest(kd.getBytes(Charset.defaultCharset())));
|
||||||
final String saslString =
|
final String saslString =
|
||||||
"username=\""
|
"username=\""
|
||||||
+ account.address.getEscapedLocal()
|
+ account.address.getLocalpartOrThrow().toString()
|
||||||
+ "\",realm=\""
|
+ "\",realm=\""
|
||||||
+ account.address.getDomain()
|
+ account.address.getDomain()
|
||||||
+ "\",nonce=\""
|
+ "\",nonce=\""
|
||||||
|
|
|
@ -25,6 +25,6 @@ public class External extends SaslMechanism {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getClientFirstMessage(final SSLSocket sslSocket) {
|
public String getClientFirstMessage(final SSLSocket sslSocket) {
|
||||||
return Base64.encodeToString(account.address.toEscapedString().getBytes(), Base64.NO_WRAP);
|
return Base64.encodeToString(account.address.toString().getBytes(), Base64.NO_WRAP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,9 +49,10 @@ public abstract class HashedToken extends SaslMechanism implements ChannelBindin
|
||||||
final byte[] cbData = getChannelBindingData(sslSocket);
|
final byte[] cbData = getChannelBindingData(sslSocket);
|
||||||
final byte[] initiatorHashedToken =
|
final byte[] initiatorHashedToken =
|
||||||
hashing.hashBytes(Bytes.concat(INITIATOR, cbData)).asBytes();
|
hashing.hashBytes(Bytes.concat(INITIATOR, cbData)).asBytes();
|
||||||
|
final String username = account.address.getLocalpartOrThrow().toString();
|
||||||
final byte[] firstMessage =
|
final byte[] firstMessage =
|
||||||
Bytes.concat(
|
Bytes.concat(
|
||||||
account.address.getEscapedLocal().getBytes(StandardCharsets.UTF_8),
|
username.getBytes(StandardCharsets.UTF_8),
|
||||||
new byte[] {0x00},
|
new byte[] {0x00},
|
||||||
initiatorHashedToken);
|
initiatorHashedToken);
|
||||||
return Base64.encodeToString(firstMessage, Base64.NO_WRAP);
|
return Base64.encodeToString(firstMessage, Base64.NO_WRAP);
|
||||||
|
|
|
@ -33,6 +33,7 @@ public class Plain extends SaslMechanism {
|
||||||
@Override
|
@Override
|
||||||
public String getClientFirstMessage(final SSLSocket sslSocket) {
|
public String getClientFirstMessage(final SSLSocket sslSocket) {
|
||||||
return getMessage(
|
return getMessage(
|
||||||
account.address.getEscapedLocal(), Strings.nullToEmpty(credential.password));
|
account.address.getLocalpartOrThrow().toString(),
|
||||||
|
Strings.nullToEmpty(credential.password));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,4 +233,11 @@ public abstract class SaslMechanism {
|
||||||
public static boolean pin(final SaslMechanism saslMechanism) {
|
public static boolean pin(final SaslMechanism saslMechanism) {
|
||||||
return !hashedToken(saslMechanism);
|
return !hashedToken(saslMechanism);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static byte[] concatenate(byte[] a, byte[] b) {
|
||||||
|
byte[] result = new byte[a.length + b.length];
|
||||||
|
System.arraycopy(a, 0, result, 0, a.length);
|
||||||
|
System.arraycopy(b, 0, result, a.length, b.length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,12 @@ import com.google.common.base.Strings;
|
||||||
import com.google.common.cache.Cache;
|
import com.google.common.cache.Cache;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.hash.HashFunction;
|
import com.google.common.hash.HashFunction;
|
||||||
import eu.siacs.conversations.utils.CryptoHelper;
|
import im.conversations.android.IDs;
|
||||||
import im.conversations.android.database.model.Account;
|
import im.conversations.android.database.model.Account;
|
||||||
import im.conversations.android.database.model.Credential;
|
import im.conversations.android.database.model.Credential;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
|
import java.text.Normalizer;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import javax.net.ssl.SSLSocket;
|
import javax.net.ssl.SSLSocket;
|
||||||
|
@ -36,6 +37,8 @@ abstract class ScramMechanism extends SaslMechanism {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final byte[] ONE = new byte[] {0, 0, 0, 1};
|
||||||
|
|
||||||
private static final byte[] CLIENT_KEY_BYTES = "Client Key".getBytes();
|
private static final byte[] CLIENT_KEY_BYTES = "Client Key".getBytes();
|
||||||
private static final byte[] SERVER_KEY_BYTES = "Server Key".getBytes();
|
private static final byte[] SERVER_KEY_BYTES = "Server Key".getBytes();
|
||||||
private static final Cache<CacheKey, KeyPair> CACHE =
|
private static final Cache<CacheKey, KeyPair> CACHE =
|
||||||
|
@ -67,7 +70,7 @@ abstract class ScramMechanism extends SaslMechanism {
|
||||||
.convert(channelBinding.toString()));
|
.convert(channelBinding.toString()));
|
||||||
}
|
}
|
||||||
// This nonce should be different for each authentication attempt.
|
// This nonce should be different for each authentication attempt.
|
||||||
this.clientNonce = CryptoHelper.random(100);
|
this.clientNonce = IDs.huge();
|
||||||
clientFirstMessageBare = "";
|
clientFirstMessageBare = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +110,7 @@ abstract class ScramMechanism extends SaslMechanism {
|
||||||
*/
|
*/
|
||||||
private byte[] hi(final byte[] key, final byte[] salt, final int iterations)
|
private byte[] hi(final byte[] key, final byte[] salt, final int iterations)
|
||||||
throws InvalidKeyException {
|
throws InvalidKeyException {
|
||||||
byte[] u = hmac(key, CryptoHelper.concatenateByteArrays(salt, CryptoHelper.ONE));
|
byte[] u = hmac(key, concatenate(salt, ONE));
|
||||||
byte[] out = u.clone();
|
byte[] out = u.clone();
|
||||||
for (int i = 1; i < iterations; i++) {
|
for (int i = 1; i < iterations; i++) {
|
||||||
u = hmac(key, u);
|
u = hmac(key, u);
|
||||||
|
@ -123,8 +126,7 @@ abstract class ScramMechanism extends SaslMechanism {
|
||||||
if (clientFirstMessageBare.isEmpty() && state == State.INITIAL) {
|
if (clientFirstMessageBare.isEmpty() && state == State.INITIAL) {
|
||||||
clientFirstMessageBare =
|
clientFirstMessageBare =
|
||||||
"n="
|
"n="
|
||||||
+ CryptoHelper.saslEscape(
|
+ escape(prep(account.address.getLocalpartOrThrow().toString()))
|
||||||
CryptoHelper.saslPrep(account.address.getEscapedLocal()))
|
|
||||||
+ ",r="
|
+ ",r="
|
||||||
+ this.clientNonce;
|
+ this.clientNonce;
|
||||||
state = State.AUTH_TEXT_SENT;
|
state = State.AUTH_TEXT_SENT;
|
||||||
|
@ -216,7 +218,7 @@ abstract class ScramMechanism extends SaslMechanism {
|
||||||
try {
|
try {
|
||||||
keys =
|
keys =
|
||||||
getKeyPair(
|
getKeyPair(
|
||||||
CryptoHelper.saslPrep(Strings.nullToEmpty(credential.password)),
|
prep(Strings.nullToEmpty(credential.password)),
|
||||||
salt,
|
salt,
|
||||||
iterationCount);
|
iterationCount);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
|
@ -269,6 +271,29 @@ abstract class ScramMechanism extends SaslMechanism {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String escape(final String s) {
|
||||||
|
final StringBuilder sb = new StringBuilder((int) (s.length() * 1.1));
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
char c = s.charAt(i);
|
||||||
|
switch (c) {
|
||||||
|
case ',':
|
||||||
|
sb.append("=2C");
|
||||||
|
break;
|
||||||
|
case '=':
|
||||||
|
sb.append("=3D");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sb.append(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String prep(final String s) {
|
||||||
|
return Normalizer.normalize(s, Normalizer.Form.NFKC);
|
||||||
|
}
|
||||||
|
|
||||||
protected byte[] getChannelBindingData(final SSLSocket sslSocket)
|
protected byte[] getChannelBindingData(final SSLSocket sslSocket)
|
||||||
throws AuthenticationException {
|
throws AuthenticationException {
|
||||||
if (this.channelBinding == ChannelBinding.NONE) {
|
if (this.channelBinding == ChannelBinding.NONE) {
|
||||||
|
|
Loading…
Reference in a new issue