From 00c35b821b000e12ed878f1611a2035f32ce5eee Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 24 Jun 2024 14:10:39 -0300 Subject: [PATCH 01/58] set property editId to save row id tha was edit --- .../parsers/whatsapp/ExtractorAndroidNew.java | 28 +++++++++++++++---- .../java/iped/parsers/whatsapp/Message.java | 9 ++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index 1e55230a28..91365fb23f 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -547,9 +547,16 @@ private void extractMessages(Connection conn, Map idToChat) throws S } else { // not found original message reference, get info from message_quotes table, // less complete - mq.setDeleted(true); - mq.setId(fakeIds--); - m.setMessageQuote(mq); + long editId = mq.getEditId(); + if (editId <= 0){ + mq.setDeleted(true); + mq.setId(fakeIds--); + m.setMessageQuote(mq); + }else{ // If quoted message was edited, set reference to jump + mq.setDeleted(false); + mq.setId(editId); + m.setMessageQuote(mq); + } } m.setQuoted(true); @@ -610,6 +617,8 @@ private Map> extractQuoteMessages(Connection conn) throws SQ m.setUuid(rs.getString("uuid")); + m.setEditId(rs.getLong("edit_row_id")); + long chatId = rs.getLong("chatId"); List messages = messagesPerChatId.get(chatId); if (messages == null) { @@ -1060,20 +1069,27 @@ private static String getSelectMessagesQuotesQuery(Connection conn) throws SQLEx String captionCol = SQLite3DBParser.checkIfColumnExists(conn, "message_quoted_media", "media_caption") ? "mm.media_caption" : "null"; + String editCol = "null as edit_row_id,"; + String editTableJoin = ""; + if (SQLite3DBParser.containsTable("message_edit_info", conn)) { + editCol = "mei.message_row_id as edit_row_id,"; + editTableJoin = " left join message_edit_info mei on mei.original_key_id=mq.key_id"; + } return "select mq.message_row_id as id,mq.chat_row_id as chatId, chatJid.raw_string as remoteId," + " jid.raw_string as remoteResource, mv.vcard, mq.text_data," + " mq.from_me as fromMe, mq.timestamp as timestamp, message_url as mediaUrl," + " mm.mime_type as mediaMime, mm.file_length as mediaSize, media_name as mediaName," + " mq.message_type as messageType, latitude, longitude, mm.media_duration, " + captionCol - + " as mediaCaption, mm.file_hash as mediaHash, mm.thumbnail as thumbData," - + " mq.key_id as uuid" + + " as mediaCaption, mm.file_hash as mediaHash, mm.thumbnail as thumbData, " + editCol + + " mq.key_id as uuid" + " from message_quoted mq" + " left join chat on mq.chat_row_id=chat._id" + " left join jid chatJid on chatJid._id=chat.jid_row_id" + " left join message_quoted_media mm on mm.message_row_id=mq.message_row_id" + " left join jid on jid._id=mq.sender_jid_row_id" + " left join message_quoted_location ml on mq.message_row_id=ml.message_row_id" - + " left join message_quoted_vcard mv on mq.message_row_id=mv.message_row_id"; + + " left join message_quoted_vcard mv on mq.message_row_id=mv.message_row_id" + + editTableJoin; } private static String getSelectBlockedQuery(Connection conn) throws SQLException { diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java index 2eb4e85870..04f231c223 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java @@ -70,6 +70,7 @@ public class Message implements Comparable { private Message messageQuote = null; private boolean quoted = false; private String uuid = null; + private long editId = -1; private byte[] metaData; private String groupInviteName; private MessageTemplate messageTemplate; @@ -570,6 +571,14 @@ public void setUuid(String uuid) { this.uuid = uuid; } + public long getEditId() { + return this.editId; + } + + public void setEditId(long editId) { + this.editId = editId; + } + public byte[] getMetaData() { return metaData; } From d9b54070c404b335008781a680ab1f841437b0b8 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 24 Jun 2024 14:11:42 -0300 Subject: [PATCH 02/58] change sql and set logic --- .../main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index 91365fb23f..f1810ba46d 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -552,7 +552,7 @@ private void extractMessages(Connection conn, Map idToChat) throws S mq.setDeleted(true); mq.setId(fakeIds--); m.setMessageQuote(mq); - }else{ // If quoted message was edited, set reference to jump + }else{ // If quoted message was edited,set reference to jump mq.setDeleted(false); mq.setId(editId); m.setMessageQuote(mq); From 759834928bd91b51e5a24f05c766a605399aa855 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 24 Jun 2024 14:41:13 -0300 Subject: [PATCH 03/58] The id of the edited message may not be in the table, test it again --- .../main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index f1810ba46d..e4d98c6333 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -548,11 +548,11 @@ private void extractMessages(Connection conn, Map idToChat) throws S // not found original message reference, get info from message_quotes table, // less complete long editId = mq.getEditId(); - if (editId <= 0){ + if (messagesMap.get(editId) == null){ // Quoted message cannot be found again mq.setDeleted(true); mq.setId(fakeIds--); m.setMessageQuote(mq); - }else{ // If quoted message was edited,set reference to jump + }else{ // If quoted message was edited, jump to the correct message mq.setDeleted(false); mq.setId(editId); m.setMessageQuote(mq); From b9b69a48e62499a35f9415e0efc5025c86f18475 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:46:43 -0300 Subject: [PATCH 04/58] add action type 63 and 142 message string --- .../resources/localization/iped-parsers-messages.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iped-app/resources/localization/iped-parsers-messages.properties b/iped-app/resources/localization/iped-parsers-messages.properties index ee4e2615c4..fa40a0c346 100644 --- a/iped-app/resources/localization/iped-parsers-messages.properties +++ b/iped-app/resources/localization/iped-parsers-messages.properties @@ -325,6 +325,8 @@ WhatsAppReport.EditedOn=Edited on WhatsAppReport.UserJoinedWhatsApp=joined WhatsApp WhatsAppReport.PinnedMessage=pinned a message WhatsAppReport.AIThirdParty=This AI is from a third-party developer. Meta receives your AI chats to improve AI quality. +WhatsAppReport.Over256MembersOnlyAdminsCanEdit=This group has over 256 members so now only admins can edit the groups settings. +WhatsAppReport.SecurityNotificationsNoLongerAvailable=Security code notifications are no longer available for this chat. VCardParser.FormattedName=Formatted Name VCardParser.Name=Name VCardParser.Nickname=Nickname From 3566aa3f474800e8a2eed1e5143d608167658826 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:46:56 -0300 Subject: [PATCH 05/58] add action type 63 and 142 --- .../java/iped/parsers/whatsapp/ExtractorAndroidNew.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index e4d98c6333..36ca0c26e1 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -88,6 +88,8 @@ import static iped.parsers.whatsapp.Message.MessageType.WAITING_MESSAGE; import static iped.parsers.whatsapp.Message.MessageType.YOU_ADMIN; import static iped.parsers.whatsapp.Message.MessageType.YOU_NOT_ADMIN; +import static iped.parsers.whatsapp.Message.MessageType.OVER_256_MEMBERS_ONLY_ADMINS_CAN_EDIT; +import static iped.parsers.whatsapp.Message.MessageType.SECURITY_NOTIFICATIONS_NO_LONGER_AVAILABLE; import java.io.File; import java.sql.Connection; @@ -733,6 +735,9 @@ protected Message.MessageType decodeMessageType(int messageType, int status, Int // Can be ignored as nothing was changed. result = EPHEMERAL_SETTINGS_NOT_APPLIED; break; + case 63: + result = SECURITY_NOTIFICATIONS_NO_LONGER_AVAILABLE; + break; // TODO: Handle business related notification (no extra tables/fields) // case 63: // result = ???; @@ -811,6 +816,9 @@ protected Message.MessageType decodeMessageType(int messageType, int status, Int case 136: result = USER_JOINED_WHATSAPP; break; + case 142: + result = OVER_256_MEMBERS_ONLY_ADMINS_CAN_EDIT; + break; case 155: result = AI_THIRD_PARTY; break; From db5e80876530ff67addb01c508a977abf98fb6c0 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:47:07 -0300 Subject: [PATCH 06/58] add action type 63 and 142 --- .../src/main/java/iped/parsers/whatsapp/Message.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java index 04f231c223..7b0f706341 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java @@ -453,6 +453,8 @@ public boolean isSystemMessage() { case USER_REMOVED_FROM_GROUP: case YOU_ADMIN: case YOU_NOT_ADMIN: + case OVER_256_MEMBERS_ONLY_ADMINS_CAN_EDIT: + case SECURITY_NOTIFICATIONS_NO_LONGER_AVAILABLE: return true; default: } @@ -644,7 +646,7 @@ public void setAddress(String address) { } public static enum MessageType { - TEXT_MESSAGE, IMAGE_MESSAGE, AUDIO_MESSAGE, VIDEO_MESSAGE, UNKNOWN_MEDIA_MESSAGE, CONTACT_MESSAGE, LOCATION_MESSAGE, SHARE_LOCATION_MESSAGE, VOICE_CALL, VIDEO_CALL, DOC_MESSAGE, GIF_MESSAGE, BLOCKED_CONTACT, UNBLOCKED_CONTACT, BUSINESS_CHAT, BUSINESS_TO_STANDARD, MESSAGES_ENCRYPTED, MESSAGES_NOW_ENCRYPTED, ENCRYPTION_KEY_CHANGED, MISSED_VOICE_CALL, MISSED_VIDEO_CALL, DELETED_MESSAGE, DELETED_BY_ADMIN, DELETED_BY_SENDER, GROUP_CREATED, USER_ADDED_TO_COMMUNITY, USER_ADDED_TO_GROUP, USER_JOINED_GROUP_FROM_COMMUNITY, USER_JOINED_GROUP_FROM_LINK, USER_JOINED_GROUP_FROM_INVITATION, USER_LEFT_GROUP, USER_REMOVED_FROM_GROUP, USER_COMMUNITY_ADMIN, URL_MESSAGE, GROUP_ICON_CHANGED, GROUP_ICON_DELETED, GROUP_DESCRIPTION_CHANGED, GROUP_DESCRIPTION_DELETED, SUBJECT_CHANGED, YOU_ADMIN, YOU_NOT_ADMIN, USER_ADMIN, WAITING_MESSAGE, STICKER_MESSAGE, REFUSED_VIDEO_CALL, REFUSED_VOICE_CALL, UNAVAILABLE_VIDEO_CALL, UNAVAILABLE_VOICE_CALL, UNKNOWN_VOICE_CALL, UNKNOWN_VIDEO_CALL, VIEW_ONCE_AUDIO_MESSAGE, VIEW_ONCE_IMAGE_MESSAGE, VIEW_ONCE_VIDEO_MESSAGE, CALL_MESSAGE, BUSINESS_META_SECURE_SERVICE, GROUP_INVITE, TEMPLATE_MESSAGE, TEMPLATE_QUOTE, POLL_MESSAGE, EPHEMERAL_DURATION_CHANGED, EPHEMERAL_SETTINGS_NOT_APPLIED, EPHEMERAL_CHANGED, EPHEMERAL_DEFAULT, EPHEMERAL_SAVE, GROUP_CHANGED_ONLY_ADMINS_CAN_ADD, GROUP_CHANGED_ONLY_ADMINS_CAN_SEND, GROUP_CHANGED_ALL_MEMBERS_CAN_SEND, GROUP_CHANGED_ONLY_ADMINS_CAN_EDIT, GROUP_CHANGED_ALL_MEMBERS_CAN_EDIT, GROUP_ONLY_ADMINS_CAN_SEND, CHANGED_DEVICE, CHANGED_NUMBER_TO, CHANGED_NUMBER_CHATTING_WITH_NEW, CHANGED_NUMBER_CHATTING_WITH_OLD, STANDARD_CHAT, SENDER_ADDED_TO_CONTACTS, SENDER_IN_CONTACTS, BUSINESS_OFFICIAL, GROUP_ADDED_TO_COMMUNITY, GROUP_REMOVED_FROM_COMMUNITY, COMMUNITY_MANAGEMENT_ACTION, COMMUNITY_WELCOME, UI_ELEMENTS, UI_ELEMENTS_QUOTE, CHAT_ADDED_PRIVACY, CHANNEL_ADDED_PRIVACY, CHANNEL_CREATED, ORDER_MESSAGE, PRODUCT_MESSAGE, BUSINESS_CHANGED_NAME, USER_JOINED_WHATSAPP, PINNED_MESSAGE, GROUP_NAME_CHANGED, AI_THIRD_PARTY, NEW_PARTICIPANTS_NEED_ADMIN_APPROVAL, RESET_GROUP_LINK, COMMUNITY_RENAMED, ANY_COMMUNITY_MEMBER_CAN_JOIN_GROUP, UNKNOWN_MESSAGE + TEXT_MESSAGE, IMAGE_MESSAGE, AUDIO_MESSAGE, VIDEO_MESSAGE, UNKNOWN_MEDIA_MESSAGE, CONTACT_MESSAGE, LOCATION_MESSAGE, SHARE_LOCATION_MESSAGE, VOICE_CALL, VIDEO_CALL, DOC_MESSAGE, GIF_MESSAGE, BLOCKED_CONTACT, UNBLOCKED_CONTACT, BUSINESS_CHAT, BUSINESS_TO_STANDARD, MESSAGES_ENCRYPTED, MESSAGES_NOW_ENCRYPTED, ENCRYPTION_KEY_CHANGED, MISSED_VOICE_CALL, MISSED_VIDEO_CALL, DELETED_MESSAGE, DELETED_BY_ADMIN, DELETED_BY_SENDER, GROUP_CREATED, USER_ADDED_TO_COMMUNITY, USER_ADDED_TO_GROUP, USER_JOINED_GROUP_FROM_COMMUNITY, USER_JOINED_GROUP_FROM_LINK, USER_JOINED_GROUP_FROM_INVITATION, USER_LEFT_GROUP, USER_REMOVED_FROM_GROUP, USER_COMMUNITY_ADMIN, URL_MESSAGE, GROUP_ICON_CHANGED, GROUP_ICON_DELETED, GROUP_DESCRIPTION_CHANGED, GROUP_DESCRIPTION_DELETED, SUBJECT_CHANGED, YOU_ADMIN, YOU_NOT_ADMIN, USER_ADMIN, WAITING_MESSAGE, STICKER_MESSAGE, REFUSED_VIDEO_CALL, REFUSED_VOICE_CALL, UNAVAILABLE_VIDEO_CALL, UNAVAILABLE_VOICE_CALL, UNKNOWN_VOICE_CALL, UNKNOWN_VIDEO_CALL, VIEW_ONCE_AUDIO_MESSAGE, VIEW_ONCE_IMAGE_MESSAGE, VIEW_ONCE_VIDEO_MESSAGE, CALL_MESSAGE, BUSINESS_META_SECURE_SERVICE, GROUP_INVITE, TEMPLATE_MESSAGE, TEMPLATE_QUOTE, POLL_MESSAGE, EPHEMERAL_DURATION_CHANGED, EPHEMERAL_SETTINGS_NOT_APPLIED, EPHEMERAL_CHANGED, EPHEMERAL_DEFAULT, EPHEMERAL_SAVE, GROUP_CHANGED_ONLY_ADMINS_CAN_ADD, GROUP_CHANGED_ONLY_ADMINS_CAN_SEND, GROUP_CHANGED_ALL_MEMBERS_CAN_SEND, GROUP_CHANGED_ONLY_ADMINS_CAN_EDIT, GROUP_CHANGED_ALL_MEMBERS_CAN_EDIT, GROUP_ONLY_ADMINS_CAN_SEND, CHANGED_DEVICE, CHANGED_NUMBER_TO, CHANGED_NUMBER_CHATTING_WITH_NEW, CHANGED_NUMBER_CHATTING_WITH_OLD, STANDARD_CHAT, SENDER_ADDED_TO_CONTACTS, SENDER_IN_CONTACTS, BUSINESS_OFFICIAL, GROUP_ADDED_TO_COMMUNITY, GROUP_REMOVED_FROM_COMMUNITY, COMMUNITY_MANAGEMENT_ACTION, COMMUNITY_WELCOME, UI_ELEMENTS, UI_ELEMENTS_QUOTE, CHAT_ADDED_PRIVACY, CHANNEL_ADDED_PRIVACY, CHANNEL_CREATED, ORDER_MESSAGE, PRODUCT_MESSAGE, BUSINESS_CHANGED_NAME, USER_JOINED_WHATSAPP, PINNED_MESSAGE, GROUP_NAME_CHANGED, AI_THIRD_PARTY, NEW_PARTICIPANTS_NEED_ADMIN_APPROVAL, RESET_GROUP_LINK, COMMUNITY_RENAMED, ANY_COMMUNITY_MEMBER_CAN_JOIN_GROUP, UNKNOWN_MESSAGE, OVER_256_MEMBERS_ONLY_ADMINS_CAN_EDIT, SECURITY_NOTIFICATIONS_NO_LONGER_AVAILABLE } public static enum MessageStatus { From a6c86f5a463772b36e7b562216a804c68ac72d23 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:47:23 -0300 Subject: [PATCH 07/58] add action type 63 and 142 --- .../main/java/iped/parsers/whatsapp/ReportGenerator.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java index cef506198a..73852f2673 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java @@ -648,6 +648,14 @@ private synchronized void printMessage(PrintWriter out, Message message, boolean out.println("
"); out.println(Messages.getString("WhatsAppReport.YouNotAdmin") + "
"); break; + case OVER_256_MEMBERS_ONLY_ADMINS_CAN_EDIT: + out.println("
"); + out.println(Messages.getString("WhatsAppReport.Over256MembersOnlyAdminsCanEdit") + "
"); + break; + case SECURITY_NOTIFICATIONS_NO_LONGER_AVAILABLE: + out.println("
"); + out.println(Messages.getString("WhatsAppReport.SecurityNotificationsNoLongerAvailable") + "
"); + break; case USER_ADMIN: out.println("
"); out.print(name + " "); From 6f69a1b812119e1c9dab7b787b201e7f1806321f Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:48:10 -0300 Subject: [PATCH 08/58] message type 15 and status 13 is deleted message --- .../main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index 36ca0c26e1..e686b66e00 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -882,7 +882,7 @@ protected Message.MessageType decodeMessageType(int messageType, int status, Int } else { if (status == 0) { result = DELETED_BY_SENDER; - } else if (status == 4 || status == 5) { + } else if (status == 4 || status == 5 || status == 13) { result = DELETED_MESSAGE; } } From c58739431f9873598cf1124c731581abffb0eddc Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:36:13 -0300 Subject: [PATCH 09/58] add action type 63 and 142 message string --- .../localization/iped-parsers-messages_de_DE.properties | 2 ++ .../localization/iped-parsers-messages_es_AR.properties | 2 ++ .../localization/iped-parsers-messages_fr_FR.properties | 2 ++ .../localization/iped-parsers-messages_it_IT.properties | 2 ++ .../localization/iped-parsers-messages_pt_BR.properties | 2 ++ 5 files changed, 10 insertions(+) diff --git a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties index 06d93740bf..c8c9471365 100644 --- a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties +++ b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties @@ -325,6 +325,8 @@ WhatsAppReport.EditedOn=Edited on[TBT] WhatsAppReport.UserJoinedWhatsApp=joined WhatsApp[TBT] WhatsAppReport.PinnedMessage=pinned a message[TBT] WhatsAppReport.AIThirdParty=This AI is from a third-party developer. Meta receives your AI chats to improve AI quality.[TBT] +WhatsAppReport.Over256MembersOnlyAdminsCanEdit=This group has over 256 members so now only admins can edit the groups settings.[TBT] +WhatsAppReport.SecurityNotificationsNoLongerAvailable=Security code notifications are no longer available for this chat.[TBT] VCardParser.FormattedName=Name formatiert VCardParser.Name=Name VCardParser.Nickname=Nickname diff --git a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties index 98359140cc..0ae49c6248 100644 --- a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties @@ -325,6 +325,8 @@ WhatsAppReport.EditedOn=Edited on[TBT] WhatsAppReport.UserJoinedWhatsApp=joined WhatsApp[TBT] WhatsAppReport.PinnedMessage=pinned a message[TBT] WhatsAppReport.AIThirdParty=This AI is from a third-party developer. Meta receives your AI chats to improve AI quality.[TBT] +WhatsAppReport.Over256MembersOnlyAdminsCanEdit=This group has over 256 members so now only admins can edit the groups settings.[TBT] +WhatsAppReport.SecurityNotificationsNoLongerAvailable=Security code notifications are no longer available for this chat.[TBT] VCardParser.FormattedName=Nombre con formato VCardParser.Name=Nombre VCardParser.Nickname=Sobrenombre diff --git a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties index a1b81febd7..bd8aa38017 100644 --- a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties @@ -325,6 +325,8 @@ WhatsAppReport.EditedOn=Modifié en WhatsAppReport.UserJoinedWhatsApp=a rejoint WhatsApp WhatsAppReport.PinnedMessage=a epinglé un message WhatsAppReport.AIThirdParty=Cette IA provient d'un développeur tiers. Meta reçoit vos discussions IA pour améliorer la qualité de l'IA. +WhatsAppReport.Over256MembersOnlyAdminsCanEdit=This group has over 256 members so now only admins can edit the groups settings.[TBT] +WhatsAppReport.SecurityNotificationsNoLongerAvailable=Security code notifications are no longer available for this chat.[TBT] VCardParser.FormattedName=Nom formaté VCardParser.Name=Nom VCardParser.Nickname=Surnom diff --git a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties index abfee09355..da3880def0 100644 --- a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties +++ b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties @@ -325,6 +325,8 @@ WhatsAppReport.EditedOn=Edited on[TBT] WhatsAppReport.UserJoinedWhatsApp=joined WhatsApp[TBT] WhatsAppReport.PinnedMessage=pinned a message[TBT] WhatsAppReport.AIThirdParty=This AI is from a third-party developer. Meta receives your AI chats to improve AI quality.[TBT] +WhatsAppReport.Over256MembersOnlyAdminsCanEdit=This group has over 256 members so now only admins can edit the groups settings.[TBT] +WhatsAppReport.SecurityNotificationsNoLongerAvailable=Security code notifications are no longer available for this chat.[TBT] VCardParser.FormattedName=Nome formattato VCardParser.Name=Nome VCardParser.Nickname=Nickname diff --git a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties index 81c372bb6e..916a3385a4 100644 --- a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties @@ -325,6 +325,8 @@ WhatsAppReport.EditedOn=Editada em WhatsAppReport.UserJoinedWhatsApp=entrou no WhatsApp WhatsAppReport.PinnedMessage=fixou uma mensagem WhatsAppReport.AIThirdParty=Esta IA pertence a um desenvolvedor terceirizado. A Meta recebe suas conversas com IA para melhorar a qualidade desse recurso. +WhatsAppReport.Over256MembersOnlyAdminsCanEdit=Agora somente admins podem editar as configurações porque o grupo tem mais de 256 membros. +WhatsAppReport.SecurityNotificationsNoLongerAvailable=As notificações sobre o código de segurança não estão mais disponíveis para esta conversa. VCardParser.FormattedName=Nome Formatado VCardParser.Name=Nome VCardParser.Nickname=Apelido From 89294eee70c3c73e59544df19eb2ea86d3292ba8 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:37:22 -0300 Subject: [PATCH 10/58] action 69 has a subtype message on table message_system_business_state --- .../parsers/whatsapp/ExtractorAndroidNew.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index e686b66e00..bf994af820 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -417,7 +417,7 @@ private void extractMessages(Connection conn, Map idToChat) throws S int actionType = rs.getInt("actionType"); m.setMessageType(decodeMessageType(type, status, edit_version, caption, actionType, - rs.getInt("bizStateId"), m.getMediaMime())); + rs.getInt("bizStateId"), rs.getInt("privacyType"), m.getMediaMime())); if (m.getMessageType() == EPHEMERAL_SETTINGS_NOT_APPLIED) { // Ignore this type of message, as it does nothing and it is not visible in the application itself. @@ -604,7 +604,7 @@ private Map> extractQuoteMessages(Connection conn) throws SQ m.setMediaSize(media_size); m.setLatitude(rs.getDouble("latitude")); //$NON-NLS-1$ m.setLongitude(rs.getDouble("longitude")); //$NON-NLS-1$ - m.setMessageType(decodeMessageType(type, -1, -1, caption, -1, -1, m.getMediaMime())); + m.setMessageType(decodeMessageType(type, -1, -1, caption, -1, -1, -1, m.getMediaMime())); m.setDuration(rs.getInt("media_duration")); //$NON-NLS-1$ if (m.getMessageType() == CONTACT_MESSAGE) { m.setVcards(Arrays.asList(new String[] { Util.getUTF8String(rs, "vcard") })); @@ -634,7 +634,7 @@ private Map> extractQuoteMessages(Connection conn) throws SQ } protected Message.MessageType decodeMessageType(int messageType, int status, Integer edit_version, String caption, - int actionType, int bizStateId, String mediaMime) { + int actionType, int bizStateId, int privacyType, String mediaMime) { Message.MessageType result = UNKNOWN_MESSAGE; switch (messageType) { case 0: @@ -753,7 +753,11 @@ protected Message.MessageType decodeMessageType(int messageType, int status, Int result = EPHEMERAL_DEFAULT; break; case 69: - result = BUSINESS_META_SECURE_SERVICE; + if (privacyType == 1) { + result = MESSAGES_ENCRYPTED; + } else { + result = BUSINESS_META_SECURE_SERVICE; + } break; case 70: result = CALL_MESSAGE; @@ -1022,6 +1026,13 @@ private static String getSelectMessagesQuery(Connection conn) throws SQLExceptio bizStateTableJoin = " left join message_system_initial_privacy_provider msipp on m._id=msipp.message_row_id"; } + String privacyTypeCol = "0"; + String privacyTypeTableJoin = ""; + if (SQLite3DBParser.containsTable("message_system_business_state", conn)) { + privacyTypeCol = "msbs.privacy_message_type"; + privacyTypeTableJoin = " left join message_system_business_state msbs on m._id=msbs.message_row_id"; + } + String grpInvCol = "null"; String grpInvTableJoin = ""; if (SQLite3DBParser.containsTable("message_group_invite", conn)) { @@ -1053,6 +1064,7 @@ private static String getSelectMessagesQuery(Connection conn) throws SQLExceptio + " (m.origination_flags & 1) as forwarded," + " " + mhtCol + " as thumbData2," + " " + bizStateCol + " as bizStateId," + + " " + privacyTypeCol + " as privacyType," + " " + grpInvCol + " as groupInviteName," + " " + sortCol + " as sortId," + " " + uiElemCol + " as uiElem," @@ -1067,6 +1079,7 @@ private static String getSelectMessagesQuery(Connection conn) throws SQLExceptio + " left join message_vcard mv on m._id=mv.message_row_id" + mhtTableJoin + bizStateTableJoin + + privacyTypeTableJoin + grpInvTableJoin + uiElemTableJoin + editTableJoin From 1b8a85a07aa44eb6161472bc8699ef0c9c8e8a96 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Thu, 27 Jun 2024 09:50:24 -0300 Subject: [PATCH 11/58] add new QuoteStatus --- iped-app/resources/localization/iped-parsers-messages.properties | 1 + .../localization/iped-parsers-messages_de_DE.properties | 1 + .../localization/iped-parsers-messages_es_AR.properties | 1 + .../localization/iped-parsers-messages_fr_FR.properties | 1 + .../localization/iped-parsers-messages_it_IT.properties | 1 + .../localization/iped-parsers-messages_pt_BR.properties | 1 + 6 files changed, 6 insertions(+) diff --git a/iped-app/resources/localization/iped-parsers-messages.properties b/iped-app/resources/localization/iped-parsers-messages.properties index fa40a0c346..ef2cf5a9bf 100644 --- a/iped-app/resources/localization/iped-parsers-messages.properties +++ b/iped-app/resources/localization/iped-parsers-messages.properties @@ -276,6 +276,7 @@ WhatsAppReport.FoundInPedoHashDB=Found in Child Porn Alert Hash Database WhatsAppReport.Owner=Owner WhatsAppReport.Recovered=Recovered WhatsAppReport.QuoteNotFound=Quoted message not found +WhatsAppReport.QuoteStaus=Quoted Status WhatsAppReport.Document=Document WhatsAppReport.Photo=Photo WhatsAppReport.Audio=Audio diff --git a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties index c8c9471365..aac31d4135 100644 --- a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties +++ b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties @@ -276,6 +276,7 @@ WhatsAppReport.FoundInPedoHashDB=gefunden in KiPo Hash Database WhatsAppReport.Owner=Besitzer WhatsAppReport.Recovered=Recovered[TBT] WhatsAppReport.QuoteNotFound=Quoted message not found[TBT] +WhatsAppReport.QuoteStaus=Quoted Status[TBT] WhatsAppReport.Document=Document[TBT] WhatsAppReport.Photo=Photo[TBT] WhatsAppReport.Audio=Audio[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties index 0ae49c6248..b7e1ca18aa 100644 --- a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties @@ -276,6 +276,7 @@ WhatsAppReport.FoundInPedoHashDB=Encontrado en la base de datos Hash de Alerta d WhatsAppReport.Owner=Propietario WhatsAppReport.Recovered=Recovered[TBT] WhatsAppReport.QuoteNotFound=Quoted message not found[TBT] +WhatsAppReport.QuoteStaus=Quoted Status[TBT] WhatsAppReport.Document=Document[TBT] WhatsAppReport.Photo=Photo[TBT] WhatsAppReport.Audio=Audio[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties index bd8aa38017..03eb2fda7b 100644 --- a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties @@ -276,6 +276,7 @@ WhatsAppReport.FoundInPedoHashDB=Contenu pédopornographique détecté via la ba WhatsAppReport.Owner=Propriétaire WhatsAppReport.Recovered=Récupéré WhatsAppReport.QuoteNotFound=Message cité est introuvable +WhatsAppReport.QuoteStaus=Quoted Status[TBT] WhatsAppReport.Document=Document WhatsAppReport.Photo=Photo WhatsAppReport.Audio=Audio diff --git a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties index da3880def0..dd6fe2de88 100644 --- a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties +++ b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties @@ -276,6 +276,7 @@ WhatsAppReport.FoundInPedoHashDB=Trovato nel Database di materiale pedopornograf WhatsAppReport.Owner=Proprietario WhatsAppReport.Recovered=Recovered[TBT] WhatsAppReport.QuoteNotFound=Quoted message not found[TBT] +WhatsAppReport.QuoteStaus=Quoted Status[TBT] WhatsAppReport.Document=Document[TBT] WhatsAppReport.Photo=Photo[TBT] WhatsAppReport.Audio=Audio[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties index 916a3385a4..2276854b07 100644 --- a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties @@ -276,6 +276,7 @@ WhatsAppReport.FoundInPedoHashDB=Encontrado em base de hashes de pornografia inf WhatsAppReport.Owner=Proprietário WhatsAppReport.Recovered=Recuperado WhatsAppReport.QuoteNotFound=Mensagem citada não localizada +WhatsAppReport.QuoteStaus=Status citado WhatsAppReport.Document=Documento WhatsAppReport.Photo=Foto WhatsAppReport.Audio=Áudio From b247afaef982ed45c6abea171ccb3b46f3a39068 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Thu, 27 Jun 2024 09:53:43 -0300 Subject: [PATCH 12/58] implement quoted status messages --- .../parsers/whatsapp/ExtractorAndroidNew.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index bf994af820..a9518957c7 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -108,6 +108,7 @@ import iped.parsers.sqlite.SQLite3DBParser; import iped.parsers.whatsapp.Message.MessageStatus; import iped.parsers.whatsapp.Message.MessageType; +import iped.parsers.whatsapp.Message.MessageQuotedType; /** * @@ -545,17 +546,21 @@ private void extractMessages(Connection conn, Map idToChat) throws S Message original = messagesMapUuid.get(mq.getUuid()); if (original != null) { // has found original message reference, more complete + mq.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); m.setMessageQuote(original); } else { // not found original message reference, get info from message_quotes table, // less complete long editId = mq.getEditId(); if (messagesMap.get(editId) == null){ // Quoted message cannot be found again - mq.setDeleted(true); + if (mq.getMessageQuotedType()==MessageQuotedType.QUOTE_NOT_FOUND){ + mq.setDeleted(true); + } mq.setId(fakeIds--); m.setMessageQuote(mq); }else{ // If quoted message was edited, jump to the correct message mq.setDeleted(false); + mq.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); mq.setId(editId); m.setMessageQuote(mq); } @@ -622,6 +627,15 @@ private Map> extractQuoteMessages(Connection conn) throws SQ m.setEditId(rs.getLong("edit_row_id")); long chatId = rs.getLong("chatId"); + + String remoteId = rs.getString("remoteId"); + if (remoteId !=null && remoteId.compareTo(Message.STATUS_BROADCAST)==0){ + chatId = rs.getLong("parent_message_chat_row_id"); + m.setMessageQuotedType(MessageQuotedType.QUOTE_STATUS); + }else{ + m.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); // just set for now + } + List messages = messagesPerChatId.get(chatId); if (messages == null) { messagesPerChatId.put(chatId, messages = new ArrayList()); @@ -1097,7 +1111,7 @@ private static String getSelectMessagesQuotesQuery(Connection conn) throws SQLEx editTableJoin = " left join message_edit_info mei on mei.original_key_id=mq.key_id"; } return "select mq.message_row_id as id,mq.chat_row_id as chatId, chatJid.raw_string as remoteId," - + " jid.raw_string as remoteResource, mv.vcard, mq.text_data," + + " jid.raw_string as remoteResource, mv.vcard, mq.text_data, mq.parent_message_chat_row_id," + " mq.from_me as fromMe, mq.timestamp as timestamp, message_url as mediaUrl," + " mm.mime_type as mediaMime, mm.file_length as mediaSize, media_name as mediaName," + " mq.message_type as messageType, latitude, longitude, mm.media_duration, " + captionCol From dfd1753fcbe29681f2003f4751a985092e46fd8e Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Thu, 27 Jun 2024 09:57:06 -0300 Subject: [PATCH 13/58] implement quoted status messages logic --- .../java/iped/parsers/whatsapp/ExtractorIOS.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java index 950e2c9ae6..ed9ff82051 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java @@ -95,6 +95,7 @@ import iped.parsers.sqlite.SQLiteUndeleteTable; import iped.parsers.whatsapp.Message.MessageStatus; import iped.parsers.whatsapp.Message.MessageType; +import iped.parsers.whatsapp.Message.MessageQuotedType; import iped.parsers.whatsapp.ProtoBufDecoder.Part; /** @@ -574,8 +575,19 @@ private void findQuotedMessages(List messages, Map mes } messageQuote.setMessageType(type); - messageQuote.setDeleted(true); + + String status = ProtoBufDecoder.findString(main, 7); + if (status!=null && status.compareTo(Message.STATUS_BROADCAST)==0){ + messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_STATUS); + }else{ + messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); + messageQuote.setDeleted(true); + } + }else{ + messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); } + + if (messageQuote.getThumbData() == null && childs != null) { byte[] thumbData = null; for (Part c : childs) { From a6bb06ba68ceb0188316ec449f7f14adfb4681db Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Thu, 27 Jun 2024 09:58:07 -0300 Subject: [PATCH 14/58] add messagequotetype for quoted messages --- .../main/java/iped/parsers/whatsapp/Message.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java index 7b0f706341..ee38dcb5c5 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java @@ -30,6 +30,7 @@ public class Message implements Comparable { private static FileChannel fileChannel; private static AtomicLong fileOffset = new AtomicLong(); private static AtomicInteger deletedCounter = new AtomicInteger(); + public static String STATUS_BROADCAST = "status@broadcast"; private long id; private int deletedId = -1; @@ -69,6 +70,7 @@ public class Message implements Comparable { private long idQuote; private Message messageQuote = null; private boolean quoted = false; + private MessageQuotedType messageQuotedType; private String uuid = null; private long editId = -1; private byte[] metaData; @@ -557,6 +559,14 @@ public void setQuoted(boolean quoted) { this.quoted = quoted; } + public MessageQuotedType getMessageQuotedType() { + return messageQuotedType; + } + + public void setMessageQuotedType(MessageQuotedType messageQuotedType) { + this.messageQuotedType = messageQuotedType; + } + public Message getMessageQuote(){ return this.messageQuote; } @@ -653,6 +663,10 @@ public static enum MessageStatus { MESSAGE_UNSENT, MESSAGE_SENT, MESSAGE_DELIVERED, MESSAGE_VIEWED } + public static enum MessageQuotedType { + QUOTE_FOUND, QUOTE_NOT_FOUND, QUOTE_STATUS + } + @Override public int compareTo(Message o) { if (getSortId() != 0 && o.getSortId() != 0) { From f06af9a8e51b0c8d3710498d21decf090e623364 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Thu, 27 Jun 2024 09:59:30 -0300 Subject: [PATCH 15/58] add statusIcon for quoted status messages, fix vertical-align on deleteIcon --- .../resources/iped/parsers/whatsapp/css/whatsapp.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/css/whatsapp.css b/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/css/whatsapp.css index 56473e6f7b..765f05640a 100644 --- a/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/css/whatsapp.css +++ b/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/css/whatsapp.css @@ -101,10 +101,20 @@ div.deletedIcon { display: inline-block; width: 16px; height: 16px; + vertical-align: bottom; background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACGElEQVR42pWTz2saQRTH39j9oWs09LQW2720ppRe9lQotJce+i/0EPIHBBIqBEJNDh6ChyaX4EEPPSpCTjn03oMBKY1kEdIt2I0FW4kYNdYUZd1dp2+XZnGrsfTBlxmGeZ958+Y7BP5Ep9NJE0Keww0xHo8hHo+/y+fzmcl1MgFQcJBhTiSTSdrtdtcKhUJmCtButxXLsmTDMGYm+/1+yOVy0Gw2KcMwa6lUKuMBtFotxTRNWdf1mYBgMOjOKaWaKIoxDwDJ/7zCRGiRSMQLaDQaCp4uD4fDuZmBQAB4ntei0agXUK/X/6sCSZK8gFqt5lQwGAxmZlDTBMIwIAgC8Bynvd/aevz64GDkAqrVqoI+kFFTyY10GgbHx3B/bw+IKIJ+enr1LZEgY4576+5WVdV5BZT3ZDTQ55UVuHVxAbclCe6srsKP3V3oX16CTsgHF1CpVBR8Htl23N8xOj+Hs40N2yzgwwrHlMKI0vJXw3jpAsrl8twmXh0dgbazAz67KkJoSBSfvVLVkgsolUqOE6+vYPeC4zhnrmsaqNvbYPb7zjpWCuzCQpMRxRcuoFgsOk2c6r5lwcflZRj1erC4tAQP1tfhC1YyaLWAE4QKyWazIYy74XD4DcuyTzGHRzEo3zXk++Eh+/PkhH+4udllQyH9F5rmbH//kT8WSxD8nvdwzxNUBLWICs6A2J2172Z/FNsoPVQT9ek3OcbuBA+nPxcAAAAASUVORK5CYII="); margin: 0; } +div.statusIcon { + display: inline-block; + width: 16px; + height: 16px; + vertical-align: bottom; + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAWFJREFUOE/Vkr9LAnEUwD/nnZ13aHUcYVqtTkXQcIEE3SFnHdKPoakIWwrEKepoaHANkhbXoIiGHFqFpjaHJhed+gOCmsoWpzhRKDU0nPqOj+/7vPc+7wkM+YQh8/kLYALYAsLAM3DrFe8HmAF2BEFYMwwjnkql0HWdbDb7AKx2AjItenMqSZJmDcPYdBxHdByHSCTSjNdqNWzb7gLspeXRq42RUPOTqo0zXSqiaVqXomq1SjKZrAEG8NkeIV8MRY+W/WozoSH6ECuPPf16HeRyOcrlsgvk24Dzu1D02BwQ4LoulUplH7hsA3bjknIT9yvMiSOMyQFez06xLAtFUX500nLwBCx2SvQCmZOAlp6XZLbrL++qqn5YljXl2U8kEgSDwV8ltqscLknKRdgnct+ol4B1wAZWZFk+ME1TjcViFAqFnmv0ID4gDejANfD2rf9JYKFlf+BD6nvp/S7xHwC+ALvtVBEa/F+QAAAAAElFTkSuQmCC"); + margin: 0; +} + /******************** * WhatsApp Top Bar * ********************/ From d0346122f7da99c1e7bdd3c304dacc1b81a2e0e0 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:01:23 -0300 Subject: [PATCH 16/58] change flag to quoted type. Use messagequotetype instead of isDeleted --- .../main/java/iped/parsers/whatsapp/ReportGenerator.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java index 73852f2673..28bf89b892 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java @@ -22,6 +22,7 @@ import iped.parsers.util.Messages; import iped.parsers.vcard.VCardParser; import iped.parsers.whatsapp.Message.MessageType; +import iped.parsers.whatsapp.Message.MessageQuotedType; import iped.properties.ExtraProperties; import iped.utils.EmojiUtil; import iped.utils.LocalizedFormat; @@ -1251,9 +1252,12 @@ private void printQuote(PrintWriter out, Message message, WAContactsDirectory co } String quoteEnd = "
"; - if (messageQuote.isDeleted()) { + if (messageQuote.getMessageQuotedType()==MessageQuotedType.QUOTE_NOT_FOUND) { quoteEnd = "
" + Messages.getString("WhatsAppReport.QuoteNotFound") + "" + quoteEnd; + }else if (messageQuote.getMessageQuotedType()==MessageQuotedType.QUOTE_STATUS) { + quoteEnd = "

" + + Messages.getString("WhatsAppReport.QuoteStaus") + "" + quoteEnd; } switch (messageQuote.getMessageType()) { From eacf7156e101b51a51d2f09dedfde494ea4d4079 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:51:44 -0300 Subject: [PATCH 17/58] add new messages for Quoted Status and Quoted Privately --- .../resources/localization/iped-parsers-messages.properties | 3 +++ .../localization/iped-parsers-messages_de_DE.properties | 3 +++ .../localization/iped-parsers-messages_es_AR.properties | 3 +++ .../localization/iped-parsers-messages_fr_FR.properties | 3 +++ .../localization/iped-parsers-messages_it_IT.properties | 3 +++ .../localization/iped-parsers-messages_pt_BR.properties | 3 +++ 6 files changed, 18 insertions(+) diff --git a/iped-app/resources/localization/iped-parsers-messages.properties b/iped-app/resources/localization/iped-parsers-messages.properties index ef2cf5a9bf..83ddfcaa21 100644 --- a/iped-app/resources/localization/iped-parsers-messages.properties +++ b/iped-app/resources/localization/iped-parsers-messages.properties @@ -277,6 +277,9 @@ WhatsAppReport.Owner=Owner WhatsAppReport.Recovered=Recovered WhatsAppReport.QuoteNotFound=Quoted message not found WhatsAppReport.QuoteStaus=Quoted Status +WhatsAppReport.QuotePrivacy=Message quoted privately through the group +WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group +WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found WhatsAppReport.Document=Document WhatsAppReport.Photo=Photo WhatsAppReport.Audio=Audio diff --git a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties index aac31d4135..b726291932 100644 --- a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties +++ b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties @@ -277,6 +277,9 @@ WhatsAppReport.Owner=Besitzer WhatsAppReport.Recovered=Recovered[TBT] WhatsAppReport.QuoteNotFound=Quoted message not found[TBT] WhatsAppReport.QuoteStaus=Quoted Status[TBT] +WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] +WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] +WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] WhatsAppReport.Document=Document[TBT] WhatsAppReport.Photo=Photo[TBT] WhatsAppReport.Audio=Audio[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties index b7e1ca18aa..078b5e5d38 100644 --- a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties @@ -277,6 +277,9 @@ WhatsAppReport.Owner=Propietario WhatsAppReport.Recovered=Recovered[TBT] WhatsAppReport.QuoteNotFound=Quoted message not found[TBT] WhatsAppReport.QuoteStaus=Quoted Status[TBT] +WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] +WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] +WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] WhatsAppReport.Document=Document[TBT] WhatsAppReport.Photo=Photo[TBT] WhatsAppReport.Audio=Audio[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties index 03eb2fda7b..450ed6ac37 100644 --- a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties @@ -277,6 +277,9 @@ WhatsAppReport.Owner=Propriétaire WhatsAppReport.Recovered=Récupéré WhatsAppReport.QuoteNotFound=Message cité est introuvable WhatsAppReport.QuoteStaus=Quoted Status[TBT] +WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] +WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] +WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] WhatsAppReport.Document=Document WhatsAppReport.Photo=Photo WhatsAppReport.Audio=Audio diff --git a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties index dd6fe2de88..dc41e2504d 100644 --- a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties +++ b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties @@ -277,6 +277,9 @@ WhatsAppReport.Owner=Proprietario WhatsAppReport.Recovered=Recovered[TBT] WhatsAppReport.QuoteNotFound=Quoted message not found[TBT] WhatsAppReport.QuoteStaus=Quoted Status[TBT] +WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] +WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] +WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] WhatsAppReport.Document=Document[TBT] WhatsAppReport.Photo=Photo[TBT] WhatsAppReport.Audio=Audio[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties index 2276854b07..3be7d76139 100644 --- a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties @@ -277,6 +277,9 @@ WhatsAppReport.Owner=Proprietário WhatsAppReport.Recovered=Recuperado WhatsAppReport.QuoteNotFound=Mensagem citada não localizada WhatsAppReport.QuoteStaus=Status citado +WhatsAppReport.QuotePrivacy=Mensagem citada em particular através de grupo +WhatsAppReport.QuotePrivacyMessage=Esta mensagem citada está localizada no grupo +WhatsAppReport.QuotePrivacyNotFound=Mensagem citada em particular através de grupo não encontrada WhatsAppReport.Document=Documento WhatsAppReport.Photo=Foto WhatsAppReport.Audio=Áudio From 60d2d0b3bf5ab6ceaf13ef15a69e2cb89f855275 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:52:37 -0300 Subject: [PATCH 18/58] implement quoted status and quoted privately --- .../parsers/whatsapp/ExtractorAndroidNew.java | 72 +++++++++++-------- .../iped/parsers/whatsapp/ExtractorIOS.java | 51 +++++++++++-- 2 files changed, 91 insertions(+), 32 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index a9518957c7..dafee5af46 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -539,31 +539,51 @@ private void extractMessages(Connection conn, Map idToChat) throws S // Find quote messages for (Message mq : messagesQuotes) { Message m = messagesMap.get(mq.getId()); - if (m != null) { - // Has quote - + if (m != null) {// Has quote // Try to find original message in messages Message original = messagesMapUuid.get(mq.getUuid()); - if (original != null) { - // has found original message reference, more complete - mq.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); + if (original != null) {//has found original message reference m.setMessageQuote(original); - } else { - // not found original message reference, get info from message_quotes table, - // less complete - long editId = mq.getEditId(); - if (messagesMap.get(editId) == null){ // Quoted message cannot be found again - if (mq.getMessageQuotedType()==MessageQuotedType.QUOTE_NOT_FOUND){ + } else {// not found original message reference + mq.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); + if (chatId == mq.getQuoteChatId()){// msgs In same chat + long editId = mq.getEditId(); + if (messagesMap.get(editId) != null){ // Quoted was edited + mq.setDeleted(false); + mq.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); + mq.setId(editId); + }else{ // Quoted message cannot be found again + mq.setId(fakeIds--); + mq.setDeleted(true); + } + }else { //Exception, msgs not in the same chat + String remoteId = mq.getRemoteId(); + if (remoteId !=null){ + if (remoteId.compareTo(Message.STATUS_BROADCAST)==0){ + mq.setMessageQuotedType(MessageQuotedType.QUOTE_STATUS); + mq.setId(fakeIds--); + }else if (remoteId.contains(Message.GROUP)){ + mq.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP); + + //Find friendly group name + for (Chat cq : idToChat.values()) { + if(remoteId.contains(cq.getPrintId())){ + mq.setRemoteId(cq.getTitle()); + break; + } + } + + }else{ + mq.setId(fakeIds--); + mq.setDeleted(true); + } + }else{ + mq.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP_NOT_FOUND); + mq.setId(fakeIds--); mq.setDeleted(true); } - mq.setId(fakeIds--); - m.setMessageQuote(mq); - }else{ // If quoted message was edited, jump to the correct message - mq.setDeleted(false); - mq.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); - mq.setId(editId); - m.setMessageQuote(mq); - } + } + m.setMessageQuote(mq); } m.setQuoted(true); @@ -626,15 +646,11 @@ private Map> extractQuoteMessages(Connection conn) throws SQ m.setEditId(rs.getLong("edit_row_id")); - long chatId = rs.getLong("chatId"); + m.setQuoteChatId(rs.getLong("chatId")); - String remoteId = rs.getString("remoteId"); - if (remoteId !=null && remoteId.compareTo(Message.STATUS_BROADCAST)==0){ - chatId = rs.getLong("parent_message_chat_row_id"); - m.setMessageQuotedType(MessageQuotedType.QUOTE_STATUS); - }else{ - m.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); // just set for now - } + m.setRemoteId(rs.getString("remoteId")); + + long chatId = rs.getLong("parent_message_chat_row_id"); List messages = messagesPerChatId.get(chatId); if (messages == null) { diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java index ed9ff82051..cabde61b96 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java @@ -266,7 +266,7 @@ protected List extractChatList() throws WAExtractorException { } // Find quoted messages - findQuotedMessages(c.getMessages(), messagesMap); + findQuotedMessages(c.getMessages(), messagesMap, idToChat); } if (recoverDeletedRecords && !firstTry) { @@ -387,7 +387,7 @@ private void mergeUndeletedMessages(Chat chat, Map messagesMap, } } - private void findQuotedMessages(List messages, Map messagesMap) { + private void findQuotedMessages(List messages, Map messagesMap, Map idToChat) { long fakeIds = 2000000000L; for (Message m : messages) { byte[] metadata = m.getMetaData(); @@ -577,8 +577,51 @@ private void findQuotedMessages(List messages, Map mes messageQuote.setMessageType(type); String status = ProtoBufDecoder.findString(main, 7); - if (status!=null && status.compareTo(Message.STATUS_BROADCAST)==0){ - messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_STATUS); + if (status!=null){ // find quotes outside this chat + + if (status.compareTo(Message.STATUS_BROADCAST)==0){ + + messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_STATUS); + + }else if (status.contains(Message.GROUP)){ + + messageQuote.setRemoteId(status); + boolean found = false; + String title = ""; + for (Chat cq : idToChat.values()) { + + if(status.contains(cq.getPrintId())) + title = cq.getTitle(); + + for (Message mq : cq.getMessages()) { + if (mq.getUuid() != null && mq.getUuid().compareTo(uuidQuote)==0) { + messageQuote.setId(mq.getId()); + found = true; + break; + } + } + + if (found){ + break; + } + } + + if (!title.isEmpty()) + messageQuote.setRemoteId(title); + + + if (found){ + messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP); + }else{ + messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP_NOT_FOUND); + messageQuote.setDeleted(true); + } + + }else{ + messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); + messageQuote.setDeleted(true); + } + }else{ messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); messageQuote.setDeleted(true); From 152bc3de91b1a1bd0c8be27eb78a0c6b9ed9dcc4 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:53:07 -0300 Subject: [PATCH 19/58] add quoted types quoted status and quoted privately, add quotechatid property --- .../main/java/iped/parsers/whatsapp/Message.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java index ee38dcb5c5..f54605756d 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java @@ -31,6 +31,8 @@ public class Message implements Comparable { private static AtomicLong fileOffset = new AtomicLong(); private static AtomicInteger deletedCounter = new AtomicInteger(); public static String STATUS_BROADCAST = "status@broadcast"; + public static String GROUP = "@g.us"; + private long id; private int deletedId = -1; @@ -70,9 +72,10 @@ public class Message implements Comparable { private long idQuote; private Message messageQuote = null; private boolean quoted = false; - private MessageQuotedType messageQuotedType; + private MessageQuotedType messageQuotedType = MessageQuotedType.QUOTE_FOUND; private String uuid = null; private long editId = -1; + private long quoteChatId = -1; private byte[] metaData; private String groupInviteName; private MessageTemplate messageTemplate; @@ -591,6 +594,14 @@ public void setEditId(long editId) { this.editId = editId; } + public long getQuoteChatId() { + return this.quoteChatId; + } + + public void setQuoteChatId(long quoteChatId) { + this.quoteChatId = quoteChatId; + } + public byte[] getMetaData() { return metaData; } @@ -664,7 +675,7 @@ public static enum MessageStatus { } public static enum MessageQuotedType { - QUOTE_FOUND, QUOTE_NOT_FOUND, QUOTE_STATUS + QUOTE_NOT_FOUND, QUOTE_FOUND, QUOTE_STATUS, QUOTE_PRIVACY_GROUP, QUOTE_PRIVACY_GROUP_NOT_FOUND } @Override From 44b90da5388c569d7a9d2539ba084b8064ee1df3 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:53:17 -0300 Subject: [PATCH 20/58] add showmessage function --- .../src/main/resources/iped/parsers/whatsapp/js/whatsapp.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/js/whatsapp.js b/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/js/whatsapp.js index 5a58551291..5f3e192a3c 100644 --- a/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/js/whatsapp.js +++ b/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/js/whatsapp.js @@ -68,6 +68,12 @@ function createMediaControls() { }); } +function showMessage(message){ + var fragMessageClose = document.getElementById('fragMessageClose').value; + show_prompt("",message,false,fragMessageClose); + return false; +} + function goToAnchorId(id){ var scroll_padding_top = document.getElementById('topbar').getBoundingClientRect().height; var r = document.querySelector(':root'); From 09b7595f2773fb6a9d3be674764b0143b2987678 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:53:53 -0300 Subject: [PATCH 21/58] add privacy icons for quoted private messages, add class for blue font --- .../iped/parsers/whatsapp/css/whatsapp.css | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/css/whatsapp.css b/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/css/whatsapp.css index 765f05640a..ee88a94395 100644 --- a/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/css/whatsapp.css +++ b/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/css/whatsapp.css @@ -115,6 +115,24 @@ div.statusIcon { margin: 0; } +div.privacyIcon { + display: inline-block; + width: 16px; + height: 16px; + vertical-align: bottom; + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAZhJREFUOE/Vk0FIWnEcxz/vpZk2dvQsHny0Q6DzIDvMIBFfGVgM2s2dxKOdAj2JN5nu7HlM6iRG+UhCNJCxUgMhGDIhzx5t1WONtxW8ZfaQrvsf///f58P3/4WfwNPjEkVxJxAIuB0Ox/1rv9+nVqt1NE3bBH6MI8IE77NarceFQsFss9lotVqIoojH42E0GhGPx29UVfUDJzo3Kejncjlnu92mWCz+cwuCQDQaxeVykUwmvwMLRoJXkiSd5/N5wuEwmqY9CneXRFEUYrEYg8FAAnp3A+MJVoPB4L7f7yeVShlUA9lslkqlQr1eDwGHk4KILMslr9dLJpMxFKTTaZrNJtVqNQKUxwUm4LMsy++fKfgCfABu9S+8dTtp7H5c4uULC8Ph0DCB3W5ndHnNxlaD7gVvgK+6ILTyGqX8yYdp1mwI65e36g3hxCmHZ9z38Eiwl/cwY5mfKvit/mRtq4PS+a8Fq4nOkw6WfRJHpewi5jnb1A6ur654t93lW48loKGXOAuU/i7JylT64fEAWAd+TS7TM/mHsT8WHKIRDu7JDgAAAABJRU5ErkJggg=="); + margin: 0; +} + +div.privacyDeleteIcon { + display: inline-block; + width: 16px; + height: 16px; + vertical-align: bottom; + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAHYYAAB2GAV2iE4EAAAGuSURBVDhPjZO/S0JRFMe/76mvtBCyMIRAjUhoyykaqsEhGqMIbHF07Z9wyj/AvaEgaBJyEWoJQkJbWhQagiAxKg2fmd7Oud5nPhXqA+fd8z3v3u/99Z6GUZZ1XT+NxWKroVBIFiqVCvL5/J0Q4oBkWRYVwwZrbrf7OpPJuDweDwqFAsgM0WgU9XodyWTSbLVam9Tvttd9lEo6nRbxeFxQ3g9N00QikRCpVIr1A8VYViKRiMhms3IAaVvQSkQulxPBYJD1MoVEVy0TppcoFougvarSL91uF6VSCeFwmKV8MIMGLofDAdM0lRyl2WzCMAxOJ2WBsAycFHzC/2Wfgsf0b2FjdRFXZ8db8E5PoFqtqrIdv9+PeqOJ3aMr3D9inUo30oXwBGZoY3MmnEYH894pVQZe955l6zsP0PMTPsME9yUDb21hSQyeATTxpbJRLCMNHei0bhp8ydpmMI7ezD0sk5OXJdkyfxowgybvhx8qA2afytq/DJhBE4YGb3NrGbRfG0D17Ru19/bYsJZvYZ2BdY38dVxQ7Eg1BHVWmZzZpsf9zjb4qlQq96xSVQd+AHevnpnE6uxJAAAAAElFTkSuQmCC"); + margin: 0; +} + /******************** * WhatsApp Top Bar * ********************/ @@ -496,6 +514,13 @@ div:target { font-size: small; } +#conversation .outside { + color: #0000ff; + float: left; + padding-right: 10px; + font-size: small; +} + #conversation .incoming { color: #000000; background-color: #fcfbf6; From e13c79fd4ad86de9182775e6100e6162f9e4725c Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:55:00 -0300 Subject: [PATCH 22/58] render the new types of quoted messages, status, privacy and privacy note found --- .../parsers/whatsapp/ReportGenerator.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java index 28bf89b892..595afbedae 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java @@ -1252,12 +1252,29 @@ private void printQuote(PrintWriter out, Message message, WAContactsDirectory co } String quoteEnd = "
"; - if (messageQuote.getMessageQuotedType()==MessageQuotedType.QUOTE_NOT_FOUND) { - quoteEnd = "
" + switch(messageQuote.getMessageQuotedType()){ + case QUOTE_NOT_FOUND: + quoteEnd = "

" + Messages.getString("WhatsAppReport.QuoteNotFound") + "" + quoteEnd; - }else if (messageQuote.getMessageQuotedType()==MessageQuotedType.QUOTE_STATUS) { - quoteEnd = "

" + break; + case QUOTE_STATUS: + quoteEnd = "

" + Messages.getString("WhatsAppReport.QuoteStaus") + "" + quoteEnd; + break; + case QUOTE_PRIVACY_GROUP: + quoteEnd = "

" + + Messages.getString("WhatsAppReport.QuotePrivacy") + "" + quoteEnd; + String messageQuoteRemoteId = messageQuote.getRemoteId(); + if (messageQuoteRemoteId != null){ + String ms = Messages.getString("WhatsAppReport.QuotePrivacyMessage") + ": "+ messageQuoteRemoteId +"
" + + Messages.getString("WhatsAppReport.ReferenceId") + " " +messageQuote.getId(); + quoteClick = "onclick=\"showMessage('" + ms + "');\""; + } + break; + case QUOTE_PRIVACY_GROUP_NOT_FOUND: + quoteEnd = "

" + + Messages.getString("WhatsAppReport.QuotePrivacyNotFound") + "" + quoteEnd; + break; } switch (messageQuote.getMessageType()) { From c923947f5acd9d848ba846f49cb3f7dec12c3883 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Tue, 2 Jul 2024 17:39:36 -0300 Subject: [PATCH 23/58] set default quoted type to quote_not_found, add quote_catalog type --- .../src/main/java/iped/parsers/whatsapp/Message.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java index f54605756d..4a94d81b2a 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java @@ -72,7 +72,7 @@ public class Message implements Comparable { private long idQuote; private Message messageQuote = null; private boolean quoted = false; - private MessageQuotedType messageQuotedType = MessageQuotedType.QUOTE_FOUND; + private MessageQuotedType messageQuotedType = MessageQuotedType.QUOTE_NOT_FOUND; private String uuid = null; private long editId = -1; private long quoteChatId = -1; @@ -667,7 +667,7 @@ public void setAddress(String address) { } public static enum MessageType { - TEXT_MESSAGE, IMAGE_MESSAGE, AUDIO_MESSAGE, VIDEO_MESSAGE, UNKNOWN_MEDIA_MESSAGE, CONTACT_MESSAGE, LOCATION_MESSAGE, SHARE_LOCATION_MESSAGE, VOICE_CALL, VIDEO_CALL, DOC_MESSAGE, GIF_MESSAGE, BLOCKED_CONTACT, UNBLOCKED_CONTACT, BUSINESS_CHAT, BUSINESS_TO_STANDARD, MESSAGES_ENCRYPTED, MESSAGES_NOW_ENCRYPTED, ENCRYPTION_KEY_CHANGED, MISSED_VOICE_CALL, MISSED_VIDEO_CALL, DELETED_MESSAGE, DELETED_BY_ADMIN, DELETED_BY_SENDER, GROUP_CREATED, USER_ADDED_TO_COMMUNITY, USER_ADDED_TO_GROUP, USER_JOINED_GROUP_FROM_COMMUNITY, USER_JOINED_GROUP_FROM_LINK, USER_JOINED_GROUP_FROM_INVITATION, USER_LEFT_GROUP, USER_REMOVED_FROM_GROUP, USER_COMMUNITY_ADMIN, URL_MESSAGE, GROUP_ICON_CHANGED, GROUP_ICON_DELETED, GROUP_DESCRIPTION_CHANGED, GROUP_DESCRIPTION_DELETED, SUBJECT_CHANGED, YOU_ADMIN, YOU_NOT_ADMIN, USER_ADMIN, WAITING_MESSAGE, STICKER_MESSAGE, REFUSED_VIDEO_CALL, REFUSED_VOICE_CALL, UNAVAILABLE_VIDEO_CALL, UNAVAILABLE_VOICE_CALL, UNKNOWN_VOICE_CALL, UNKNOWN_VIDEO_CALL, VIEW_ONCE_AUDIO_MESSAGE, VIEW_ONCE_IMAGE_MESSAGE, VIEW_ONCE_VIDEO_MESSAGE, CALL_MESSAGE, BUSINESS_META_SECURE_SERVICE, GROUP_INVITE, TEMPLATE_MESSAGE, TEMPLATE_QUOTE, POLL_MESSAGE, EPHEMERAL_DURATION_CHANGED, EPHEMERAL_SETTINGS_NOT_APPLIED, EPHEMERAL_CHANGED, EPHEMERAL_DEFAULT, EPHEMERAL_SAVE, GROUP_CHANGED_ONLY_ADMINS_CAN_ADD, GROUP_CHANGED_ONLY_ADMINS_CAN_SEND, GROUP_CHANGED_ALL_MEMBERS_CAN_SEND, GROUP_CHANGED_ONLY_ADMINS_CAN_EDIT, GROUP_CHANGED_ALL_MEMBERS_CAN_EDIT, GROUP_ONLY_ADMINS_CAN_SEND, CHANGED_DEVICE, CHANGED_NUMBER_TO, CHANGED_NUMBER_CHATTING_WITH_NEW, CHANGED_NUMBER_CHATTING_WITH_OLD, STANDARD_CHAT, SENDER_ADDED_TO_CONTACTS, SENDER_IN_CONTACTS, BUSINESS_OFFICIAL, GROUP_ADDED_TO_COMMUNITY, GROUP_REMOVED_FROM_COMMUNITY, COMMUNITY_MANAGEMENT_ACTION, COMMUNITY_WELCOME, UI_ELEMENTS, UI_ELEMENTS_QUOTE, CHAT_ADDED_PRIVACY, CHANNEL_ADDED_PRIVACY, CHANNEL_CREATED, ORDER_MESSAGE, PRODUCT_MESSAGE, BUSINESS_CHANGED_NAME, USER_JOINED_WHATSAPP, PINNED_MESSAGE, GROUP_NAME_CHANGED, AI_THIRD_PARTY, NEW_PARTICIPANTS_NEED_ADMIN_APPROVAL, RESET_GROUP_LINK, COMMUNITY_RENAMED, ANY_COMMUNITY_MEMBER_CAN_JOIN_GROUP, UNKNOWN_MESSAGE, OVER_256_MEMBERS_ONLY_ADMINS_CAN_EDIT, SECURITY_NOTIFICATIONS_NO_LONGER_AVAILABLE + TEXT_MESSAGE, IMAGE_MESSAGE, AUDIO_MESSAGE, VIDEO_MESSAGE, UNKNOWN_MEDIA_MESSAGE, CONTACT_MESSAGE, LOCATION_MESSAGE, SHARE_LOCATION_MESSAGE, VOICE_CALL, VIDEO_CALL, DOC_MESSAGE, GIF_MESSAGE, BLOCKED_CONTACT, UNBLOCKED_CONTACT, BUSINESS_CHAT, BUSINESS_TO_STANDARD, MESSAGES_ENCRYPTED, MESSAGES_NOW_ENCRYPTED, ENCRYPTION_KEY_CHANGED, MISSED_VOICE_CALL, MISSED_VIDEO_CALL, DELETED_MESSAGE, DELETED_BY_ADMIN, DELETED_BY_SENDER, GROUP_CREATED, USER_ADDED_TO_COMMUNITY, USER_ADDED_TO_GROUP, USER_JOINED_GROUP_FROM_COMMUNITY, USER_JOINED_GROUP_FROM_LINK, USER_JOINED_GROUP_FROM_INVITATION, USER_LEFT_GROUP, USER_REMOVED_FROM_GROUP, USER_COMMUNITY_ADMIN, URL_MESSAGE, GROUP_ICON_CHANGED, GROUP_ICON_DELETED, GROUP_DESCRIPTION_CHANGED, GROUP_DESCRIPTION_DELETED, SUBJECT_CHANGED, YOU_ADMIN, YOU_NOT_ADMIN, USER_ADMIN, WAITING_MESSAGE, STICKER_MESSAGE, REFUSED_VIDEO_CALL, REFUSED_VOICE_CALL, UNAVAILABLE_VIDEO_CALL, UNAVAILABLE_VOICE_CALL, UNKNOWN_VOICE_CALL, UNKNOWN_VIDEO_CALL, VIEW_ONCE_AUDIO_MESSAGE, VIEW_ONCE_IMAGE_MESSAGE, VIEW_ONCE_VIDEO_MESSAGE, CALL_MESSAGE, BUSINESS_META_SECURE_SERVICE, GROUP_INVITE, TEMPLATE_MESSAGE, TEMPLATE_QUOTE, POLL_MESSAGE, EPHEMERAL_DURATION_CHANGED, EPHEMERAL_SETTINGS_NOT_APPLIED, EPHEMERAL_CHANGED, EPHEMERAL_DEFAULT, EPHEMERAL_SAVE, GROUP_CHANGED_ONLY_ADMINS_CAN_ADD, GROUP_CHANGED_ONLY_ADMINS_CAN_SEND, GROUP_CHANGED_ALL_MEMBERS_CAN_SEND, GROUP_CHANGED_ONLY_ADMINS_CAN_EDIT, GROUP_CHANGED_ALL_MEMBERS_CAN_EDIT, GROUP_ONLY_ADMINS_CAN_SEND, CHANGED_DEVICE, CHANGED_NUMBER_TO, CHANGED_NUMBER_CHATTING_WITH_NEW, CHANGED_NUMBER_CHATTING_WITH_OLD, STANDARD_CHAT, SENDER_ADDED_TO_CONTACTS, SENDER_IN_CONTACTS, BUSINESS_OFFICIAL, GROUP_ADDED_TO_COMMUNITY, GROUP_REMOVED_FROM_COMMUNITY, COMMUNITY_MANAGEMENT_ACTION, COMMUNITY_WELCOME, UI_ELEMENTS, UI_ELEMENTS_QUOTE, CHAT_ADDED_PRIVACY, CHANNEL_ADDED_PRIVACY, CHANNEL_CREATED, ORDER_MESSAGE, PRODUCT_MESSAGE, BUSINESS_CHANGED_NAME, USER_JOINED_WHATSAPP, PINNED_MESSAGE, GROUP_NAME_CHANGED, AI_THIRD_PARTY, NEW_PARTICIPANTS_NEED_ADMIN_APPROVAL, RESET_GROUP_LINK, COMMUNITY_RENAMED, ANY_COMMUNITY_MEMBER_CAN_JOIN_GROUP, UNKNOWN_MESSAGE, OVER_256_MEMBERS_ONLY_ADMINS_CAN_EDIT, SECURITY_NOTIFICATIONS_NO_LONGER_AVAILABLE, CONTACTED_FIND_BUSINESSES } public static enum MessageStatus { @@ -675,7 +675,7 @@ public static enum MessageStatus { } public static enum MessageQuotedType { - QUOTE_NOT_FOUND, QUOTE_FOUND, QUOTE_STATUS, QUOTE_PRIVACY_GROUP, QUOTE_PRIVACY_GROUP_NOT_FOUND + QUOTE_NOT_FOUND, QUOTE_FOUND, QUOTE_STATUS, QUOTE_PRIVACY_GROUP, QUOTE_PRIVACY_GROUP_NOT_FOUND, QUOTE_CATALOG } @Override From f990992b91202180d3f6ff86e4e892aa181aebdd Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Tue, 2 Jul 2024 17:39:48 -0300 Subject: [PATCH 24/58] add catalog icon --- .../main/resources/iped/parsers/whatsapp/css/whatsapp.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/css/whatsapp.css b/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/css/whatsapp.css index ee88a94395..c8cd2e78a5 100644 --- a/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/css/whatsapp.css +++ b/iped-parsers/iped-parsers-impl/src/main/resources/iped/parsers/whatsapp/css/whatsapp.css @@ -133,6 +133,14 @@ div.privacyDeleteIcon { margin: 0; } +div.catalogIcon { + display: inline-block; + width: 16px; + height: 16px; + vertical-align: bottom; + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAeJJREFUOE+lkzFoE2EYhp/cHY1UEqUYrIFkMBYRC8olqNShktCOLVwEN60uoiAHvVqnbIlQ2kEILoKidNMhQZASEs3kUEocaoUOojYlCNVWuTRpq5eLRGxMyB0q/tv/fh8P3/t+/++g84SAGQu9IWlAobXmsGgcjkajmcioilOq4XFts/Dew1I+QSqVGgJyfwSoqpo5fznBm6KIXoXSuoC5PEEymbQFBADfL3JIVdXp3tNT9HlNDveaFN4KLGZuNQATLRaKwLtdCzNjvv3aKf+h5nRutxtd13/eXS4X5XK5WZsvfuTR6tdpYLIJGL86qzmdfpvs2uWt7RXu3LvYDkin09qJwQjKqsQFt8n1nhpjJQnBAQ+8Bnc3RB7rAmmfQSGfRVGUTkBwMEzsk0Rkr8moy2Tqs0hjxMkDNdK6wIuqQMJjMJ/PWQPC/UeR1koYy4tIx4OYayXqgkh9YAhEqekjl7MBnKlXKPqOUZl7wj7lEptLr+g2DfrkIInnWcqBECPrr9nac9B6gt0MWiM70lXnvtfg5tNnfAic5cbKHN+6PDYWwmHbLTy8FsH4voM8coWNbn8nIB6Pa7Is2wIWZm+zU63gPXmOL1IPsVisbQvDwMBfPYLfTS+BrNVn+ifOfwN+ANvFuxHI5I9YAAAAAElFTkSuQmCC"); + margin: 0; +} /******************** * WhatsApp Top Bar * ********************/ From de7859941125eec6d100b2cbd162d99bd0871503 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Tue, 2 Jul 2024 17:40:20 -0300 Subject: [PATCH 25/58] add quote catalog info, add contacted find bysinesses action type 76 --- .../resources/localization/iped-parsers-messages.properties | 2 ++ .../localization/iped-parsers-messages_de_DE.properties | 2 ++ .../localization/iped-parsers-messages_es_AR.properties | 2 ++ .../localization/iped-parsers-messages_fr_FR.properties | 2 ++ .../localization/iped-parsers-messages_it_IT.properties | 2 ++ .../localization/iped-parsers-messages_pt_BR.properties | 2 ++ 6 files changed, 12 insertions(+) diff --git a/iped-app/resources/localization/iped-parsers-messages.properties b/iped-app/resources/localization/iped-parsers-messages.properties index 83ddfcaa21..3a7b81f0d1 100644 --- a/iped-app/resources/localization/iped-parsers-messages.properties +++ b/iped-app/resources/localization/iped-parsers-messages.properties @@ -280,6 +280,8 @@ WhatsAppReport.QuoteStaus=Quoted Status WhatsAppReport.QuotePrivacy=Message quoted privately through the group WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found +WhatsAppReport.QuoteCatalog=Quoted Catalog +WhatsAppReport.ContactedFindBusinesses=You contacted this from find businesses WhatsAppReport.Document=Document WhatsAppReport.Photo=Photo WhatsAppReport.Audio=Audio diff --git a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties index b726291932..85e843a0f8 100644 --- a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties +++ b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties @@ -280,6 +280,8 @@ WhatsAppReport.QuoteStaus=Quoted Status[TBT] WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] +WhatsAppReport.QuoteCatalog=Quoted Catalog[TBT] +WhatsAppReport.ContactedFindBusinesses=You contacted this from find businesses[TBT] WhatsAppReport.Document=Document[TBT] WhatsAppReport.Photo=Photo[TBT] WhatsAppReport.Audio=Audio[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties index 078b5e5d38..01baf02049 100644 --- a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties @@ -280,6 +280,8 @@ WhatsAppReport.QuoteStaus=Quoted Status[TBT] WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] +WhatsAppReport.QuoteCatalog=Quoted Catalog[TBT] +WhatsAppReport.ContactedFindBusinesses=You contacted this from find businesses[TBT] WhatsAppReport.Document=Document[TBT] WhatsAppReport.Photo=Photo[TBT] WhatsAppReport.Audio=Audio[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties index 450ed6ac37..bfb07d6601 100644 --- a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties @@ -280,6 +280,8 @@ WhatsAppReport.QuoteStaus=Quoted Status[TBT] WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] +WhatsAppReport.QuoteCatalog=Quoted Catalog[TBT] +WhatsAppReport.ContactedFindBusinesses=You contacted this from find businesses[TBT] WhatsAppReport.Document=Document WhatsAppReport.Photo=Photo WhatsAppReport.Audio=Audio diff --git a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties index dc41e2504d..2c162bd7dc 100644 --- a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties +++ b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties @@ -280,6 +280,8 @@ WhatsAppReport.QuoteStaus=Quoted Status[TBT] WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] +WhatsAppReport.QuoteCatalog=Quoted Catalog[TBT] +WhatsAppReport.ContactedFindBusinesses=You contacted this from find businesses[TBT] WhatsAppReport.Document=Document[TBT] WhatsAppReport.Photo=Photo[TBT] WhatsAppReport.Audio=Audio[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties index 3be7d76139..6691f93d53 100644 --- a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties @@ -280,6 +280,8 @@ WhatsAppReport.QuoteStaus=Status citado WhatsAppReport.QuotePrivacy=Mensagem citada em particular através de grupo WhatsAppReport.QuotePrivacyMessage=Esta mensagem citada está localizada no grupo WhatsAppReport.QuotePrivacyNotFound=Mensagem citada em particular através de grupo não encontrada +WhatsAppReport.QuoteCatalog=Catálogo citado +WhatsAppReport.ContactedFindBusinesses=Você entrou em contato com essa empresa usando o recurso de encontrar empresas WhatsAppReport.Document=Documento WhatsAppReport.Photo=Foto WhatsAppReport.Audio=Áudio From 7c66840dde77e1425cef8bf815fffc2556fde7da Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Tue, 2 Jul 2024 17:41:19 -0300 Subject: [PATCH 26/58] add product _message from quoted catalog, add contacted_find_businesses --- .../parsers/whatsapp/ReportGenerator.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java index 595afbedae..25ce8743d9 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java @@ -656,7 +656,11 @@ private synchronized void printMessage(PrintWriter out, Message message, boolean case SECURITY_NOTIFICATIONS_NO_LONGER_AVAILABLE: out.println("
"); out.println(Messages.getString("WhatsAppReport.SecurityNotificationsNoLongerAvailable") + "
"); - break; + break; + case CONTACTED_FIND_BUSINESSES: + out.println("
"); + out.println(Messages.getString("WhatsAppReport.ContactedFindBusinesses") + "
"); + break; case USER_ADMIN: out.println("
"); out.print(name + " "); @@ -1261,6 +1265,10 @@ private void printQuote(PrintWriter out, Message message, WAContactsDirectory co quoteEnd = "
" + Messages.getString("WhatsAppReport.QuoteStaus") + "" + quoteEnd; break; + case QUOTE_CATALOG: + quoteEnd = "

" + + Messages.getString("WhatsAppReport.QuoteCatalog") + "" + quoteEnd; + break; case QUOTE_PRIVACY_GROUP: quoteEnd = "

" + Messages.getString("WhatsAppReport.QuotePrivacy") + "" + quoteEnd; @@ -1381,7 +1389,20 @@ private void printQuote(PrintWriter out, Message message, WAContactsDirectory co } out.print(quoteEnd); break; - + case PRODUCT_MESSAGE: + MessageProduct product = messageQuote.getProduct(); + String seller = null; + if (product != null) { + seller = getBestContactName(false, product.getSeller(), contactsDirectory, account); + } + out.print("
" + quoteUser + + "
" + formatProduct(product, seller) + quoteEnd); + if (quoteThumb != null) { + out.print("
"); + } + break; default: out.print("
" + quoteUser From b23c1f3849d721b7268651210b473ca832be31f1 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Tue, 2 Jul 2024 17:42:52 -0300 Subject: [PATCH 27/58] add quoted catalog to iphone logic, set quoted type uuid is found, add decodequotedproduct function --- .../iped/parsers/whatsapp/ExtractorIOS.java | 76 +++++++++++++++---- 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java index cabde61b96..893e6515d0 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java @@ -401,7 +401,9 @@ private void findQuotedMessages(List messages, Map mes List childs = ProtoBufDecoder.findChilds(main, 19); Message messageQuote = messagesMap.get(uuidQuote); - if (messageQuote == null) { + if (messageQuote != null) { + messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); + }else { // Referenced message was deleted, so create a new message and fill with data // extracted from referencing message metadata. messageQuote = new Message(); @@ -567,7 +569,11 @@ private void findQuotedMessages(List messages, Map mes } } break; - + case 30: + type = MessageType.PRODUCT_MESSAGE; + messageQuote.setProduct(decodeQuotedProductInfo(c, messageQuote)); + messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_CATALOG); + break; default: break; } @@ -616,21 +622,10 @@ private void findQuotedMessages(List messages, Map mes messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP_NOT_FOUND); messageQuote.setDeleted(true); } - - }else{ - messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); - messageQuote.setDeleted(true); - } - - }else{ - messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); - messageQuote.setDeleted(true); + } } - }else{ - messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); } - if (messageQuote.getThumbData() == null && childs != null) { byte[] thumbData = null; for (Part c : childs) { @@ -979,6 +974,59 @@ private MessageProduct decodeProductInfo(byte[] metadata, Message m) { return null; } + private MessageProduct decodeQuotedProductInfo(Part p2, Message m) { + String title = null; + String observation = null; + String currency = null; + String seller = null; + int amount = 0; + if (p2 != null) { + Part p3 = p2.getChild(1); + if (p3 != null) { + Part p4 = p3.getChild(1); + if (p4 != null) { + Part p5 = p4.getChild(16); + if (p5 != null) { + byte[] bytes = p5.getBytes(); + if (bytes != null) { + m.setThumbData(bytes); + } + } + } + p4 = p3.getChild(3); + if (p4 != null) { + title = p4.getString(); + } + p4 = p3.getChild(4); + if (p4 != null) { + observation = p4.getString(); + } + p4 = p3.getChild(5); + if (p4 != null) { + currency = p4.getString(); + } + p4 = p3.getChild(6); + if (p4 != null) { + String v = p4.getString(); + if (v != null && !v.isBlank()) { + try { + amount = Integer.parseInt(v); + } catch (NumberFormatException e) { + } + } + } + p3 = p2.getChild(2); + if (p3 != null) { + seller = p3.getString(); + } + } + } + if (title != null || currency != null || amount != 0 || seller != null) { + return new MessageProduct(title, seller, currency, amount, observation); + } + return null; + } + private String decodeGroupInvite(byte[] metadata) { Part p1 = new ProtoBufDecoder(metadata).decode(28); if (p1 != null) { From ff4352158778178d5202ef6735e5b4338707de9b Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Tue, 2 Jul 2024 17:45:04 -0300 Subject: [PATCH 28/58] add quoted catalog to android set quoted type if original id found, add sql to found quoted product, add action type 76 --- .../parsers/whatsapp/ExtractorAndroidNew.java | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index dafee5af46..995ae27c8c 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -349,6 +349,17 @@ private void extractProductInfo(Connection conn, Message m) throws SQLException } } + private void extractQuotedProductInfo(Connection conn, Message m) throws SQLException { + try (PreparedStatement stmt = conn.prepareStatement(SELECT_QUOTED_PRODUCT)) { + stmt.setLong(1, m.getId()); + ResultSet rs = stmt.executeQuery(); + if (rs.next()) { + m.setProduct(new MessageProduct(rs.getString("title"), rs.getString("seller"), rs.getString("currency"), + rs.getInt("amount"), rs.getString("description"))); + } + } + } + private void extractEphemeralDuration(Connection conn, Message m) throws SQLException { try (PreparedStatement stmt = conn.prepareStatement(SELECT_EPHEMERAL_SETTING)) { stmt.setLong(1, m.getId()); @@ -543,9 +554,13 @@ private void extractMessages(Connection conn, Map idToChat) throws S // Try to find original message in messages Message original = messagesMapUuid.get(mq.getUuid()); if (original != null) {//has found original message reference + original.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); m.setMessageQuote(original); + } else if (mq.getProduct() != null){ // Quoted Catalog + mq.setMessageQuotedType(MessageQuotedType.QUOTE_CATALOG); + mq.setId(fakeIds--); + m.setMessageQuote(mq); } else {// not found original message reference - mq.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); if (chatId == mq.getQuoteChatId()){// msgs In same chat long editId = mq.getEditId(); if (messagesMap.get(editId) != null){ // Quoted was edited @@ -553,6 +568,7 @@ private void extractMessages(Connection conn, Map idToChat) throws S mq.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); mq.setId(editId); }else{ // Quoted message cannot be found again + mq.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); mq.setId(fakeIds--); mq.setDeleted(true); } @@ -574,6 +590,7 @@ private void extractMessages(Connection conn, Map idToChat) throws S } }else{ + mq.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); mq.setId(fakeIds--); mq.setDeleted(true); } @@ -603,6 +620,8 @@ private Map> extractQuoteMessages(Connection conn) throws SQ Map> messagesPerChatId = new HashMap>(); String query = getSelectMessagesQuotesQuery(conn); + boolean hasQuotedProductTable = SQLite3DBParser.containsTable("message_quoted_product", conn); + try (PreparedStatement stmt = conn.prepareStatement(query)) { ResultSet rs = stmt.executeQuery(); while (rs.next()) { @@ -652,6 +671,10 @@ private Map> extractQuoteMessages(Connection conn) throws SQ long chatId = rs.getLong("parent_message_chat_row_id"); + if (hasQuotedProductTable && m.getMessageType() == PRODUCT_MESSAGE) { + extractQuotedProductInfo(conn, m); + } + List messages = messagesPerChatId.get(chatId); if (messages == null) { messagesPerChatId.put(chatId, messages = new ArrayList()); @@ -792,6 +815,9 @@ protected Message.MessageType decodeMessageType(int messageType, int status, Int case 70: result = CALL_MESSAGE; break; + case 76: + result = CONTACTED_FIND_BUSINESSES; + break; case 75: case 108: result = GROUP_ADDED_TO_COMMUNITY; @@ -1026,7 +1052,11 @@ protected Message.MessageType decodeMessageType(int messageType, int status, Int private static final String SELECT_PRODUCT = "select raw_string as seller, title," + " currency_code as currency, amount_1000 as amount, description" + " from message_product left join jid on business_owner_jid = jid._id where message_row_id=?"; - + + private static final String SELECT_QUOTED_PRODUCT = "select raw_string as seller, title," + + " currency_code as currency, amount_1000 as amount, description" + + " from message_quoted_product left join jid on business_owner_jid = jid._id where message_row_id=?"; + private static final String SELECT_POLL_OPTION = "SELECT option_name as name, vote_total as total FROM message_poll_option where message_row_id=? order by _id"; private static final String SELECT_EPHEMERAL_SETTING = "SELECT setting_duration as duration FROM message_ephemeral_setting where message_row_id=?"; From 3e10a0e9319f84878bd841a9977c2d0a41ca78e5 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Tue, 2 Jul 2024 17:53:30 -0300 Subject: [PATCH 29/58] fix import --- .../src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java | 1 + 1 file changed, 1 insertion(+) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index 995ae27c8c..c197c75484 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -29,6 +29,7 @@ import static iped.parsers.whatsapp.Message.MessageType.EPHEMERAL_SAVE; import static iped.parsers.whatsapp.Message.MessageType.GIF_MESSAGE; import static iped.parsers.whatsapp.Message.MessageType.GROUP_ADDED_TO_COMMUNITY; +import static iped.parsers.whatsapp.Message.MessageType.CONTACTED_FIND_BUSINESSES; import static iped.parsers.whatsapp.Message.MessageType.GROUP_CHANGED_ALL_MEMBERS_CAN_EDIT; import static iped.parsers.whatsapp.Message.MessageType.GROUP_CHANGED_ALL_MEMBERS_CAN_SEND; import static iped.parsers.whatsapp.Message.MessageType.GROUP_CHANGED_ONLY_ADMINS_CAN_ADD; From 63438067d3800b67c4711bb2b7ef91da47f0ce07 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Tue, 2 Jul 2024 18:10:38 -0300 Subject: [PATCH 30/58] add case CONTACTED_FIND_BUSINESSES to system message --- .../src/main/java/iped/parsers/whatsapp/Message.java | 1 + 1 file changed, 1 insertion(+) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java index 4a94d81b2a..477e9f5f95 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java @@ -460,6 +460,7 @@ public boolean isSystemMessage() { case YOU_NOT_ADMIN: case OVER_256_MEMBERS_ONLY_ADMINS_CAN_EDIT: case SECURITY_NOTIFICATIONS_NO_LONGER_AVAILABLE: + case CONTACTED_FIND_BUSINESSES: return true; default: } From 44ac7438663dd1320553b47f44944228f8850c4f Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Wed, 3 Jul 2024 09:03:59 -0300 Subject: [PATCH 31/58] fix android old with new message quote type --- .../src/main/java/iped/parsers/whatsapp/ExtractorAndroid.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroid.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroid.java index 5f8519d2ec..c4c00069f2 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroid.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroid.java @@ -61,6 +61,7 @@ import iped.parsers.sqlite.SQLiteUndeleteTable; import iped.parsers.sqlite.SQLiteUndeleteTableResultSetAdapter; import iped.parsers.whatsapp.Message.MessageStatus; +import iped.parsers.whatsapp.Message.MessageQuotedType; /** * @@ -436,8 +437,10 @@ private List extractMessages(Connection conn, WAContact remote, boolean if (m != null){// Has quote Message original = messagesMapUuid.get(mq.getUuid());//Try to find orginal message in messages if (original != null){// has found original message reference, more complete + original.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); m.setMessageQuote(original); }else{// not found original message reference, get info from message_quotes table, less complete + mq.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); mq.setDeleted(true); mq.setId(fakeIds--); m.setMessageQuote(mq); From d44a936a98a5b031da88ea19e7e2ce9a76d921cb Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 5 Jul 2024 16:27:51 -0300 Subject: [PATCH 32/58] add group name parameter on message --- .../src/main/java/iped/parsers/whatsapp/ReportGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java index 25ce8743d9..3d97f7bb60 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java @@ -659,7 +659,7 @@ private synchronized void printMessage(PrintWriter out, Message message, boolean break; case CONTACTED_FIND_BUSINESSES: out.println("
"); - out.println(Messages.getString("WhatsAppReport.ContactedFindBusinesses") + "
"); + out.println(Messages.getString("WhatsAppReport.ContactedFindBusinesses", name) + "
"); break; case USER_ADMIN: out.println("
"); From 2f952ba412c6bed71e219122663c879ed55e3d8a Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 5 Jul 2024 16:28:20 -0300 Subject: [PATCH 33/58] add group name parameter on message --- .../resources/localization/iped-parsers-messages.properties | 2 +- .../localization/iped-parsers-messages_de_DE.properties | 2 +- .../localization/iped-parsers-messages_es_AR.properties | 2 +- .../localization/iped-parsers-messages_fr_FR.properties | 2 +- .../localization/iped-parsers-messages_it_IT.properties | 2 +- .../localization/iped-parsers-messages_pt_BR.properties | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iped-app/resources/localization/iped-parsers-messages.properties b/iped-app/resources/localization/iped-parsers-messages.properties index 3a7b81f0d1..37112b70f6 100644 --- a/iped-app/resources/localization/iped-parsers-messages.properties +++ b/iped-app/resources/localization/iped-parsers-messages.properties @@ -281,7 +281,7 @@ WhatsAppReport.QuotePrivacy=Message quoted privately through the group WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found WhatsAppReport.QuoteCatalog=Quoted Catalog -WhatsAppReport.ContactedFindBusinesses=You contacted this from find businesses +WhatsAppReport.ContactedFindBusinesses=You contacted {0} from find businesses WhatsAppReport.Document=Document WhatsAppReport.Photo=Photo WhatsAppReport.Audio=Audio diff --git a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties index 85e843a0f8..7d5ef9525a 100644 --- a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties +++ b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties @@ -281,7 +281,7 @@ WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] WhatsAppReport.QuoteCatalog=Quoted Catalog[TBT] -WhatsAppReport.ContactedFindBusinesses=You contacted this from find businesses[TBT] +WhatsAppReport.ContactedFindBusinesses=You contacted {0} from find businesses[TBT] WhatsAppReport.Document=Document[TBT] WhatsAppReport.Photo=Photo[TBT] WhatsAppReport.Audio=Audio[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties index 01baf02049..1d8c168a60 100644 --- a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties @@ -281,7 +281,7 @@ WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] WhatsAppReport.QuoteCatalog=Quoted Catalog[TBT] -WhatsAppReport.ContactedFindBusinesses=You contacted this from find businesses[TBT] +WhatsAppReport.ContactedFindBusinesses=You contacted {0} from find businesses[TBT] WhatsAppReport.Document=Document[TBT] WhatsAppReport.Photo=Photo[TBT] WhatsAppReport.Audio=Audio[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties index bfb07d6601..14f3f84fa1 100644 --- a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties @@ -281,7 +281,7 @@ WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] WhatsAppReport.QuoteCatalog=Quoted Catalog[TBT] -WhatsAppReport.ContactedFindBusinesses=You contacted this from find businesses[TBT] +WhatsAppReport.ContactedFindBusinesses=You contacted {0} from find businesses[TBT] WhatsAppReport.Document=Document WhatsAppReport.Photo=Photo WhatsAppReport.Audio=Audio diff --git a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties index 2c162bd7dc..9ae28a2490 100644 --- a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties +++ b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties @@ -281,7 +281,7 @@ WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] WhatsAppReport.QuoteCatalog=Quoted Catalog[TBT] -WhatsAppReport.ContactedFindBusinesses=You contacted this from find businesses[TBT] +WhatsAppReport.ContactedFindBusinesses=You contacted {0} from find businesses[TBT] WhatsAppReport.Document=Document[TBT] WhatsAppReport.Photo=Photo[TBT] WhatsAppReport.Audio=Audio[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties index 6691f93d53..05360490ad 100644 --- a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties @@ -281,7 +281,7 @@ WhatsAppReport.QuotePrivacy=Mensagem citada em particular através de grupo WhatsAppReport.QuotePrivacyMessage=Esta mensagem citada está localizada no grupo WhatsAppReport.QuotePrivacyNotFound=Mensagem citada em particular através de grupo não encontrada WhatsAppReport.QuoteCatalog=Catálogo citado -WhatsAppReport.ContactedFindBusinesses=Você entrou em contato com essa empresa usando o recurso de encontrar empresas +WhatsAppReport.ContactedFindBusinesses=Você entrou em contato com a empresa {0} usando o recurso de encontrar empresas WhatsAppReport.Document=Documento WhatsAppReport.Photo=Foto WhatsAppReport.Audio=Áudio From 94db5bab99fad21d70e35aa5d71441c3223ec469 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Fri, 5 Jul 2024 16:35:47 -0300 Subject: [PATCH 34/58] add variable args on getString method --- .../src/main/java/iped/parsers/util/Messages.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/util/Messages.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/util/Messages.java index a3fc6e6ca7..c3ad3c63ba 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/util/Messages.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/util/Messages.java @@ -3,6 +3,7 @@ import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; +import java.text.MessageFormat; public class Messages { @@ -13,7 +14,7 @@ public class Messages { private Messages() { } - public static String getString(String key) { + public static String get(String key) { if (RESOURCE_BUNDLE == null) { String str = System.getProperty(iped.localization.Messages.LOCALE_SYS_PROP); // $NON-NLS-1$ Locale locale = str != null ? Locale.forLanguageTag(str) : Locale.getDefault(); @@ -27,4 +28,11 @@ public static String getString(String key) { throw e; } } + + public static String getString(String key, Object... args) { + String value = get(key); + if (args != null) + value = MessageFormat.format(value, args); + return value; + } } From 72ab684024c875036627a82f2b5c543ce555ff93 Mon Sep 17 00:00:00 2001 From: Hauck Date: Mon, 8 Jul 2024 00:27:47 -0300 Subject: [PATCH 35/58] First version of the remote transcription using whisper --- .../resources/scripts/tasks/WhisperProcess.py | 48 +++---- .../RemoteTranscriptionService.java | 118 +++++++++++++++--- .../transcript/Wav2Vec2TranscriptTask.java | 12 +- .../transcript/WhisperTranscriptTask.java | 57 +++++++++ 4 files changed, 192 insertions(+), 43 deletions(-) diff --git a/iped-app/resources/scripts/tasks/WhisperProcess.py b/iped-app/resources/scripts/tasks/WhisperProcess.py index a53203bc47..66f92d84e0 100644 --- a/iped-app/resources/scripts/tasks/WhisperProcess.py +++ b/iped-app/resources/scripts/tasks/WhisperProcess.py @@ -1,4 +1,4 @@ -import sys +import sys import numpy stdout = sys.stdout sys.stdout = sys.stderr @@ -10,7 +10,6 @@ ping = 'ping' def main(): - modelName = sys.argv[1] deviceNum = int(sys.argv[2]) threads = int(sys.argv[3]) @@ -74,38 +73,45 @@ def main(): if line == ping: print(ping, file=stdout, flush=True) continue - - transcription = '' + + files=line.split(",") + transcription = [] logprobs = [] + for file in files: + transcription.append("") + logprobs.append([]) try: if whisperx_found: - audio = whisperx.load_audio(line) - result = model.transcribe(audio, batch_size=batch_size, language=language) + #audio = whisperx.load_audio(line) + result = model.transcribe(files, batch_size=batch_size, language=language) for segment in result['segments']: - transcription += segment['text'] + idx=segment["audio"] + transcription[idx] += segment['text'] if 'avg_logprob' in segment: - logprobs.append(segment['avg_logprob']) + logprobs[idx].append(segment['avg_logprob']) else: - segments, info = model.transcribe(audio=line, language=language, beam_size=5, vad_filter=True) - for segment in segments: - transcription += segment.text - logprobs.append(segment.avg_logprob) + for idx in range(len(files)): + segments, info = model.transcribe(audio=files[idx], language=language, beam_size=5, vad_filter=True) + for segment in segments: + transcription[idx] += segment.text + logprobs[idx].append(segment.avg_logprob) except Exception as e: msg = repr(e).replace('\n', ' ').replace('\r', ' ') print(msg, file=stdout, flush=True) continue - text = transcription.replace('\n', ' ').replace('\r', ' ') - - if len(logprobs) == 0: - finalScore = 0 - else: - finalScore = numpy.mean(numpy.exp(logprobs)) - print(finished, file=stdout, flush=True) - print(str(finalScore), file=stdout, flush=True) - print(text, file=stdout, flush=True) + + for idx in range(len(files)): + text = transcription[idx].replace('\n', ' ').replace('\r', ' ') + + if len(logprobs[idx]) == 0: + finalScore = 0 + else: + finalScore = numpy.mean(numpy.exp(logprobs[idx])) + print(str(finalScore), file=stdout, flush=True) + print(text, file=stdout, flush=True) return diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java index 39f974ddf1..9b3df80047 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java @@ -16,6 +16,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Deque; import java.util.LinkedList; import java.util.List; import java.util.concurrent.ExecutorService; @@ -51,12 +53,23 @@ static enum MESSAGES { VERSION_1_0, PING } - + static class TranscribeRequest { + File wavAudio; + TextAndScore result=null; + + + public TranscribeRequest(File wavAudio) { + this.wavAudio=wavAudio; + } + } static class OpenConnectons { Socket conn; BufferedInputStream bis; PrintWriter writer; Thread t; + File wavAudio; + TextAndScore result=null; + public OpenConnectons(Socket conn, BufferedInputStream bis, PrintWriter writer, Thread t) { this.conn = conn; @@ -92,6 +105,8 @@ public void sendBeacon() { * Control number of simultaneous audio conversions to WAV. */ private static Semaphore wavConvSemaphore; + + private static int BATCH_SIZE=1; private static final AtomicLong audiosTranscripted = new AtomicLong(); private static final AtomicLong audiosDuration = new AtomicLong(); @@ -99,7 +114,9 @@ public void sendBeacon() { private static final AtomicLong transcriptionTime = new AtomicLong(); private static final AtomicLong requestsReceived = new AtomicLong(); private static final AtomicLong requestsAccepted = new AtomicLong(); - private static List beaconQueq = new LinkedList<>(); + private static final List beaconQueq = new LinkedList<>(); + private static final Deque toTranscribe = new LinkedList<>(); + private static Logger logger; @@ -149,7 +166,7 @@ public static void main(String[] args) throws Exception { AbstractTranscriptTask task = (AbstractTranscriptTask) Class.forName(audioConfig.getClassName()).getDeclaredConstructor().newInstance(); audioConfig.setEnabled(true); task.init(cm); - + BATCH_SIZE=audioConfig.getBatchSize(); int numConcurrentTranscriptions = Wav2Vec2TranscriptTask.getNumConcurrentTranscriptions(); int numLogicalCores = Runtime.getRuntime().availableProcessors(); @@ -175,6 +192,10 @@ public static void main(String[] args) throws Exception { startSendStatsThread(discoveryIp, discoveryPort, localPort, numConcurrentTranscriptions, numLogicalCores); startBeaconThread(); + for(int i=0;i transcribeRequests=new ArrayList<>(); + ArrayList files=new ArrayList(); + + if (executor.isShutdown()) { + throw new Exception("Shutting down service instance..."); + } + + synchronized (toTranscribe) { + if(toTranscribe.size()==0) + return; + while(toTranscribe.size()>0 && transcribeRequests.size() results = ((WhisperTranscriptTask)task).transcribeAudios(files); + for(int i=0;i deque = new LinkedBlockingDeque<>(); + protected static LinkedBlockingDeque deque = new LinkedBlockingDeque<>(); protected static volatile Level logLevel = Level.forName("MSG", 250); @@ -199,7 +199,7 @@ public void finish() throws Exception { deque.clear(); } - private void terminateServer(Server server) throws InterruptedException { + protected void terminateServer(Server server) throws InterruptedException { Process process = server.process; try { process.getOutputStream().write(TERMINATE.getBytes(Charsets.UTF8_CHARSET)); @@ -216,7 +216,7 @@ private void terminateServer(Server server) throws InterruptedException { } } - private boolean ping(Server server) { + protected boolean ping(Server server) { try { server.process.getOutputStream().write(PING.getBytes(Charsets.UTF8_CHARSET)); server.process.getOutputStream().write(NEW_LINE); diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/WhisperTranscriptTask.java b/iped-engine/src/main/java/iped/engine/task/transcript/WhisperTranscriptTask.java index 697273efb2..f34893a203 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/WhisperTranscriptTask.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/WhisperTranscriptTask.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; @@ -17,6 +18,8 @@ import iped.engine.config.AudioTranscriptConfig; import iped.engine.config.Configuration; import iped.engine.config.ConfigurationManager; +import iped.engine.task.transcript.AbstractTranscriptTask.TextAndScore; +import iped.engine.task.transcript.Wav2Vec2TranscriptTask.Server; import iped.exception.IPEDException; public class WhisperTranscriptTask extends Wav2Vec2TranscriptTask { @@ -127,6 +130,60 @@ protected Server startServer0(int device) throws IOException { protected TextAndScore transcribeAudio(File tmpFile) throws Exception { return transcribeWavPart(tmpFile); } + + protected List transcribeAudios(ArrayList tmpFiles) throws Exception { + + ArrayList textAndScores = new ArrayList<>(); + for(int i=0;i= MAX_TRANSCRIPTIONS) { + terminateServer(server); + server = startServer(server.device); + } + + StringBuilder filePaths = new StringBuilder(); + for(int i=0;i0) { + filePaths.append(","); + } + filePaths.append(tmpFiles.get(i).getAbsolutePath().replace('\\', '/')); + + } + server.process.getOutputStream().write(filePaths.toString().getBytes("UTF-8")); + server.process.getOutputStream().write(NEW_LINE); + server.process.getOutputStream().flush(); + + String line; + while (!TRANSCRIPTION_FINISHED.equals(line = server.reader.readLine())) { + if (line == null) { + throw new ProcessCrashedException(); + } else { + throw new RuntimeException("Transcription failed, returned: " + line); + } + } + for(int i=0;i Date: Mon, 8 Jul 2024 00:44:02 -0300 Subject: [PATCH 36/58] Only sleep if the queue is empty --- .../transcript/RemoteTranscriptionService.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java index 9b3df80047..af01b60513 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java @@ -576,8 +576,20 @@ private static void startTrancribeThreads(AbstractTranscriptTask task) { @Override public void run() { while (true) { + Boolean empty=true; + synchronized (toTranscribe) { + empty=toTranscribe.isEmpty(); + } + if(empty) { + try { + Thread.sleep(100); + + }catch (Exception e) { + // TODO: handle exception + } + continue; + } try { - Thread.sleep(100); transcriptSemaphore.acquire(); transcribeAudios(task); From 9dbd88f68f6cc32695c677aa657753ea3afe0b0b Mon Sep 17 00:00:00 2001 From: Hauck Date: Mon, 8 Jul 2024 10:38:26 -0300 Subject: [PATCH 37/58] Always notify the thread to prevent blocking --- .../RemoteTranscriptionService.java | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java index af01b60513..5f7fe9f419 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java @@ -232,7 +232,7 @@ public void run() { private static void transcribeAudios(AbstractTranscriptTask task ) throws Exception { ArrayList transcribeRequests=new ArrayList<>(); ArrayList files=new ArrayList(); - + Exception error=null; if (executor.isShutdown()) { throw new Exception("Shutting down service instance..."); } @@ -251,23 +251,30 @@ private static void transcribeAudios(AbstractTranscriptTask task ) throws Except long t2 = System.currentTimeMillis(); - - if(task instanceof WhisperTranscriptTask) { - List results = ((WhisperTranscriptTask)task).transcribeAudios(files); - for(int i=0;i results = ((WhisperTranscriptTask)task).transcribeAudios(files); + for(int i=0;i Date: Mon, 8 Jul 2024 15:26:42 -0300 Subject: [PATCH 38/58] Do not retry audios with errors --- .../iped/engine/task/transcript/RemoteTranscriptionService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java index 5f7fe9f419..cd303da89e 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java @@ -489,7 +489,7 @@ public void run() { } result=req.result; if(result==null) { - error=true; + error = false; throw new Exception("Error processing the audio"); } From 9b62ea5c03a700a650fb2e680ebdd57b14277173 Mon Sep 17 00:00:00 2001 From: Hauck Date: Mon, 8 Jul 2024 19:41:08 -0300 Subject: [PATCH 39/58] Better error handling --- .../RemoteTranscriptionService.java | 95 ++++++++++--------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java index cd303da89e..7d67dd8fdc 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java @@ -56,6 +56,7 @@ static enum MESSAGES { static class TranscribeRequest { File wavAudio; TextAndScore result=null; + Exception error=null; public TranscribeRequest(File wavAudio) { @@ -229,52 +230,57 @@ public void run() { }); } - private static void transcribeAudios(AbstractTranscriptTask task ) throws Exception { - ArrayList transcribeRequests=new ArrayList<>(); - ArrayList files=new ArrayList(); - Exception error=null; + private static void transcribeAudios(AbstractTranscriptTask task) throws Exception { + ArrayList transcribeRequests = new ArrayList<>(); + ArrayList files = new ArrayList(); + if (executor.isShutdown()) { throw new Exception("Shutting down service instance..."); } - + synchronized (toTranscribe) { - if(toTranscribe.size()==0) + if (toTranscribe.size() == 0) return; - while(toTranscribe.size()>0 && transcribeRequests.size() 0 && transcribeRequests.size() < BATCH_SIZE) { + TranscribeRequest req = toTranscribe.poll(); transcribeRequests.add(req); files.add(req.wavAudio); } } - logger.info("inicio da transcricao de "+files.size()+" audios"); - - + logger.info("inicio da transcricao de " + files.size() + " audios"); + long t2 = System.currentTimeMillis(); - - try { - if(task instanceof WhisperTranscriptTask) { - List results = ((WhisperTranscriptTask)task).transcribeAudios(files); - for(int i=0;i results = ((WhisperTranscriptTask) task).transcribeAudios(files); + for (int i = 0; i < results.size(); i++) { + transcribeRequests.get(i).result = results.get(i); } + } catch (Exception e) {// case fail, try each audio individually + batchTrancribe = false; + logger.error("Error while doing batch transcribe " + e.toString()); } - }catch (Exception e) { - error=e; - }finally { - for(int i=0;i Date: Tue, 9 Jul 2024 19:46:42 -0300 Subject: [PATCH 40/58] Pass new parameter --- iped-app/resources/scripts/tasks/WhisperProcess.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/iped-app/resources/scripts/tasks/WhisperProcess.py b/iped-app/resources/scripts/tasks/WhisperProcess.py index 66f92d84e0..6c669920b2 100644 --- a/iped-app/resources/scripts/tasks/WhisperProcess.py +++ b/iped-app/resources/scripts/tasks/WhisperProcess.py @@ -82,8 +82,7 @@ def main(): logprobs.append([]) try: if whisperx_found: - #audio = whisperx.load_audio(line) - result = model.transcribe(files, batch_size=batch_size, language=language) + result = model.transcribe(files, batch_size=batch_size, language=language,wav=True) for segment in result['segments']: idx=segment["audio"] transcription[idx] += segment['text'] From 4a76d17015d82145556da49e914a172307086dbb Mon Sep 17 00:00:00 2001 From: Hauck Date: Tue, 9 Jul 2024 19:47:47 -0300 Subject: [PATCH 41/58] Remove compatibility with protocols older than 1.2 --- .../RemoteTranscriptionService.java | 47 ++++++------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java index 7d67dd8fdc..b1873d51d0 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java @@ -387,29 +387,24 @@ public void run() { logger.info(prefix + "Accepted connection."); - int min = Math.min(MESSAGES.AUDIO_SIZE.toString().length(), - MESSAGES.VERSION_1_1.toString().length()); - bis.mark(min + 1); - byte[] bytes = bis.readNBytes(min); - String cmd = new String(bytes); - if (!MESSAGES.AUDIO_SIZE.toString().startsWith(cmd)) { - bis.reset(); - bytes = bis.readNBytes(MESSAGES.VERSION_1_1.toString().length()); - protocol = new String(bytes); - bis.mark(min + 1); - synchronized (beaconQueq) { - opc = new OpenConnectons(client, bis, writer, this); - beaconQueq.add(opc); - } + byte[] bytes = bis.readNBytes(MESSAGES.VERSION_1_2.toString().length()); + protocol = new String(bytes); + synchronized (beaconQueq) { + opc = new OpenConnectons(client, bis, writer, this); + beaconQueq.add(opc); } + + logger.info("Protocol Version {}", protocol); + if (protocol.compareTo(MESSAGES.VERSION_1_2.toString()) < 0) { + throw new Exception("Procol version " + protocol + " not supported"); + } // read the audio_size message - bis.reset(); bytes = bis.readNBytes(MESSAGES.AUDIO_SIZE.toString().length()); - cmd = new String(bytes); + String cmd = new String(bytes); if (!MESSAGES.AUDIO_SIZE.toString().equals(cmd)) { error = true; @@ -418,11 +413,8 @@ public void run() { DataInputStream dis = new DataInputStream(bis); long size; - if (protocol.compareTo(MESSAGES.VERSION_1_2.toString()) >= 0) { - size = dis.readLong(); - } else { - size = dis.readInt(); - } + size = dis.readLong(); + if (size < 0) { error = true; try { @@ -531,17 +523,8 @@ public void run() { String errorMsg = "Exception while transcribing"; logger.warn(errorMsg, e); if (writer != null) { - if (e.getMessage() != null && e.getMessage().startsWith("Invalid file size:") - && protocol.compareTo(MESSAGES.VERSION_1_2.toString()) < 0) { - writer.println("0"); - writer.println( - "Audios longer than 2GB are not supported by old clients, please update your client version!"); - writer.println(MESSAGES.DONE); - } else { - writer.println(error ? MESSAGES.ERROR : MESSAGES.WARN); - writer.println( - errorMsg + ": " + e.toString().replace('\n', ' ').replace('\r', ' ')); - } + writer.println(error ? MESSAGES.ERROR : MESSAGES.WARN); + writer.println(errorMsg + ": " + e.toString().replace('\n', ' ').replace('\r', ' ')); writer.flush(); } } finally { From 8b5f7fdf5765ba64a5c01bd99d8a4415c9b4c3c3 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 29 Jul 2024 11:15:57 -0300 Subject: [PATCH 42/58] change message to correct info about quote privacey --- .../resources/localization/iped-parsers-messages.properties | 2 +- .../localization/iped-parsers-messages_de_DE.properties | 2 +- .../localization/iped-parsers-messages_es_AR.properties | 2 +- .../localization/iped-parsers-messages_fr_FR.properties | 2 +- .../localization/iped-parsers-messages_it_IT.properties | 2 +- .../localization/iped-parsers-messages_pt_BR.properties | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iped-app/resources/localization/iped-parsers-messages.properties b/iped-app/resources/localization/iped-parsers-messages.properties index 37112b70f6..c9836cfa6e 100644 --- a/iped-app/resources/localization/iped-parsers-messages.properties +++ b/iped-app/resources/localization/iped-parsers-messages.properties @@ -278,7 +278,7 @@ WhatsAppReport.Recovered=Recovered WhatsAppReport.QuoteNotFound=Quoted message not found WhatsAppReport.QuoteStaus=Quoted Status WhatsAppReport.QuotePrivacy=Message quoted privately through the group -WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group +WhatsAppReport.QuotePrivacyMessage=This quoted message was created in the group WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found WhatsAppReport.QuoteCatalog=Quoted Catalog WhatsAppReport.ContactedFindBusinesses=You contacted {0} from find businesses diff --git a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties index 7d5ef9525a..7f2e9950c6 100644 --- a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties +++ b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties @@ -278,7 +278,7 @@ WhatsAppReport.Recovered=Recovered[TBT] WhatsAppReport.QuoteNotFound=Quoted message not found[TBT] WhatsAppReport.QuoteStaus=Quoted Status[TBT] WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] -WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] +WhatsAppReport.QuotePrivacyMessage=This quoted message was created in the group[TBT] WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] WhatsAppReport.QuoteCatalog=Quoted Catalog[TBT] WhatsAppReport.ContactedFindBusinesses=You contacted {0} from find businesses[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties index 1d8c168a60..8f2e03964c 100644 --- a/iped-app/resources/localization/iped-parsers-messages_es_AR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_es_AR.properties @@ -278,7 +278,7 @@ WhatsAppReport.Recovered=Recovered[TBT] WhatsAppReport.QuoteNotFound=Quoted message not found[TBT] WhatsAppReport.QuoteStaus=Quoted Status[TBT] WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] -WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] +WhatsAppReport.QuotePrivacyMessage=This quoted message was created in the group[TBT] WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] WhatsAppReport.QuoteCatalog=Quoted Catalog[TBT] WhatsAppReport.ContactedFindBusinesses=You contacted {0} from find businesses[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties index 14f3f84fa1..80cce88c1b 100644 --- a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties @@ -278,7 +278,7 @@ WhatsAppReport.Recovered=Récupéré WhatsAppReport.QuoteNotFound=Message cité est introuvable WhatsAppReport.QuoteStaus=Quoted Status[TBT] WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] -WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] +WhatsAppReport.QuotePrivacyMessage=This quoted message was created in the group[TBT] WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] WhatsAppReport.QuoteCatalog=Quoted Catalog[TBT] WhatsAppReport.ContactedFindBusinesses=You contacted {0} from find businesses[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties index 9ae28a2490..dd32dcfb45 100644 --- a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties +++ b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties @@ -278,7 +278,7 @@ WhatsAppReport.Recovered=Recovered[TBT] WhatsAppReport.QuoteNotFound=Quoted message not found[TBT] WhatsAppReport.QuoteStaus=Quoted Status[TBT] WhatsAppReport.QuotePrivacy=Message quoted privately through the group[TBT] -WhatsAppReport.QuotePrivacyMessage=This quoted message is located in the group[TBT] +WhatsAppReport.QuotePrivacyMessage=This quoted message was created in the group[TBT] WhatsAppReport.QuotePrivacyNotFound=Message quoted privately through the group not found[TBT] WhatsAppReport.QuoteCatalog=Quoted Catalog[TBT] WhatsAppReport.ContactedFindBusinesses=You contacted {0} from find businesses[TBT] diff --git a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties index 05360490ad..fae85613f2 100644 --- a/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_pt_BR.properties @@ -278,7 +278,7 @@ WhatsAppReport.Recovered=Recuperado WhatsAppReport.QuoteNotFound=Mensagem citada não localizada WhatsAppReport.QuoteStaus=Status citado WhatsAppReport.QuotePrivacy=Mensagem citada em particular através de grupo -WhatsAppReport.QuotePrivacyMessage=Esta mensagem citada está localizada no grupo +WhatsAppReport.QuotePrivacyMessage=Esta mensagem citada foi criada no grupo WhatsAppReport.QuotePrivacyNotFound=Mensagem citada em particular através de grupo não encontrada WhatsAppReport.QuoteCatalog=Catálogo citado WhatsAppReport.ContactedFindBusinesses=Você entrou em contato com a empresa {0} usando o recurso de encontrar empresas From a71efdd65b987e7bf326c584fe0362f568f39f56 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 29 Jul 2024 11:28:00 -0300 Subject: [PATCH 43/58] translate from whatsapp app --- .../localization/iped-parsers-messages_de_DE.properties | 4 ++-- .../localization/iped-parsers-messages_fr_FR.properties | 4 ++-- .../localization/iped-parsers-messages_it_IT.properties | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties index 7f2e9950c6..75f3839d10 100644 --- a/iped-app/resources/localization/iped-parsers-messages_de_DE.properties +++ b/iped-app/resources/localization/iped-parsers-messages_de_DE.properties @@ -331,8 +331,8 @@ WhatsAppReport.EditedOn=Edited on[TBT] WhatsAppReport.UserJoinedWhatsApp=joined WhatsApp[TBT] WhatsAppReport.PinnedMessage=pinned a message[TBT] WhatsAppReport.AIThirdParty=This AI is from a third-party developer. Meta receives your AI chats to improve AI quality.[TBT] -WhatsAppReport.Over256MembersOnlyAdminsCanEdit=This group has over 256 members so now only admins can edit the groups settings.[TBT] -WhatsAppReport.SecurityNotificationsNoLongerAvailable=Security code notifications are no longer available for this chat.[TBT] +WhatsAppReport.Over256MembersOnlyAdminsCanEdit=Diese Gruppe hat mehr als 256 Mitglieder. Daher können jetzt nur noch Admins die Gruppeneinstellungen bearbeiten. +WhatsAppReport.SecurityNotificationsNoLongerAvailable=Benachrichtigungen zur Sicherheitsnummer sind für diesen Chat nicht länger verfügbar. VCardParser.FormattedName=Name formatiert VCardParser.Name=Name VCardParser.Nickname=Nickname diff --git a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties index 80cce88c1b..b4f6b74443 100644 --- a/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties +++ b/iped-app/resources/localization/iped-parsers-messages_fr_FR.properties @@ -331,8 +331,8 @@ WhatsAppReport.EditedOn=Modifié en WhatsAppReport.UserJoinedWhatsApp=a rejoint WhatsApp WhatsAppReport.PinnedMessage=a epinglé un message WhatsAppReport.AIThirdParty=Cette IA provient d'un développeur tiers. Meta reçoit vos discussions IA pour améliorer la qualité de l'IA. -WhatsAppReport.Over256MembersOnlyAdminsCanEdit=This group has over 256 members so now only admins can edit the groups settings.[TBT] -WhatsAppReport.SecurityNotificationsNoLongerAvailable=Security code notifications are no longer available for this chat.[TBT] +WhatsAppReport.Over256MembersOnlyAdminsCanEdit=Comme ce groupe inclut plus de 256 membres, désormais, seulement les admins peuvent modifier les paramètres du groupe. +WhatsAppReport.SecurityNotificationsNoLongerAvailable=Les notifications relatives aux codes de sécurité ne sont plus disponibles pour cette discoussion. VCardParser.FormattedName=Nom formaté VCardParser.Name=Nom VCardParser.Nickname=Surnom diff --git a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties index dd32dcfb45..c03a30d7e1 100644 --- a/iped-app/resources/localization/iped-parsers-messages_it_IT.properties +++ b/iped-app/resources/localization/iped-parsers-messages_it_IT.properties @@ -331,8 +331,8 @@ WhatsAppReport.EditedOn=Edited on[TBT] WhatsAppReport.UserJoinedWhatsApp=joined WhatsApp[TBT] WhatsAppReport.PinnedMessage=pinned a message[TBT] WhatsAppReport.AIThirdParty=This AI is from a third-party developer. Meta receives your AI chats to improve AI quality.[TBT] -WhatsAppReport.Over256MembersOnlyAdminsCanEdit=This group has over 256 members so now only admins can edit the groups settings.[TBT] -WhatsAppReport.SecurityNotificationsNoLongerAvailable=Security code notifications are no longer available for this chat.[TBT] +WhatsAppReport.Over256MembersOnlyAdminsCanEdit=Dato che questo gruppo ha più di 256 membri, solo gli amministratori potranno modificarne le impostazioni. +WhatsAppReport.SecurityNotificationsNoLongerAvailable=Le notifiche sul codice di sicurezza non sono più disponibili per questa chat. VCardParser.FormattedName=Nome formattato VCardParser.Name=Nome VCardParser.Nickname=Nickname From f6824da81f11f9dff3632b6e60e08b015ff26f22 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 29 Jul 2024 11:30:46 -0300 Subject: [PATCH 44/58] Add message about group name even if the message id is not identified (iphone) --- .../java/iped/parsers/whatsapp/ReportGenerator.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java index 3d97f7bb60..924c488f0a 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java @@ -1256,6 +1256,7 @@ private void printQuote(PrintWriter out, Message message, WAContactsDirectory co } String quoteEnd = "
"; + String messageQuoteRemoteId; switch(messageQuote.getMessageQuotedType()){ case QUOTE_NOT_FOUND: quoteEnd = "
" @@ -1272,8 +1273,8 @@ private void printQuote(PrintWriter out, Message message, WAContactsDirectory co case QUOTE_PRIVACY_GROUP: quoteEnd = "

" + Messages.getString("WhatsAppReport.QuotePrivacy") + "" + quoteEnd; - String messageQuoteRemoteId = messageQuote.getRemoteId(); - if (messageQuoteRemoteId != null){ + messageQuoteRemoteId = messageQuote.getRemoteId(); + if (messageQuoteRemoteId != null && !messageQuoteRemoteId.isEmpty()){ String ms = Messages.getString("WhatsAppReport.QuotePrivacyMessage") + ": "+ messageQuoteRemoteId +"
" + Messages.getString("WhatsAppReport.ReferenceId") + " " +messageQuote.getId(); quoteClick = "onclick=\"showMessage('" + ms + "');\""; @@ -1282,6 +1283,13 @@ private void printQuote(PrintWriter out, Message message, WAContactsDirectory co case QUOTE_PRIVACY_GROUP_NOT_FOUND: quoteEnd = "

" + Messages.getString("WhatsAppReport.QuotePrivacyNotFound") + "" + quoteEnd; + messageQuoteRemoteId = messageQuote.getRemoteId(); + String ms = ""; + if (messageQuoteRemoteId != null && !messageQuoteRemoteId.isEmpty()){ + ms = Messages.getString("WhatsAppReport.QuotePrivacyMessage") + ": "+ messageQuoteRemoteId +"
"; + } + ms += Messages.getString("WhatsAppReport.QuoteNotFound"); + quoteClick = "onclick=\"showMessage('" + ms + "');\""; break; } From c8b7b7701b51f0f3619a885bb567a6ef720bec6e Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 29 Jul 2024 11:32:04 -0300 Subject: [PATCH 45/58] Get the group name even if the message is not identified, search optimization for groups only --- .../java/iped/parsers/whatsapp/ExtractorIOS.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java index 893e6515d0..20b208a71f 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java @@ -593,11 +593,13 @@ private void findQuotedMessages(List messages, Map mes messageQuote.setRemoteId(status); boolean found = false; - String title = ""; - for (Chat cq : idToChat.values()) { + for (Chat cq : idToChat.values()) { //Search for the message in chat groups - if(status.contains(cq.getPrintId())) - title = cq.getTitle(); + if(!cq.isGroupChat()) + continue; + + if(cq.getPrintId()!=null && status.contains(cq.getPrintId())) + messageQuote.setRemoteId(cq.getTitle()); for (Message mq : cq.getMessages()) { if (mq.getUuid() != null && mq.getUuid().compareTo(uuidQuote)==0) { @@ -611,10 +613,6 @@ private void findQuotedMessages(List messages, Map mes break; } } - - if (!title.isEmpty()) - messageQuote.setRemoteId(title); - if (found){ messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP); From 1649c2b5003124df52a1af0c8a0417737c47534c Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:41:06 -0300 Subject: [PATCH 46/58] create new property to save quoted Private Group Name --- .../src/main/java/iped/parsers/whatsapp/Message.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java index 477e9f5f95..f9fae1a459 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/Message.java @@ -76,6 +76,7 @@ public class Message implements Comparable { private String uuid = null; private long editId = -1; private long quoteChatId = -1; + private String quotePrivateGroupName; private byte[] metaData; private String groupInviteName; private MessageTemplate messageTemplate; @@ -619,6 +620,14 @@ public void setGroupInviteName(String groupInviteName) { this.groupInviteName = groupInviteName; } + public String getQuotePrivateGroupName() { + return quotePrivateGroupName; + } + + public void setQuotePrivateGroupName(String quotePrivateGroupName) { + this.quotePrivateGroupName = quotePrivateGroupName; + } + public MessageTemplate getMessageTemplate() { return messageTemplate; } From 8fe4ce495d0d5a1734518964f7be946e3b56b85a Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:42:08 -0300 Subject: [PATCH 47/58] save quoted private group name in reserverd property --- .../main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index c197c75484..164e8bb8ba 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -584,8 +584,8 @@ private void extractMessages(Connection conn, Map idToChat) throws S //Find friendly group name for (Chat cq : idToChat.values()) { - if(remoteId.contains(cq.getPrintId())){ - mq.setRemoteId(cq.getTitle()); + if(cq.getPrintId()!=null && remoteId.contains(cq.getPrintId())){ + mq.setQuotePrivateGroupName(cq.getTitle()); break; } } From f12e7759d713ea28378204ece4bd71dab51b3183 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:42:51 -0300 Subject: [PATCH 48/58] get quoted private group name from reserverd property --- .../java/iped/parsers/whatsapp/ReportGenerator.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java index 924c488f0a..9d43fd4152 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ReportGenerator.java @@ -1256,7 +1256,7 @@ private void printQuote(PrintWriter out, Message message, WAContactsDirectory co } String quoteEnd = "
"; - String messageQuoteRemoteId; + String privateGroupName = messageQuote.getQuotePrivateGroupName(); switch(messageQuote.getMessageQuotedType()){ case QUOTE_NOT_FOUND: quoteEnd = "

" @@ -1273,9 +1273,8 @@ private void printQuote(PrintWriter out, Message message, WAContactsDirectory co case QUOTE_PRIVACY_GROUP: quoteEnd = "

" + Messages.getString("WhatsAppReport.QuotePrivacy") + "" + quoteEnd; - messageQuoteRemoteId = messageQuote.getRemoteId(); - if (messageQuoteRemoteId != null && !messageQuoteRemoteId.isEmpty()){ - String ms = Messages.getString("WhatsAppReport.QuotePrivacyMessage") + ": "+ messageQuoteRemoteId +"
" + if (privateGroupName != null && !privateGroupName.isEmpty()){ + String ms = Messages.getString("WhatsAppReport.QuotePrivacyMessage") + ": "+ privateGroupName +"
" + Messages.getString("WhatsAppReport.ReferenceId") + " " +messageQuote.getId(); quoteClick = "onclick=\"showMessage('" + ms + "');\""; } @@ -1283,10 +1282,9 @@ private void printQuote(PrintWriter out, Message message, WAContactsDirectory co case QUOTE_PRIVACY_GROUP_NOT_FOUND: quoteEnd = "

" + Messages.getString("WhatsAppReport.QuotePrivacyNotFound") + "" + quoteEnd; - messageQuoteRemoteId = messageQuote.getRemoteId(); String ms = ""; - if (messageQuoteRemoteId != null && !messageQuoteRemoteId.isEmpty()){ - ms = Messages.getString("WhatsAppReport.QuotePrivacyMessage") + ": "+ messageQuoteRemoteId +"
"; + if (privateGroupName != null && !privateGroupName.isEmpty()){ + ms = Messages.getString("WhatsAppReport.QuotePrivacyMessage") + ": "+ privateGroupName +"
"; } ms += Messages.getString("WhatsAppReport.QuoteNotFound"); quoteClick = "onclick=\"showMessage('" + ms + "');\""; From e59710b6337138230824c3e93a248028fcf43013 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:43:35 -0300 Subject: [PATCH 49/58] save quoted private group name in reserverd property --- .../java/iped/parsers/whatsapp/ExtractorIOS.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java index 20b208a71f..a0da323857 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java @@ -582,24 +582,24 @@ private void findQuotedMessages(List messages, Map mes messageQuote.setMessageType(type); - String status = ProtoBufDecoder.findString(main, 7); - if (status!=null){ // find quotes outside this chat + String contactQuote = ProtoBufDecoder.findString(main, 7); + if (contactQuote!=null){ // find quotes outside this chat - if (status.compareTo(Message.STATUS_BROADCAST)==0){ + if (contactQuote.compareTo(Message.STATUS_BROADCAST)==0){ messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_STATUS); - }else if (status.contains(Message.GROUP)){ + }else if (contactQuote.contains(Message.GROUP)){ - messageQuote.setRemoteId(status); + messageQuote.setRemoteId(contactQuote); boolean found = false; for (Chat cq : idToChat.values()) { //Search for the message in chat groups if(!cq.isGroupChat()) continue; - if(cq.getPrintId()!=null && status.contains(cq.getPrintId())) - messageQuote.setRemoteId(cq.getTitle()); + if(cq.getPrintId()!=null && contactQuote.contains(cq.getPrintId())) + messageQuote.setQuotePrivateGroupName(cq.getTitle()); for (Message mq : cq.getMessages()) { if (mq.getUuid() != null && mq.getUuid().compareTo(uuidQuote)==0) { From 21216e6161bef55a989a31d258ccb15a8f2012b9 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:56:32 -0300 Subject: [PATCH 50/58] speed up search --- .../main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index 164e8bb8ba..57cca0e100 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -584,6 +584,10 @@ private void extractMessages(Connection conn, Map idToChat) throws S //Find friendly group name for (Chat cq : idToChat.values()) { + + if(!cq.isGroupChat()) + continue; + if(cq.getPrintId()!=null && remoteId.contains(cq.getPrintId())){ mq.setQuotePrivateGroupName(cq.getTitle()); break; From 06901794272887ce29ac3e4ee760ef0eebf16188 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 29 Jul 2024 16:19:57 -0300 Subject: [PATCH 51/58] set privateGroupName even if not found ( maybe the chat group was deleted ) --- .../main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java | 1 + .../src/main/java/iped/parsers/whatsapp/ExtractorIOS.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index 57cca0e100..3fbec00564 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -581,6 +581,7 @@ private void extractMessages(Connection conn, Map idToChat) throws S mq.setId(fakeIds--); }else if (remoteId.contains(Message.GROUP)){ mq.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP); + mq.setQuotePrivateGroupName(remoteId); //Find friendly group name for (Chat cq : idToChat.values()) { diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java index a0da323857..4e0be306a6 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java @@ -592,8 +592,9 @@ private void findQuotedMessages(List messages, Map mes }else if (contactQuote.contains(Message.GROUP)){ messageQuote.setRemoteId(contactQuote); + messageQuote.setQuotePrivateGroupName(contactQuote); boolean found = false; - for (Chat cq : idToChat.values()) { //Search for the message in chat groups + for (Chat cq : idToChat.values()) { //Find friendly group name if(!cq.isGroupChat()) continue; From a8e49737198cf4a77f1d56028c76abf4e7def543 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Mon, 29 Jul 2024 18:42:48 -0300 Subject: [PATCH 52/58] fix chat owner for quote catalgo on iphone --- .../src/main/java/iped/parsers/whatsapp/ExtractorIOS.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java index 4e0be306a6..bbf1cc802c 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java @@ -571,8 +571,12 @@ private void findQuotedMessages(List messages, Map mes break; case 30: type = MessageType.PRODUCT_MESSAGE; - messageQuote.setProduct(decodeQuotedProductInfo(c, messageQuote)); + MessageProduct mp = decodeQuotedProductInfo(c, messageQuote); + messageQuote.setProduct(mp); messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_CATALOG); + messageQuote.setFromMe(false); + if (mp != null) + messageQuote.setRemoteResource(mp.getSeller()); break; default: break; @@ -591,8 +595,8 @@ private void findQuotedMessages(List messages, Map mes }else if (contactQuote.contains(Message.GROUP)){ - messageQuote.setRemoteId(contactQuote); messageQuote.setQuotePrivateGroupName(contactQuote); + messageQuote.setFromMe(true); boolean found = false; for (Chat cq : idToChat.values()) { //Find friendly group name From 54475e7643703e865552f62e4432f2d9c0af6f8e Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Tue, 30 Jul 2024 09:13:36 -0300 Subject: [PATCH 53/58] remove delete flag, fix quote private id in the groups, simplify logic --- .../parsers/whatsapp/ExtractorAndroidNew.java | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index 3fbec00564..cfcf95a09e 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -565,45 +565,44 @@ private void extractMessages(Connection conn, Map idToChat) throws S if (chatId == mq.getQuoteChatId()){// msgs In same chat long editId = mq.getEditId(); if (messagesMap.get(editId) != null){ // Quoted was edited - mq.setDeleted(false); mq.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); mq.setId(editId); - }else{ // Quoted message cannot be found again + }else{ // Quoted message cannot be found again ( maybe deleted or not in the DB) mq.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); mq.setId(fakeIds--); - mq.setDeleted(true); } - }else { //Exception, msgs not in the same chat + }else { // Msgs is quoted private group or quoted status + mq.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP_NOT_FOUND); // just set default case if does not match order cases ... + mq.setId(fakeIds--); String remoteId = mq.getRemoteId(); if (remoteId !=null){ if (remoteId.compareTo(Message.STATUS_BROADCAST)==0){ mq.setMessageQuotedType(MessageQuotedType.QUOTE_STATUS); - mq.setId(fakeIds--); }else if (remoteId.contains(Message.GROUP)){ - mq.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP); - mq.setQuotePrivateGroupName(remoteId); - - //Find friendly group name - for (Chat cq : idToChat.values()) { + mq.setQuotePrivateGroupName(remoteId); // set it first in case if not found + boolean found = false; + for (Chat cq : idToChat.values()) { // Find friendly group name and message Id if(!cq.isGroupChat()) continue; if(cq.getPrintId()!=null && remoteId.contains(cq.getPrintId())){ mq.setQuotePrivateGroupName(cq.getTitle()); - break; } + + for (Message ori : cq.getMessages()) { + if (ori.getUuid() != null && mq.getUuid()!= null && ori.getUuid().compareTo(mq.getUuid())==0) { + mq.setId(ori.getId()); + mq.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP); + found = true; + break; + } + } + if (found) + break; } - }else{ - mq.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); - mq.setId(fakeIds--); - mq.setDeleted(true); } - }else{ - mq.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP_NOT_FOUND); - mq.setId(fakeIds--); - mq.setDeleted(true); } } m.setMessageQuote(mq); From cfb13ded80bb19d57bdcab10a27c5bf1a91d8851 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Tue, 30 Jul 2024 09:14:33 -0300 Subject: [PATCH 54/58] remove delete flag, simplify logic, adjust message owner --- .../iped/parsers/whatsapp/ExtractorIOS.java | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java index bbf1cc802c..d4663e369d 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java @@ -589,16 +589,18 @@ private void findQuotedMessages(List messages, Map mes String contactQuote = ProtoBufDecoder.findString(main, 7); if (contactQuote!=null){ // find quotes outside this chat + messageQuote.setFromMe(!m.isFromMe()); // is the reverse of real msg + messageQuote.setRemoteResource(m.getRemoteResource()); // set remote resource if is no from me + messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP_NOT_FOUND); // just set default case if does not match order cases ... if (contactQuote.compareTo(Message.STATUS_BROADCAST)==0){ messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_STATUS); }else if (contactQuote.contains(Message.GROUP)){ - messageQuote.setQuotePrivateGroupName(contactQuote); - messageQuote.setFromMe(true); + messageQuote.setQuotePrivateGroupName(contactQuote);// set it first in case if not found boolean found = false; - for (Chat cq : idToChat.values()) { //Find friendly group name + for (Chat cq : idToChat.values()) { //Find friendly group name and message id if(!cq.isGroupChat()) continue; @@ -606,25 +608,19 @@ private void findQuotedMessages(List messages, Map mes if(cq.getPrintId()!=null && contactQuote.contains(cq.getPrintId())) messageQuote.setQuotePrivateGroupName(cq.getTitle()); - for (Message mq : cq.getMessages()) { - if (mq.getUuid() != null && mq.getUuid().compareTo(uuidQuote)==0) { - messageQuote.setId(mq.getId()); - found = true; + for (Message origin : cq.getMessages()) { + if (origin.getUuid() != null && origin.getUuid().compareTo(uuidQuote)==0) { + messageQuote.setId(origin.getId()); + messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP); + found = true; break; } } - if (found){ + if (found) break; - } } - if (found){ - messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP); - }else{ - messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP_NOT_FOUND); - messageQuote.setDeleted(true); - } } } } From 93e89d688796479d5a8a11ae88bb3685a82cc464 Mon Sep 17 00:00:00 2001 From: gfd2020 <59742865+gfd2020@users.noreply.github.com> Date: Tue, 30 Jul 2024 10:38:04 -0300 Subject: [PATCH 55/58] remove delete flag --- .../src/main/java/iped/parsers/whatsapp/ExtractorAndroid.java | 1 - 1 file changed, 1 deletion(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroid.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroid.java index c4c00069f2..7d8cb94984 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroid.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroid.java @@ -441,7 +441,6 @@ private List extractMessages(Connection conn, WAContact remote, boolean m.setMessageQuote(original); }else{// not found original message reference, get info from message_quotes table, less complete mq.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); - mq.setDeleted(true); mq.setId(fakeIds--); m.setMessageQuote(mq); } From 153b60a67c562c1c217a887379a426aa9d8c591f Mon Sep 17 00:00:00 2001 From: Hauck Date: Tue, 17 Sep 2024 19:23:51 -0300 Subject: [PATCH 56/58] Break audios larger than 30 minutes. --- .../transcript/AbstractTranscriptTask.java | 6 +- .../RemoteTranscriptionService.java | 72 +++++++++++++++---- 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java b/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java index 8c66a3c569..d3573f785d 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java @@ -218,6 +218,10 @@ public static TextAndScore transcribeWavBreaking(File tmpFile, String itemPath, } protected static Collection getAudioSplits(File inFile, String itemPath) { + return getAudioSplits(inFile, itemPath, MAX_WAV_TIME); + } + + protected static Collection getAudioSplits(File inFile, String itemPath, int max_wave_time) { List splitFiles = new ArrayList(); AudioInputStream aIn = null; AudioInputStream aOut = null; @@ -226,7 +230,7 @@ protected static Collection getAudioSplits(File inFile, String itemPath) { outFile.delete(); aIn = AudioSystem.getAudioInputStream(inFile); int bytesPerFrame = aIn.getFormat().getFrameSize(); - int framesPerPart = Math.round(aIn.getFormat().getFrameRate() * MAX_WAV_TIME); + int framesPerPart = Math.round(aIn.getFormat().getFrameRate() * max_wave_time); byte[] partBytes = new byte[framesPerPart * bytesPerFrame]; int numBytesRead = 0; int seq = 0; diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java index b1873d51d0..e6d99db766 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java @@ -38,7 +38,9 @@ import iped.utils.IOUtil; public class RemoteTranscriptionService { - + // 30 minutos + private static final int MAX_WAV_TIME = 30 * 60; + private static final int MAX_WAV_SIZE = 16000 * 2 * MAX_WAV_TIME; static enum MESSAGES { ACCEPTED, AUDIO_SIZE, @@ -364,6 +366,8 @@ public void run() { boolean error = false; OpenConnectons opc = null; String protocol = MESSAGES.VERSION_1_0.toString(); + ArrayList reqs = null; + try { client.setSoTimeout(CLIENT_TIMEOUT_MILLIS); bis = new BufferedInputStream(client.getInputStream()); @@ -475,22 +479,59 @@ public void run() { } long durationMillis = 1000 * wavFile.length() / (16000 * 2); - TextAndScore result=null; - long t2, t3; + TextAndScore result = new TextAndScore(); + result.text=""; + result.score=0; try { - TranscribeRequest req=new TranscribeRequest(wavFile); - synchronized (toTranscribe) { - toTranscribe.add(req); + reqs = new ArrayList(); + TranscribeRequest last=null; + if (wavFile.length() <= MAX_WAV_SIZE) { + TranscribeRequest req = new TranscribeRequest(wavFile); + reqs.add(req); + + } else { + + for (File wavPart : AbstractTranscriptTask.getAudioSplits(wavFile, + wavFile.getPath(), MAX_WAV_TIME)) { + TranscribeRequest req = new TranscribeRequest(wavPart); + reqs.add(req); + } + logger.info(prefix + "Audio breaked into {} parts", reqs.size()); + wavFile.delete(); + } - synchronized(req) { - req.wait(); + wavFile = null; + + // dispatch all parts to be executed + for (TranscribeRequest req : reqs) { + synchronized (toTranscribe) { + toTranscribe.add(req); + } + last=req; } - result=req.result; - if(result==null) { - error = false; - throw new Exception("Error processing the audio", req.error); + + // wait until the last wav part is transcribed + synchronized (last) { + last.wait(); } + + for (TranscribeRequest req : reqs) { + TextAndScore partResult = req.result; + if (partResult == null) { + error = false; + throw new Exception("Error processing the audio", req.error); + } + + if (result.score > 0) + result.text += " "; + result.text += partResult.text; + result.score += partResult.score; + result = req.result; + + } + result.score /= reqs.size(); + } catch (ProcessCrashedException e) { // retry audio error = true; @@ -538,6 +579,13 @@ public void run() { if (wavFile != null) { wavFile.delete(); } + if (reqs != null) { + for (TranscribeRequest req : reqs) { + if (req.wavAudio != null && req.wavAudio != wavFile) { + req.wavAudio.delete(); + } + } + } removeFrombeaconQueq(opc); } } From 3fd0bdac847aa500f65ebbf9b853068be75ff2af Mon Sep 17 00:00:00 2001 From: tc-wleite Date: Thu, 3 Oct 2024 19:22:47 -0300 Subject: [PATCH 57/58] '#2246: Apply project's code formatting. --- .../parsers/whatsapp/ExtractorAndroidNew.java | 51 +++++++++++-------- .../iped/parsers/whatsapp/ExtractorIOS.java | 35 +++++++------ 2 files changed, 50 insertions(+), 36 deletions(-) diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java index f2663f441c..a37f2609c6 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorAndroidNew.java @@ -551,47 +551,58 @@ private void extractMessages(Connection conn, Map idToChat) throws S // Find quote messages for (Message mq : messagesQuotes) { Message m = messagesMap.get(mq.getId()); - if (m != null) {// Has quote + if (m != null) { + // Has quote // Try to find original message in messages Message original = messagesMapUuid.get(mq.getUuid()); - if (original != null) {//has found original message reference + if (original != null) { + // Has found original message reference original.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); m.setMessageQuote(original); - } else if (mq.getProduct() != null){ // Quoted Catalog + } else if (mq.getProduct() != null) { + // Quoted Catalog mq.setMessageQuotedType(MessageQuotedType.QUOTE_CATALOG); mq.setId(fakeIds--); m.setMessageQuote(mq); - } else {// not found original message reference - if (chatId == mq.getQuoteChatId()){// msgs In same chat - long editId = mq.getEditId(); - if (messagesMap.get(editId) != null){ // Quoted was edited + } else { + // Original message reference not found + if (chatId == mq.getQuoteChatId()) { + // Message in same chat + long editId = mq.getEditId(); + if (messagesMap.get(editId) != null) { + // Quoted was edited mq.setMessageQuotedType(MessageQuotedType.QUOTE_FOUND); mq.setId(editId); - }else{ // Quoted message cannot be found again ( maybe deleted or not in the DB) + } else { + // Quoted message cannot be found again ( maybe deleted or not in the DB) mq.setMessageQuotedType(MessageQuotedType.QUOTE_NOT_FOUND); mq.setId(fakeIds--); } - }else { // Msgs is quoted private group or quoted status - mq.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP_NOT_FOUND); // just set default case if does not match order cases ... + } else { + // Message is quoted private group or quoted status + mq.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP_NOT_FOUND); + // Just set default case if does not match order cases ... mq.setId(fakeIds--); String remoteId = mq.getRemoteId(); - if (remoteId !=null){ - if (remoteId.compareTo(Message.STATUS_BROADCAST)==0){ + if (remoteId != null) { + if (remoteId.compareTo(Message.STATUS_BROADCAST) == 0) { mq.setMessageQuotedType(MessageQuotedType.QUOTE_STATUS); - }else if (remoteId.contains(Message.GROUP)){ - mq.setQuotePrivateGroupName(remoteId); // set it first in case if not found + } else if (remoteId.contains(Message.GROUP)) { + // Set it first in case if not found + mq.setQuotePrivateGroupName(remoteId); boolean found = false; - for (Chat cq : idToChat.values()) { // Find friendly group name and message Id - - if(!cq.isGroupChat()) + for (Chat cq : idToChat.values()) { + // Find friendly group name and message Id + if (!cq.isGroupChat()) continue; - if(cq.getPrintId()!=null && remoteId.contains(cq.getPrintId())){ + if (cq.getPrintId() != null && remoteId.contains(cq.getPrintId())) { mq.setQuotePrivateGroupName(cq.getTitle()); } for (Message ori : cq.getMessages()) { - if (ori.getUuid() != null && mq.getUuid()!= null && ori.getUuid().compareTo(mq.getUuid())==0) { + if (ori.getUuid() != null && mq.getUuid() != null + && ori.getUuid().compareTo(mq.getUuid()) == 0) { mq.setId(ori.getId()); mq.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP); found = true; @@ -604,7 +615,7 @@ private void extractMessages(Connection conn, Map idToChat) throws S } } - } + } m.setMessageQuote(mq); } m.setQuoted(true); diff --git a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java index d4663e369d..a5f8e6215d 100644 --- a/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java +++ b/iped-parsers/iped-parsers-impl/src/main/java/iped/parsers/whatsapp/ExtractorIOS.java @@ -587,40 +587,43 @@ private void findQuotedMessages(List messages, Map mes messageQuote.setMessageType(type); String contactQuote = ProtoBufDecoder.findString(main, 7); - if (contactQuote!=null){ // find quotes outside this chat - - messageQuote.setFromMe(!m.isFromMe()); // is the reverse of real msg - messageQuote.setRemoteResource(m.getRemoteResource()); // set remote resource if is no from me - messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP_NOT_FOUND); // just set default case if does not match order cases ... - if (contactQuote.compareTo(Message.STATUS_BROADCAST)==0){ + if (contactQuote != null) { + // find quotes outside this chat + // is the reverse of real msg + messageQuote.setFromMe(!m.isFromMe()); + // set remote resource if is not from me + messageQuote.setRemoteResource(m.getRemoteResource()); + // just set default case if does not match order cases ... + messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP_NOT_FOUND); + if (contactQuote.compareTo(Message.STATUS_BROADCAST) == 0) { messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_STATUS); - }else if (contactQuote.contains(Message.GROUP)){ + } else if (contactQuote.contains(Message.GROUP)) { - messageQuote.setQuotePrivateGroupName(contactQuote);// set it first in case if not found + // set it first in case if not found + messageQuote.setQuotePrivateGroupName(contactQuote); boolean found = false; - for (Chat cq : idToChat.values()) { //Find friendly group name and message id + for (Chat cq : idToChat.values()) { + // Find friendly group name and message id - if(!cq.isGroupChat()) + if (!cq.isGroupChat()) continue; - if(cq.getPrintId()!=null && contactQuote.contains(cq.getPrintId())) + if (cq.getPrintId() != null && contactQuote.contains(cq.getPrintId())) messageQuote.setQuotePrivateGroupName(cq.getTitle()); for (Message origin : cq.getMessages()) { - if (origin.getUuid() != null && origin.getUuid().compareTo(uuidQuote)==0) { + if (origin.getUuid() != null && origin.getUuid().compareTo(uuidQuote) == 0) { messageQuote.setId(origin.getId()); messageQuote.setMessageQuotedType(MessageQuotedType.QUOTE_PRIVACY_GROUP); - found = true; + found = true; break; } } - if (found) break; } - } } } @@ -1019,7 +1022,7 @@ private MessageProduct decodeQuotedProductInfo(Part p2, Message m) { seller = p3.getString(); } } - } + } if (title != null || currency != null || amount != 0 || seller != null) { return new MessageProduct(title, seller, currency, amount, observation); } From c51db60cb8287285a2a0141e10c7ab28169e2d97 Mon Sep 17 00:00:00 2001 From: Luis Nassif Date: Mon, 7 Oct 2024 21:27:28 -0300 Subject: [PATCH 58/58] '#1539: code formatting --- .../resources/scripts/tasks/WhisperProcess.py | 4 +- .../transcript/AbstractTranscriptTask.java | 16 ++-- .../RemoteTranscriptionService.java | 89 +++++++------------ .../transcript/WhisperTranscriptTask.java | 30 +++---- 4 files changed, 52 insertions(+), 87 deletions(-) diff --git a/iped-app/resources/scripts/tasks/WhisperProcess.py b/iped-app/resources/scripts/tasks/WhisperProcess.py index 6c669920b2..e31c9a1854 100644 --- a/iped-app/resources/scripts/tasks/WhisperProcess.py +++ b/iped-app/resources/scripts/tasks/WhisperProcess.py @@ -74,7 +74,7 @@ def main(): print(ping, file=stdout, flush=True) continue - files=line.split(",") + files = line.split(",") transcription = [] logprobs = [] for file in files: @@ -84,7 +84,7 @@ def main(): if whisperx_found: result = model.transcribe(files, batch_size=batch_size, language=language,wav=True) for segment in result['segments']: - idx=segment["audio"] + idx = segment["audio"] transcription[idx] += segment['text'] if 'avg_logprob' in segment: logprobs[idx].append(segment['avg_logprob']) diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java b/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java index d3573f785d..bbd2637ea7 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/AbstractTranscriptTask.java @@ -70,7 +70,7 @@ public abstract class AbstractTranscriptTask extends AbstractTask { private static final int MAX_WAV_SIZE = 16000 * 2 * MAX_WAV_TIME; protected AudioTranscriptConfig transcriptConfig; - + // Variables to store some statistics private static final AtomicLong wavTime = new AtomicLong(); private static final AtomicLong transcriptionTime = new AtomicLong(); @@ -91,8 +91,7 @@ public boolean isEnabled() { protected boolean isToProcess(IItem evidence) { - if (evidence.getLength() == null || evidence.getLength() == 0 || !evidence.isToAddToCase() - || evidence.getMetadata().get(ExtraProperties.TRANSCRIPT_ATTR) != null) { + if (evidence.getLength() == null || evidence.getLength() == 0 || !evidence.isToAddToCase() || evidence.getMetadata().get(ExtraProperties.TRANSCRIPT_ATTR) != null) { return false; } if (transcriptConfig.getSkipKnownFiles() && evidence.getExtraAttribute(HashDBLookupTask.STATUS_ATTRIBUTE) != null) { @@ -192,8 +191,7 @@ public void init(ConfigurationManager configurationManager) throws Exception { } - public static TextAndScore transcribeWavBreaking(File tmpFile, String itemPath, - Function transcribeWavPart) throws Exception { + public static TextAndScore transcribeWavBreaking(File tmpFile, String itemPath, Function transcribeWavPart) throws Exception { if (tmpFile.length() <= MAX_WAV_SIZE) { return transcribeWavPart.apply(tmpFile); } else { @@ -316,7 +314,7 @@ public void finish() throws Exception { conn.close(); conn = null; } - + long totWavConversions = wavSuccess.longValue() + wavFail.longValue(); if (totWavConversions != 0) { LOGGER.info("Total conversions to WAV: " + totWavConversions); @@ -340,8 +338,7 @@ public void finish() throws Exception { } } - protected File getTempFileToTranscript(IItem evidence, TemporaryResources tmp) - throws IOException, InterruptedException { + protected File getTempFileToTranscript(IItem evidence, TemporaryResources tmp) throws IOException, InterruptedException { long t = System.currentTimeMillis(); File tempWav = null; try { @@ -373,8 +370,7 @@ protected void process(IItem evidence) throws Exception { return; } - if (evidence.getMetadata().get(ExtraProperties.TRANSCRIPT_ATTR) != null - && evidence.getMetadata().get(ExtraProperties.CONFIDENCE_ATTR) != null) + if (evidence.getMetadata().get(ExtraProperties.TRANSCRIPT_ATTR) != null && evidence.getMetadata().get(ExtraProperties.CONFIDENCE_ATTR) != null) return; TextAndScore prevResult = getTextFromDb(evidence.getHash()); diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java index e6d99db766..f67a42fef5 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/RemoteTranscriptionService.java @@ -41,38 +41,28 @@ public class RemoteTranscriptionService { // 30 minutos private static final int MAX_WAV_TIME = 30 * 60; private static final int MAX_WAV_SIZE = 16000 * 2 * MAX_WAV_TIME; + static enum MESSAGES { - ACCEPTED, - AUDIO_SIZE, - BUSY, - DISCOVER, - DONE, - ERROR, - REGISTER, - STATS, - WARN, VERSION_1_1, - VERSION_1_2, - VERSION_1_0, - PING + ACCEPTED, AUDIO_SIZE, BUSY, DISCOVER, DONE, ERROR, REGISTER, STATS, WARN, VERSION_1_1, VERSION_1_2, VERSION_1_0, PING } + static class TranscribeRequest { File wavAudio; - TextAndScore result=null; - Exception error=null; - + TextAndScore result = null; + Exception error = null; public TranscribeRequest(File wavAudio) { - this.wavAudio=wavAudio; + this.wavAudio = wavAudio; } } + static class OpenConnectons { Socket conn; BufferedInputStream bis; PrintWriter writer; Thread t; File wavAudio; - TextAndScore result=null; - + TextAndScore result = null; public OpenConnectons(Socket conn, BufferedInputStream bis, PrintWriter writer, Thread t) { this.conn = conn; @@ -108,8 +98,8 @@ public void sendBeacon() { * Control number of simultaneous audio conversions to WAV. */ private static Semaphore wavConvSemaphore; - - private static int BATCH_SIZE=1; + + private static int BATCH_SIZE = 1; private static final AtomicLong audiosTranscripted = new AtomicLong(); private static final AtomicLong audiosDuration = new AtomicLong(); @@ -119,16 +109,11 @@ public void sendBeacon() { private static final AtomicLong requestsAccepted = new AtomicLong(); private static final List beaconQueq = new LinkedList<>(); private static final Deque toTranscribe = new LinkedList<>(); - private static Logger logger; private static void printHelpAndExit() { - System.out.println( - "Params: IP:Port [LocalPort]\n" - + "IP:Port IP and port of the naming node.\n" - + "LocalPort [optional] local port to listen for connections.\n" - + " If not provided, a random port will be used."); + System.out.println("Params: IP:Port [LocalPort]\n" + "IP:Port IP and port of the naming node.\n" + "LocalPort [optional] local port to listen for connections.\n" + " If not provided, a random port will be used."); System.exit(1); } @@ -169,7 +154,7 @@ public static void main(String[] args) throws Exception { AbstractTranscriptTask task = (AbstractTranscriptTask) Class.forName(audioConfig.getClassName()).getDeclaredConstructor().newInstance(); audioConfig.setEnabled(true); task.init(cm); - BATCH_SIZE=audioConfig.getBatchSize(); + BATCH_SIZE = audioConfig.getBatchSize(); int numConcurrentTranscriptions = Wav2Vec2TranscriptTask.getNumConcurrentTranscriptions(); int numLogicalCores = Runtime.getRuntime().availableProcessors(); @@ -195,10 +180,9 @@ public static void main(String[] args) throws Exception { startSendStatsThread(discoveryIp, discoveryPort, localPort, numConcurrentTranscriptions, numLogicalCores); startBeaconThread(); - for(int i=0;i(); - TranscribeRequest last=null; + TranscribeRequest last = null; if (wavFile.length() <= MAX_WAV_SIZE) { TranscribeRequest req = new TranscribeRequest(wavFile); reqs.add(req); } else { - for (File wavPart : AbstractTranscriptTask.getAudioSplits(wavFile, - wavFile.getPath(), MAX_WAV_TIME)) { + for (File wavPart : AbstractTranscriptTask.getAudioSplits(wavFile, wavFile.getPath(), MAX_WAV_TIME)) { TranscribeRequest req = new TranscribeRequest(wavPart); reqs.add(req); } @@ -501,15 +478,15 @@ public void run() { } wavFile = null; - + // dispatch all parts to be executed for (TranscribeRequest req : reqs) { synchronized (toTranscribe) { toTranscribe.add(req); } - last=req; + last = req; } - + // wait until the last wav part is transcribed synchronized (last) { last.wait(); @@ -521,7 +498,7 @@ public void run() { error = false; throw new Exception("Error processing the audio", req.error); } - + if (result.score > 0) result.text += " "; result.text += partResult.text; @@ -530,7 +507,6 @@ public void run() { } result.score /= reqs.size(); - } catch (ProcessCrashedException e) { // retry audio @@ -542,12 +518,12 @@ public void run() { executor.shutdown(); server.close(); throw e; - } + } audiosTranscripted.incrementAndGet(); audiosDuration.addAndGet(durationMillis); conversionTime.addAndGet(t1 - t0); - + logger.info(prefix + "Transcritpion done."); // removes from the beacon queue to prevent beacons in the middle of the @@ -617,7 +593,7 @@ public void run() { } }); } - + private static void startTrancribeThreads(AbstractTranscriptTask task) { executor.execute(new Runnable() { @Override @@ -628,12 +604,12 @@ public void run() { empty = toTranscribe.isEmpty(); } if (empty) { - try { + try { Thread.sleep(100); - + } catch (Exception e) { // TODO: handle exception - } + } continue; } try { @@ -646,10 +622,9 @@ public void run() { transcriptSemaphore.release(); } - } + } } }); } - } diff --git a/iped-engine/src/main/java/iped/engine/task/transcript/WhisperTranscriptTask.java b/iped-engine/src/main/java/iped/engine/task/transcript/WhisperTranscriptTask.java index f34893a203..aa519387d8 100644 --- a/iped-engine/src/main/java/iped/engine/task/transcript/WhisperTranscriptTask.java +++ b/iped-engine/src/main/java/iped/engine/task/transcript/WhisperTranscriptTask.java @@ -130,11 +130,11 @@ protected Server startServer0(int device) throws IOException { protected TextAndScore transcribeAudio(File tmpFile) throws Exception { return transcribeWavPart(tmpFile); } - + protected List transcribeAudios(ArrayList tmpFiles) throws Exception { ArrayList textAndScores = new ArrayList<>(); - for(int i=0;i transcribeAudios(ArrayList tmpFiles) throws E } StringBuilder filePaths = new StringBuilder(); - for(int i=0;i0) { - filePaths.append(","); - } + for (int i = 0; i < tmpFiles.size(); i++) { + if (i > 0) { + filePaths.append(","); + } filePaths.append(tmpFiles.get(i).getAbsolutePath().replace('\\', '/')); - - } + + } server.process.getOutputStream().write(filePaths.toString().getBytes("UTF-8")); server.process.getOutputStream().write(NEW_LINE); server.process.getOutputStream().flush(); @@ -165,10 +165,10 @@ protected List transcribeAudios(ArrayList tmpFiles) throws E throw new RuntimeException("Transcription failed, returned: " + line); } } - for(int i=0;i transcribeAudios(ArrayList tmpFiles) throws E return textAndScores; } - - @Override protected void logInputStream(InputStream is) { - List ignoreMsgs = Arrays.asList( - "With dispatcher enabled, this function is no-op. You can remove the function call.", - "torchvision is not available - cannot save figures", - "Lightning automatically upgraded your loaded checkpoint from", - "Model was trained with pyannote.audio 0.0.1, yours is", - "Model was trained with torch 1.10.0+cu102, yours is"); + List ignoreMsgs = Arrays.asList("With dispatcher enabled, this function is no-op. You can remove the function call.", "torchvision is not available - cannot save figures", + "Lightning automatically upgraded your loaded checkpoint from", "Model was trained with pyannote.audio 0.0.1, yours is", "Model was trained with torch 1.10.0+cu102, yours is"); Thread t = new Thread() { public void run() { byte[] buf = new byte[1024];