]> nmode's Git Repositories - signal-cli/commitdiff
Add support for about and aboutEmoji for profiles
authorAsamK <asamk@gmx.de>
Sat, 23 Jan 2021 23:02:07 +0000 (00:02 +0100)
committerAsamK <asamk@gmx.de>
Sat, 23 Jan 2021 23:02:07 +0000 (00:02 +0100)
lib/src/main/java/org/asamk/signal/manager/Manager.java
lib/src/main/java/org/asamk/signal/manager/storage/profiles/SignalProfile.java
lib/src/main/java/org/asamk/signal/manager/util/ProfileUtils.java
src/main/java/org/asamk/signal/commands/UpdateProfileCommand.java

index 11ee137d9fa0be905e761d907233e46beef52a50..be31493de7f00798650d5c7c4735cba77754e42f 100644 (file)
@@ -362,22 +362,33 @@ public class Manager implements Closeable {
     }
 
     /**
     }
 
     /**
-     * @param avatar if avatar is null the image from the local avatar store is used (if present),
-     *               if it's Optional.absent(), the avatar will be removed
+     * @param name       if null, the previous name will be kept
+     * @param about      if null, the previous about text will be kept
+     * @param aboutEmoji if null, the previous about emoji will be kept
+     * @param avatar     if avatar is null the image from the local avatar store is used (if present),
+     *                   if it's Optional.absent(), the avatar will be removed
      */
      */
-    public void setProfile(String name, Optional<File> avatar) throws IOException {
-        // TODO
-        String about = null;
-        String aboutEmoji = null;
+    public void setProfile(String name, String about, String aboutEmoji, Optional<File> avatar) throws IOException {
+        SignalProfileEntry profileEntry = account.getProfileStore().getProfileEntry(getSelfAddress());
+        SignalProfile profile = profileEntry == null ? null : profileEntry.getProfile();
+        SignalProfile newProfile = new SignalProfile(profile == null ? null : profile.getIdentityKey(),
+                name != null ? name : profile == null || profile.getName() == null ? "" : profile.getName(),
+                about != null ? about : profile == null || profile.getAbout() == null ? "" : profile.getAbout(),
+                aboutEmoji != null
+                        ? aboutEmoji
+                        : profile == null || profile.getAboutEmoji() == null ? "" : profile.getAboutEmoji(),
+                profile == null ? null : profile.getUnidentifiedAccess(),
+                account.isUnrestrictedUnidentifiedAccess(),
+                profile == null ? null : profile.getCapabilities());
 
         try (final StreamDetails streamDetails = avatar == null
                 ? avatarStore.retrieveProfileAvatar(getSelfAddress())
                 : avatar.isPresent() ? Utils.createStreamDetailsFromFile(avatar.get()) : null) {
             accountManager.setVersionedProfile(account.getUuid(),
                     account.getProfileKey(),
 
         try (final StreamDetails streamDetails = avatar == null
                 ? avatarStore.retrieveProfileAvatar(getSelfAddress())
                 : avatar.isPresent() ? Utils.createStreamDetailsFromFile(avatar.get()) : null) {
             accountManager.setVersionedProfile(account.getUuid(),
                     account.getProfileKey(),
-                    name,
-                    about,
-                    aboutEmoji,
+                    newProfile.getName(),
+                    newProfile.getAbout(),
+                    newProfile.getAboutEmoji(),
                     streamDetails);
         }
 
                     streamDetails);
         }
 
@@ -389,6 +400,12 @@ public class Manager implements Closeable {
                 avatarStore.deleteProfileAvatar(getSelfAddress());
             }
         }
                 avatarStore.deleteProfileAvatar(getSelfAddress());
             }
         }
+        account.getProfileStore()
+                .updateProfile(getSelfAddress(),
+                        account.getProfileKey(),
+                        System.currentTimeMillis(),
+                        newProfile,
+                        profileEntry == null ? null : profileEntry.getProfileKeyCredential());
 
         try {
             sendSyncMessage(SignalServiceSyncMessage.forFetchLatest(SignalServiceSyncMessage.FetchType.LOCAL_PROFILE));
 
         try {
             sendSyncMessage(SignalServiceSyncMessage.forFetchLatest(SignalServiceSyncMessage.FetchType.LOCAL_PROFILE));
index 1ec2eeaaf6a26dd4e61543d52743ebb50b3145c6..6a761c293d9bc3fa1f1a01640aa16d8d479eca05 100644 (file)
@@ -13,6 +13,12 @@ public class SignalProfile {
     @JsonProperty
     private final String name;
 
     @JsonProperty
     private final String name;
 
+    @JsonProperty
+    private final String about;
+
+    @JsonProperty
+    private final String aboutEmoji;
+
     @JsonProperty
     private final String unidentifiedAccess;
 
     @JsonProperty
     private final String unidentifiedAccess;
 
@@ -25,12 +31,16 @@ public class SignalProfile {
     public SignalProfile(
             final String identityKey,
             final String name,
     public SignalProfile(
             final String identityKey,
             final String name,
+            final String about,
+            final String aboutEmoji,
             final String unidentifiedAccess,
             final boolean unrestrictedUnidentifiedAccess,
             final SignalServiceProfile.Capabilities capabilities
     ) {
         this.identityKey = identityKey;
         this.name = name;
             final String unidentifiedAccess,
             final boolean unrestrictedUnidentifiedAccess,
             final SignalServiceProfile.Capabilities capabilities
     ) {
         this.identityKey = identityKey;
         this.name = name;
+        this.about = about;
+        this.aboutEmoji = aboutEmoji;
         this.unidentifiedAccess = unidentifiedAccess;
         this.unrestrictedUnidentifiedAccess = unrestrictedUnidentifiedAccess;
         this.capabilities = new Capabilities();
         this.unidentifiedAccess = unidentifiedAccess;
         this.unrestrictedUnidentifiedAccess = unrestrictedUnidentifiedAccess;
         this.capabilities = new Capabilities();
@@ -42,12 +52,16 @@ public class SignalProfile {
     public SignalProfile(
             @JsonProperty("identityKey") final String identityKey,
             @JsonProperty("name") final String name,
     public SignalProfile(
             @JsonProperty("identityKey") final String identityKey,
             @JsonProperty("name") final String name,
+            @JsonProperty("about") final String about,
+            @JsonProperty("aboutEmoji") final String aboutEmoji,
             @JsonProperty("unidentifiedAccess") final String unidentifiedAccess,
             @JsonProperty("unrestrictedUnidentifiedAccess") final boolean unrestrictedUnidentifiedAccess,
             @JsonProperty("capabilities") final Capabilities capabilities
     ) {
         this.identityKey = identityKey;
         this.name = name;
             @JsonProperty("unidentifiedAccess") final String unidentifiedAccess,
             @JsonProperty("unrestrictedUnidentifiedAccess") final boolean unrestrictedUnidentifiedAccess,
             @JsonProperty("capabilities") final Capabilities capabilities
     ) {
         this.identityKey = identityKey;
         this.name = name;
+        this.about = about;
+        this.aboutEmoji = aboutEmoji;
         this.unidentifiedAccess = unidentifiedAccess;
         this.unrestrictedUnidentifiedAccess = unrestrictedUnidentifiedAccess;
         this.capabilities = capabilities;
         this.unidentifiedAccess = unidentifiedAccess;
         this.unrestrictedUnidentifiedAccess = unrestrictedUnidentifiedAccess;
         this.capabilities = capabilities;
@@ -61,6 +75,14 @@ public class SignalProfile {
         return name;
     }
 
         return name;
     }
 
+    public String getAbout() {
+        return about;
+    }
+
+    public String getAboutEmoji() {
+        return aboutEmoji;
+    }
+
     public String getUnidentifiedAccess() {
         return unidentifiedAccess;
     }
     public String getUnidentifiedAccess() {
         return unidentifiedAccess;
     }
@@ -82,7 +104,12 @@ public class SignalProfile {
                 + ", name='"
                 + name
                 + '\''
                 + ", name='"
                 + name
                 + '\''
-                + ", avatarFile="
+                + ", about='"
+                + about
+                + '\''
+                + ", aboutEmoji='"
+                + aboutEmoji
+                + '\''
                 + ", unidentifiedAccess='"
                 + unidentifiedAccess
                 + '\''
                 + ", unidentifiedAccess='"
                 + unidentifiedAccess
                 + '\''
index b91e864a43471d1e31ae85c7eeb87bcf8f7a7b2d..1136244459cb55b4a6c1f44d5a83f19433fae35d 100644 (file)
@@ -15,14 +15,9 @@ public class ProfileUtils {
     ) {
         ProfileCipher profileCipher = new ProfileCipher(profileKey);
         try {
     ) {
         ProfileCipher profileCipher = new ProfileCipher(profileKey);
         try {
-            String name;
-            try {
-                name = encryptedProfile.getName() == null
-                        ? null
-                        : new String(profileCipher.decryptName(Base64.getDecoder().decode(encryptedProfile.getName())));
-            } catch (IllegalArgumentException e) {
-                name = null;
-            }
+            String name = decryptName(encryptedProfile.getName(), profileCipher);
+            String about = decryptName(encryptedProfile.getAbout(), profileCipher);
+            String aboutEmoji = decryptName(encryptedProfile.getAboutEmoji(), profileCipher);
             String unidentifiedAccess;
             try {
                 unidentifiedAccess = encryptedProfile.getUnidentifiedAccess() == null
             String unidentifiedAccess;
             try {
                 unidentifiedAccess = encryptedProfile.getUnidentifiedAccess() == null
@@ -35,6 +30,8 @@ public class ProfileUtils {
             }
             return new SignalProfile(encryptedProfile.getIdentityKey(),
                     name,
             }
             return new SignalProfile(encryptedProfile.getIdentityKey(),
                     name,
+                    about,
+                    aboutEmoji,
                     unidentifiedAccess,
                     encryptedProfile.isUnrestrictedUnidentifiedAccess(),
                     encryptedProfile.getCapabilities());
                     unidentifiedAccess,
                     encryptedProfile.isUnrestrictedUnidentifiedAccess(),
                     encryptedProfile.getCapabilities());
@@ -42,4 +39,16 @@ public class ProfileUtils {
             return null;
         }
     }
             return null;
         }
     }
+
+    private static String decryptName(
+            final String encryptedName, final ProfileCipher profileCipher
+    ) throws InvalidCiphertextException {
+        try {
+            return encryptedName == null
+                    ? null
+                    : new String(profileCipher.decryptName(Base64.getDecoder().decode(encryptedName)));
+        } catch (IllegalArgumentException e) {
+            return null;
+        }
+    }
 }
 }
index c2ff2e5e0e624d920097a1d0f4b65b089fdc18df..35190fe8066dc15fcbbf8a50fa8208e81b23403c 100644 (file)
@@ -15,18 +15,22 @@ public class UpdateProfileCommand implements LocalCommand {
 
     @Override
     public void attachToSubparser(final Subparser subparser) {
 
     @Override
     public void attachToSubparser(final Subparser subparser) {
+        subparser.addArgument("--name").help("New profile name");
+        subparser.addArgument("--about").help("New profile about text");
+        subparser.addArgument("--about-emoji").help("New profile about emoji");
+
         final MutuallyExclusiveGroup avatarOptions = subparser.addMutuallyExclusiveGroup();
         avatarOptions.addArgument("--avatar").help("Path to new profile avatar");
         avatarOptions.addArgument("--remove-avatar").action(Arguments.storeTrue());
 
         final MutuallyExclusiveGroup avatarOptions = subparser.addMutuallyExclusiveGroup();
         avatarOptions.addArgument("--avatar").help("Path to new profile avatar");
         avatarOptions.addArgument("--remove-avatar").action(Arguments.storeTrue());
 
-        subparser.addArgument("--name").required(true).help("New profile name");
-
-        subparser.help("Set a name and avatar image for the user profile");
+        subparser.help("Set a name, about and avatar image for the user profile");
     }
 
     @Override
     public int handleCommand(final Namespace ns, final Manager m) {
         String name = ns.getString("name");
     }
 
     @Override
     public int handleCommand(final Namespace ns, final Manager m) {
         String name = ns.getString("name");
+        String about = ns.getString("about");
+        String aboutEmoji = ns.getString("about_emoji");
         String avatarPath = ns.getString("avatar");
         boolean removeAvatar = ns.getBoolean("remove_avatar");
 
         String avatarPath = ns.getString("avatar");
         boolean removeAvatar = ns.getBoolean("remove_avatar");
 
@@ -34,7 +38,7 @@ public class UpdateProfileCommand implements LocalCommand {
             Optional<File> avatarFile = removeAvatar
                     ? Optional.absent()
                     : avatarPath == null ? null : Optional.of(new File(avatarPath));
             Optional<File> avatarFile = removeAvatar
                     ? Optional.absent()
                     : avatarPath == null ? null : Optional.of(new File(avatarPath));
-            m.setProfile(name, avatarFile);
+            m.setProfile(name, about, aboutEmoji, avatarFile);
         } catch (IOException e) {
             System.err.println("UpdateAccount error: " + e.getMessage());
             return 3;
         } catch (IOException e) {
             System.err.println("UpdateAccount error: " + e.getMessage());
             return 3;