From 04570ce22aa2777be76b2be1c485b6886f0e1d3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Plo=C3=9F?= Date: Sun, 30 Oct 2022 22:05:13 +0100 Subject: [PATCH] fix session migration and assign message history to correct sessions --- app/store/db.go | 7 +- app/store/message.go | 9 +-- app/store/migrations.go | 138 ++++++++++++++++++++++++++++++++++++++++ app/store/sessionV2.go | 4 +- go.mod | 2 + go.sum | 4 ++ 6 files changed, 156 insertions(+), 8 deletions(-) diff --git a/app/store/db.go b/app/store/db.go index 0b98c1342..17fcc1baf 100644 --- a/app/store/db.go +++ b/app/store/db.go @@ -39,7 +39,7 @@ var ( sessionsSelect = "SELECT * FROM sessions ORDER BY timestamp DESC" - messagesSchema = "CREATE TABLE IF NOT EXISTS messages (id INTEGER PRIMARY KEY, sid integer, source text, srcUUID string NOT NULL DEFAULT 0, message text, outgoing boolean, sentat integer, receivedat integer, ctype integer, attachment string, issent boolean, isread boolean, flags integer default 0, sendingError boolean, expireTimer integer default 0, receipt boolean default 0, statusMessage boolean default 0, quoteId integer NOT NULL default -1)" + messagesSchema = "CREATE TABLE IF NOT EXISTS messages (id INTEGER PRIMARY KEY, sv2id integer, source text, srcUUID string NOT NULL DEFAULT 0, message text, outgoing boolean, sentat integer, receivedat integer, ctype integer, attachment string, issent boolean, isread boolean, flags integer default 0, sendingError boolean, expireTimer integer default 0, receipt boolean default 0, statusMessage boolean default 0, quoteId integer NOT NULL default -1)" messagesInsert = "INSERT INTO messages (sid, source, srcUUID, message, outgoing, sentat, receivedat, ctype, attachment, issent, isread, flags, sendingError, expireTimer, statusMessage, quoteID) VALUES (:sid, :source, :srcUUID, :message, :outgoing, :sentat, :receivedat, :ctype, :attachment, :issent, :isread, :flags, :sendingError, :expireTimer, :statusMessage, :quoteId)" messagesSelectWhereMore = "SELECT * FROM messages WHERE sid = ? AND sentat < ? ORDER BY sentat DESC LIMIT 20" @@ -306,5 +306,10 @@ func Migrate() error { log.Errorln("[axolotl] setupDb: Couldn't migrate db: " + err.Error()) return err } + err = update_v_1_6_1() + if err != nil { + log.Errorln("[axolotl] Couldn't migrate sessions: " + err.Error()) + return err + } return nil } diff --git a/app/store/message.go b/app/store/message.go index 0fe6d34af..79ca66f42 100644 --- a/app/store/message.go +++ b/app/store/message.go @@ -11,11 +11,12 @@ import ( log "github.com/sirupsen/logrus" ) -const getLastMessagesQuery = "SELECT *, max(sentat) FROM messages GROUP BY sid ORDER BY sentat DESC" +const getLastMessagesQuery = "SELECT *, max(sentat) FROM messages GROUP BY sv2id ORDER BY sentat DESC" type Message struct { - ID int64 `db:"id"` - SID int64 + ID int64 `db:"id"` + SID int64 `db:"sv2id"` + SV1ID *int64 `db:"sid"` ChatID string Source string `db:"source"` SourceUUID string `db:"srcUUID"` @@ -181,7 +182,7 @@ func GetLastMessagesForAllSessions() ([]Message, error) { func getMessagesForSession(id int64, limit, offset int) ([]*Message, error) { var messages = []*Message{} - err := DS.Dbx.Select(&messages, "SELECT * FROM messages WHERE sid = ? ORDER BY sentat DESC LIMIT ? OFFSET ?", id, limit, offset) + err := DS.Dbx.Select(&messages, "SELECT * FROM messages WHERE sv2id = ? ORDER BY sentat DESC LIMIT ? OFFSET ?", id, limit, offset) if err != nil { return nil, err } diff --git a/app/store/migrations.go b/app/store/migrations.go index cfe264dc2..d5ccc1c29 100644 --- a/app/store/migrations.go +++ b/app/store/migrations.go @@ -243,3 +243,141 @@ func update_v_1_6_0() error { } return nil } + +// update_v_1_6_1 fixes the message histroy by introducing the new column sv2id in messages +func update_v_1_6_1() error { + err := sessionsV1toSessionsV2() + if err != nil { + return err + } + return migrateMessageIds() +} + +func migrateMessageIds() error { + // check if new column exists and only migrate if it does not + _, err := DS.Dbx.Prepare("SELECT sv2id FROM messages limit 1") + if err == nil { + return nil + } + log.Infoln("[axolotl][update v_1_6_1] add column sv2id") + _, err = DS.Dbx.Exec("ALTER TABLE messages ADD sv2id integer;") + if err != nil { + return err + } + + log.Infoln("[axolotl][update v_1_6_1] set sv2id for group messages") + _, err = DS.Dbx.Exec("UPDATE messages SET sV2id = (SELECT v2.ID from sessions v1 JOIN sessionsv2 v2 ON v1.uuid = v2.groupV2Id where v1.ID = messages.sid) WHERE sv2id IS null;") + if err != nil { + return err + } + log.Infoln("[axolotl][update v_1_6_1] set sv2id for direct messages") + _, err = DS.Dbx.Exec("UPDATE messages SET sv2id = (SELECT ID from sessionsv2 WHERE directMessageRecipientId = (SELECT r.id from recipients r JOIN sessions v1 ON r.uuid = v1.uuid WHERE v1.id = messages.sid)) WHERE sv2id IS null;") + if err != nil { + return err + } + log.Infoln("[axolotl][update v_1_6_1] set sv2id for messages of newly created sessions") + _, err = DS.Dbx.Exec("UPDATE messages SET sV2id = sid WHERE sv2id IS null;") + return err +} + +func sessionV1ToGroupV2(session *Session) error { + group, err := GroupV2sModel.GetGroupById(session.UUID) + if group != nil && err == nil { + //allready migrated + return nil + } + log.Infoln("[axolotl][update v_1_6_1] migrate groupv2 session") + + group, err = GroupV2sModel.Create(&GroupV2{ + Id: session.UUID, + Name: session.Name, + JoinStatus: session.GroupJoinStatus, + }) + if err != nil { + return fmt.Errorf("error creating group v2: %s", err) + } + _, err = SessionsV2Model.SaveSession(&SessionV2{ + ID: session.ID, + DirectMessageRecipientID: int64(GroupRecipientsID), + GroupV2ID: session.UUID, + }) + if err != nil { + return fmt.Errorf("error creating session groupv2: %s", err) + } + log.Infoln("[axolotl][update v_1_6_1] migrate groupv2 session: members") + groupMembers, err := textsecure.GetGroupV2MembersForGroup(session.UUID) + if err != nil { + return fmt.Errorf("[axolotl][update v_1_6_1] error getting group members: %s", err) + } + err = group.AddGroupMembers(groupMembers) + if err != nil { + return fmt.Errorf("[axolotl][update v_1_6_1] error adding group members: %s", err) + } + return nil +} + +func sessionV1ToSessionV2(session *Session) error { + if session.IsGroup && session.Type == SessionTypeGroupV2 { + err := sessionV1ToGroupV2(session) + if err != nil { + return err + } + } else if session.IsGroup && session.Type == SessionTypeGroupV1 { + sessionV2, err := SessionsV2Model.GetSessionByID(session.ID) + if sessionV2 != nil && err == nil { + //allready migrated + return nil + } + log.Infoln("[axolotl][update v_1_6_1] migrate groupv1 session") + _, err = SessionsV2Model.SaveSession(&SessionV2{ + ID: session.ID, + GroupV1ID: session.UUID, + DirectMessageRecipientID: int64(GroupRecipientsID), + }) + if err != nil { + return err + } + } else if session.Type == SessionTypePrivateChat { + sessionV2, err := SessionsV2Model.GetSessionByID(session.ID) + if sessionV2 != nil && err == nil { + //allready migrated + return nil + } + recipient := RecipientsModel.GetRecipientByUUID(session.UUID) + log.Infoln("[axolotl][update v_1_6_1] migrate private chat session") + if recipient == nil { + recipient, err = RecipientsModel.CreateRecipientWithoutProfileUpdate(&Recipient{ + UUID: session.UUID, + ProfileGivenName: session.Name, + E164: session.Tel, + }) + if err != nil { + return err + } + } + _, err = SessionsV2Model.SaveSession(&SessionV2{ + ID: session.ID, + DirectMessageRecipientID: recipient.Id, + }) + if err != nil { + return err + } + } + return nil +} + +func sessionsV1toSessionsV2() error { + var sessions []*Session + err := DS.Dbx.Select(&sessions, sessionsSelect) + if err != nil { + return fmt.Errorf("error loading sessions: %s", err) + } + log.Infoln("[axolotl][update v_1_6_1] migrate sessionsv1 to sessionsv2") + for _, session := range sessions { + err = sessionV1ToSessionV2(session) + if err != nil { + log.Errorf("failed to migrate session %s. Error: %s", session.UUID, err) + } + } + return nil +} diff --git a/app/store/sessionV2.go b/app/store/sessionV2.go index 015663add..87ad5ce05 100644 --- a/app/store/sessionV2.go +++ b/app/store/sessionV2.go @@ -324,10 +324,8 @@ func (s *SessionV2) NotificationsToggle() error { func (s *SessionV2) GetName() (string, error) { if s.IsGroup() { return s.getGroupName() - } else { - return s.getDirectChatName() } - return "", fmt.Errorf("GetSessionNames failed") + return s.getDirectChatName() } func (s *SessionV2) getDirectChatName() (string, error) { diff --git a/go.mod b/go.mod index 8f95e88f5..e8b0730d8 100644 --- a/go.mod +++ b/go.mod @@ -31,3 +31,5 @@ require ( gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect launchpad.net/gocheck v0.0.0-20140225173054-000000000087 // indirect ) + +replace github.com/signal-golang/textsecure v1.18.0 => github.com/Blackoverflow/textsecure v1.4.3-0.20221029211627-ba3c0a915b70 diff --git a/go.sum b/go.sum index 9c4d6d8f2..ffa2a44f3 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/Blackoverflow/gcmsiv v0.0.0-20201031155123-20af2af977ff h1:l3WopnX/gWnDItXZdr2Ygq0+4ZwXCSyozyPNR8jdb8I= github.com/Blackoverflow/gcmsiv v0.0.0-20201031155123-20af2af977ff/go.mod h1:t1lmwOv+IYxaUkr2qIKXEfn90t4GgocS0qy8jkDonbg= +github.com/Blackoverflow/textsecure v1.4.3-0.20221028183342-5dd575a18460 h1:ZPUbXWULhddzbWI9AnpKdbKGY317FatHsAyTQzJg3Xs= +github.com/Blackoverflow/textsecure v1.4.3-0.20221028183342-5dd575a18460/go.mod h1:sna5yQxNwY/F54q/K4xxP90VgWMSBgm3L8zbWOkF2mk= +github.com/Blackoverflow/textsecure v1.4.3-0.20221029211627-ba3c0a915b70 h1:uAVKek9XGhmBDU9FHs41IlY3GfJRtBaEuFcspouhLts= +github.com/Blackoverflow/textsecure v1.4.3-0.20221029211627-ba3c0a915b70/go.mod h1:sna5yQxNwY/F54q/K4xxP90VgWMSBgm3L8zbWOkF2mk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw=